summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityManager.java4
-rw-r--r--core/java/android/app/ActivityManagerNative.java10
-rw-r--r--core/java/android/app/ActivityOptions.java45
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--core/java/android/app/AlarmManager.java23
-rw-r--r--core/java/android/app/AppOpsManager.java43
-rw-r--r--core/java/android/app/AssistContent.java37
-rw-r--r--core/java/android/app/AssistStructure.java190
-rw-r--r--core/java/android/app/BackStackRecord.java102
-rw-r--r--core/java/android/app/BroadcastOptions.java85
-rw-r--r--core/java/android/app/ContextImpl.java90
-rw-r--r--core/java/android/app/DownloadManager.java2
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/Notification.java13
-rw-r--r--core/java/android/app/PendingIntent.java72
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java36
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java7
-rw-r--r--core/java/android/bluetooth/BluetoothActivityEnergyInfo.java40
-rw-r--r--core/java/android/content/ContentProvider.java10
-rw-r--r--core/java/android/content/ContentProviderClient.java103
-rw-r--r--core/java/android/content/Context.java91
-rw-r--r--core/java/android/content/ContextWrapper.java20
-rw-r--r--core/java/android/content/IIntentSender.aidl3
-rw-r--r--core/java/android/content/IntentFilter.java2
-rw-r--r--core/java/android/content/IntentSender.java2
-rw-r--r--core/java/android/content/pm/PackageParser.java21
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java135
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java24
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java32
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java2
-rw-r--r--core/java/android/hardware/camera2/legacy/RequestThreadManager.java14
-rw-r--r--core/java/android/hardware/camera2/utils/CameraBinderDecorator.java4
-rw-r--r--core/java/android/net/ConnectivityManager.java52
-rw-r--r--core/java/android/net/IConnectivityManager.aidl6
-rw-r--r--core/java/android/net/Network.java3
-rw-r--r--core/java/android/net/NetworkInfo.java23
-rw-r--r--core/java/android/net/NetworkPolicyManager.java11
-rw-r--r--core/java/android/net/TrafficStats.java2
-rw-r--r--core/java/android/os/BatteryStats.java20
-rw-r--r--core/java/android/os/INetworkManagementService.aidl4
-rw-r--r--core/java/android/os/PowerManager.java26
-rw-r--r--core/java/android/os/UserManager.java12
-rw-r--r--core/java/android/os/storage/DiskInfo.java2
-rw-r--r--core/java/android/os/storage/IMountServiceListener.java26
-rw-r--r--core/java/android/os/storage/StorageEventListener.java3
-rw-r--r--core/java/android/os/storage/StorageManager.java12
-rw-r--r--core/java/android/os/storage/VolumeInfo.java2
-rw-r--r--core/java/android/provider/Browser.java264
-rw-r--r--core/java/android/provider/DocumentsContract.java5
-rw-r--r--core/java/android/provider/Settings.java68
-rw-r--r--core/java/android/security/keymaster/KeymasterDefs.java1
-rw-r--r--core/java/android/security/keymaster/OperationResult.java13
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java4
-rw-r--r--core/java/android/speech/srec/MicrophoneInputStream.java110
-rw-r--r--core/java/android/speech/srec/Recognizer.java716
-rw-r--r--core/java/android/speech/srec/UlawEncoderInputStream.java187
-rw-r--r--core/java/android/speech/srec/WaveHeader.java276
-rw-r--r--core/java/android/speech/srec/package.html6
-rw-r--r--core/java/android/speech/tts/UtteranceProgressListener.java12
-rw-r--r--core/java/android/text/format/Formatter.java64
-rw-r--r--core/java/android/text/style/TtsSpan.java2
-rw-r--r--core/java/android/transition/Explode.java4
-rw-r--r--core/java/android/transition/Slide.java4
-rw-r--r--core/java/android/transition/TranslationAnimationCreator.java32
-rw-r--r--core/java/android/transition/Visibility.java2
-rw-r--r--core/java/android/util/TimeUtils.java86
-rw-r--r--core/java/android/view/View.java29
-rw-r--r--core/java/android/view/ViewGroup.java6
-rw-r--r--core/java/android/view/ViewPropertyAnimator.java15
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/view/ViewStructure.java11
-rw-r--r--core/java/android/view/accessibility/CaptioningManager.java19
-rw-r--r--core/java/android/view/textservice/SpellCheckerSession.java168
-rw-r--r--core/java/android/widget/AbsListView.java11
-rw-r--r--core/java/android/widget/Editor.java149
-rw-r--r--core/java/android/widget/ImageView.java11
-rw-r--r--core/java/android/widget/RelativeLayout.java18
-rw-r--r--core/java/android/widget/TextView.java92
-rw-r--r--core/java/android/widget/Toolbar.java92
79 files changed, 1801 insertions, 2151 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index da345a6..b65593d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2812,7 +2812,9 @@ public class ActivityManager {
* continues running even if the process is killed and restarted. To remove the watch,
* use {@link #clearWatchHeapLimit()}.
*
- * <p>This API only work if running on a debuggable (userdebug or eng) build.</p>
+ * <p>This API only work if the calling process has been marked as
+ * {@link ApplicationInfo#FLAG_DEBUGGABLE} or this is running on a debuggable
+ * (userdebug or eng) build.</p>
*
* <p>Callers can optionally implement {@link #ACTION_REPORT_HEAP_LIMIT} to directly
* handle heap limit reports themselves.</p>
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6ae21eb..680feae 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -108,7 +108,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
try {
getDefault().broadcastIntent(
null, intent, null, null, Activity.RESULT_OK, null, null,
- null /*permission*/, appOp, false, true, userId);
+ null /*permission*/, appOp, null, false, true, userId);
} catch (RemoteException ex) {
}
}
@@ -458,12 +458,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
Bundle resultExtras = data.readBundle();
String perm = data.readString();
int appOp = data.readInt();
+ Bundle options = data.readBundle();
boolean serialized = data.readInt() != 0;
boolean sticky = data.readInt() != 0;
int userId = data.readInt();
int res = broadcastIntent(app, intent, resolvedType, resultTo,
resultCode, resultData, resultExtras, perm, appOp,
- serialized, sticky, userId);
+ options, serialized, sticky, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
@@ -2991,9 +2992,9 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
public int broadcastIntent(IApplicationThread caller,
- Intent intent, String resolvedType, IIntentReceiver resultTo,
+ Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
- String requiredPermission, int appOp, boolean serialized,
+ String requiredPermission, int appOp, Bundle options, boolean serialized,
boolean sticky, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -3008,6 +3009,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeBundle(map);
data.writeString(requiredPermission);
data.writeInt(appOp);
+ data.writeBundle(options);
data.writeInt(serialized ? 1 : 0);
data.writeInt(sticky ? 1 : 0);
data.writeInt(userId);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 6fb997e..2406985 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -43,7 +43,7 @@ public class ActivityOptions {
* A long in the extras delivered by {@link #requestUsageTimeReport} that contains
* the total time (in ms) the user spent in the app flow.
*/
- public static final String EXTRA_USAGE_TIME_REPORT = "android.usage_time";
+ public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
/**
* A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
@@ -56,67 +56,67 @@ public class ActivityOptions {
* The package name that created the options.
* @hide
*/
- public static final String KEY_PACKAGE_NAME = "android:packageName";
+ public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
/**
* Type of animation that arguments specify.
* @hide
*/
- public static final String KEY_ANIM_TYPE = "android:animType";
+ public static final String KEY_ANIM_TYPE = "android:activity.animType";
/**
* Custom enter animation resource ID.
* @hide
*/
- public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes";
+ public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
/**
* Custom exit animation resource ID.
* @hide
*/
- public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";
+ public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
/**
* Custom in-place animation resource ID.
* @hide
*/
- public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:animInPlaceRes";
+ public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
/**
* Bitmap for thumbnail animation.
* @hide
*/
- public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail";
+ public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
/**
* Start X position of thumbnail animation.
* @hide
*/
- public static final String KEY_ANIM_START_X = "android:animStartX";
+ public static final String KEY_ANIM_START_X = "android:activity.animStartX";
/**
* Start Y position of thumbnail animation.
* @hide
*/
- public static final String KEY_ANIM_START_Y = "android:animStartY";
+ public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
/**
* Initial width of the animation.
* @hide
*/
- public static final String KEY_ANIM_WIDTH = "android:animWidth";
+ public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
/**
* Initial height of the animation.
* @hide
*/
- public static final String KEY_ANIM_HEIGHT = "android:animHeight";
+ public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
/**
* Callback for when animation is started.
* @hide
*/
- public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
+ public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
/**
* For Activity transitions, the calling Activity's TransitionListener used to
@@ -124,15 +124,18 @@ public class ActivityOptions {
* complete.
*/
private static final String KEY_TRANSITION_COMPLETE_LISTENER
- = "android:transitionCompleteListener";
-
- private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning";
- private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames";
- private static final String KEY_RESULT_DATA = "android:resultData";
- private static final String KEY_RESULT_CODE = "android:resultCode";
- private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex";
-
- private static final String KEY_USAGE_TIME_REPORT = "android:usageTimeReport";
+ = "android:activity.transitionCompleteListener";
+
+ private static final String KEY_TRANSITION_IS_RETURNING
+ = "android:activity.transitionIsReturning";
+ private static final String KEY_TRANSITION_SHARED_ELEMENTS
+ = "android:activity.sharedElementNames";
+ private static final String KEY_RESULT_DATA = "android:activity.resultData";
+ private static final String KEY_RESULT_CODE = "android:activity.resultCode";
+ private static final String KEY_EXIT_COORDINATOR_INDEX
+ = "android:activity.exitCoordinatorIndex";
+
+ private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
/** @hide */
public static final int ANIM_NONE = 0;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e21c04a..828dc0a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5375,6 +5375,7 @@ public final class ActivityThread {
}
public static void main(String[] args) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
@@ -5409,6 +5410,8 @@ public final class ActivityThread {
LogPrinter(Log.DEBUG, "ActivityThread"));
}
+ // End of event ActivityThreadMain.
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 5e7bd0d..9ea1606 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -142,13 +142,22 @@ public class AlarmManager {
public static final int FLAG_ALLOW_WHILE_IDLE = 1<<2;
/**
+ * Flag for alarms: same as {@link #FLAG_ALLOW_WHILE_IDLE}, but doesn't have restrictions
+ * on how frequently it can be scheduled. Only available (and automatically applied) to
+ * system alarms.
+ *
+ * @hide
+ */
+ public static final int FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED = 1<<3;
+
+ /**
* Flag for alarms: this alarm marks the point where we would like to come out of idle
* mode. It may be moved by the alarm manager to match the first wake-from-idle alarm.
* Scheduling an alarm with this flag puts the alarm manager in to idle mode, where it
* avoids scheduling any further alarms until the marker alarm is executed.
* @hide
*/
- public static final int FLAG_IDLE_UNTIL = 1<<3;
+ public static final int FLAG_IDLE_UNTIL = 1<<4;
private final IAlarmManager mService;
private final boolean mAlwaysExact;
@@ -565,6 +574,12 @@ public class AlarmManager {
* of the device when idle (and thus cause significant battery blame to the app scheduling
* them), so they should be used with care.
*
+ * <p>To reduce abuse, there are restrictions on how frequently these alarms will go off
+ * for a particular application. Under normal system operation, it will not dispatch these
+ * alarms more than about every minute (at which point every such pending alarm is
+ * dispatched); when in low-power idle modes this duration may be significantly longer,
+ * such as 15 minutes.</p>
+ *
* <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
* out of order with any other alarms, even those from the same app. This will clearly happen
* when the device is idle (since this alarm can go off while idle, when any other alarms
@@ -608,6 +623,12 @@ public class AlarmManager {
* of the device when idle (and thus cause significant battery blame to the app scheduling
* them), so they should be used with care.
*
+ * <p>To reduce abuse, there are restrictions on how frequently these alarms will go off
+ * for a particular application. Under normal system operation, it will not dispatch these
+ * alarms more than about every minute (at which point every such pending alarm is
+ * dispatched); when in low-power idle modes this duration may be significantly longer,
+ * such as 15 minutes.</p>
+ *
* <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
* out of order with any other alarms, even those from the same app. This will clearly happen
* when the device is idle (since this alarm can go off while idle, when any other alarms
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e728971..8a61ec6 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -250,64 +250,64 @@ public class AppOpsManager {
@SystemApi
public static final String OPSTR_ACTIVATE_VPN
= "android:activate_vpn";
- /** @hide Allows an application to read the user's contacts data. */
+ /** Allows an application to read the user's contacts data. */
public static final String OPSTR_READ_CONTACTS
= "android:read_contacts";
- /** @hide Allows an application to write to the user's contacts data. */
+ /** Allows an application to write to the user's contacts data. */
public static final String OPSTR_WRITE_CONTACTS
= "android:write_contacts";
- /** @hide Allows an application to read the user's call log. */
+ /** Allows an application to read the user's call log. */
public static final String OPSTR_READ_CALL_LOG
= "android:read_call_log";
- /** @hide Allows an application to write to the user's call log. */
+ /** Allows an application to write to the user's call log. */
public static final String OPSTR_WRITE_CALL_LOG
= "android:write_call_log";
- /** @hide Allows an application to read the user's calendar data. */
+ /** Allows an application to read the user's calendar data. */
public static final String OPSTR_READ_CALENDAR
= "android:read_calendar";
- /** @hide Allows an application to write to the user's calendar data. */
+ /** Allows an application to write to the user's calendar data. */
public static final String OPSTR_WRITE_CALENDAR
= "android:write_calendar";
- /** @hide Allows an application to initiate a phone call. */
+ /** Allows an application to initiate a phone call. */
public static final String OPSTR_CALL_PHONE
= "android:call_phone";
- /** @hide Allows an application to read SMS messages. */
+ /** Allows an application to read SMS messages. */
public static final String OPSTR_READ_SMS
= "android:read_sms";
- /** @hide Allows an application to receive SMS messages. */
+ /** Allows an application to receive SMS messages. */
public static final String OPSTR_RECEIVE_SMS
= "android:receive_sms";
- /** @hide Allows an application to receive MMS messages. */
+ /** Allows an application to receive MMS messages. */
public static final String OPSTR_RECEIVE_MMS
= "android:receive_mms";
- /** @hide Allows an application to receive WAP push messages. */
+ /** Allows an application to receive WAP push messages. */
public static final String OPSTR_RECEIVE_WAP_PUSH
= "android:receive_wap_push";
- /** @hide Allows an application to send SMS messages. */
+ /** Allows an application to send SMS messages. */
public static final String OPSTR_SEND_SMS
= "android:send_sms";
- /** @hide Required to be able to access the camera device. */
+ /** Required to be able to access the camera device. */
public static final String OPSTR_CAMERA
= "android:camera";
- /** @hide Required to be able to access the microphone device. */
+ /** Required to be able to access the microphone device. */
public static final String OPSTR_RECORD_AUDIO
= "android:record_audio";
- /** @hide Required to access phone state related information. */
+ /** Required to access phone state related information. */
public static final String OPSTR_READ_PHONE_STATE
= "android:read_phone_state";
- /** @hide Required to access phone state related information. */
+ /** Required to access phone state related information. */
public static final String OPSTR_ADD_VOICEMAIL
= "android:add_voicemail";
- /** @hide Access APIs for SIP calling over VOIP or WiFi */
+ /** Access APIs for SIP calling over VOIP or WiFi */
public static final String OPSTR_USE_SIP
= "android:use_sip";
- /** @hide Use the fingerprint API. */
+ /** Use the fingerprint API. */
public static final String OPSTR_USE_FINGERPRINT
= "android:use_fingerprint";
- /** @hide Access to body sensors such as heart rate, etc. */
+ /** Access to body sensors such as heart rate, etc. */
public static final String OPSTR_BODY_SENSORS
= "android:body_sensors";
- /** @hide Read previously received cell broadcast messages. */
+ /** Read previously received cell broadcast messages. */
public static final String OPSTR_READ_CELL_BROADCASTS
= "android:read_cell_broadcasts";
/** Inject mock location into the system. */
@@ -1217,10 +1217,7 @@ public class AppOpsManager {
*
* @param permission The permission.
* @return The app op associated with the permission or null.
- *
- * @hide
*/
- @SystemApi
public static String permissionToOp(String permission) {
final Integer opCode = sPermToOp.get(permission);
if (opCode == null) {
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
index 173b237..ad2ba39 100644
--- a/core/java/android/app/AssistContent.java
+++ b/core/java/android/app/AssistContent.java
@@ -33,8 +33,10 @@ import android.os.Parcelable;
public class AssistContent {
private boolean mIsAppProvidedIntent = false;
private Intent mIntent;
+ private String mStructuredData;
private ClipData mClipData;
private Uri mUri;
+ private final Bundle mExtras;
/**
* @hide
@@ -53,6 +55,7 @@ public class AssistContent {
}
public AssistContent() {
+ mExtras = new Bundle();
}
/**
@@ -123,6 +126,22 @@ public class AssistContent {
}
/**
+ * Sets optional structured data regarding the content being viewed. The provided data
+ * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
+ * <a href="http://schema.org/">schema.org</a> vocabulary.
+ */
+ public void setStructuredData(String structuredData) {
+ mStructuredData = structuredData;
+ }
+
+ /**
+ * Returns the current {@link #setStructuredData}.
+ */
+ public String getStructuredData() {
+ return mStructuredData;
+ }
+
+ /**
* Set a web URI associated with the current data being shown to the user.
* This URI could be opened in a web browser, or in the app as an
* {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
@@ -143,6 +162,13 @@ public class AssistContent {
return mUri;
}
+ /**
+ * Return Bundle for extra vendor-specific data that can be modified and examined.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
/** @hide */
public AssistContent(Parcel in) {
if (in.readInt() != 0) {
@@ -154,7 +180,11 @@ public class AssistContent {
if (in.readInt() != 0) {
mUri = Uri.CREATOR.createFromParcel(in);
}
+ if (in.readInt() != 0) {
+ mStructuredData = in.readString();
+ }
mIsAppProvidedIntent = in.readInt() == 1;
+ mExtras = in.readBundle();
}
/** @hide */
@@ -177,6 +207,13 @@ public class AssistContent {
} else {
dest.writeInt(0);
}
+ if (mStructuredData != null) {
+ dest.writeInt(1);
+ dest.writeString(mStructuredData);
+ } else {
+ dest.writeInt(0);
+ }
dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
+ dest.writeBundle(mExtras);
}
}
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index 0f69817..7f6dae5 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -131,6 +131,7 @@ public class AssistStructure {
final int mWidth;
final int mHeight;
final CharSequence mTitle;
+ final int mDisplayId;
final ViewNode mRoot;
WindowNode(AssistStructure assist, ViewRootImpl root) {
@@ -142,6 +143,7 @@ public class AssistStructure {
mWidth = rect.width();
mHeight = rect.height();
mTitle = root.getTitle();
+ mDisplayId = root.getDisplayId();
mRoot = new ViewNode();
ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false);
if ((root.getWindowFlags()&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
@@ -160,6 +162,7 @@ public class AssistStructure {
mWidth = in.readInt();
mHeight = in.readInt();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mDisplayId = in.readInt();
mRoot = new ViewNode(in, preader);
}
@@ -169,29 +172,58 @@ public class AssistStructure {
out.writeInt(mWidth);
out.writeInt(mHeight);
TextUtils.writeToParcel(mTitle, out, 0);
+ out.writeInt(mDisplayId);
mRoot.writeToParcel(out, pwriter);
}
+ /**
+ * Returns the left edge of the window, in pixels, relative to the left
+ * edge of the screen.
+ */
public int getLeft() {
return mX;
}
+ /**
+ * Returns the top edge of the window, in pixels, relative to the top
+ * edge of the screen.
+ */
public int getTop() {
return mY;
}
+ /**
+ * Returns the total width of the window in pixels.
+ */
public int getWidth() {
return mWidth;
}
+ /**
+ * Returns the total height of the window in pixels.
+ */
public int getHeight() {
return mHeight;
}
+ /**
+ * Returns the title associated with the window, if it has one.
+ */
public CharSequence getTitle() {
return mTitle;
}
+ /**
+ * Returns the ID of the display this window is on, for use with
+ * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
+ * Returns the {@link ViewNode} containing the root content of the window.
+ */
public ViewNode getRootViewNode() {
return mRoot;
}
@@ -325,146 +357,288 @@ public class AssistStructure {
}
}
+ /**
+ * Returns the ID associated with this view, as per {@link View#getId() View.getId()}.
+ */
public int getId() {
return mId;
}
+ /**
+ * If {@link #getId()} is a resource identifier, this is the package name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
public String getIdPackage() {
return mIdPackage;
}
+ /**
+ * If {@link #getId()} is a resource identifier, this is the type name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
public String getIdType() {
return mIdType;
}
+ /**
+ * If {@link #getId()} is a resource identifier, this is the entry name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
public String getIdEntry() {
return mIdEntry;
}
+ /**
+ * Returns the left edge of this view, in pixels, relative to the left edge of its parent.
+ */
public int getLeft() {
return mX;
}
+ /**
+ * Returns the top edge of this view, in pixels, relative to the top edge of its parent.
+ */
public int getTop() {
return mY;
}
+ /**
+ * Returns the current X scroll offset of this view, as per
+ * {@link android.view.View#getScrollX() View.getScrollX()}.
+ */
public int getScrollX() {
return mScrollX;
}
+ /**
+ * Returns the current Y scroll offset of this view, as per
+ * {@link android.view.View#getScrollX() View.getScrollY()}.
+ */
public int getScrollY() {
return mScrollY;
}
+ /**
+ * Returns the width of this view, in pixels.
+ */
public int getWidth() {
return mWidth;
}
+ /**
+ * Returns the height of this view, in pixels.
+ */
public int getHeight() {
return mHeight;
}
+ /**
+ * Returns the visibility mode of this view, as per
+ * {@link android.view.View#getVisibility() View.getVisibility()}.
+ */
public int getVisibility() {
return mFlags&ViewNode.FLAGS_VISIBILITY_MASK;
}
+ /**
+ * Returns true if assist data has been blocked starting at this node in the hierarchy.
+ */
public boolean isAssistBlocked() {
return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0;
}
+ /**
+ * Returns true if this node is in an enabled state.
+ */
public boolean isEnabled() {
return (mFlags&ViewNode.FLAGS_DISABLED) == 0;
}
+ /**
+ * Returns true if this node is clickable by the user.
+ */
public boolean isClickable() {
return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0;
}
+ /**
+ * Returns true if this node can take input focus.
+ */
public boolean isFocusable() {
return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0;
}
+ /**
+ * Returns true if this node currently had input focus at the time that the
+ * structure was collected.
+ */
public boolean isFocused() {
return (mFlags&ViewNode.FLAGS_FOCUSED) != 0;
}
+ /**
+ * Returns true if this node currently had accessibility focus at the time that the
+ * structure was collected.
+ */
public boolean isAccessibilityFocused() {
return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
}
+ /**
+ * Returns true if this node represents something that is checkable by the user.
+ */
public boolean isCheckable() {
return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0;
}
+ /**
+ * Returns true if this node is currently in a checked state.
+ */
public boolean isChecked() {
return (mFlags&ViewNode.FLAGS_CHECKED) != 0;
}
+ /**
+ * Returns true if this node has currently been selected by the user.
+ */
public boolean isSelected() {
return (mFlags&ViewNode.FLAGS_SELECTED) != 0;
}
+ /**
+ * Returns true if this node has currently been activated by the user.
+ */
public boolean isActivated() {
return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0;
}
+ /**
+ * Returns true if this node is something the user can perform a long click/press on.
+ */
public boolean isLongClickable() {
return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
}
+ /**
+ * Returns true if this node is something the user can perform a context click on.
+ */
public boolean isContextClickable() {
return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0;
}
+ /**
+ * Returns the class name of the node's implementation, indicating its behavior.
+ * For example, a button will report "android.widget.Button" meaning it behaves
+ * like a {@link android.widget.Button}.
+ */
public String getClassName() {
return mClassName;
}
+ /**
+ * Returns any content description associated with the node, which semantically describes
+ * its purpose for accessibility and other uses.
+ */
public CharSequence getContentDescription() {
return mContentDescription;
}
+ /**
+ * Returns any text associated with the node that is displayed to the user, or null
+ * if there is none.
+ */
public CharSequence getText() {
return mText != null ? mText.mText : null;
}
+ /**
+ * If {@link #getText()} is non-null, this is where the current selection starts.
+ */
public int getTextSelectionStart() {
return mText != null ? mText.mTextSelectionStart : -1;
}
+ /**
+ * If {@link #getText()} is non-null, this is where the current selection starts.
+ * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
+ * indicating the cursor position.
+ */
public int getTextSelectionEnd() {
return mText != null ? mText.mTextSelectionEnd : -1;
}
+ /**
+ * If {@link #getText()} is non-null, this is the main text color associated with it.
+ * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned.
+ * Note that the text may also contain style spans that modify the color of specific
+ * parts of the text.
+ */
public int getTextColor() {
return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED;
}
+ /**
+ * If {@link #getText()} is non-null, this is the main text background color associated
+ * with it.
+ * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned.
+ * Note that the text may also contain style spans that modify the color of specific
+ * parts of the text.
+ */
public int getTextBackgroundColor() {
return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
}
+ /**
+ * If {@link #getText()} is non-null, this is the main text size (in pixels) associated
+ * with it.
+ * Note that the text may also contain style spans that modify the size of specific
+ * parts of the text.
+ */
public float getTextSize() {
return mText != null ? mText.mTextSize : 0;
}
+ /**
+ * If {@link #getText()} is non-null, this is the main text style associated
+ * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD},
+ * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or
+ * {@link #TEXT_STYLE_UNDERLINE}.
+ * Note that the text may also contain style spans that modify the style of specific
+ * parts of the text.
+ */
public int getTextStyle() {
return mText != null ? mText.mTextStyle : 0;
}
+ /**
+ * Return additional hint text associated with the node; this is typically used with
+ * a node that takes user input, describing to the user what the input means.
+ */
public String getHint() {
return mText != null ? mText.mHint : null;
}
+ /**
+ * Return a Bundle containing optional vendor-specific extension information.
+ */
public Bundle getExtras() {
return mExtras;
}
+ /**
+ * Return the number of children this node has.
+ */
public int getChildCount() {
return mChildren != null ? mChildren.length : 0;
}
+ /**
+ * Return a child of this node, given an index value from 0 to
+ * {@link #getChildCount()}-1.
+ */
public ViewNode getChildAt(int index) {
return mChildren[index];
}
@@ -663,6 +837,19 @@ public class AssistStructure {
}
@Override
+ public int addChildCount(int num) {
+ if (mNode.mChildren == null) {
+ setChildCount(num);
+ return 0;
+ }
+ final int start = mNode.mChildren.length;
+ ViewNode[] newArray = new ViewNode[start + num];
+ System.arraycopy(mNode.mChildren, 0, newArray, 0, start);
+ mNode.mChildren = newArray;
+ return start;
+ }
+
+ @Override
public int getChildCount() {
return mNode.mChildren != null ? mNode.mChildren.length : 0;
}
@@ -801,6 +988,9 @@ public class AssistStructure {
return assistBundle.getParcelable(ASSIST_KEY);
}
+ /**
+ * Return the activity this AssistStructure came from.
+ */
public ComponentName getActivityComponent() {
ensureData();
return mActivityComponent;
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 02e26a5..903411e 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -28,7 +28,6 @@ import android.transition.TransitionSet;
import android.util.ArrayMap;
import android.util.Log;
import android.util.LogWriter;
-import android.util.Pair;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
@@ -1005,13 +1004,20 @@ final class BackStackRecord extends FragmentTransaction implements
outFragment.getExitTransition());
}
- private static Transition getSharedElementTransition(Fragment inFragment, Fragment outFragment,
- boolean isBack) {
+ private static TransitionSet getSharedElementTransition(Fragment inFragment,
+ Fragment outFragment, boolean isBack) {
if (inFragment == null || outFragment == null) {
return null;
}
- return cloneTransition(isBack ? outFragment.getSharedElementReturnTransition() :
- inFragment.getSharedElementEnterTransition());
+ Transition transition = cloneTransition(isBack
+ ? outFragment.getSharedElementReturnTransition()
+ : inFragment.getSharedElementEnterTransition());
+ if (transition == null) {
+ return null;
+ }
+ TransitionSet transitionSet = new TransitionSet();
+ transitionSet.addTransition(transition);
+ return transitionSet;
}
private static ArrayList<View> captureExitingViews(Transition exitTransition,
@@ -1070,7 +1076,7 @@ final class BackStackRecord extends FragmentTransaction implements
* capturing the final state of the Transition.</p>
*/
private ArrayList<View> addTransitionTargets(final TransitionState state,
- final Transition enterTransition, final Transition sharedElementTransition,
+ final Transition enterTransition, final TransitionSet sharedElementTransition,
final Transition overallTransition, final View container,
final Fragment inFragment, final Fragment outFragment,
final ArrayList<View> hiddenFragmentViews, final boolean isBack,
@@ -1094,11 +1100,8 @@ final class BackStackRecord extends FragmentTransaction implements
if (sharedElementTransition != null) {
namedViews = mapSharedElementsIn(state, isBack, inFragment);
removeTargets(sharedElementTransition, sharedElementTargets);
- sharedElementTargets.clear();
- sharedElementTargets.add(state.nonExistentView);
- sharedElementTargets.addAll(namedViews.values());
-
- addTargets(sharedElementTransition, sharedElementTargets);
+ setSharedElementTargets(sharedElementTransition,
+ state.nonExistentView, namedViews, sharedElementTargets);
setEpicenterIn(namedViews, state);
@@ -1241,8 +1244,8 @@ final class BackStackRecord extends FragmentTransaction implements
Fragment outFragment = firstOutFragments.get(containerId);
Transition enterTransition = getEnterTransition(inFragment, isBack);
- Transition sharedElementTransition = getSharedElementTransition(inFragment, outFragment,
- isBack);
+ TransitionSet sharedElementTransition =
+ getSharedElementTransition(inFragment, outFragment, isBack);
Transition exitTransition = getExitTransition(outFragment, isBack);
if (enterTransition == null && sharedElementTransition == null &&
@@ -1256,9 +1259,8 @@ final class BackStackRecord extends FragmentTransaction implements
ArrayList<View> sharedElementTargets = new ArrayList<View>();
if (sharedElementTransition != null) {
namedViews = remapSharedElements(state, outFragment, isBack);
- sharedElementTargets.add(state.nonExistentView);
- sharedElementTargets.addAll(namedViews.values());
- addTargets(sharedElementTransition, sharedElementTargets);
+ setSharedElementTargets(sharedElementTransition,
+ state.nonExistentView, namedViews, sharedElementTargets);
// Notify the start of the transition.
SharedElementCallback callback = isBack ?
@@ -1294,8 +1296,8 @@ final class BackStackRecord extends FragmentTransaction implements
if (transition != null) {
ArrayList<View> hiddenFragments = new ArrayList<View>();
ArrayList<View> enteringViews = addTransitionTargets(state, enterTransition,
- sharedElementTransition, transition, sceneRoot, inFragment, outFragment,
- hiddenFragments, isBack, sharedElementTargets);
+ sharedElementTransition, transition, sceneRoot, inFragment,
+ outFragment, hiddenFragments, isBack, sharedElementTargets);
transition.setNameOverrides(state.nameOverrides);
// We want to exclude hidden views later, so we need a non-null list in the
@@ -1307,9 +1309,71 @@ final class BackStackRecord extends FragmentTransaction implements
// Remove the view targeting after the transition starts
removeTargetedViewsFromTransitions(sceneRoot, state.nonExistentView,
enterTransition, enteringViews, exitTransition, exitingViews,
- sharedElementTransition, sharedElementTargets, transition, hiddenFragments);
+ sharedElementTransition, sharedElementTargets, transition,
+ hiddenFragments);
+ }
+ }
+ }
+
+ /**
+ * Finds all children of the shared elements and sets the wrapping TransitionSet
+ * targets to point to those. It also limits transitions that have no targets to the
+ * specific shared elements. This allows developers to target child views of the
+ * shared elements specifically, but this doesn't happen by default.
+ */
+ private static void setSharedElementTargets(TransitionSet transition,
+ View nonExistentView, ArrayMap<String, View> namedViews,
+ ArrayList<View> sharedElementTargets) {
+ sharedElementTargets.clear();
+ sharedElementTargets.addAll(namedViews.values());
+
+ final List<View> views = transition.getTargets();
+ views.clear();
+ final int count = sharedElementTargets.size();
+ for (int i = 0; i < count; i++) {
+ final View view = sharedElementTargets.get(i);
+ bfsAddViewChildren(views, view);
+ }
+ sharedElementTargets.add(nonExistentView);
+ addTargets(transition, sharedElementTargets);
+ }
+
+ /**
+ * Uses a breadth-first scheme to add startView and all of its children to views.
+ * It won't add a child if it is already in views.
+ */
+ private static void bfsAddViewChildren(final List<View> views, final View startView) {
+ final int startIndex = views.size();
+ if (containedBeforeIndex(views, startView, startIndex)) {
+ return; // This child is already in the list, so all its children are also.
+ }
+ views.add(startView);
+ for (int index = startIndex; index < views.size(); index++) {
+ final View view = views.get(index);
+ if (view instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) view;
+ final int childCount = viewGroup.getChildCount();
+ for (int childIndex = 0; childIndex < childCount; childIndex++) {
+ final View child = viewGroup.getChildAt(childIndex);
+ if (!containedBeforeIndex(views, child, startIndex)) {
+ views.add(child);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Does a linear search through views for view, limited to maxIndex.
+ */
+ private static boolean containedBeforeIndex(final List<View> views, final View view,
+ final int maxIndex) {
+ for (int i = 0; i < maxIndex; i++) {
+ if (views.get(i) == view) {
+ return true;
}
}
+ return false;
}
/**
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
new file mode 100644
index 0000000..1f378da
--- /dev/null
+++ b/core/java/android/app/BroadcastOptions.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.SystemApi;
+import android.os.Bundle;
+
+/**
+ * Helper class for building an options Bundle that can be used with
+ * {@link android.content.Context#sendBroadcast(android.content.Intent)
+ * Context.sendBroadcast(Intent)} and related methods.
+ * {@hide}
+ */
+@SystemApi
+public class BroadcastOptions {
+ private long mTemporaryAppWhitelistDuration;
+
+ /**
+ * How long to temporarily put an app on the power whitelist when executing this broadcast
+ * to it.
+ * @hide
+ */
+ public static final String KEY_TEMPORARY_APP_WHITELIST_DURATION
+ = "android:broadcast.temporaryAppWhitelistDuration";
+
+ public static BroadcastOptions makeBasic() {
+ BroadcastOptions opts = new BroadcastOptions();
+ return opts;
+ }
+
+ private BroadcastOptions() {
+ }
+
+ /** @hide */
+ public BroadcastOptions(Bundle opts) {
+ mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION);
+ }
+
+ /**
+ * Set a duration for which the system should temporary place an application on the
+ * power whitelist when this broadcast is being delivered to it.
+ * @param duration The duration in milliseconds; 0 means to not place on whitelist.
+ */
+ public void setTemporaryAppWhitelistDuration(long duration) {
+ mTemporaryAppWhitelistDuration = duration;
+ }
+
+ /**
+ * Return {@link #setTemporaryAppWhitelistDuration}.
+ * @hide
+ */
+ public long getTemporaryAppWhitelistDuration() {
+ return mTemporaryAppWhitelistDuration;
+ }
+
+ /**
+ * Returns the created options as a Bundle, which can be passed to
+ * {@link android.content.Context#sendBroadcast(android.content.Intent)
+ * Context.sendBroadcast(Intent)} and related methods.
+ * Note that the returned Bundle is still owned by the ActivityOptions
+ * object; you must not modify it, but can supply it to the sendBroadcast
+ * methods that take an options Bundle.
+ */
+ public Bundle toBundle() {
+ Bundle b = new Bundle();
+ if (mTemporaryAppWhitelistDuration > 0) {
+ b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration);
+ }
+ return b.isEmpty() ? null : b;
+ }
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index be36af7..0420fb6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -46,7 +46,6 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -676,8 +675,8 @@ class ContextImpl extends Context {
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
- getOuterContext(), mMainThread.getApplicationThread(), null,
- (Activity)null, intent, -1, options);
+ getOuterContext(), mMainThread.getApplicationThread(), null,
+ (Activity) null, intent, -1, options);
}
/** @hide */
@@ -710,8 +709,8 @@ class ContextImpl extends Context {
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivitiesAsUser(
- getOuterContext(), mMainThread.getApplicationThread(), null,
- (Activity)null, intents, options, userHandle.getIdentifier());
+ getOuterContext(), mMainThread.getApplicationThread(), null,
+ (Activity) null, intents, options, userHandle.getIdentifier());
}
@Override
@@ -724,8 +723,8 @@ class ContextImpl extends Context {
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivities(
- getOuterContext(), mMainThread.getApplicationThread(), null,
- (Activity)null, intents, options);
+ getOuterContext(), mMainThread.getApplicationThread(), null,
+ (Activity) null, intents, options);
}
@Override
@@ -766,9 +765,9 @@ class ContextImpl extends Context {
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
- mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
- getUserId());
+ mMainThread.getApplicationThread(), intent, resolvedType, null,
+ Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
+ getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -781,9 +780,24 @@ class ContextImpl extends Context {
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
- mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
- false, false, getUserId());
+ mMainThread.getApplicationThread(), intent, resolvedType, null,
+ Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+ null, false, false, getUserId());
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failure from system", e);
+ }
+ }
+
+ @Override
+ public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+ warnIfCallingFromSystemProcess();
+ String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ try {
+ intent.prepareToLeaveProcess();
+ ActivityManagerNative.getDefault().broadcastIntent(
+ mMainThread.getApplicationThread(), intent, resolvedType, null,
+ Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+ options, false, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -796,25 +810,24 @@ class ContextImpl extends Context {
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
- mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
- getUserId());
+ mMainThread.getApplicationThread(), intent, resolvedType, null,
+ Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false,
+ getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
}
@Override
- public void sendOrderedBroadcast(Intent intent,
- String receiverPermission) {
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
- mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false,
- getUserId());
+ mMainThread.getApplicationThread(), intent, resolvedType, null,
+ Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+ null, true, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -826,7 +839,16 @@ class ContextImpl extends Context {
Handler scheduler, int initialCode, String initialData,
Bundle initialExtras) {
sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
- resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
+ }
+
+ @Override
+ public void sendOrderedBroadcast(Intent intent,
+ String receiverPermission, Bundle options, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
+ resultReceiver, scheduler, initialCode, initialData, initialExtras, options);
}
@Override
@@ -834,6 +856,14 @@ class ContextImpl extends Context {
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData,
Bundle initialExtras) {
+ sendOrderedBroadcast(intent, receiverPermission, appOp,
+ resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
+ }
+
+ void sendOrderedBroadcast(Intent intent,
+ String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras, Bundle options) {
warnIfCallingFromSystemProcess();
IIntentReceiver rd = null;
if (resultReceiver != null) {
@@ -858,7 +888,7 @@ class ContextImpl extends Context {
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, receiverPermission, appOp,
- true, false, getUserId());
+ options, true, false, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -871,7 +901,7 @@ class ContextImpl extends Context {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
- AppOpsManager.OP_NONE, false, false, user.getIdentifier());
+ AppOpsManager.OP_NONE, null, false, false, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -891,7 +921,7 @@ class ContextImpl extends Context {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
+ Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false,
user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -934,7 +964,7 @@ class ContextImpl extends Context {
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, receiverPermission,
- appOp, true, false, user.getIdentifier());
+ appOp, null, true, false, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -949,7 +979,7 @@ class ContextImpl extends Context {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true,
+ Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
@@ -986,7 +1016,7 @@ class ContextImpl extends Context {
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, null,
- AppOpsManager.OP_NONE, true, true, getUserId());
+ AppOpsManager.OP_NONE, null, true, true, getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -1017,7 +1047,7 @@ class ContextImpl extends Context {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
- Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier());
+ Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
@@ -1052,7 +1082,7 @@ class ContextImpl extends Context {
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, null,
- AppOpsManager.OP_NONE, true, true, user.getIdentifier());
+ AppOpsManager.OP_NONE, null, true, true, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 2ed8b0f..5327646 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -418,7 +418,7 @@ public class DownloadManager {
private int mNotificationVisibility = VISIBILITY_VISIBLE;
/**
- * @param uri the HTTP URI to download.
+ * @param uri the HTTP or HTTPS URI to download.
*/
public Request(Uri uri) {
if (uri == null) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9311e5e..e7f7e13 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -107,7 +107,7 @@ public interface IActivityManager extends IInterface {
public int broadcastIntent(IApplicationThread caller, Intent intent,
String resolvedType, IIntentReceiver resultTo, int resultCode,
String resultData, Bundle map, String requiredPermission,
- int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException;
+ int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
boolean abortBroadcast, int flags) throws RemoteException;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 96c6878..33a47b2 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1331,11 +1331,14 @@ public class Notification implements Parcelable
public Notification(Context context, int icon, CharSequence tickerText, long when,
CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
{
- this.when = when;
- this.icon = icon;
- this.tickerText = tickerText;
- setLatestEventInfo(context, contentTitle, contentText,
- PendingIntent.getActivity(context, 0, contentIntent, 0));
+ new Builder(context)
+ .setWhen(when)
+ .setSmallIcon(icon)
+ .setTicker(tickerText)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, 0))
+ .buildInto(this);
}
/**
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 031854a..c42ba65 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -613,7 +613,7 @@ public final class PendingIntent implements Parcelable {
* is no longer allowing more intents to be sent through it.
*/
public void send() throws CanceledException {
- send(null, 0, null, null, null, null);
+ send(null, 0, null, null, null, null, null);
}
/**
@@ -627,7 +627,7 @@ public final class PendingIntent implements Parcelable {
* is no longer allowing more intents to be sent through it.
*/
public void send(int code) throws CanceledException {
- send(null, code, null, null, null, null);
+ send(null, code, null, null, null, null, null);
}
/**
@@ -646,9 +646,9 @@ public final class PendingIntent implements Parcelable {
* @throws CanceledException Throws CanceledException if the PendingIntent
* is no longer allowing more intents to be sent through it.
*/
- public void send(Context context, int code, Intent intent)
+ public void send(Context context, int code, @Nullable Intent intent)
throws CanceledException {
- send(context, code, intent, null, null, null);
+ send(context, code, intent, null, null, null, null);
}
/**
@@ -667,9 +667,9 @@ public final class PendingIntent implements Parcelable {
* @throws CanceledException Throws CanceledException if the PendingIntent
* is no longer allowing more intents to be sent through it.
*/
- public void send(int code, OnFinished onFinished, Handler handler)
+ public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)
throws CanceledException {
- send(null, code, null, onFinished, handler, null);
+ send(null, code, null, onFinished, handler, null, null);
}
/**
@@ -705,9 +705,9 @@ public final class PendingIntent implements Parcelable {
* @throws CanceledException Throws CanceledException if the PendingIntent
* is no longer allowing more intents to be sent through it.
*/
- public void send(Context context, int code, Intent intent,
- OnFinished onFinished, Handler handler) throws CanceledException {
- send(context, code, intent, onFinished, handler, null);
+ public void send(Context context, int code, @Nullable Intent intent,
+ @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException {
+ send(context, code, intent, onFinished, handler, null, null);
}
/**
@@ -748,8 +748,56 @@ public final class PendingIntent implements Parcelable {
* @throws CanceledException Throws CanceledException if the PendingIntent
* is no longer allowing more intents to be sent through it.
*/
- public void send(Context context, int code, Intent intent,
- OnFinished onFinished, Handler handler, String requiredPermission)
+ public void send(Context context, int code, @Nullable Intent intent,
+ @Nullable OnFinished onFinished, @Nullable Handler handler,
+ @Nullable String requiredPermission)
+ throws CanceledException {
+ send(context, code, intent, onFinished, handler, requiredPermission, null);
+ }
+
+ /**
+ * Perform the operation associated with this PendingIntent, allowing the
+ * caller to specify information about the Intent to use and be notified
+ * when the send has completed.
+ *
+ * <p>For the intent parameter, a PendingIntent
+ * often has restrictions on which fields can be supplied here, based on
+ * how the PendingIntent was retrieved in {@link #getActivity},
+ * {@link #getBroadcast}, or {@link #getService}.
+ *
+ * @param context The Context of the caller. This may be null if
+ * <var>intent</var> is also null.
+ * @param code Result code to supply back to the PendingIntent's target.
+ * @param intent Additional Intent data. See {@link Intent#fillIn
+ * Intent.fillIn()} for information on how this is applied to the
+ * original Intent. Use null to not modify the original Intent.
+ * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
+ * created, this argument will be ignored.
+ * @param onFinished The object to call back on when the send has
+ * completed, or null for no callback.
+ * @param handler Handler identifying the thread on which the callback
+ * should happen. If null, the callback will happen from the thread
+ * pool of the process.
+ * @param requiredPermission Name of permission that a recipient of the PendingIntent
+ * is required to hold. This is only valid for broadcast intents, and
+ * corresponds to the permission argument in
+ * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
+ * If null, no permission is required.
+ * @param options Additional options the caller would like to provide to modify the sending
+ * behavior. May be built from an {@link ActivityOptions} to apply to an activity start.
+ *
+ * @see #send()
+ * @see #send(int)
+ * @see #send(Context, int, Intent)
+ * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
+ * @see #send(Context, int, Intent, OnFinished, Handler)
+ *
+ * @throws CanceledException Throws CanceledException if the PendingIntent
+ * is no longer allowing more intents to be sent through it.
+ */
+ public void send(Context context, int code, @Nullable Intent intent,
+ @Nullable OnFinished onFinished, @Nullable Handler handler,
+ @Nullable String requiredPermission, @Nullable Bundle options)
throws CanceledException {
try {
String resolvedType = intent != null ?
@@ -759,7 +807,7 @@ public final class PendingIntent implements Parcelable {
onFinished != null
? new FinishedDispatcher(this, onFinished, handler)
: null,
- requiredPermission);
+ requiredPermission, options);
if (res < 0) {
throw new CanceledException();
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 42d0dcb..ed20086 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -149,6 +149,7 @@ public class DevicePolicyManager {
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
* <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
* </ul>
*
* <p> When device owner provisioning has completed, an intent of the type
@@ -163,14 +164,19 @@ public class DevicePolicyManager {
= "android.app.action.PROVISION_MANAGED_DEVICE";
/**
- * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that allows
- * a mobile device management application that starts managed profile provisioning to pass data
- * to itself on the managed profile when provisioning completes. The mobile device management
- * application sends this extra in an intent with the action
- * {@link #ACTION_PROVISION_MANAGED_PROFILE} and receives it in
+ * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
+ * allows a mobile device management application which starts managed provisioning to pass data
+ * to itself.
+ * <p>
+ * If used with {@link #ACTION_PROVISION_MANAGED_PROFILE} it can be used by the application that
+ * sends the intent to pass data to itself on the newly created profile.
+ * If used with {@link #ACTION_PROVISION_MANAGED_DEVICE} it allows passing data to the same
+ * instance of the app on the primary user.
+ * <p>
+ * In both cases the application receives the data in
* {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with the action
* {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. The bundle is not changed
- * during the managed profile provisioning.
+ * during the managed provisioning.
*/
public static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE =
"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
@@ -397,8 +403,9 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of the file at download
- * location specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
+ * A String extra holding the URL-safe base64 encoded SHA-256 or SHA-1 hash (see notes below) of
+ * the file at download location specified in
+ * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
*
* <p>Either this extra or {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM} should be
* present. The provided checksum should match the checksum of the file at the download
@@ -407,12 +414,17 @@ public class DevicePolicyManager {
*
* <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
* provisioning via an NFC bump.
+ *
+ * <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP}
+ * and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported.
+ * Starting from {@link android.os.Build.VERSION_CODES#MNC}, this parameter accepts SHA-256 in
+ * addition to SHA-1. Support for SHA-1 is likely to be removed in future OS releases.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of any signature of the
+ * A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
* android package archive at the download location specified in {@link
* #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -504,7 +516,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of the file at download
+ * A String extra holding the URL-safe base64 encoded SHA-256 checksum of the file at download
* location specified in
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -520,7 +532,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
/**
- * A String extra holding the URL-safe base64 encoded SHA-1 checksum of any signature of the
+ * A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
* android package archive at the download location specified in {@link
* #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -918,7 +930,7 @@ public class DevicePolicyManager {
/**
* Constant for {@link #setPasswordQuality}: the policy requires some kind
- * of password, but doesn't care what it is. Note that quality constants
+ * of password or pattern, but doesn't care what it is. Note that quality constants
* are ordered so that higher values are more restrictive.
*/
public static final int PASSWORD_QUALITY_SOMETHING = 0x10000;
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 1205708..278c9d6 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
@@ -753,16 +754,16 @@ public class AppWidgetManager {
}
try {
- List<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile(
+ ParceledListSlice<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile(
categoryFilter, profile.getIdentifier());
if (providers == null) {
return Collections.emptyList();
}
- for (AppWidgetProviderInfo info : providers) {
+ for (AppWidgetProviderInfo info : providers.getList()) {
// Converting complex to dp.
convertSizesToPixels(info);
}
- return providers;
+ return providers.getList();
}
catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
index 161c339..834a587 100644
--- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
@@ -28,10 +28,10 @@ import android.os.Parcelable;
public final class BluetoothActivityEnergyInfo implements Parcelable {
private final long mTimestamp;
private final int mBluetoothStackState;
- private final int mControllerTxTimeMs;
- private final int mControllerRxTimeMs;
- private final int mControllerIdleTimeMs;
- private final int mControllerEnergyUsed;
+ private final long mControllerTxTimeMs;
+ private final long mControllerRxTimeMs;
+ private final long mControllerIdleTimeMs;
+ private final long mControllerEnergyUsed;
public static final int BT_STACK_STATE_INVALID = 0;
public static final int BT_STACK_STATE_STATE_ACTIVE = 1;
@@ -39,7 +39,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
public static final int BT_STACK_STATE_STATE_IDLE = 3;
public BluetoothActivityEnergyInfo(long timestamp, int stackState,
- int txTime, int rxTime, int idleTime, int energyUsed) {
+ long txTime, long rxTime, long idleTime, long energyUsed) {
mTimestamp = timestamp;
mBluetoothStackState = stackState;
mControllerTxTimeMs = txTime;
@@ -65,10 +65,10 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
long timestamp = in.readLong();
int stackState = in.readInt();
- int txTime = in.readInt();
- int rxTime = in.readInt();
- int idleTime = in.readInt();
- int energyUsed = in.readInt();
+ long txTime = in.readLong();
+ long rxTime = in.readLong();
+ long idleTime = in.readLong();
+ long energyUsed = in.readLong();
return new BluetoothActivityEnergyInfo(timestamp, stackState,
txTime, rxTime, idleTime, energyUsed);
}
@@ -80,10 +80,10 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
out.writeLong(mTimestamp);
out.writeInt(mBluetoothStackState);
- out.writeInt(mControllerTxTimeMs);
- out.writeInt(mControllerRxTimeMs);
- out.writeInt(mControllerIdleTimeMs);
- out.writeInt(mControllerEnergyUsed);
+ out.writeLong(mControllerTxTimeMs);
+ out.writeLong(mControllerRxTimeMs);
+ out.writeLong(mControllerIdleTimeMs);
+ out.writeLong(mControllerEnergyUsed);
}
public int describeContents() {
@@ -100,21 +100,21 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
/**
* @return tx time in ms
*/
- public int getControllerTxTimeMillis() {
+ public long getControllerTxTimeMillis() {
return mControllerTxTimeMs;
}
/**
* @return rx time in ms
*/
- public int getControllerRxTimeMillis() {
+ public long getControllerRxTimeMillis() {
return mControllerRxTimeMs;
}
/**
* @return idle time in ms
*/
- public int getControllerIdleTimeMillis() {
+ public long getControllerIdleTimeMillis() {
return mControllerIdleTimeMs;
}
@@ -122,7 +122,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
* product of current(mA), voltage(V) and time(ms)
* @return energy used
*/
- public int getControllerEnergyUsed() {
+ public long getControllerEnergyUsed() {
return mControllerEnergyUsed;
}
@@ -137,8 +137,8 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
* @return if the record is valid
*/
public boolean isValid() {
- return ((getControllerTxTimeMillis() !=0) ||
- (getControllerRxTimeMillis() !=0) ||
- (getControllerIdleTimeMillis() !=0));
+ return ((mControllerTxTimeMs !=0) ||
+ (mControllerRxTimeMs !=0) ||
+ (mControllerIdleTimeMs !=0));
}
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 494f821..d4c4437 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -223,16 +223,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
Cursor cursor = ContentProvider.this.query(uri, projection, selection,
selectionArgs, sortOrder, CancellationSignal.fromTransport(
cancellationSignal));
-
- // Create a projection for all columns.
- final int columnCount = cursor.getCount();
- String[] allColumns = new String[columnCount];
- for (int i = 0; i < columnCount; i++) {
- allColumns[i] = cursor.getColumnName(i);
+ if (cursor == null) {
+ return null;
}
// Return an empty cursor for all columns.
- return new MatrixCursor(allColumns, 0);
+ return new MatrixCursor(cursor.getColumnNames(), 0);
}
final String original = setCallingPackage(callingPkg);
try {
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index e15ac94..d12595f 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -16,6 +16,8 @@
package android.content;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
@@ -30,6 +32,7 @@ import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard;
@@ -109,14 +112,19 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#query ContentProvider.query} */
- public Cursor query(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) throws RemoteException {
+ public @Nullable Cursor query(@NonNull Uri url, @Nullable String[] projection,
+ @Nullable String selection, @Nullable String[] selectionArgs,
+ @Nullable String sortOrder) throws RemoteException {
return query(url, projection, selection, selectionArgs, sortOrder, null);
}
/** See {@link ContentProvider#query ContentProvider.query} */
- public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder, CancellationSignal cancellationSignal) throws RemoteException {
+ public @Nullable Cursor query(@NonNull Uri url, @Nullable String[] projection,
+ @Nullable String selection, @Nullable String[] selectionArgs,
+ @Nullable String sortOrder, @Nullable CancellationSignal cancellationSignal)
+ throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
ICancellationSignal remoteCancellationSignal = null;
@@ -138,7 +146,9 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#getType ContentProvider.getType} */
- public String getType(Uri url) throws RemoteException {
+ public @Nullable String getType(@NonNull Uri url) throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
return mContentProvider.getType(url);
@@ -153,7 +163,11 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#getStreamTypes ContentProvider.getStreamTypes} */
- public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+ public @Nullable String[] getStreamTypes(@NonNull Uri url, @NonNull String mimeTypeFilter)
+ throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+ Preconditions.checkNotNull(mimeTypeFilter, "mimeTypeFilter");
+
beforeRemote();
try {
return mContentProvider.getStreamTypes(url, mimeTypeFilter);
@@ -168,7 +182,9 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#canonicalize} */
- public final Uri canonicalize(Uri url) throws RemoteException {
+ public final @Nullable Uri canonicalize(@NonNull Uri url) throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
return mContentProvider.canonicalize(mPackageName, url);
@@ -183,7 +199,9 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#uncanonicalize} */
- public final Uri uncanonicalize(Uri url) throws RemoteException {
+ public final @Nullable Uri uncanonicalize(@NonNull Uri url) throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
return mContentProvider.uncanonicalize(mPackageName, url);
@@ -198,7 +216,10 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#insert ContentProvider.insert} */
- public Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
+ public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues)
+ throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
return mContentProvider.insert(mPackageName, url, initialValues);
@@ -213,7 +234,11 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#bulkInsert ContentProvider.bulkInsert} */
- public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
+ public int bulkInsert(@NonNull Uri url, @NonNull ContentValues[] initialValues)
+ throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+ Preconditions.checkNotNull(initialValues, "initialValues");
+
beforeRemote();
try {
return mContentProvider.bulkInsert(mPackageName, url, initialValues);
@@ -228,8 +253,10 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#delete ContentProvider.delete} */
- public int delete(Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
+ public int delete(@NonNull Uri url, @Nullable String selection,
+ @Nullable String[] selectionArgs) throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
return mContentProvider.delete(mPackageName, url, selection, selectionArgs);
@@ -244,8 +271,10 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#update ContentProvider.update} */
- public int update(Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException {
+ public int update(@NonNull Uri url, @Nullable ContentValues values, @Nullable String selection,
+ @Nullable String[] selectionArgs) throws RemoteException {
+ Preconditions.checkNotNull(url, "url");
+
beforeRemote();
try {
return mContentProvider.update(mPackageName, url, values, selection, selectionArgs);
@@ -266,7 +295,7 @@ public class ContentProviderClient {
* you use the {@link ContentResolver#openFileDescriptor
* ContentResolver.openFileDescriptor} API instead.
*/
- public ParcelFileDescriptor openFile(Uri url, String mode)
+ public @Nullable ParcelFileDescriptor openFile(@NonNull Uri url, @NonNull String mode)
throws RemoteException, FileNotFoundException {
return openFile(url, mode, null);
}
@@ -278,8 +307,11 @@ public class ContentProviderClient {
* you use the {@link ContentResolver#openFileDescriptor
* ContentResolver.openFileDescriptor} API instead.
*/
- public ParcelFileDescriptor openFile(Uri url, String mode, CancellationSignal signal)
- throws RemoteException, FileNotFoundException {
+ public @Nullable ParcelFileDescriptor openFile(@NonNull Uri url, @NonNull String mode,
+ @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
+ Preconditions.checkNotNull(url, "url");
+ Preconditions.checkNotNull(mode, "mode");
+
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
@@ -306,7 +338,7 @@ public class ContentProviderClient {
* you use the {@link ContentResolver#openAssetFileDescriptor
* ContentResolver.openAssetFileDescriptor} API instead.
*/
- public AssetFileDescriptor openAssetFile(Uri url, String mode)
+ public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri url, @NonNull String mode)
throws RemoteException, FileNotFoundException {
return openAssetFile(url, mode, null);
}
@@ -318,8 +350,11 @@ public class ContentProviderClient {
* you use the {@link ContentResolver#openAssetFileDescriptor
* ContentResolver.openAssetFileDescriptor} API instead.
*/
- public AssetFileDescriptor openAssetFile(Uri url, String mode, CancellationSignal signal)
- throws RemoteException, FileNotFoundException {
+ public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri url, @NonNull String mode,
+ @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
+ Preconditions.checkNotNull(url, "url");
+ Preconditions.checkNotNull(mode, "mode");
+
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
@@ -340,15 +375,19 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
- public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
- String mimeType, Bundle opts) throws RemoteException, FileNotFoundException {
+ public final @Nullable AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri,
+ @NonNull String mimeType, @Nullable Bundle opts)
+ throws RemoteException, FileNotFoundException {
return openTypedAssetFileDescriptor(uri, mimeType, opts, null);
}
/** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
- public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
- String mimeType, Bundle opts, CancellationSignal signal)
- throws RemoteException, FileNotFoundException {
+ public final @Nullable AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri,
+ @NonNull String mimeType, @Nullable Bundle opts, @Nullable CancellationSignal signal)
+ throws RemoteException, FileNotFoundException {
+ Preconditions.checkNotNull(uri, "uri");
+ Preconditions.checkNotNull(mimeType, "mimeType");
+
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
@@ -370,8 +409,11 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#applyBatch ContentProvider.applyBatch} */
- public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
- throws RemoteException, OperationApplicationException {
+ public @NonNull ContentProviderResult[] applyBatch(
+ @NonNull ArrayList<ContentProviderOperation> operations)
+ throws RemoteException, OperationApplicationException {
+ Preconditions.checkNotNull(operations, "operations");
+
beforeRemote();
try {
return mContentProvider.applyBatch(mPackageName, operations);
@@ -386,7 +428,10 @@ public class ContentProviderClient {
}
/** See {@link ContentProvider#call(String, String, Bundle)} */
- public Bundle call(String method, String arg, Bundle extras) throws RemoteException {
+ public @Nullable Bundle call(@NonNull String method, @Nullable String arg,
+ @Nullable Bundle extras) throws RemoteException {
+ Preconditions.checkNotNull(method, "method");
+
beforeRemote();
try {
return mContentProvider.call(mPackageName, method, arg, extras);
@@ -436,7 +481,7 @@ public class ContentProviderClient {
* @return If the associated {@link ContentProvider} is local, returns it.
* Otherwise returns null.
*/
- public ContentProvider getLocalContentProvider() {
+ public @Nullable ContentProvider getLocalContentProvider() {
return ContentProvider.coerceToLocalContentProvider(mContentProvider);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 970623a..675515b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1517,6 +1517,38 @@ public abstract class Context {
@Nullable String receiverPermission);
/**
+ * Broadcast the given intent to all interested BroadcastReceivers, allowing
+ * an optional required permission to be enforced. This
+ * call is asynchronous; it returns immediately, and you will continue
+ * executing while the receivers are run. No results are propagated from
+ * receivers and receivers can not abort the broadcast. If you want
+ * to allow receivers to propagate results or abort the broadcast, you must
+ * send an ordered broadcast using
+ * {@link #sendOrderedBroadcast(Intent, String)}.
+ *
+ * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+ *
+ * @param intent The Intent to broadcast; all receivers matching this
+ * Intent will receive the broadcast.
+ * @param receiverPermission (optional) String naming a permission that
+ * a receiver must hold in order to receive your broadcast.
+ * If null, no permission is required.
+ * @param options (optional) Additional sending options, generated from a
+ * {@link android.app.BroadcastOptions}.
+ *
+ * @see android.content.BroadcastReceiver
+ * @see #registerReceiver
+ * @see #sendBroadcast(Intent)
+ * @see #sendOrderedBroadcast(Intent, String)
+ * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
+ * @hide
+ */
+ @SystemApi
+ public abstract void sendBroadcast(Intent intent,
+ @Nullable String receiverPermission,
+ @Nullable Bundle options);
+
+ /**
* Like {@link #sendBroadcast(Intent, String)}, but also allows specification
* of an associated app op as per {@link android.app.AppOpsManager}.
* @hide
@@ -1588,11 +1620,60 @@ public abstract class Context {
* @see android.app.Activity#RESULT_OK
*/
public abstract void sendOrderedBroadcast(@NonNull Intent intent,
- @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
+ @Nullable String receiverPermission, @Nullable BroadcastReceiver resultReceiver,
@Nullable Handler scheduler, int initialCode, @Nullable String initialData,
@Nullable Bundle initialExtras);
/**
+ * Version of {@link #sendBroadcast(Intent)} that allows you to
+ * receive data back from the broadcast. This is accomplished by
+ * supplying your own BroadcastReceiver when calling, which will be
+ * treated as a final receiver at the end of the broadcast -- its
+ * {@link BroadcastReceiver#onReceive} method will be called with
+ * the result values collected from the other receivers. The broadcast will
+ * be serialized in the same way as calling
+ * {@link #sendOrderedBroadcast(Intent, String)}.
+ *
+ * <p>Like {@link #sendBroadcast(Intent)}, this method is
+ * asynchronous; it will return before
+ * resultReceiver.onReceive() is called.
+ *
+ * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+ *
+ *
+ * @param intent The Intent to broadcast; all receivers matching this
+ * Intent will receive the broadcast.
+ * @param receiverPermission String naming a permissions that
+ * a receiver must hold in order to receive your broadcast.
+ * If null, no permission is required.
+ * @param options (optional) Additional sending options, generated from a
+ * {@link android.app.BroadcastOptions}.
+ * @param resultReceiver Your own BroadcastReceiver to treat as the final
+ * receiver of the broadcast.
+ * @param scheduler A custom Handler with which to schedule the
+ * resultReceiver callback; if null it will be
+ * scheduled in the Context's main thread.
+ * @param initialCode An initial value for the result code. Often
+ * Activity.RESULT_OK.
+ * @param initialData An initial value for the result data. Often
+ * null.
+ * @param initialExtras An initial value for the result extras. Often
+ * null.
+ * @see #sendBroadcast(Intent)
+ * @see #sendBroadcast(Intent, String)
+ * @see #sendOrderedBroadcast(Intent, String)
+ * @see android.content.BroadcastReceiver
+ * @see #registerReceiver
+ * @see android.app.Activity#RESULT_OK
+ * @hide
+ */
+ @SystemApi
+ public abstract void sendOrderedBroadcast(@NonNull Intent intent,
+ @Nullable String receiverPermission, @Nullable Bundle options,
+ @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
+ int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras);
+
+ /**
* Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler,
* int, String, android.os.Bundle)}, but also allows specification
* of an associated app op as per {@link android.app.AppOpsManager}.
@@ -2248,6 +2329,7 @@ public abstract class Context {
//@hide: VOICE_INTERACTION_MANAGER_SERVICE,
//@hide: BACKUP_SERVICE,
DROPBOX_SERVICE,
+ //@hide: DEVICE_IDLE_CONTROLLER,
DEVICE_POLICY_SERVICE,
UI_MODE_SERVICE,
DOWNLOAD_SERVICE,
@@ -2874,6 +2956,13 @@ public abstract class Context {
public static final String DROPBOX_SERVICE = "dropbox";
/**
+ * System service name for the DeviceIdleController. There is no Java API for this.
+ * @see #getSystemService
+ * @hide
+ */
+ public static final String DEVICE_IDLE_CONTROLLER = "deviceidle";
+
+ /**
* Use with {@link #getSystemService} to retrieve a
* {@link android.app.admin.DevicePolicyManager} for working with global
* device policy management.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index fb9e194..4e7c832 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -16,6 +16,7 @@
package android.content;
+import android.annotation.SystemApi;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
@@ -401,6 +402,13 @@ public class ContextWrapper extends Context {
}
/** @hide */
+ @SystemApi
+ @Override
+ public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+ mBase.sendBroadcast(intent, receiverPermission, options);
+ }
+
+ /** @hide */
@Override
public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
mBase.sendBroadcast(intent, receiverPermission, appOp);
@@ -423,6 +431,18 @@ public class ContextWrapper extends Context {
}
/** @hide */
+ @SystemApi
+ @Override
+ public void sendOrderedBroadcast(
+ Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ mBase.sendOrderedBroadcast(intent, receiverPermission,
+ options, resultReceiver, scheduler, initialCode,
+ initialData, initialExtras);
+ }
+
+ /** @hide */
@Override
public void sendOrderedBroadcast(
Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
diff --git a/core/java/android/content/IIntentSender.aidl b/core/java/android/content/IIntentSender.aidl
index 7dbd6f2..f3affa7 100644
--- a/core/java/android/content/IIntentSender.aidl
+++ b/core/java/android/content/IIntentSender.aidl
@@ -18,9 +18,10 @@ package android.content;
import android.content.IIntentReceiver;
import android.content.Intent;
+import android.os.Bundle;
/** @hide */
interface IIntentSender {
int send(int code, in Intent intent, String resolvedType,
- IIntentReceiver finishedReceiver, String requiredPermission);
+ IIntentReceiver finishedReceiver, String requiredPermission, in Bundle options);
}
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 33c0b87..08c5236 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -254,12 +254,14 @@ public class IntentFilter implements Parcelable {
* HTTP scheme.
*
* @see #addDataScheme(String)
+ * @hide
*/
public static final String SCHEME_HTTP = "http";
/**
* HTTPS scheme.
*
* @see #addDataScheme(String)
+ * @hide
*/
public static final String SCHEME_HTTPS = "https";
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 166495b..13a767e 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -195,7 +195,7 @@ public class IntentSender implements Parcelable {
onFinished != null
? new FinishedDispatcher(this, onFinished, handler)
: null,
- requiredPermission);
+ requiredPermission, null);
if (res < 0) {
throw new SendIntentException();
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c92c256..287e0c5 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4024,7 +4024,7 @@ public class PackageParser {
public static final PublicKey parsePublicKey(final String encodedPublicKey) {
if (encodedPublicKey == null) {
- Slog.i(TAG, "Could not parse null public key");
+ Slog.w(TAG, "Could not parse null public key");
return null;
}
@@ -4033,7 +4033,7 @@ public class PackageParser {
final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT);
keySpec = new X509EncodedKeySpec(encoded);
} catch (IllegalArgumentException e) {
- Slog.i(TAG, "Could not parse verifier public key; invalid Base64");
+ Slog.w(TAG, "Could not parse verifier public key; invalid Base64");
return null;
}
@@ -4042,23 +4042,32 @@ public class PackageParser {
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
- Log.wtf(TAG, "Could not parse public key because RSA isn't included in build");
- return null;
+ Slog.wtf(TAG, "Could not parse public key: RSA KeyFactory not included in build");
} catch (InvalidKeySpecException e) {
// Not a RSA public key.
}
+ /* Now try it as a ECDSA key. */
+ try {
+ final KeyFactory keyFactory = KeyFactory.getInstance("EC");
+ return keyFactory.generatePublic(keySpec);
+ } catch (NoSuchAlgorithmException e) {
+ Slog.wtf(TAG, "Could not parse public key: EC KeyFactory not included in build");
+ } catch (InvalidKeySpecException e) {
+ // Not a ECDSA public key.
+ }
+
/* Now try it as a DSA key. */
try {
final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
- Log.wtf(TAG, "Could not parse public key because DSA isn't included in build");
- return null;
+ Slog.wtf(TAG, "Could not parse public key: DSA KeyFactory not included in build");
} catch (InvalidKeySpecException e) {
// Not a DSA public key.
}
+ /* Not a supported key type */
return null;
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index b69ca88..27d14b3 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1093,14 +1093,28 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>so <code>[x_s, y_s]</code> is the pixel coordinates of the world
* point, <code>z_s = 1</code>, and <code>w_s</code> is a measurement of disparity
* (depth) in pixel coordinates.</p>
+ * <p>Note that the coordinate system for this transform is the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} system,
+ * where <code>(0,0)</code> is the top-left of the
+ * preCorrectionActiveArraySize rectangle. Once the pose and
+ * intrinsic calibration transforms have been applied to a
+ * world point, then the android.lens.radialDistortion
+ * transform needs to be applied, and the result adjusted to
+ * be in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
+ * system (where <code>(0, 0)</code> is the top-left of the
+ * activeArraySize rectangle), to determine the final pixel
+ * coordinate of the world point for processed (non-RAW)
+ * output buffers.</p>
* <p><b>Units</b>:
- * Pixels in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
- * system.</p>
+ * Pixels in the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * coordinate system.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#LENS_POSE_ROTATION
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<float[]> LENS_INTRINSIC_CALIBRATION =
@@ -1109,13 +1123,13 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>The correction coefficients to correct for this camera device's
* radial and tangential lens distortion.</p>
- * <p>Three radial distortion coefficients <code>[kappa_1, kappa_2,
+ * <p>Four radial distortion coefficients <code>[kappa_0, kappa_1, kappa_2,
* kappa_3]</code> and two tangential distortion coefficients
* <code>[kappa_4, kappa_5]</code> that can be used to correct the
* lens's geometric distortion with the mapping equations:</p>
- * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * <pre><code> x_c = x_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
* kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
- * y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * y_c = y_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
* kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
* </code></pre>
* <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
@@ -1959,22 +1973,25 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<Integer>("android.scaler.croppingType", int.class);
/**
- * <p>The area of the image sensor which corresponds to
- * active pixels.</p>
- * <p>This is the region of the sensor that actually receives light from the scene.
- * Therefore, the size of this region determines the maximum field of view and the maximum
- * number of pixels that an image from this sensor can contain.</p>
- * <p>The rectangle is defined in terms of the full pixel array; (0,0) is the top-left of the
- * full pixel array, and the size of the full pixel array is given by
+ * <p>The area of the image sensor which corresponds to active pixels after any geometric
+ * distortion correction has been applied.</p>
+ * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
+ * the region that actually receives light from the scene) after any geometric correction
+ * has been applied, and should be treated as the maximum size in pixels of any of the
+ * image output formats aside from the raw formats.</p>
+ * <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
+ * the full pixel array, and the size of the full pixel array is given by
* {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</p>
- * <p>Most other keys listing pixel coordinates have their coordinate systems based on the
- * active array, with <code>(0, 0)</code> being the top-left of the active array rectangle.</p>
+ * <p>The coordinate system for most other keys that list pixel coordinates, including
+ * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, is defined relative to the active array rectangle given in
+ * this field, with <code>(0, 0)</code> being the top-left of this rectangle.</p>
* <p>The active array may be smaller than the full pixel array, since the full array may
- * include black calibration pixels or other inactive regions.</p>
+ * include black calibration pixels or other inactive regions, and geometric correction
+ * resulting in scaling or cropping may have been applied.</p>
* <p><b>Units</b>: Pixel coordinates on the image sensor</p>
- * <p><b>Range of valid values:</b><br></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
*/
@PublicKey
@@ -1982,6 +1999,70 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<android.graphics.Rect>("android.sensor.info.activeArraySize", android.graphics.Rect.class);
/**
+ * <p>The area of the image sensor which corresponds to active pixels prior to the
+ * application of any geometric distortion correction.</p>
+ * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
+ * the region that actually receives light from the scene) before any geometric correction
+ * has been applied, and should be treated as the active region rectangle for any of the
+ * raw formats. All metadata associated with raw processing (e.g. the lens shading
+ * correction map, and radial distortion fields) treats the top, left of this rectangle as
+ * the origin, (0,0).</p>
+ * <p>The size of this region determines the maximum field of view and the maximum number of
+ * pixels that an image from this sensor can contain, prior to the application of
+ * geometric distortion correction. The effective maximum pixel dimensions of a
+ * post-distortion-corrected image is given by the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}
+ * field, and the effective maximum field of view for a post-distortion-corrected image
+ * can be calculated by applying the geometric distortion correction fields to this
+ * rectangle, and cropping to the rectangle given in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>E.g. to calculate position of a pixel, (x,y), in a processed YUV output image with the
+ * dimensions in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} given the position of a pixel,
+ * (x', y'), in the raw pixel array with dimensions give in
+ * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}:</p>
+ * <ol>
+ * <li>Choose a pixel (x', y') within the active array region of the raw buffer given in
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, otherwise this pixel is considered
+ * to be outside of the FOV, and will not be shown in the processed output image.</li>
+ * <li>Apply geometric distortion correction to get the post-distortion pixel coordinate,
+ * (x_i, y_i). When applying geometric correction metadata, note that metadata for raw
+ * buffers is defined relative to the top, left of the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} rectangle.</li>
+ * <li>If the resulting corrected pixel coordinate is within the region given in
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, then the position of this pixel in the
+ * processed output image buffer is <code>(x_i - activeArray.left, y_i - activeArray.top)</code>,
+ * when the top, left coordinate of that buffer is treated as (0, 0).</li>
+ * </ol>
+ * <p>Thus, for pixel x',y' = (25, 25) on a sensor where {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}
+ * is (100,100), {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} is (10, 10, 100, 100),
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is (20, 20, 80, 80), and the geometric distortion
+ * correction doesn't change the pixel coordinate, the resulting pixel selected in
+ * pixel coordinates would be x,y = (25, 25) relative to the top,left of the raw buffer
+ * with dimensions given in {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}, and would be (5, 5)
+ * relative to the top,left of post-processed YUV output buffer with dimensions given in
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>The currently supported fields that correct for geometric distortion are:</p>
+ * <ol>
+ * <li>android.lens.radialDistortion.</li>
+ * </ol>
+ * <p>If all of the geometric distortion fields are no-ops, this rectangle will be the same
+ * as the post-distortion-corrected rectangle given in
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
+ * the full pixel array, and the size of the full pixel array is given by
+ * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</p>
+ * <p>The pre-correction active array may be smaller than the full pixel array, since the
+ * full array may include black calibration pixels or other inactive regions.</p>
+ * <p><b>Units</b>: Pixel coordinates on the image sensor</p>
+ * <p>This key is available on all devices.</p>
+ *
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+ */
+ @PublicKey
+ public static final Key<android.graphics.Rect> SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE =
+ new Key<android.graphics.Rect>("android.sensor.info.preCorrectionActiveArraySize", android.graphics.Rect.class);
+
+ /**
* <p>Range of sensitivities for {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} supported by this
* camera device.</p>
* <p>The values are the standard ISO sensitivity values,
@@ -2089,22 +2170,24 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>Dimensions of the full pixel array, possibly
* including black calibration pixels.</p>
- * <p>The pixel count of the full pixel array,
- * which covers {@link CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE android.sensor.info.physicalSize} area.</p>
- * <p>If a camera device supports raw sensor formats, either this
- * or {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is the maximum output
- * raw size listed in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.
- * If a size corresponding to pixelArraySize is listed, the resulting
- * raw sensor image will include black pixels.</p>
+ * <p>The pixel count of the full pixel array of the image sensor, which covers
+ * {@link CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE android.sensor.info.physicalSize} area. This represents the full pixel dimensions of
+ * the raw buffers produced by this sensor.</p>
+ * <p>If a camera device supports raw sensor formats, either this or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} is the maximum dimensions for the raw
+ * output formats listed in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} (this depends on
+ * whether or not the image sensor returns buffers containing pixels that are not
+ * part of the active array region for blacklevel calibration or other purposes).</p>
* <p>Some parts of the full pixel array may not receive light from the scene,
- * or are otherwise inactive. The {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} key
- * defines the rectangle of active pixels that actually forms an image.</p>
+ * or be otherwise inactive. The {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} key
+ * defines the rectangle of active pixels that will be included in processed image
+ * formats.</p>
* <p><b>Units</b>: Pixels</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
- * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE =
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3bb2fdb..da216aa 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2655,14 +2655,28 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p>so <code>[x_s, y_s]</code> is the pixel coordinates of the world
* point, <code>z_s = 1</code>, and <code>w_s</code> is a measurement of disparity
* (depth) in pixel coordinates.</p>
+ * <p>Note that the coordinate system for this transform is the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} system,
+ * where <code>(0,0)</code> is the top-left of the
+ * preCorrectionActiveArraySize rectangle. Once the pose and
+ * intrinsic calibration transforms have been applied to a
+ * world point, then the android.lens.radialDistortion
+ * transform needs to be applied, and the result adjusted to
+ * be in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
+ * system (where <code>(0, 0)</code> is the top-left of the
+ * activeArraySize rectangle), to determine the final pixel
+ * coordinate of the world point for processed (non-RAW)
+ * output buffers.</p>
* <p><b>Units</b>:
- * Pixels in the {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} coordinate
- * system.</p>
+ * Pixels in the
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * coordinate system.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#LENS_POSE_ROTATION
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<float[]> LENS_INTRINSIC_CALIBRATION =
@@ -2671,13 +2685,13 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
/**
* <p>The correction coefficients to correct for this camera device's
* radial and tangential lens distortion.</p>
- * <p>Three radial distortion coefficients <code>[kappa_1, kappa_2,
+ * <p>Four radial distortion coefficients <code>[kappa_0, kappa_1, kappa_2,
* kappa_3]</code> and two tangential distortion coefficients
* <code>[kappa_4, kappa_5]</code> that can be used to correct the
* lens's geometric distortion with the mapping equations:</p>
- * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * <pre><code> x_c = x_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
* kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
- * y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+ * y_c = y_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
* kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
* </code></pre>
* <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 8512b23..83128c3 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -537,12 +537,16 @@ public class CameraDeviceImpl extends CameraDevice {
CameraAccessException pendingException = null;
Surface input = null;
try {
- // configure streams and then block until IDLE
+ // configure streams and then block until IDLE
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
isConstrainedHighSpeed);
- if (inputConfig != null) {
+ if (configureSuccess == true && inputConfig != null) {
input = new Surface();
- mRemoteDevice.getInputSurface(/*out*/input);
+ try {
+ mRemoteDevice.getInputSurface(/*out*/input);
+ } catch (CameraRuntimeException e) {
+ e.asChecked();
+ }
}
} catch (CameraAccessException e) {
configureSuccess = false;
@@ -2049,12 +2053,16 @@ public class CameraDeviceImpl extends CameraDevice {
// Prepare the Request builders: need carry over the request controls.
// First, create a request builder that will only include preview or recording target.
CameraMetadataNative requestMetadata = new CameraMetadataNative(request.getNativeCopy());
+ // Note that after this step, the requestMetadata is mutated (swapped) and can not be used
+ // for next request builder creation.
CaptureRequest.Builder singleTargetRequestBuilder = new CaptureRequest.Builder(
requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
// Overwrite the capture intent to make sure a good value is set.
- Surface[] surfaces = (Surface[])outputSurfaces.toArray();
- if (outputSurfaces.size() == 1 && SurfaceUtils.isSurfaceForHwVideoEncoder(surfaces[0])) {
+ Iterator<Surface> iterator = outputSurfaces.iterator();
+ Surface firstSurface = iterator.next();
+ Surface secondSurface = null;
+ if (outputSurfaces.size() == 1 && SurfaceUtils.isSurfaceForHwVideoEncoder(firstSurface)) {
singleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
} else {
@@ -2067,23 +2075,27 @@ public class CameraDeviceImpl extends CameraDevice {
// Second, Create a request builder that will include both preview and recording targets.
CaptureRequest.Builder doubleTargetRequestBuilder = null;
if (outputSurfaces.size() == 2) {
+ // Have to create a new copy, the original one was mutated after a new
+ // CaptureRequest.Builder creation.
+ requestMetadata = new CameraMetadataNative(request.getNativeCopy());
doubleTargetRequestBuilder = new CaptureRequest.Builder(
requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
doubleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
- doubleTargetRequestBuilder.addTarget(surfaces[0]);
- doubleTargetRequestBuilder.addTarget(surfaces[1]);
+ doubleTargetRequestBuilder.addTarget(firstSurface);
+ secondSurface = iterator.next();
+ doubleTargetRequestBuilder.addTarget(secondSurface);
doubleTargetRequestBuilder.setPartOfCHSRequestList(/*partOfCHSList*/true);
// Make sure singleTargetRequestBuilder contains only recording surface for
// preview + recording case.
- Surface recordingSurface = surfaces[0];
+ Surface recordingSurface = firstSurface;
if (!SurfaceUtils.isSurfaceForHwVideoEncoder(recordingSurface)) {
- recordingSurface = surfaces[1];
+ recordingSurface = secondSurface;
}
singleTargetRequestBuilder.addTarget(recordingSurface);
} else {
// Single output case: either recording or preview.
- singleTargetRequestBuilder.addTarget(surfaces[0]);
+ singleTargetRequestBuilder.addTarget(firstSurface);
}
// Generate the final request list.
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index cc95c0e..2fb3203 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -85,7 +85,7 @@ public class LegacyCameraDevice implements AutoCloseable {
private static final int GRALLOC_USAGE_HW_RENDER = 0x00000200;
private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000;
- public static final int MAX_DIMEN_FOR_ROUNDING = 1080; // maximum allowed width for rounding
+ public static final int MAX_DIMEN_FOR_ROUNDING = 1920; // maximum allowed width for rounding
// Keep up to date with values in system/core/include/system/window.h
public static final int NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1;
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 348b14a..4866598 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -187,8 +187,18 @@ public class RequestThreadManager {
private final Camera.ErrorCallback mErrorCallback = new Camera.ErrorCallback() {
@Override
public void onError(int i, Camera camera) {
- Log.e(TAG, "Received error " + i + " from the Camera1 ErrorCallback");
- mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
+ switch(i) {
+ case Camera.CAMERA_ERROR_EVICTED: {
+ flush();
+ mDeviceState.setError(
+ CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DISCONNECTED);
+ } break;
+ default: {
+ Log.e(TAG, "Received error " + i + " from the Camera1 ErrorCallback");
+ mDeviceState.setError(
+ CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
+ } break;
+ }
}
};
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index d461bca..1aee794 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -138,8 +138,8 @@ public class CameraBinderDecorator {
* errors, then add them to the top switch statement
*/
if (errorFlag < 0) {
- throw new UnsupportedOperationException(String.format("Unknown error %d",
- errorFlag));
+ throw new CameraRuntimeException(CAMERA_ERROR,
+ String.format("Unknown camera device error %d", errorFlag));
}
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3a3c47d..a2ca41c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -801,28 +801,6 @@ public class ConnectivityManager {
}
/**
- * Returns details about the Provisioning or currently active default data network. When
- * connected, this network is the default route for outgoing connections.
- * You should always check {@link NetworkInfo#isConnected()} before initiating
- * network traffic. This may return {@code null} when there is no default
- * network.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * or {@code null} if no default network is currently active
- *
- * {@hide}
- */
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- try {
- return mService.getProvisioningOrActiveNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
* Returns the IP information for the current default network.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
@@ -2007,24 +1985,6 @@ public class ConnectivityManager {
}
/**
- * Signal that the captive portal check on the indicated network
- * is complete and whether its a captive portal or not.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
- *
- * @param info the {@link NetworkInfo} object for the networkType
- * in question.
- * @param isCaptivePortal true/false.
- * {@hide}
- */
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- try {
- mService.captivePortalCheckCompleted(info, isCaptivePortal);
- } catch (RemoteException e) {
- }
- }
-
- /**
* Check mobile provisioning.
*
* @param suggestedTimeOutMs, timeout in milliseconds
@@ -2056,18 +2016,6 @@ public class ConnectivityManager {
}
/**
- * Get the mobile redirected provisioning url.
- * {@hide}
- */
- public String getMobileRedirectedProvisioningUrl() {
- try {
- return mService.getMobileRedirectedProvisioningUrl();
- } catch (RemoteException e) {
- }
- return null;
- }
-
- /**
* Set sign in error notification to visible or in visible
*
* @param visible
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 89d23a2..29557bb 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -53,8 +53,6 @@ interface IConnectivityManager
Network[] getAllNetworks();
NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId);
- NetworkInfo getProvisioningOrActiveNetworkInfo();
-
boolean isNetworkSupported(int networkType);
LinkProperties getActiveLinkProperties();
@@ -122,14 +120,10 @@ interface IConnectivityManager
boolean updateLockdownVpn();
- void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
-
int checkMobileProvisioning(int suggestedTimeOutMs);
String getMobileProvisioningUrl();
- String getMobileRedirectedProvisioningUrl();
-
void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
void setAirplaneMode(boolean enable);
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 9628bae..fe69320 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -378,6 +378,9 @@ public class Network implements Parcelable {
//
// The HANDLE_MAGIC value MUST be kept in sync with the corresponding
// value in the native/android/net.c NDK implementation.
+ if (netId == 0) {
+ return 0L; // make this zero condition obvious for debugging
+ }
final long HANDLE_MAGIC = 0xfacade;
return (((long) netId) << 32) | HANDLE_MAGIC;
}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 393637e..af7a465 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -120,7 +120,6 @@ public class NetworkInfo implements Parcelable {
private String mExtraInfo;
private boolean mIsFailover;
private boolean mIsRoaming;
- private boolean mIsConnectedToProvisioningNetwork;
/**
* Indicates whether network connectivity is possible:
@@ -142,7 +141,6 @@ public class NetworkInfo implements Parcelable {
mState = State.UNKNOWN;
mIsAvailable = false; // until we're told otherwise, assume unavailable
mIsRoaming = false;
- mIsConnectedToProvisioningNetwork = false;
}
/** {@hide} */
@@ -160,7 +158,6 @@ public class NetworkInfo implements Parcelable {
mIsFailover = source.mIsFailover;
mIsRoaming = source.mIsRoaming;
mIsAvailable = source.mIsAvailable;
- mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
}
}
}
@@ -332,22 +329,6 @@ public class NetworkInfo implements Parcelable {
}
}
- /** {@hide} */
- @VisibleForTesting
- public boolean isConnectedToProvisioningNetwork() {
- synchronized (this) {
- return mIsConnectedToProvisioningNetwork;
- }
- }
-
- /** {@hide} */
- @VisibleForTesting
- public void setIsConnectedToProvisioningNetwork(boolean val) {
- synchronized (this) {
- mIsConnectedToProvisioningNetwork = val;
- }
- }
-
/**
* Reports the current coarse-grained state of the network.
* @return the coarse-grained state
@@ -431,8 +412,6 @@ public class NetworkInfo implements Parcelable {
append(", roaming: ").append(mIsRoaming).
append(", failover: ").append(mIsFailover).
append(", isAvailable: ").append(mIsAvailable).
- append(", isConnectedToProvisioningNetwork: ").
- append(mIsConnectedToProvisioningNetwork).
append("]");
return builder.toString();
}
@@ -461,7 +440,6 @@ public class NetworkInfo implements Parcelable {
dest.writeInt(mIsFailover ? 1 : 0);
dest.writeInt(mIsAvailable ? 1 : 0);
dest.writeInt(mIsRoaming ? 1 : 0);
- dest.writeInt(mIsConnectedToProvisioningNetwork ? 1 : 0);
dest.writeString(mReason);
dest.writeString(mExtraInfo);
}
@@ -484,7 +462,6 @@ public class NetworkInfo implements Parcelable {
netInfo.mIsFailover = in.readInt() != 0;
netInfo.mIsAvailable = in.readInt() != 0;
netInfo.mIsRoaming = in.readInt() != 0;
- netInfo.mIsConnectedToProvisioningNetwork = in.readInt() != 0;
netInfo.mReason = in.readString();
netInfo.mExtraInfo = in.readString();
return netInfo;
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index ecc3fb4..3f40484 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -61,6 +61,17 @@ public class NetworkPolicyManager {
public static final int FIREWALL_RULE_ALLOW = 1;
public static final int FIREWALL_RULE_DENY = 2;
+ public static final int FIREWALL_TYPE_WHITELIST = 0;
+ public static final int FIREWALL_TYPE_BLACKLIST = 1;
+
+ public static final int FIREWALL_CHAIN_NONE = 0;
+ public static final int FIREWALL_CHAIN_DOZABLE = 1;
+ public static final int FIREWALL_CHAIN_STANDBY = 2;
+
+ public static final String FIREWALL_CHAIN_NAME_NONE = "none";
+ public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable";
+ public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
+
private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
/**
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index ff3de2b..bb08be2 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -53,6 +53,8 @@ public class TrafficStats {
public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
/** @hide */
public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
+ /** @hide */
+ public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;
/**
* Special UID value used when collecting {@link NetworkStatsHistory} for
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index a6efc58..d165240 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1177,8 +1177,13 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_ALARM = 0x000e;
// Record that we have decided we need to collect new stats data.
public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000f;
+ // Event for a package becoming inactive due to being unused for a period of time.
+ public static final int EVENT_PACKAGE_INACTIVE = 0x0010;
+ // Event for a package becoming active due to an interaction.
+ public static final int EVENT_PACKAGE_ACTIVE = 0x0011;
+
// Number of event types.
- public static final int EVENT_COUNT = 0x0010;
+ public static final int EVENT_COUNT = 0x0012;
// Mask to extract out only the type part of the event.
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
@@ -1835,12 +1840,12 @@ public abstract class BatteryStats implements Parcelable {
public static final String[] HISTORY_EVENT_NAMES = new String[] {
"null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
- "motion", "active", "pkginst", "pkgunin", "alarm", "stats"
+ "motion", "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active"
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
"Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
- "Esm", "Eac", "Epi", "Epu", "Eal", "Est"
+ "Esm", "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa"
};
/**
@@ -3536,8 +3541,15 @@ public abstract class BatteryStats implements Parcelable {
}
printmAh(pw, bs.totalPowerMah);
- if (bs.drainType == BatterySipper.DrainType.APP) {
+ if (bs.usagePowerMah != bs.totalPowerMah) {
+ // If the usage (generic power) isn't the whole amount, we list out
+ // what components are involved in the calculation.
+
pw.print(" (");
+ if (bs.usagePowerMah != 0) {
+ pw.print(" usage=");
+ printmAh(pw, bs.usagePowerMah);
+ }
if (bs.cpuPowerMah != 0) {
pw.print(" cpu=");
printmAh(pw, bs.cpuPowerMah);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index b29e8d0..8114155 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -342,7 +342,9 @@ interface INetworkManagementService
void setFirewallInterfaceRule(String iface, boolean allow);
void setFirewallEgressSourceRule(String addr, boolean allow);
void setFirewallEgressDestRule(String addr, int port, boolean allow);
- void setFirewallUidRule(int uid, int rule);
+ void setFirewallUidRule(int chain, int uid, int rule);
+ void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
+ void setFirewallChainEnabled(int chain, boolean enable);
/**
* Set all packets from users in ranges to go through VPN specified by netId.
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 8b18f32..6ef1cd0 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -392,6 +392,8 @@ public final class PowerManager {
final IPowerManager mService;
final Handler mHandler;
+ IDeviceIdleController mIDeviceIdleController;
+
/**
* {@hide}
*/
@@ -878,7 +880,10 @@ public final class PowerManager {
* off network access to apps. You can monitor for changes to this state with
* {@link #ACTION_DEVICE_IDLE_MODE_CHANGED}.
*
- * @return Returns true if currently in low power mode, else false.
+ * @return Returns true if currently in active device idle mode, else false. This is
+ * when idle mode restrictions are being actively applied; it will return false if the
+ * device is in a long-term idle mode but currently running a maintenance window where
+ * restrictions have been lifted.
*/
public boolean isDeviceIdleMode() {
try {
@@ -889,6 +894,25 @@ public final class PowerManager {
}
/**
+ * Return whether the given application package name is on the device's power whitelist.
+ * Apps can be placed on the whitelist through the settings UI invoked by
+ * {@link android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}.
+ */
+ public boolean isIgnoringBatteryOptimizations(String packageName) {
+ synchronized (this) {
+ if (mIDeviceIdleController == null) {
+ mIDeviceIdleController = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ }
+ }
+ try {
+ return mIDeviceIdleController.isPowerSaveWhitelistApp(packageName);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
* Turn off the device.
*
* @param confirm If true, shows a shutdown confirmation dialog.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ef7e747..00350ec 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -362,6 +362,18 @@ public class UserManager {
public static final String DISALLOW_SMS = "no_sms";
/**
+ * Specifies if the user is not allowed to have fun. In some cases, the
+ * device owner may wish to prevent the user from experiencing amusement or
+ * joy while using the device. The default value is <code>false</code>.
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_FUN = "no_fun";
+
+ /**
* Specifies that windows besides app windows should not be
* created. This will block the creation of the following types of windows.
* <li>{@link LayoutParams#TYPE_TOAST}</li>
diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java
index 5bc45d5..397d87e 100644
--- a/core/java/android/os/storage/DiskInfo.java
+++ b/core/java/android/os/storage/DiskInfo.java
@@ -40,6 +40,8 @@ public class DiskInfo implements Parcelable {
"android.os.storage.action.DISK_SCANNED";
public static final String EXTRA_DISK_ID =
"android.os.storage.extra.DISK_ID";
+ public static final String EXTRA_VOLUME_COUNT =
+ "android.os.storage.extra.VOLUME_COUNT";
public static final int FLAG_ADOPTABLE = 1 << 0;
public static final int FLAG_DEFAULT_PRIMARY = 1 << 1;
diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
index c958fb0..cade9d7 100644
--- a/core/java/android/os/storage/IMountServiceListener.java
+++ b/core/java/android/os/storage/IMountServiceListener.java
@@ -113,6 +113,13 @@ public interface IMountServiceListener extends IInterface {
reply.writeNoException();
return true;
}
+ case TRANSACTION_onDiskDestroyed: {
+ data.enforceInterface(DESCRIPTOR);
+ final DiskInfo disk = (DiskInfo) data.readParcelable(null);
+ onDiskDestroyed(disk);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
}
@@ -246,6 +253,22 @@ public interface IMountServiceListener extends IInterface {
_data.recycle();
}
}
+
+ @Override
+ public void onDiskDestroyed(DiskInfo disk) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeParcelable(disk, 0);
+ mRemote.transact(Stub.TRANSACTION_onDiskDestroyed, _data, _reply,
+ android.os.IBinder.FLAG_ONEWAY);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
}
static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0);
@@ -254,6 +277,7 @@ public interface IMountServiceListener extends IInterface {
static final int TRANSACTION_onVolumeRecordChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_onVolumeForgotten = (IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 5);
+ static final int TRANSACTION_onDiskDestroyed = (IBinder.FIRST_CALL_TRANSACTION + 6);
}
/**
@@ -280,4 +304,6 @@ public interface IMountServiceListener extends IInterface {
public void onVolumeForgotten(String fsUuid) throws RemoteException;
public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
+
+ public void onDiskDestroyed(DiskInfo disk) throws RemoteException;
}
diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java
index 214c60d..4cf83fd 100644
--- a/core/java/android/os/storage/StorageEventListener.java
+++ b/core/java/android/os/storage/StorageEventListener.java
@@ -49,4 +49,7 @@ public class StorageEventListener {
public void onDiskScanned(DiskInfo disk, int volumeCount) {
}
+
+ public void onDiskDestroyed(DiskInfo disk) {
+ }
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 4bbaaa1..9b26f24 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -101,6 +101,7 @@ public class StorageManager {
private static final int MSG_VOLUME_RECORD_CHANGED = 3;
private static final int MSG_VOLUME_FORGOTTEN = 4;
private static final int MSG_DISK_SCANNED = 5;
+ private static final int MSG_DISK_DESTROYED = 6;
final StorageEventListener mCallback;
final Handler mHandler;
@@ -135,6 +136,10 @@ public class StorageManager {
mCallback.onDiskScanned((DiskInfo) args.arg1, args.argi2);
args.recycle();
return true;
+ case MSG_DISK_DESTROYED:
+ mCallback.onDiskDestroyed((DiskInfo) args.arg1);
+ args.recycle();
+ return true;
}
args.recycle();
return false;
@@ -184,6 +189,13 @@ public class StorageManager {
args.argi2 = volumeCount;
mHandler.obtainMessage(MSG_DISK_SCANNED, args).sendToTarget();
}
+
+ @Override
+ public void onDiskDestroyed(DiskInfo disk) throws RemoteException {
+ final SomeArgs args = SomeArgs.obtain();
+ args.arg1 = disk;
+ mHandler.obtainMessage(MSG_DISK_DESTROYED, args).sendToTarget();
+ }
}
/**
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 372725f..8d11527 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -55,6 +55,8 @@ public class VolumeInfo implements Parcelable {
"android.os.storage.action.VOLUME_STATE_CHANGED";
public static final String EXTRA_VOLUME_ID =
"android.os.storage.extra.VOLUME_ID";
+ public static final String EXTRA_VOLUME_STATE =
+ "android.os.storage.extra.VOLUME_STATE";
/** Stub volume representing internal private storage */
public static final String ID_PRIVATE_INTERNAL = "private";
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index bae06b8..7d05522 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -16,7 +16,6 @@
package android.provider;
-import android.annotation.RequiresPermission;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -24,6 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
+import android.database.MatrixCursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.BrowserContract.Bookmarks;
@@ -33,20 +33,14 @@ import android.provider.BrowserContract.Searches;
import android.util.Log;
import android.webkit.WebIconDatabase;
-import static android.Manifest.permission.READ_HISTORY_BOOKMARKS;
-import static android.Manifest.permission.WRITE_HISTORY_BOOKMARKS;
-
public class Browser {
private static final String LOGTAG = "browser";
/**
* A table containing both bookmarks and history items. The columns of the table are defined in
- * {@link BookmarkColumns}. Reading this table requires the
- * {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS} permission and writing to it
- * requires the {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS} permission.
+ * {@link BookmarkColumns}.
+ * @removed
*/
- @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
- @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
/**
@@ -79,8 +73,7 @@ public class Browser {
*/
public static final String EXTRA_HEADERS = "com.android.browser.headers";
- /* if you change column order you must also change indices
- below */
+ /** @removed if you change column order you must also change indices below */
public static final String[] HISTORY_PROJECTION = new String[] {
BookmarkColumns._ID, // 0
BookmarkColumns.URL, // 1
@@ -94,13 +87,25 @@ public class Browser {
BookmarkColumns.USER_ENTERED, // 9
};
- /* these indices dependent on HISTORY_PROJECTION */
+ /** @removed these indices dependent on HISTORY_PROJECTION */
public static final int HISTORY_PROJECTION_ID_INDEX = 0;
+
+ /** @removed */
public static final int HISTORY_PROJECTION_URL_INDEX = 1;
+
+ /** @removed */
public static final int HISTORY_PROJECTION_VISITS_INDEX = 2;
+
+ /** @removed */
public static final int HISTORY_PROJECTION_DATE_INDEX = 3;
+
+ /** @removed */
public static final int HISTORY_PROJECTION_BOOKMARK_INDEX = 4;
+
+ /** @removed */
public static final int HISTORY_PROJECTION_TITLE_INDEX = 5;
+
+ /** @removed */
public static final int HISTORY_PROJECTION_FAVICON_INDEX = 6;
/**
* @hide
@@ -111,30 +116,29 @@ public class Browser {
*/
public static final int HISTORY_PROJECTION_TOUCH_ICON_INDEX = 8;
- /* columns needed to determine whether to truncate history */
+ /** @removed columns needed to determine whether to truncate history @removed */
public static final String[] TRUNCATE_HISTORY_PROJECTION = new String[] {
BookmarkColumns._ID,
BookmarkColumns.DATE,
};
+ /** @removed */
public static final int TRUNCATE_HISTORY_PROJECTION_ID_INDEX = 0;
- /* truncate this many history items at a time */
+ /** @removed truncate this many history items at a time */
public static final int TRUNCATE_N_OLDEST = 5;
/**
* A table containing a log of browser searches. The columns of the table are defined in
- * {@link SearchColumns}. Reading this table requires the
- * {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS} permission and writing to it
- * requires the {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS} permission.
+ * {@link SearchColumns}.
+ * @removed
*/
- @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
- @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri SEARCHES_URI = Uri.parse("content://browser/searches");
/**
* A projection of {@link #SEARCHES_URI} that contains {@link SearchColumns#_ID},
* {@link SearchColumns#SEARCH}, and {@link SearchColumns#DATE}.
+ * @removed
*/
public static final String[] SEARCHES_PROJECTION = new String[] {
// if you change column order you must also change indices below
@@ -143,8 +147,9 @@ public class Browser {
SearchColumns.DATE, // 2
};
- /* these indices dependent on SEARCHES_PROJECTION */
+ /** @removed these indices dependent on SEARCHES_PROJECTION */
public static final int SEARCHES_PROJECTION_SEARCH_INDEX = 1;
+ /** @removed */
public static final int SEARCHES_PROJECTION_DATE_INDEX = 2;
/* Set a cap on the count of history items in the history/bookmark
@@ -162,14 +167,11 @@ public class Browser {
* @param c Context used to launch the activity to add a bookmark.
* @param title Title for the bookmark. Can be null or empty string.
* @param url Url for the bookmark. Can be null or empty string.
+ * @removed
*/
public static final void saveBookmark(Context c,
String title,
String url) {
- Intent i = new Intent(Intent.ACTION_INSERT, Browser.BOOKMARKS_URI);
- i.putExtra("title", title);
- i.putExtra("url", url);
- c.startActivity(i);
}
/**
@@ -236,33 +238,25 @@ public class Browser {
/**
* Return a cursor pointing to a list of all the bookmarks. The cursor will have a single
* column, {@link BookmarkColumns#URL}.
- * <p>
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
*
* @param cr The ContentResolver used to access the database.
+ * @removed
*/
- @RequiresPermission(READ_HISTORY_BOOKMARKS)
public static final Cursor getAllBookmarks(ContentResolver cr) throws
IllegalStateException {
- return cr.query(Bookmarks.CONTENT_URI,
- new String[] { Bookmarks.URL },
- Bookmarks.IS_FOLDER + " = 0", null, null);
+ return new MatrixCursor(new String[]{Bookmarks.URL}, 0);
}
/**
* Return a cursor pointing to a list of all visited site urls. The cursor will
* have a single column, {@link BookmarkColumns#URL}.
- * <p>
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
*
* @param cr The ContentResolver used to access the database.
+ * @removed
*/
- @RequiresPermission(READ_HISTORY_BOOKMARKS)
public static final Cursor getAllVisitedUrls(ContentResolver cr) throws
IllegalStateException {
- return cr.query(Combined.CONTENT_URI,
- new String[] { Combined.URL }, null, null,
- Combined.DATE_CREATED + " ASC");
+ return new MatrixCursor(new String[]{Combined.URL}, 0);
}
private static final void addOrUrlEquals(StringBuilder sb) {
@@ -311,87 +305,26 @@ public class Browser {
/**
* Update the visited history to acknowledge that a site has been
* visited.
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @param url The site being visited.
* @param real If true, this is an actual visit, and should add to the
* number of visits. If false, the user entered it manually.
+ * @removed
*/
- @RequiresPermission(allOf = {READ_HISTORY_BOOKMARKS, WRITE_HISTORY_BOOKMARKS})
public static final void updateVisitedHistory(ContentResolver cr,
String url, boolean real) {
- long now = System.currentTimeMillis();
- Cursor c = null;
- try {
- c = getVisitedLike(cr, url);
- /* We should only get one answer that is exactly the same. */
- if (c.moveToFirst()) {
- ContentValues values = new ContentValues();
- if (real) {
- values.put(History.VISITS, c.getInt(1) + 1);
- } else {
- values.put(History.USER_ENTERED, 1);
- }
- values.put(History.DATE_LAST_VISITED, now);
- cr.update(ContentUris.withAppendedId(History.CONTENT_URI, c.getLong(0)),
- values, null, null);
- } else {
- truncateHistory(cr);
- ContentValues values = new ContentValues();
- int visits;
- int user_entered;
- if (real) {
- visits = 1;
- user_entered = 0;
- } else {
- visits = 0;
- user_entered = 1;
- }
- values.put(History.URL, url);
- values.put(History.VISITS, visits);
- values.put(History.DATE_LAST_VISITED, now);
- values.put(History.TITLE, url);
- values.put(History.DATE_CREATED, 0);
- values.put(History.USER_ENTERED, user_entered);
- cr.insert(History.CONTENT_URI, values);
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "updateVisitedHistory", e);
- } finally {
- if (c != null) c.close();
- }
}
/**
* Returns all the URLs in the history.
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @hide pending API council approval
*/
- @RequiresPermission(READ_HISTORY_BOOKMARKS)
+ @Deprecated
public static final String[] getVisitedHistory(ContentResolver cr) {
- Cursor c = null;
- String[] str = null;
- try {
- String[] projection = new String[] {
- History.URL,
- };
- c = cr.query(History.CONTENT_URI, projection, History.VISITS + " > 0", null, null);
- if (c == null) return new String[0];
- str = new String[c.getCount()];
- int i = 0;
- while (c.moveToNext()) {
- str[i] = c.getString(0);
- i++;
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "getVisitedHistory", e);
- str = new String[0];
- } finally {
- if (c != null) c.close();
- }
- return str;
+ return new String[0];
}
/**
@@ -400,184 +333,91 @@ public class Browser {
* of them. This is used to keep our history table to a
* reasonable size. Note: it does not prune bookmarks. If the
* user wants 1000 bookmarks, the user gets 1000 bookmarks.
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
*
* @param cr The ContentResolver used to access the database.
+ * @removed
*/
- @RequiresPermission(allOf = {READ_HISTORY_BOOKMARKS, WRITE_HISTORY_BOOKMARKS})
public static final void truncateHistory(ContentResolver cr) {
- // TODO make a single request to the provider to do this in a single transaction
- Cursor cursor = null;
- try {
-
- // Select non-bookmark history, ordered by date
- cursor = cr.query(History.CONTENT_URI,
- new String[] { History._ID, History.URL, History.DATE_LAST_VISITED },
- null, null, History.DATE_LAST_VISITED + " ASC");
-
- if (cursor.moveToFirst() && cursor.getCount() >= MAX_HISTORY_COUNT) {
- /* eliminate oldest history items */
- for (int i = 0; i < TRUNCATE_N_OLDEST; i++) {
- cr.delete(ContentUris.withAppendedId(History.CONTENT_URI, cursor.getLong(0)),
- null, null);
- if (!cursor.moveToNext()) break;
- }
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "truncateHistory", e);
- } finally {
- if (cursor != null) cursor.close();
- }
}
/**
* Returns whether there is any history to clear.
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @return boolean True if the history can be cleared.
+ * @removed
*/
- @RequiresPermission(READ_HISTORY_BOOKMARKS)
public static final boolean canClearHistory(ContentResolver cr) {
- Cursor cursor = null;
- boolean ret = false;
- try {
- cursor = cr.query(History.CONTENT_URI,
- new String [] { History._ID, History.VISITS },
- null, null, null);
- ret = cursor.getCount() > 0;
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "canClearHistory", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return ret;
+ return false;
}
/**
* Delete all entries from the bookmarks/history table which are
* not bookmarks. Also set all visited bookmarks to unvisited.
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
+ * @removed
*/
- @RequiresPermission(WRITE_HISTORY_BOOKMARKS)
public static final void clearHistory(ContentResolver cr) {
- deleteHistoryWhere(cr, null);
- }
- /**
- * Helper function to delete all history items and release the icons for them in the
- * {@link WebIconDatabase}.
- *
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
- *
- * @param cr The ContentResolver used to access the database.
- * @param whereClause String to limit the items affected.
- * null means all items.
- */
- @RequiresPermission(allOf = {READ_HISTORY_BOOKMARKS, WRITE_HISTORY_BOOKMARKS})
- private static final void deleteHistoryWhere(ContentResolver cr, String whereClause) {
- Cursor cursor = null;
- try {
- cursor = cr.query(History.CONTENT_URI, new String[] { History.URL }, whereClause,
- null, null);
- if (cursor.moveToFirst()) {
- cr.delete(History.CONTENT_URI, whereClause, null);
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "deleteHistoryWhere", e);
- return;
- } finally {
- if (cursor != null) cursor.close();
- }
}
/**
* Delete all history items from begin to end.
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @param begin First date to remove. If -1, all dates before end.
* Inclusive.
* @param end Last date to remove. If -1, all dates after begin.
* Non-inclusive.
+ * @removed
*/
- @RequiresPermission(WRITE_HISTORY_BOOKMARKS)
public static final void deleteHistoryTimeFrame(ContentResolver cr,
long begin, long end) {
- String whereClause;
- String date = BookmarkColumns.DATE;
- if (-1 == begin) {
- if (-1 == end) {
- clearHistory(cr);
- return;
- }
- whereClause = date + " < " + Long.toString(end);
- } else if (-1 == end) {
- whereClause = date + " >= " + Long.toString(begin);
- } else {
- whereClause = date + " >= " + Long.toString(begin) + " AND " + date
- + " < " + Long.toString(end);
- }
- deleteHistoryWhere(cr, whereClause);
}
/**
* Remove a specific url from the history database.
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @param url url to remove.
+ * @removed
*/
- @RequiresPermission(WRITE_HISTORY_BOOKMARKS)
public static final void deleteFromHistory(ContentResolver cr,
String url) {
- cr.delete(History.CONTENT_URI, History.URL + "=?", new String[] { url });
}
/**
* Add a search string to the searches database.
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @param search The string to add to the searches database.
+ * @removed
*/
- @RequiresPermission(allOf = {READ_HISTORY_BOOKMARKS, WRITE_HISTORY_BOOKMARKS})
public static final void addSearchUrl(ContentResolver cr, String search) {
- // The content provider will take care of updating existing searches instead of duplicating
- ContentValues values = new ContentValues();
- values.put(Searches.SEARCH, search);
- values.put(Searches.DATE, System.currentTimeMillis());
- cr.insert(Searches.CONTENT_URI, values);
}
/**
* Remove all searches from the search database.
- * Requires {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
+ * @removed
*/
- @RequiresPermission(WRITE_HISTORY_BOOKMARKS)
public static final void clearSearches(ContentResolver cr) {
- // FIXME: Should this clear the urls to which these searches lead?
- // (i.e. remove google.com/query= blah blah blah)
- try {
- cr.delete(Searches.CONTENT_URI, null, null);
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "clearSearches", e);
- }
}
/**
* Request all icons from the database. This call must either be called
* in the main thread or have had Looper.prepare() invoked in the calling
* thread.
- * Requires {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
+ *
* @param cr The ContentResolver used to access the database.
* @param where Clause to be used to limit the query from the database.
* Must be an allowable string to be passed into a database query.
* @param listener IconListener that gets the icons once they are
* retrieved.
+ * @removed
*/
- @RequiresPermission(READ_HISTORY_BOOKMARKS)
public static final void requestAllIcons(ContentResolver cr, String where,
WebIconDatabase.IconListener listener) {
// Do nothing: this is no longer used.
@@ -586,6 +426,7 @@ public class Browser {
/**
* Column definitions for the mixed bookmark and history items available
* at {@link #BOOKMARKS_URI}.
+ * @removed
*/
public static class BookmarkColumns implements BaseColumns {
/**
@@ -649,6 +490,7 @@ public class Browser {
/**
* Column definitions for the search history table, available at {@link #SEARCHES_URI}.
+ * @removed
*/
public static class SearchColumns implements BaseColumns {
/**
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 30535ff..c7ba607 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -107,6 +107,11 @@ public final class DocumentsContract {
*/
public static final String EXTRA_ORIENTATION = "android.content.extra.ORIENTATION";
+ /**
+ * Overrides the default prompt text in DocumentsUI when set in an intent.
+ */
+ public static final String EXTRA_PROMPT = "android.provider.extra.PROMPT";
+
/** {@hide} */
public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT";
/** {@hide} */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f2d3e71..56cd1a7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -579,13 +579,14 @@ public final class Settings {
/**
* Activity Action: Show screen for controlling which apps can ignore battery optimizations.
* <p>
- * In some cases, a matching Activity may not exist, so ensure you
- * safeguard against this.
- * <p>
- * Input: The Intent's data URI specifies the application package name
+ * Input: Optionally, the Intent's data URI specifies the application package name
* to be shown, with the "package" scheme. That is "package:com.my.app".
* <p>
* Output: Nothing.
+ * <p>
+ * You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations
+ * PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is
+ * already ignoring optimizations.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS =
@@ -5551,13 +5552,6 @@ public final class Settings {
public static final String SLEEP_TIMEOUT = "sleep_timeout";
/**
- * Duration in milliseconds that an app should be inactive before it is considered idle.
- * <p/>Type: Long
- * @hide
- */
- public static final String APP_IDLE_DURATION = "app_idle_duration";
-
- /**
* Controls whether double tap to wake is enabled.
* @hide
*/
@@ -7117,6 +7111,51 @@ public final class Settings {
public static final String DEVICE_IDLE_CONSTANTS = "device_idle_constants";
/**
+ * App standby (app idle) specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "idle_duration=5000,parole_interval=4500"
+ *
+ * The following keys are supported:
+ *
+ * <pre>
+ * idle_duration (long)
+ * wallclock_threshold (long)
+ * parole_interval (long)
+ * parole_duration (long)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * @hide
+ * @see com.android.server.usage.UsageStatsService.SettingsObserver
+ */
+ public static final String APP_IDLE_CONSTANTS = "app_idle_constants";
+
+ /**
+ * Alarm manager specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "min_futurity=5000,allow_while_idle_short_time=4500"
+ *
+ * The following keys are supported:
+ *
+ * <pre>
+ * min_futurity (long)
+ * min_interval (long)
+ * allow_while_idle_short_time (long)
+ * allow_while_idle_long_time (long)
+ * allow_while_idle_whitelist_duration (long)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * @hide
+ * @see com.android.server.AlarmManagerService.Constants
+ */
+ public static final String ALARM_MANAGER_CONSTANTS = "alarm_manager_constants";
+
+ /**
* Get the key that retrieves a bluetooth headset's priority.
* @hide
*/
@@ -7216,13 +7255,6 @@ public final class Settings {
"preferred_network_mode";
/**
- * Setting to 1 will hide carrier network settings.
- * Default is 0.
- */
- public static final String HIDE_CARRIER_NETWORK_SETTINGS =
- "hide_carrier_network_settings";
-
- /**
* Name of an application package to be debugged.
*/
public static final String DEBUG_APP = "debug_app";
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 6e40c6c..3fb93c4 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -81,7 +81,6 @@ public final class KeymasterDefs {
public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000;
public static final int KM_TAG_NONCE = KM_BYTES | 1001;
- public static final int KM_TAG_AEAD_TAG = KM_BYTES | 1002;
public static final int KM_TAG_AUTH_TOKEN = KM_BYTES | 1003;
public static final int KM_TAG_MAC_LENGTH = KM_INT | 1004;
diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java
index 911a05a..3065966 100644
--- a/core/java/android/security/keymaster/OperationResult.java
+++ b/core/java/android/security/keymaster/OperationResult.java
@@ -35,15 +35,28 @@ public class OperationResult implements Parcelable {
public static final Parcelable.Creator<OperationResult> CREATOR = new
Parcelable.Creator<OperationResult>() {
+ @Override
public OperationResult createFromParcel(Parcel in) {
return new OperationResult(in);
}
+ @Override
public OperationResult[] newArray(int length) {
return new OperationResult[length];
}
};
+ public OperationResult(
+ int resultCode, IBinder token, long operationHandle, int inputConsumed, byte[] output,
+ KeymasterArguments outParams) {
+ this.resultCode = resultCode;
+ this.token = token;
+ this.operationHandle = operationHandle;
+ this.inputConsumed = inputConsumed;
+ this.output = output;
+ this.outParams = outParams;
+ }
+
protected OperationResult(Parcel in) {
resultCode = in.readInt();
token = in.readStrongBinder();
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index d5ee7e7..98c684c 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -80,7 +80,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
public static final int SHOW_WITH_ASSIST = 1<<0;
/**
- * @hide
* Flag received in {@link #onShow}: originator requested that the session be started with
* a screen shot of the currently focused activity.
*/
@@ -1143,7 +1142,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
mContentFrame.addView(view, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
-
+ mContentFrame.requestApplyInsets();
}
/** @hide */
@@ -1162,7 +1161,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
onHandleAssist(data);
}
- /** @hide */
public void onHandleScreenshot(Bitmap screenshot) {
}
diff --git a/core/java/android/speech/srec/MicrophoneInputStream.java b/core/java/android/speech/srec/MicrophoneInputStream.java
deleted file mode 100644
index 94db176..0000000
--- a/core/java/android/speech/srec/MicrophoneInputStream.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*---------------------------------------------------------------------------*
- * MicrophoneInputStream.java *
- * *
- * Copyright 2007 Nuance Communciations, Inc. *
- * *
- * Licensed under the Apache License, Version 2.0 (the 'License'); *
- * you may not use this file except in compliance with the License. *
- * *
- * You may obtain a copy of the License at *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, software *
- * distributed under the License is distributed on an 'AS IS' BASIS, *
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
- * See the License for the specific language governing permissions and *
- * limitations under the License. *
- * *
- *---------------------------------------------------------------------------*/
-
-
-package android.speech.srec;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.IllegalStateException;
-
-
-/**
- * PCM input stream from the microphone, 16 bits per sample.
- */
-public final class MicrophoneInputStream extends InputStream {
- static {
- System.loadLibrary("srec_jni");
- }
-
- private final static String TAG = "MicrophoneInputStream";
- private long mAudioRecord = 0;
- private byte[] mOneByte = new byte[1];
-
- /**
- * MicrophoneInputStream constructor.
- * @param sampleRate sample rate of the microphone, typically 11025 or 8000.
- * @param fifoDepth depth of the real time fifo, measured in sampleRate clock ticks.
- * This determines how long an application may delay before losing data.
- */
- public MicrophoneInputStream(int sampleRate, int fifoDepth) throws IOException {
- mAudioRecord = AudioRecordNew(sampleRate, fifoDepth);
- if (mAudioRecord == 0) throw new IOException("AudioRecord constructor failed - busy?");
- int status = AudioRecordStart(mAudioRecord);
- if (status != 0) {
- close();
- throw new IOException("AudioRecord start failed: " + status);
- }
- }
-
- @Override
- public int read() throws IOException {
- if (mAudioRecord == 0) throw new IllegalStateException("not open");
- int rtn = AudioRecordRead(mAudioRecord, mOneByte, 0, 1);
- return rtn == 1 ? ((int)mOneByte[0] & 0xff) : -1;
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- if (mAudioRecord == 0) throw new IllegalStateException("not open");
- return AudioRecordRead(mAudioRecord, b, 0, b.length);
- }
-
- @Override
- public int read(byte[] b, int offset, int length) throws IOException {
- if (mAudioRecord == 0) throw new IllegalStateException("not open");
- // TODO: should we force all reads to be a multiple of the sample size?
- return AudioRecordRead(mAudioRecord, b, offset, length);
- }
-
- /**
- * Closes this stream.
- */
- @Override
- public void close() throws IOException {
- if (mAudioRecord != 0) {
- try {
- AudioRecordStop(mAudioRecord);
- } finally {
- try {
- AudioRecordDelete(mAudioRecord);
- } finally {
- mAudioRecord = 0;
- }
- }
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- if (mAudioRecord != 0) {
- close();
- throw new IOException("someone forgot to close MicrophoneInputStream");
- }
- }
-
- //
- // AudioRecord JNI interface
- //
- private static native long AudioRecordNew(int sampleRate, int fifoDepth);
- private static native int AudioRecordStart(long audioRecord);
- private static native int AudioRecordRead(long audioRecord, byte[] b, int offset, int length) throws IOException;
- private static native void AudioRecordStop(long audioRecord) throws IOException;
- private static native void AudioRecordDelete(long audioRecord) throws IOException;
-}
diff --git a/core/java/android/speech/srec/Recognizer.java b/core/java/android/speech/srec/Recognizer.java
deleted file mode 100644
index 6c491a0..0000000
--- a/core/java/android/speech/srec/Recognizer.java
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * Recognizer.java
- *
- * Copyright 2007 Nuance Communciations, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the 'License'); you may not
- * use this file except in compliance with the License.
- *
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- *
- * ---------------------------------------------------------------------------
- */
-
-
-package android.speech.srec;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.Locale;
-
-/**
- * Simple, synchronous speech recognizer, using the Nuance SREC package.
- * Usages proceeds as follows:
- *
- * <ul>
- * <li>Create a <code>Recognizer</code>.
- * <li>Create a <code>Recognizer.Grammar</code>.
- * <li>Setup the <code>Recognizer.Grammar</code>.
- * <li>Reset the <code>Recognizer.Grammar</code> slots, if needed.
- * <li>Fill the <code>Recognizer.Grammar</code> slots, if needed.
- * <li>Compile the <code>Recognizer.Grammar</code>, if needed.
- * <li>Save the filled <code>Recognizer.Grammar</code>, if needed.
- * <li>Start the <code>Recognizer</code>.
- * <li>Loop over <code>advance</code> and <code>putAudio</code> until recognition complete.
- * <li>Fetch and process results, or notify of failure.
- * <li>Stop the <code>Recognizer</code>.
- * <li>Destroy the <code>Recognizer</code>.
- * </ul>
- *
- * <p>Below is example code</p>
- *
- * <pre class="prettyprint">
- *
- * // create and start audio input
- * InputStream audio = new MicrophoneInputStream(11025, 11025*5);
- * // create a Recognizer
- * String cdir = Recognizer.getConfigDir(null);
- * Recognizer recognizer = new Recognizer(cdir + "/baseline11k.par");
- * // create and load a Grammar
- * Recognizer.Grammar grammar = recognizer.new Grammar(cdir + "/grammars/VoiceDialer.g2g");
- * // setup the Grammar to work with the Recognizer
- * grammar.setupRecognizer();
- * // fill the Grammar slots with names and save, if required
- * grammar.resetAllSlots();
- * for (String name : names) grammar.addWordToSlot("@Names", name, null, 1, "V=1");
- * grammar.compile();
- * grammar.save(".../foo.g2g");
- * // start the Recognizer
- * recognizer.start();
- * // loop over Recognizer events
- * while (true) {
- * switch (recognizer.advance()) {
- * case Recognizer.EVENT_INCOMPLETE:
- * case Recognizer.EVENT_STARTED:
- * case Recognizer.EVENT_START_OF_VOICING:
- * case Recognizer.EVENT_END_OF_VOICING:
- * // let the Recognizer continue to run
- * continue;
- * case Recognizer.EVENT_RECOGNITION_RESULT:
- * // success, so fetch results here!
- * for (int i = 0; i < recognizer.getResultCount(); i++) {
- * String result = recognizer.getResult(i, Recognizer.KEY_LITERAL);
- * }
- * break;
- * case Recognizer.EVENT_NEED_MORE_AUDIO:
- * // put more audio in the Recognizer
- * recognizer.putAudio(audio);
- * continue;
- * default:
- * notifyFailure();
- * break;
- * }
- * break;
- * }
- * // stop the Recognizer
- * recognizer.stop();
- * // destroy the Recognizer
- * recognizer.destroy();
- * // stop the audio device
- * audio.close();
- *
- * </pre>
- */
-public final class Recognizer {
- static {
- System.loadLibrary("srec_jni");
- }
-
- private static String TAG = "Recognizer";
-
- /**
- * Result key corresponding to confidence score.
- */
- public static final String KEY_CONFIDENCE = "conf";
-
- /**
- * Result key corresponding to literal text.
- */
- public static final String KEY_LITERAL = "literal";
-
- /**
- * Result key corresponding to semantic meaning text.
- */
- public static final String KEY_MEANING = "meaning";
-
- // handle to SR_Vocabulary object
- private long mVocabulary = 0;
-
- // handle to SR_Recognizer object
- private long mRecognizer = 0;
-
- // Grammar currently associated with Recognizer via SR_GrammarSetupRecognizer
- private Grammar mActiveGrammar = null;
-
- /**
- * Get the pathname of the SREC configuration directory corresponding to the
- * language indicated by the Locale.
- * This directory contains dictionaries, speech models,
- * configuration files, and other data needed by the Recognizer.
- * @param locale <code>Locale</code> corresponding to the desired language,
- * or null for default, currently <code>Locale.US</code>.
- * @return Pathname of the configuration directory.
- */
- public static String getConfigDir(Locale locale) {
- if (locale == null) locale = Locale.US;
- String dir = "/system/usr/srec/config/" +
- locale.toString().replace('_', '.').toLowerCase(Locale.ROOT);
- if ((new File(dir)).isDirectory()) return dir;
- return null;
- }
-
- /**
- * Create an instance of a SREC speech recognizer.
- *
- * @param configFile pathname of the baseline*.par configuration file,
- * which in turn contains references to dictionaries, speech models,
- * and other data needed to configure and operate the recognizer.
- * A separate config file is needed for each audio sample rate.
- * Two files, baseline11k.par and baseline8k.par, which correspond to
- * 11025 and 8000 hz, are present in the directory indicated by
- * {@link #getConfigDir}.
- * @throws IOException
- */
- public Recognizer(String configFile) throws IOException {
- PMemInit();
- SR_SessionCreate(configFile);
- mRecognizer = SR_RecognizerCreate();
- SR_RecognizerSetup(mRecognizer);
- mVocabulary = SR_VocabularyLoad();
- }
-
- /**
- * Represents a grammar loaded into the Recognizer.
- */
- public class Grammar {
- private long mGrammar = 0;
-
- /**
- * Create a <code>Grammar</code> instance.
- * @param g2gFileName pathname of g2g file.
- */
- public Grammar(String g2gFileName) throws IOException {
- mGrammar = SR_GrammarLoad(g2gFileName);
- SR_GrammarSetupVocabulary(mGrammar, mVocabulary);
- }
-
- /**
- * Reset all slots.
- */
- public void resetAllSlots() {
- SR_GrammarResetAllSlots(mGrammar);
- }
-
- /**
- * Add a word to a slot.
- *
- * @param slot slot name.
- * @param word word to insert.
- * @param pron pronunciation, or null to derive from word.
- * @param weight weight to give the word. One is normal, 50 is low.
- * @param tag semantic meaning tag string.
- */
- public void addWordToSlot(String slot, String word, String pron, int weight, String tag) {
- SR_GrammarAddWordToSlot(mGrammar, slot, word, pron, weight, tag);
- }
-
- /**
- * Compile all slots.
- */
- public void compile() {
- SR_GrammarCompile(mGrammar);
- }
-
- /**
- * Setup <code>Grammar</code> with <code>Recognizer</code>.
- */
- public void setupRecognizer() {
- SR_GrammarSetupRecognizer(mGrammar, mRecognizer);
- mActiveGrammar = this;
- }
-
- /**
- * Save <code>Grammar</code> to g2g file.
- *
- * @param g2gFileName
- * @throws IOException
- */
- public void save(String g2gFileName) throws IOException {
- SR_GrammarSave(mGrammar, g2gFileName);
- }
-
- /**
- * Release resources associated with this <code>Grammar</code>.
- */
- public void destroy() {
- // TODO: need to do cleanup and disassociation with Recognizer
- if (mGrammar != 0) {
- SR_GrammarDestroy(mGrammar);
- mGrammar = 0;
- }
- }
-
- /**
- * Clean up resources.
- */
- protected void finalize() {
- if (mGrammar != 0) {
- destroy();
- throw new IllegalStateException("someone forgot to destroy Grammar");
- }
- }
- }
-
- /**
- * Start recognition
- */
- public void start() {
- // TODO: shouldn't be here?
- SR_RecognizerActivateRule(mRecognizer, mActiveGrammar.mGrammar, "trash", 1);
- SR_RecognizerStart(mRecognizer);
- }
-
- /**
- * Process some audio and return the current status.
- * @return recognition event, one of:
- * <ul>
- * <li><code>EVENT_INVALID</code>
- * <li><code>EVENT_NO_MATCH</code>
- * <li><code>EVENT_INCOMPLETE</code>
- * <li><code>EVENT_STARTED</code>
- * <li><code>EVENT_STOPPED</code>
- * <li><code>EVENT_START_OF_VOICING</code>
- * <li><code>EVENT_END_OF_VOICING</code>
- * <li><code>EVENT_SPOKE_TOO_SOON</code>
- * <li><code>EVENT_RECOGNITION_RESULT</code>
- * <li><code>EVENT_START_OF_UTTERANCE_TIMEOUT</code>
- * <li><code>EVENT_RECOGNITION_TIMEOUT</code>
- * <li><code>EVENT_NEED_MORE_AUDIO</code>
- * <li><code>EVENT_MAX_SPEECH</code>
- * </ul>
- */
- public int advance() {
- return SR_RecognizerAdvance(mRecognizer);
- }
-
- /**
- * Put audio samples into the <code>Recognizer</code>.
- * @param buf holds the audio samples.
- * @param offset offset of the first sample.
- * @param length number of bytes containing samples.
- * @param isLast indicates no more audio data, normally false.
- * @return number of bytes accepted.
- */
- public int putAudio(byte[] buf, int offset, int length, boolean isLast) {
- return SR_RecognizerPutAudio(mRecognizer, buf, offset, length, isLast);
- }
-
- /**
- * Read audio samples from an <code>InputStream</code> and put them in the
- * <code>Recognizer</code>.
- * @param audio <code>InputStream</code> containing PCM audio samples.
- */
- public void putAudio(InputStream audio) throws IOException {
- // make sure the audio buffer is allocated
- if (mPutAudioBuffer == null) mPutAudioBuffer = new byte[512];
- // read some data
- int nbytes = audio.read(mPutAudioBuffer);
- // eof, so signal Recognizer
- if (nbytes == -1) {
- SR_RecognizerPutAudio(mRecognizer, mPutAudioBuffer, 0, 0, true);
- }
- // put it into the Recognizer
- else if (nbytes != SR_RecognizerPutAudio(mRecognizer, mPutAudioBuffer, 0, nbytes, false)) {
- throw new IOException("SR_RecognizerPutAudio failed nbytes=" + nbytes);
- }
- }
-
- // audio buffer for putAudio(InputStream)
- private byte[] mPutAudioBuffer = null;
-
- /**
- * Get the number of recognition results. Must be called after
- * <code>EVENT_RECOGNITION_RESULT</code> is returned by
- * <code>advance</code>, but before <code>stop</code>.
- *
- * @return number of results in nbest list.
- */
- public int getResultCount() {
- return SR_RecognizerResultGetSize(mRecognizer);
- }
-
- /**
- * Get a set of keys for the result. Must be called after
- * <code>EVENT_RECOGNITION_RESULT</code> is returned by
- * <code>advance</code>, but before <code>stop</code>.
- *
- * @param index index of result.
- * @return array of keys.
- */
- public String[] getResultKeys(int index) {
- return SR_RecognizerResultGetKeyList(mRecognizer, index);
- }
-
- /**
- * Get a result value. Must be called after
- * <code>EVENT_RECOGNITION_RESULT</code> is returned by
- * <code>advance</code>, but before <code>stop</code>.
- *
- * @param index index of the result.
- * @param key key of the result. This is typically one of
- * <code>KEY_CONFIDENCE</code>, <code>KEY_LITERAL</code>, or
- * <code>KEY_MEANING</code>, but the user can also define their own keys
- * in a grxml file, or in the <code>tag</code> slot of
- * <code>Grammar.addWordToSlot</code>.
- * @return the result.
- */
- public String getResult(int index, String key) {
- return SR_RecognizerResultGetValue(mRecognizer, index, key);
- }
-
- /**
- * Stop the <code>Recognizer</code>.
- */
- public void stop() {
- SR_RecognizerStop(mRecognizer);
- SR_RecognizerDeactivateRule(mRecognizer, mActiveGrammar.mGrammar, "trash");
- }
-
- /**
- * Reset the acoustic state vectorto it's default value.
- *
- * @hide
- */
- public void resetAcousticState() {
- SR_AcousticStateReset(mRecognizer);
- }
-
- /**
- * Set the acoustic state vector.
- * @param state String containing the acoustic state vector.
- *
- * @hide
- */
- public void setAcousticState(String state) {
- SR_AcousticStateSet(mRecognizer, state);
- }
-
- /**
- * Get the acoustic state vector.
- * @return String containing the acoustic state vector.
- *
- * @hide
- */
- public String getAcousticState() {
- return SR_AcousticStateGet(mRecognizer);
- }
-
- /**
- * Clean up resources.
- */
- public void destroy() {
- try {
- if (mVocabulary != 0) SR_VocabularyDestroy(mVocabulary);
- } finally {
- mVocabulary = 0;
- try {
- if (mRecognizer != 0) SR_RecognizerUnsetup(mRecognizer);
- } finally {
- try {
- if (mRecognizer != 0) SR_RecognizerDestroy(mRecognizer);
- } finally {
- mRecognizer = 0;
- try {
- SR_SessionDestroy();
- } finally {
- PMemShutdown();
- }
- }
- }
- }
- }
-
- /**
- * Clean up resources.
- */
- protected void finalize() throws Throwable {
- if (mVocabulary != 0 || mRecognizer != 0) {
- destroy();
- throw new IllegalStateException("someone forgot to destroy Recognizer");
- }
- }
-
- /* an example session captured, for reference
- void doall() {
- if (PMemInit ( )
- || lhs_audioinOpen ( WAVE_MAPPER, SREC_TEST_DEFAULT_AUDIO_FREQUENCY, &audio_in_handle )
- || srec_test_init_application_data ( &applicationData, argc, argv )
- || SR_SessionCreate ( "/system/usr/srec/config/en.us/baseline11k.par" )
- || SR_RecognizerCreate ( &applicationData.recognizer )
- || SR_RecognizerSetup ( applicationData.recognizer)
- || ESR_SessionGetLCHAR ( L("cmdline.vocabulary"), filename, &flen )
- || SR_VocabularyLoad ( filename, &applicationData.vocabulary )
- || SR_VocabularyGetLanguage ( applicationData.vocabulary, &applicationData.locale )
- || (applicationData.nametag = NULL)
- || SR_NametagsCreate ( &applicationData.nametags )
- || (LSTRCPY ( applicationData.grammars [0].grammar_path, "/system/usr/srec/config/en.us/grammars/VoiceDialer.g2g" ), 0)
- || (LSTRCPY ( applicationData.grammars [0].grammarID, "BothTags" ), 0)
- || (LSTRCPY ( applicationData.grammars [0].ruleName, "trash" ), 0)
- || (applicationData.grammars [0].is_ve_grammar = ESR_FALSE, 0)
- || SR_GrammarLoad (applicationData.grammars [0].grammar_path, &applicationData.grammars [applicationData.grammarCount].grammar )
- || SR_GrammarSetupVocabulary ( applicationData.grammars [0].grammar, applicationData.vocabulary )
- || SR_GrammarSetupRecognizer( applicationData.grammars [0].grammar, applicationData.recognizer )
- || SR_GrammarSetDispatchFunction ( applicationData.grammars [0].grammar, L("myDSMCallback"), NULL, myDSMCallback )
- || (applicationData.grammarCount++, 0)
- || SR_RecognizerActivateRule ( applicationData.recognizer, applicationData.grammars [0].grammar,
- applicationData.grammars [0].ruleName, 1 )
- || (applicationData.active_grammar_num = 0, 0)
- || lhs_audioinStart ( audio_in_handle )
- || SR_RecognizerStart ( applicationData.recognizer )
- || strl ( applicationData.grammars [0].grammar, &applicationData, audio_in_handle, &recognition_count )
- || SR_RecognizerStop ( applicationData.recognizer )
- || lhs_audioinStop ( audio_in_handle )
- || SR_RecognizerDeactivateRule ( applicationData.recognizer, applicationData.grammars [0].grammar, applicationData.grammars [0].ruleName )
- || (applicationData.active_grammar_num = -1, 0)
- || SR_GrammarDestroy ( applicationData.grammars [0].grammar )
- || (applicationData.grammarCount--, 0)
- || SR_NametagsDestroy ( applicationData.nametags )
- || (applicationData.nametags = NULL, 0)
- || SR_VocabularyDestroy ( applicationData.vocabulary )
- || (applicationData.vocabulary = NULL)
- || SR_RecognizerUnsetup ( applicationData.recognizer) // releases acoustic models
- || SR_RecognizerDestroy ( applicationData.recognizer )
- || (applicationData.recognizer = NULL)
- || SR_SessionDestroy ( )
- || srec_test_shutdown_application_data ( &applicationData )
- || lhs_audioinClose ( &audio_in_handle )
- || PMemShutdown ( )
- }
- */
-
-
- //
- // PMem native methods
- //
- private static native void PMemInit();
- private static native void PMemShutdown();
-
-
- //
- // SR_Session native methods
- //
- private static native void SR_SessionCreate(String filename);
- private static native void SR_SessionDestroy();
-
-
- //
- // SR_Recognizer native methods
- //
-
- /**
- * Reserved value.
- */
- public final static int EVENT_INVALID = 0;
-
- /**
- * <code>Recognizer</code> could not find a match for the utterance.
- */
- public final static int EVENT_NO_MATCH = 1;
-
- /**
- * <code>Recognizer</code> processed one frame of audio.
- */
- public final static int EVENT_INCOMPLETE = 2;
-
- /**
- * <code>Recognizer</code> has just been started.
- */
- public final static int EVENT_STARTED = 3;
-
- /**
- * <code>Recognizer</code> is stopped.
- */
- public final static int EVENT_STOPPED = 4;
-
- /**
- * Beginning of speech detected.
- */
- public final static int EVENT_START_OF_VOICING = 5;
-
- /**
- * End of speech detected.
- */
- public final static int EVENT_END_OF_VOICING = 6;
-
- /**
- * Beginning of utterance occured too soon.
- */
- public final static int EVENT_SPOKE_TOO_SOON = 7;
-
- /**
- * Recognition match detected.
- */
- public final static int EVENT_RECOGNITION_RESULT = 8;
-
- /**
- * Timeout occured before beginning of utterance.
- */
- public final static int EVENT_START_OF_UTTERANCE_TIMEOUT = 9;
-
- /**
- * Timeout occured before speech recognition could complete.
- */
- public final static int EVENT_RECOGNITION_TIMEOUT = 10;
-
- /**
- * Not enough samples to process one frame.
- */
- public final static int EVENT_NEED_MORE_AUDIO = 11;
-
- /**
- * More audio encountered than is allowed by 'swirec_max_speech_duration'.
- */
- public final static int EVENT_MAX_SPEECH = 12;
-
- /**
- * Produce a displayable string from an <code>advance</code> event.
- * @param event
- * @return String representing the event.
- */
- public static String eventToString(int event) {
- switch (event) {
- case EVENT_INVALID:
- return "EVENT_INVALID";
- case EVENT_NO_MATCH:
- return "EVENT_NO_MATCH";
- case EVENT_INCOMPLETE:
- return "EVENT_INCOMPLETE";
- case EVENT_STARTED:
- return "EVENT_STARTED";
- case EVENT_STOPPED:
- return "EVENT_STOPPED";
- case EVENT_START_OF_VOICING:
- return "EVENT_START_OF_VOICING";
- case EVENT_END_OF_VOICING:
- return "EVENT_END_OF_VOICING";
- case EVENT_SPOKE_TOO_SOON:
- return "EVENT_SPOKE_TOO_SOON";
- case EVENT_RECOGNITION_RESULT:
- return "EVENT_RECOGNITION_RESULT";
- case EVENT_START_OF_UTTERANCE_TIMEOUT:
- return "EVENT_START_OF_UTTERANCE_TIMEOUT";
- case EVENT_RECOGNITION_TIMEOUT:
- return "EVENT_RECOGNITION_TIMEOUT";
- case EVENT_NEED_MORE_AUDIO:
- return "EVENT_NEED_MORE_AUDIO";
- case EVENT_MAX_SPEECH:
- return "EVENT_MAX_SPEECH";
- }
- return "EVENT_" + event;
- }
-
- //
- // SR_Recognizer methods
- //
- private static native void SR_RecognizerStart(long recognizer);
- private static native void SR_RecognizerStop(long recognizer);
- private static native long SR_RecognizerCreate();
- private static native void SR_RecognizerDestroy(long recognizer);
- private static native void SR_RecognizerSetup(long recognizer);
- private static native void SR_RecognizerUnsetup(long recognizer);
- private static native boolean SR_RecognizerIsSetup(long recognizer);
- private static native String SR_RecognizerGetParameter(long recognizer, String key);
- private static native int SR_RecognizerGetSize_tParameter(long recognizer, String key);
- private static native boolean SR_RecognizerGetBoolParameter(long recognizer, String key);
- private static native void SR_RecognizerSetParameter(long recognizer, String key, String value);
- private static native void SR_RecognizerSetSize_tParameter(long recognizer,
- String key, int value);
- private static native void SR_RecognizerSetBoolParameter(long recognizer, String key,
- boolean value);
- private static native void SR_RecognizerSetupRule(long recognizer, long grammar,
- String ruleName);
- private static native boolean SR_RecognizerHasSetupRules(long recognizer);
- private static native void SR_RecognizerActivateRule(long recognizer, long grammar,
- String ruleName, int weight);
- private static native void SR_RecognizerDeactivateRule(long recognizer, long grammar,
- String ruleName);
- private static native void SR_RecognizerDeactivateAllRules(long recognizer);
- private static native boolean SR_RecognizerIsActiveRule(long recognizer, long grammar,
- String ruleName);
- private static native boolean SR_RecognizerCheckGrammarConsistency(long recognizer,
- long grammar);
- private static native int SR_RecognizerPutAudio(long recognizer, byte[] buffer, int offset,
- int length, boolean isLast);
- private static native int SR_RecognizerAdvance(long recognizer);
- // private static native void SR_RecognizerLoadUtterance(long recognizer,
- // const LCHAR* filename);
- // private static native void SR_RecognizerLoadWaveFile(long recognizer,
- // const LCHAR* filename);
- // private static native void SR_RecognizerSetLockFunction(long recognizer,
- // SR_RecognizerLockFunction function, void* data);
- private static native boolean SR_RecognizerIsSignalClipping(long recognizer);
- private static native boolean SR_RecognizerIsSignalDCOffset(long recognizer);
- private static native boolean SR_RecognizerIsSignalNoisy(long recognizer);
- private static native boolean SR_RecognizerIsSignalTooQuiet(long recognizer);
- private static native boolean SR_RecognizerIsSignalTooFewSamples(long recognizer);
- private static native boolean SR_RecognizerIsSignalTooManySamples(long recognizer);
- // private static native void SR_Recognizer_Change_Sample_Rate (size_t new_sample_rate);
-
-
- //
- // SR_AcousticState native methods
- //
- private static native void SR_AcousticStateReset(long recognizer);
- private static native void SR_AcousticStateSet(long recognizer, String state);
- private static native String SR_AcousticStateGet(long recognizer);
-
-
- //
- // SR_Grammar native methods
- //
- private static native void SR_GrammarCompile(long grammar);
- private static native void SR_GrammarAddWordToSlot(long grammar, String slot,
- String word, String pronunciation, int weight, String tag);
- private static native void SR_GrammarResetAllSlots(long grammar);
- // private static native void SR_GrammarAddNametagToSlot(long grammar, String slot,
- // const struct SR_Nametag_t* nametag, int weight, String tag);
- private static native void SR_GrammarSetupVocabulary(long grammar, long vocabulary);
- // private static native void SR_GrammarSetupModels(long grammar, SR_AcousticModels* models);
- private static native void SR_GrammarSetupRecognizer(long grammar, long recognizer);
- private static native void SR_GrammarUnsetupRecognizer(long grammar);
- // private static native void SR_GrammarGetModels(long grammar,SR_AcousticModels** models);
- private static native long SR_GrammarCreate();
- private static native void SR_GrammarDestroy(long grammar);
- private static native long SR_GrammarLoad(String filename);
- private static native void SR_GrammarSave(long grammar, String filename);
- // private static native void SR_GrammarSetDispatchFunction(long grammar,
- // const LCHAR* name, void* userData, SR_GrammarDispatchFunction function);
- // private static native void SR_GrammarSetParameter(long grammar, const
- // LCHAR* key, void* value);
- // private static native void SR_GrammarSetSize_tParameter(long grammar,
- // const LCHAR* key, size_t value);
- // private static native void SR_GrammarGetParameter(long grammar, const
- // LCHAR* key, void** value);
- // private static native void SR_GrammarGetSize_tParameter(long grammar,
- // const LCHAR* key, size_t* value);
- // private static native void SR_GrammarCheckParse(long grammar, const LCHAR*
- // transcription, SR_SemanticResult** result, size_t* resultCount);
- private static native void SR_GrammarAllowOnly(long grammar, String transcription);
- private static native void SR_GrammarAllowAll(long grammar);
-
-
- //
- // SR_Vocabulary native methods
- //
- // private static native int SR_VocabularyCreate();
- private static native long SR_VocabularyLoad();
- // private static native void SR_VocabularySave(SR_Vocabulary* self,
- // const LCHAR* filename);
- // private static native void SR_VocabularyAddWord(SR_Vocabulary* self,
- // const LCHAR* word);
- // private static native void SR_VocabularyGetLanguage(SR_Vocabulary* self,
- // ESR_Locale* locale);
- private static native void SR_VocabularyDestroy(long vocabulary);
- private static native String SR_VocabularyGetPronunciation(long vocabulary, String word);
-
-
- //
- // SR_RecognizerResult native methods
- //
- private static native byte[] SR_RecognizerResultGetWaveform(long recognizer);
- private static native int SR_RecognizerResultGetSize(long recognizer);
- private static native int SR_RecognizerResultGetKeyCount(long recognizer, int nbest);
- private static native String[] SR_RecognizerResultGetKeyList(long recognizer, int nbest);
- private static native String SR_RecognizerResultGetValue(long recognizer,
- int nbest, String key);
- // private static native void SR_RecognizerResultGetLocale(long recognizer, ESR_Locale* locale);
-}
diff --git a/core/java/android/speech/srec/UlawEncoderInputStream.java b/core/java/android/speech/srec/UlawEncoderInputStream.java
deleted file mode 100644
index a488ead..0000000
--- a/core/java/android/speech/srec/UlawEncoderInputStream.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * UlawEncoderInputStream.java
- *
- * Copyright 2008 Nuance Communciations, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the 'License'); you may not
- * use this file except in compliance with the License.
- *
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- *
- * ---------------------------------------------------------------------------
- */
-
-package android.speech.srec;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * InputStream which transforms 16 bit pcm data to ulaw data.
- *
- * Not yet ready to be supported, so
- * @hide
- */
-public final class UlawEncoderInputStream extends InputStream {
- private final static String TAG = "UlawEncoderInputStream";
-
- private final static int MAX_ULAW = 8192;
- private final static int SCALE_BITS = 16;
-
- private InputStream mIn;
-
- private int mMax = 0;
-
- private final byte[] mBuf = new byte[1024];
- private int mBufCount = 0; // should be 0 or 1
-
- private final byte[] mOneByte = new byte[1];
-
-
- public static void encode(byte[] pcmBuf, int pcmOffset,
- byte[] ulawBuf, int ulawOffset, int length, int max) {
-
- // from 'ulaw' in wikipedia
- // +8191 to +8159 0x80
- // +8158 to +4063 in 16 intervals of 256 0x80 + interval number
- // +4062 to +2015 in 16 intervals of 128 0x90 + interval number
- // +2014 to +991 in 16 intervals of 64 0xA0 + interval number
- // +990 to +479 in 16 intervals of 32 0xB0 + interval number
- // +478 to +223 in 16 intervals of 16 0xC0 + interval number
- // +222 to +95 in 16 intervals of 8 0xD0 + interval number
- // +94 to +31 in 16 intervals of 4 0xE0 + interval number
- // +30 to +1 in 15 intervals of 2 0xF0 + interval number
- // 0 0xFF
-
- // -1 0x7F
- // -31 to -2 in 15 intervals of 2 0x70 + interval number
- // -95 to -32 in 16 intervals of 4 0x60 + interval number
- // -223 to -96 in 16 intervals of 8 0x50 + interval number
- // -479 to -224 in 16 intervals of 16 0x40 + interval number
- // -991 to -480 in 16 intervals of 32 0x30 + interval number
- // -2015 to -992 in 16 intervals of 64 0x20 + interval number
- // -4063 to -2016 in 16 intervals of 128 0x10 + interval number
- // -8159 to -4064 in 16 intervals of 256 0x00 + interval number
- // -8192 to -8160 0x00
-
- // set scale factors
- if (max <= 0) max = MAX_ULAW;
-
- int coef = MAX_ULAW * (1 << SCALE_BITS) / max;
-
- for (int i = 0; i < length; i++) {
- int pcm = (0xff & pcmBuf[pcmOffset++]) + (pcmBuf[pcmOffset++] << 8);
- pcm = (pcm * coef) >> SCALE_BITS;
-
- int ulaw;
- if (pcm >= 0) {
- ulaw = pcm <= 0 ? 0xff :
- pcm <= 30 ? 0xf0 + (( 30 - pcm) >> 1) :
- pcm <= 94 ? 0xe0 + (( 94 - pcm) >> 2) :
- pcm <= 222 ? 0xd0 + (( 222 - pcm) >> 3) :
- pcm <= 478 ? 0xc0 + (( 478 - pcm) >> 4) :
- pcm <= 990 ? 0xb0 + (( 990 - pcm) >> 5) :
- pcm <= 2014 ? 0xa0 + ((2014 - pcm) >> 6) :
- pcm <= 4062 ? 0x90 + ((4062 - pcm) >> 7) :
- pcm <= 8158 ? 0x80 + ((8158 - pcm) >> 8) :
- 0x80;
- } else {
- ulaw = -1 <= pcm ? 0x7f :
- -31 <= pcm ? 0x70 + ((pcm - -31) >> 1) :
- -95 <= pcm ? 0x60 + ((pcm - -95) >> 2) :
- -223 <= pcm ? 0x50 + ((pcm - -223) >> 3) :
- -479 <= pcm ? 0x40 + ((pcm - -479) >> 4) :
- -991 <= pcm ? 0x30 + ((pcm - -991) >> 5) :
- -2015 <= pcm ? 0x20 + ((pcm - -2015) >> 6) :
- -4063 <= pcm ? 0x10 + ((pcm - -4063) >> 7) :
- -8159 <= pcm ? 0x00 + ((pcm - -8159) >> 8) :
- 0x00;
- }
- ulawBuf[ulawOffset++] = (byte)ulaw;
- }
- }
-
- /**
- * Compute the maximum of the absolute value of the pcm samples.
- * The return value can be used to set ulaw encoder scaling.
- * @param pcmBuf array containing 16 bit pcm data.
- * @param offset offset of start of 16 bit pcm data.
- * @param length number of pcm samples (not number of input bytes)
- * @return maximum abs of pcm data values
- */
- public static int maxAbsPcm(byte[] pcmBuf, int offset, int length) {
- int max = 0;
- for (int i = 0; i < length; i++) {
- int pcm = (0xff & pcmBuf[offset++]) + (pcmBuf[offset++] << 8);
- if (pcm < 0) pcm = -pcm;
- if (pcm > max) max = pcm;
- }
- return max;
- }
-
- /**
- * Create an InputStream which takes 16 bit pcm data and produces ulaw data.
- * @param in InputStream containing 16 bit pcm data.
- * @param max pcm value corresponding to maximum ulaw value.
- */
- public UlawEncoderInputStream(InputStream in, int max) {
- mIn = in;
- mMax = max;
- }
-
- @Override
- public int read(byte[] buf, int offset, int length) throws IOException {
- if (mIn == null) throw new IllegalStateException("not open");
-
- // return at least one byte, but try to fill 'length'
- while (mBufCount < 2) {
- int n = mIn.read(mBuf, mBufCount, Math.min(length * 2, mBuf.length - mBufCount));
- if (n == -1) return -1;
- mBufCount += n;
- }
-
- // compand data
- int n = Math.min(mBufCount / 2, length);
- encode(mBuf, 0, buf, offset, n, mMax);
-
- // move data to bottom of mBuf
- mBufCount -= n * 2;
- for (int i = 0; i < mBufCount; i++) mBuf[i] = mBuf[i + n * 2];
-
- return n;
- }
-
- @Override
- public int read(byte[] buf) throws IOException {
- return read(buf, 0, buf.length);
- }
-
- @Override
- public int read() throws IOException {
- int n = read(mOneByte, 0, 1);
- if (n == -1) return -1;
- return 0xff & (int)mOneByte[0];
- }
-
- @Override
- public void close() throws IOException {
- if (mIn != null) {
- InputStream in = mIn;
- mIn = null;
- in.close();
- }
- }
-
- @Override
- public int available() throws IOException {
- return (mIn.available() + mBufCount) / 2;
- }
-}
diff --git a/core/java/android/speech/srec/WaveHeader.java b/core/java/android/speech/srec/WaveHeader.java
deleted file mode 100644
index 4c3b172..0000000
--- a/core/java/android/speech/srec/WaveHeader.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.speech.srec;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * This class represents the header of a WAVE format audio file, which usually
- * have a .wav suffix. The following integer valued fields are contained:
- * <ul>
- * <li> format - usually PCM, ALAW or ULAW.
- * <li> numChannels - 1 for mono, 2 for stereo.
- * <li> sampleRate - usually 8000, 11025, 16000, 22050, or 44100 hz.
- * <li> bitsPerSample - usually 16 for PCM, 8 for ALAW, or 8 for ULAW.
- * <li> numBytes - size of audio data after this header, in bytes.
- * </ul>
- *
- * Not yet ready to be supported, so
- * @hide
- */
-public class WaveHeader {
-
- // follows WAVE format in http://ccrma.stanford.edu/courses/422/projects/WaveFormat
-
- private static final String TAG = "WaveHeader";
-
- private static final int HEADER_LENGTH = 44;
-
- /** Indicates PCM format. */
- public static final short FORMAT_PCM = 1;
- /** Indicates ALAW format. */
- public static final short FORMAT_ALAW = 6;
- /** Indicates ULAW format. */
- public static final short FORMAT_ULAW = 7;
-
- private short mFormat;
- private short mNumChannels;
- private int mSampleRate;
- private short mBitsPerSample;
- private int mNumBytes;
-
- /**
- * Construct a WaveHeader, with all fields defaulting to zero.
- */
- public WaveHeader() {
- }
-
- /**
- * Construct a WaveHeader, with fields initialized.
- * @param format format of audio data,
- * one of {@link #FORMAT_PCM}, {@link #FORMAT_ULAW}, or {@link #FORMAT_ALAW}.
- * @param numChannels 1 for mono, 2 for stereo.
- * @param sampleRate typically 8000, 11025, 16000, 22050, or 44100 hz.
- * @param bitsPerSample usually 16 for PCM, 8 for ULAW or 8 for ALAW.
- * @param numBytes size of audio data after this header, in bytes.
- */
- public WaveHeader(short format, short numChannels, int sampleRate, short bitsPerSample, int numBytes) {
- mFormat = format;
- mSampleRate = sampleRate;
- mNumChannels = numChannels;
- mBitsPerSample = bitsPerSample;
- mNumBytes = numBytes;
- }
-
- /**
- * Get the format field.
- * @return format field,
- * one of {@link #FORMAT_PCM}, {@link #FORMAT_ULAW}, or {@link #FORMAT_ALAW}.
- */
- public short getFormat() {
- return mFormat;
- }
-
- /**
- * Set the format field.
- * @param format
- * one of {@link #FORMAT_PCM}, {@link #FORMAT_ULAW}, or {@link #FORMAT_ALAW}.
- * @return reference to this WaveHeader instance.
- */
- public WaveHeader setFormat(short format) {
- mFormat = format;
- return this;
- }
-
- /**
- * Get the number of channels.
- * @return number of channels, 1 for mono, 2 for stereo.
- */
- public short getNumChannels() {
- return mNumChannels;
- }
-
- /**
- * Set the number of channels.
- * @param numChannels 1 for mono, 2 for stereo.
- * @return reference to this WaveHeader instance.
- */
- public WaveHeader setNumChannels(short numChannels) {
- mNumChannels = numChannels;
- return this;
- }
-
- /**
- * Get the sample rate.
- * @return sample rate, typically 8000, 11025, 16000, 22050, or 44100 hz.
- */
- public int getSampleRate() {
- return mSampleRate;
- }
-
- /**
- * Set the sample rate.
- * @param sampleRate sample rate, typically 8000, 11025, 16000, 22050, or 44100 hz.
- * @return reference to this WaveHeader instance.
- */
- public WaveHeader setSampleRate(int sampleRate) {
- mSampleRate = sampleRate;
- return this;
- }
-
- /**
- * Get the number of bits per sample.
- * @return number of bits per sample,
- * usually 16 for PCM, 8 for ULAW or 8 for ALAW.
- */
- public short getBitsPerSample() {
- return mBitsPerSample;
- }
-
- /**
- * Set the number of bits per sample.
- * @param bitsPerSample number of bits per sample,
- * usually 16 for PCM, 8 for ULAW or 8 for ALAW.
- * @return reference to this WaveHeader instance.
- */
- public WaveHeader setBitsPerSample(short bitsPerSample) {
- mBitsPerSample = bitsPerSample;
- return this;
- }
-
- /**
- * Get the size of audio data after this header, in bytes.
- * @return size of audio data after this header, in bytes.
- */
- public int getNumBytes() {
- return mNumBytes;
- }
-
- /**
- * Set the size of audio data after this header, in bytes.
- * @param numBytes size of audio data after this header, in bytes.
- * @return reference to this WaveHeader instance.
- */
- public WaveHeader setNumBytes(int numBytes) {
- mNumBytes = numBytes;
- return this;
- }
-
- /**
- * Read and initialize a WaveHeader.
- * @param in {@link java.io.InputStream} to read from.
- * @return number of bytes consumed.
- * @throws IOException
- */
- public int read(InputStream in) throws IOException {
- /* RIFF header */
- readId(in, "RIFF");
- int numBytes = readInt(in) - 36;
- readId(in, "WAVE");
-
- /* fmt chunk */
- readId(in, "fmt ");
- if (16 != readInt(in)) throw new IOException("fmt chunk length not 16");
- mFormat = readShort(in);
- mNumChannels = readShort(in);
- mSampleRate = readInt(in);
- int byteRate = readInt(in);
- short blockAlign = readShort(in);
- mBitsPerSample = readShort(in);
- if (byteRate != mNumChannels * mSampleRate * mBitsPerSample / 8) {
- throw new IOException("fmt.ByteRate field inconsistent");
- }
- if (blockAlign != mNumChannels * mBitsPerSample / 8) {
- throw new IOException("fmt.BlockAlign field inconsistent");
- }
-
- /* data chunk */
- readId(in, "data");
- mNumBytes = readInt(in);
-
- return HEADER_LENGTH;
- }
-
- private static void readId(InputStream in, String id) throws IOException {
- for (int i = 0; i < id.length(); i++) {
- if (id.charAt(i) != in.read()) throw new IOException( id + " tag not present");
- }
- }
-
- private static int readInt(InputStream in) throws IOException {
- return in.read() | (in.read() << 8) | (in.read() << 16) | (in.read() << 24);
- }
-
- private static short readShort(InputStream in) throws IOException {
- return (short)(in.read() | (in.read() << 8));
- }
-
- /**
- * Write a WAVE file header.
- * @param out {@link java.io.OutputStream} to receive the header.
- * @return number of bytes written.
- * @throws IOException
- */
- public int write(OutputStream out) throws IOException {
- /* RIFF header */
- writeId(out, "RIFF");
- writeInt(out, 36 + mNumBytes);
- writeId(out, "WAVE");
-
- /* fmt chunk */
- writeId(out, "fmt ");
- writeInt(out, 16);
- writeShort(out, mFormat);
- writeShort(out, mNumChannels);
- writeInt(out, mSampleRate);
- writeInt(out, mNumChannels * mSampleRate * mBitsPerSample / 8);
- writeShort(out, (short)(mNumChannels * mBitsPerSample / 8));
- writeShort(out, mBitsPerSample);
-
- /* data chunk */
- writeId(out, "data");
- writeInt(out, mNumBytes);
-
- return HEADER_LENGTH;
- }
-
- private static void writeId(OutputStream out, String id) throws IOException {
- for (int i = 0; i < id.length(); i++) out.write(id.charAt(i));
- }
-
- private static void writeInt(OutputStream out, int val) throws IOException {
- out.write(val >> 0);
- out.write(val >> 8);
- out.write(val >> 16);
- out.write(val >> 24);
- }
-
- private static void writeShort(OutputStream out, short val) throws IOException {
- out.write(val >> 0);
- out.write(val >> 8);
- }
-
- @Override
- public String toString() {
- return String.format(
- "WaveHeader format=%d numChannels=%d sampleRate=%d bitsPerSample=%d numBytes=%d",
- mFormat, mNumChannels, mSampleRate, mBitsPerSample, mNumBytes);
- }
-
-}
diff --git a/core/java/android/speech/srec/package.html b/core/java/android/speech/srec/package.html
deleted file mode 100644
index 9a99df8..0000000
--- a/core/java/android/speech/srec/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Simple, synchronous SREC speech recognition API.
-@hide
-</BODY>
-</HTML>
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index 9eb22ef..890ea3d 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -61,16 +61,16 @@ public abstract class UtteranceProgressListener {
/**
* Called when an utterance has been stopped while in progress or flushed from the
- * synthesis queue. This can happen if client calls {@link TextToSpeech#stop()}
- * or use {@link TextToSpeech#QUEUE_FLUSH} as an argument in
+ * synthesis queue. This can happen if a client calls {@link TextToSpeech#stop()}
+ * or uses {@link TextToSpeech#QUEUE_FLUSH} as an argument with the
* {@link TextToSpeech#speak} or {@link TextToSpeech#synthesizeToFile} methods.
*
* @param utteranceId the utterance ID of the utterance.
- * @param isStarted If true, then utterance was interrupted while being synthesized
- * and it's output is incomplete. If it's false, then utterance was flushed
+ * @param interrupted If true, then the utterance was interrupted while being synthesized
+ * and its output is incomplete. If false, then the utterance was flushed
* before the synthesis started.
*/
- public void onStop(String utteranceId, boolean isStarted) {
+ public void onStop(String utteranceId, boolean interrupted) {
}
/**
@@ -99,7 +99,7 @@ public abstract class UtteranceProgressListener {
}
@Override
- public void onStop(String utteranceId, boolean isStarted) {
+ public void onStop(String utteranceId, boolean interrupted) {
listener.onUtteranceCompleted(utteranceId);
}
};
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index b467f5a..13a959e 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -17,7 +17,9 @@
package android.text.format;
import android.content.Context;
+import android.content.res.Resources;
import android.net.NetworkUtils;
+import android.net.TrafficStats;
/**
* Utility class to aid in formatting common values that are not covered
@@ -25,63 +27,88 @@ import android.net.NetworkUtils;
*/
public final class Formatter {
+ /** {@hide} */
+ public static final int FLAG_SHORTER = 1 << 0;
+ /** {@hide} */
+ public static final int FLAG_CALCULATE_ROUNDED = 1 << 1;
+
+ /** {@hide} */
+ public static class BytesResult {
+ public final String value;
+ public final String units;
+ public final long roundedBytes;
+
+ public BytesResult(String value, String units, long roundedBytes) {
+ this.value = value;
+ this.units = units;
+ this.roundedBytes = roundedBytes;
+ }
+ }
+
/**
* Formats a content size to be in the form of bytes, kilobytes, megabytes, etc
*
* @param context Context to use to load the localized units
- * @param number size value to be formatted
+ * @param sizeBytes size value to be formatted, in bytes
* @return formatted string with the number
*/
- public static String formatFileSize(Context context, long number) {
- return formatFileSize(context, number, false);
+ public static String formatFileSize(Context context, long sizeBytes) {
+ final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
+ return context.getString(com.android.internal.R.string.fileSizeSuffix,
+ res.value, res.units);
}
/**
* Like {@link #formatFileSize}, but trying to generate shorter numbers
* (showing fewer digits of precision).
*/
- public static String formatShortFileSize(Context context, long number) {
- return formatFileSize(context, number, true);
+ public static String formatShortFileSize(Context context, long sizeBytes) {
+ final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
+ return context.getString(com.android.internal.R.string.fileSizeSuffix,
+ res.value, res.units);
}
- private static String formatFileSize(Context context, long number, boolean shorter) {
- if (context == null) {
- return "";
- }
-
- float result = number;
+ /** {@hide} */
+ public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) {
+ float result = sizeBytes;
int suffix = com.android.internal.R.string.byteShort;
+ long mult = 1;
if (result > 900) {
suffix = com.android.internal.R.string.kilobyteShort;
+ mult = TrafficStats.KB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.megabyteShort;
+ mult = TrafficStats.MB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.gigabyteShort;
+ mult = TrafficStats.GB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.terabyteShort;
+ mult = TrafficStats.TB_IN_BYTES;
result = result / 1024;
}
if (result > 900) {
suffix = com.android.internal.R.string.petabyteShort;
+ mult = TrafficStats.PB_IN_BYTES;
result = result / 1024;
}
String value;
if (result < 1) {
value = String.format("%.2f", result);
} else if (result < 10) {
- if (shorter) {
+ if ((flags & FLAG_SHORTER) != 0) {
value = String.format("%.1f", result);
} else {
value = String.format("%.2f", result);
}
} else if (result < 100) {
- if (shorter) {
+ if ((flags & FLAG_SHORTER) != 0) {
value = String.format("%.0f", result);
} else {
value = String.format("%.2f", result);
@@ -89,9 +116,14 @@ public final class Formatter {
} else {
value = String.format("%.0f", result);
}
- return context.getResources().
- getString(com.android.internal.R.string.fileSizeSuffix,
- value, context.getString(suffix));
+ final String units = res.getString(suffix);
+ final long roundedBytes;
+ if ((flags & FLAG_CALCULATE_ROUNDED) != 0) {
+ roundedBytes = (long) (Double.parseDouble(value) * mult);
+ } else {
+ roundedBytes = 0;
+ }
+ return new BytesResult(value, units, roundedBytes);
}
/**
diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java
index c40f11f..93a156b 100644
--- a/core/java/android/text/style/TtsSpan.java
+++ b/core/java/android/text/style/TtsSpan.java
@@ -165,7 +165,7 @@ public class TtsSpan implements ParcelableSpan {
/**
* The text associated with this span is a series of characters that have to
- * be read verbatim. The engine will attempt to ready out any character like
+ * be read verbatim. The engine will attempt to read out any character like
* punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
* Also accepts the arguments {@link #ARG_GENDER},
* {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
diff --git a/core/java/android/transition/Explode.java b/core/java/android/transition/Explode.java
index 788676a..3445ef2 100644
--- a/core/java/android/transition/Explode.java
+++ b/core/java/android/transition/Explode.java
@@ -90,7 +90,7 @@ public class Explode extends Visibility {
float startY = endY + mTempLoc[1];
return TranslationAnimationCreator.createAnimation(view, endValues, bounds.left, bounds.top,
- startX, startY, endX, endY, sDecelerate);
+ startX, startY, endX, endY, sDecelerate, this);
}
@Override
@@ -119,7 +119,7 @@ public class Explode extends Visibility {
endY += mTempLoc[1];
return TranslationAnimationCreator.createAnimation(view, startValues,
- viewPosX, viewPosY, startX, startY, endX, endY, sAccelerate);
+ viewPosX, viewPosY, startX, startY, endX, endY, sAccelerate, this);
}
private void calculateOut(View sceneRoot, Rect bounds, int[] outVector) {
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index be1d907..9063b43 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -231,7 +231,7 @@ public class Slide extends Visibility {
float startY = mSlideCalculator.getGoneY(sceneRoot, view);
return TranslationAnimationCreator
.createAnimation(view, endValues, position[0], position[1],
- startX, startY, endX, endY, sDecelerate);
+ startX, startY, endX, endY, sDecelerate, this);
}
@Override
@@ -247,6 +247,6 @@ public class Slide extends Visibility {
float endY = mSlideCalculator.getGoneY(sceneRoot, view);
return TranslationAnimationCreator
.createAnimation(view, startValues, position[0], position[1],
- startX, startY, endX, endY, sAccelerate);
+ startX, startY, endX, endY, sAccelerate, this);
}
}
diff --git a/core/java/android/transition/TranslationAnimationCreator.java b/core/java/android/transition/TranslationAnimationCreator.java
index de71fd7..1554975 100644
--- a/core/java/android/transition/TranslationAnimationCreator.java
+++ b/core/java/android/transition/TranslationAnimationCreator.java
@@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.graphics.Path;
+import android.transition.Transition.TransitionListener;
import android.view.View;
/**
@@ -48,7 +49,8 @@ class TranslationAnimationCreator {
* a previous interruption, in which case it moves from the current position to (endX, endY).
*/
static Animator createAnimation(View view, TransitionValues values, int viewPosX, int viewPosY,
- float startX, float startY, float endX, float endY, TimeInterpolator interpolator) {
+ float startX, float startY, float endX, float endY, TimeInterpolator interpolator,
+ Transition transition) {
float terminalX = view.getTranslationX();
float terminalY = view.getTranslationY();
int[] startPosition = (int[]) values.view.getTag(R.id.transitionPosition);
@@ -73,13 +75,15 @@ class TranslationAnimationCreator {
TransitionPositionListener listener = new TransitionPositionListener(view, values.view,
startPosX, startPosY, terminalX, terminalY);
+ transition.addListener(listener);
anim.addListener(listener);
anim.addPauseListener(listener);
anim.setInterpolator(interpolator);
return anim;
}
- private static class TransitionPositionListener extends AnimatorListenerAdapter {
+ private static class TransitionPositionListener extends AnimatorListenerAdapter implements
+ TransitionListener {
private final View mViewInHierarchy;
private final View mMovingView;
@@ -117,8 +121,6 @@ class TranslationAnimationCreator {
@Override
public void onAnimationEnd(Animator animator) {
- mMovingView.setTranslationX(mTerminalX);
- mMovingView.setTranslationY(mTerminalY);
}
@Override
@@ -134,6 +136,28 @@ class TranslationAnimationCreator {
mMovingView.setTranslationX(mPausedX);
mMovingView.setTranslationY(mPausedY);
}
+
+ @Override
+ public void onTransitionStart(Transition transition) {
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ mMovingView.setTranslationX(mTerminalX);
+ mMovingView.setTranslationY(mTerminalY);
+ }
+
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ }
+
+ @Override
+ public void onTransitionPause(Transition transition) {
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ }
}
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index bac668a..8b74a1e 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -557,7 +557,7 @@ public abstract class Visibility extends Transition {
if (mIsForcedVisibility) {
mView.setTransitionAlpha(0);
} else {
- mView.setTransitionVisibility(mFinalVisibility);
+ mView.setVisibility(mFinalVisibility);
}
}
}
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index f7d2821..353388d 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -246,41 +246,65 @@ public class TimeUtils {
public static final long NANOS_PER_MS = 1000000;
private static final Object sFormatSync = new Object();
- private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
-
- private static final long LARGEST_DURATION = (1000 * DateUtils.DAY_IN_MILLIS) - 1;
+ private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+10];
+ private static char[] sTmpFormatStr = new char[HUNDRED_DAY_FIELD_LEN+10];
static private int accumField(int amt, int suffix, boolean always, int zeropad) {
- if (amt > 99 || (always && zeropad >= 3)) {
- return 3+suffix;
- }
- if (amt > 9 || (always && zeropad >= 2)) {
- return 2+suffix;
- }
- if (always || amt > 0) {
- return 1+suffix;
+ if (amt > 999) {
+ int num = 0;
+ while (amt != 0) {
+ num++;
+ amt /= 10;
+ }
+ return num + suffix;
+ } else {
+ if (amt > 99 || (always && zeropad >= 3)) {
+ return 3+suffix;
+ }
+ if (amt > 9 || (always && zeropad >= 2)) {
+ return 2+suffix;
+ }
+ if (always || amt > 0) {
+ return 1+suffix;
+ }
}
return 0;
}
- static private int printField(char[] formatStr, int amt, char suffix, int pos,
+ static private int printFieldLocked(char[] formatStr, int amt, char suffix, int pos,
boolean always, int zeropad) {
if (always || amt > 0) {
final int startPos = pos;
- if ((always && zeropad >= 3) || amt > 99) {
- int dig = amt/100;
- formatStr[pos] = (char)(dig + '0');
- pos++;
- amt -= (dig*100);
- }
- if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
- int dig = amt/10;
- formatStr[pos] = (char)(dig + '0');
+ if (amt > 999) {
+ int tmp = 0;
+ while (amt != 0 && tmp < sTmpFormatStr.length) {
+ int dig = amt % 10;
+ sTmpFormatStr[tmp] = (char)(dig + '0');
+ tmp++;
+ amt /= 10;
+ }
+ tmp--;
+ while (tmp >= 0) {
+ formatStr[pos] = sTmpFormatStr[tmp];
+ pos++;
+ tmp--;
+ }
+ } else {
+ if ((always && zeropad >= 3) || amt > 99) {
+ int dig = amt/100;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ amt -= (dig*100);
+ }
+ if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
+ int dig = amt/10;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ amt -= (dig*10);
+ }
+ formatStr[pos] = (char)(amt + '0');
pos++;
- amt -= (dig*10);
}
- formatStr[pos] = (char)(amt + '0');
- pos++;
formatStr[pos] = suffix;
pos++;
}
@@ -312,10 +336,6 @@ public class TimeUtils {
duration = -duration;
}
- if (duration > LARGEST_DURATION) {
- duration = LARGEST_DURATION;
- }
-
int millis = (int)(duration%1000);
int seconds = (int) Math.floor(duration / 1000);
int days = 0, hours = 0, minutes = 0;
@@ -353,11 +373,11 @@ public class TimeUtils {
int start = pos;
boolean zeropad = fieldLen != 0;
- pos = printField(formatStr, days, 'd', pos, false, 0);
- pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
- pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
- pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
- pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
+ pos = printFieldLocked(formatStr, days, 'd', pos, false, 0);
+ pos = printFieldLocked(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
+ pos = printFieldLocked(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
+ pos = printFieldLocked(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
+ pos = printFieldLocked(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
formatStr[pos] = 's';
return pos + 1;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0df8ea9..fd3ee4f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -56,6 +56,8 @@ import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerGlobal;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -95,6 +97,7 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.Checkable;
+import android.widget.FrameLayout;
import android.widget.ScrollBarDrawable;
import static android.os.Build.VERSION_CODES.*;
@@ -4274,23 +4277,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
PROVIDER_BACKGROUND));
break;
case R.styleable.View_foreground:
- setForeground(a.getDrawable(attr));
+ if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ setForeground(a.getDrawable(attr));
+ }
break;
case R.styleable.View_foregroundGravity:
- setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
+ if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
+ }
break;
case R.styleable.View_foregroundTintMode:
- setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
+ if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
+ }
break;
case R.styleable.View_foregroundTint:
- setForegroundTintList(a.getColorStateList(attr));
+ if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ setForegroundTintList(a.getColorStateList(attr));
+ }
break;
case R.styleable.View_foregroundInsidePadding:
- if (mForegroundInfo == null) {
- mForegroundInfo = new ForegroundInfo();
+ if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (mForegroundInfo == null) {
+ mForegroundInfo = new ForegroundInfo();
+ }
+ mForegroundInfo.mInsidePadding = a.getBoolean(attr,
+ mForegroundInfo.mInsidePadding);
}
- mForegroundInfo.mInsidePadding = a.getBoolean(attr,
- mForegroundInfo.mInsidePadding);
break;
case R.styleable.View_scrollIndicators:
final int scrollIndicators =
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 89743e5..73cfd8c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2939,11 +2939,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
- /** @hide */
@Override
- public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
- super.onInitializeAccessibilityEventInternal(event);
- event.setClassName(ViewGroup.class.getName());
+ public CharSequence getAccessibilityClassName() {
+ return ViewGroup.class.getName();
}
@Override
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index bd45007..f18b7ac 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -80,12 +80,18 @@ public class ViewPropertyAnimator {
/**
* The interpolator of the underlying Animator object. By default, we don't set the interpolator
- * on the Animator and just use its default interpolator. If the interpolator is set to a
- * non-null value on this Animator, then we use the interpolator that it was set to.
+ * on the Animator and just use its default interpolator. If the interpolator is ever set on
+ * this Animator, then we use the interpolator that it was set to.
*/
private TimeInterpolator mInterpolator;
/**
+ * A flag indicating whether the interpolator has been set on this object. If not, we don't set
+ * the interpolator on the underlying Animator, but instead just use its default interpolator.
+ */
+ private boolean mInterpolatorSet = false;
+
+ /**
* Listener for the lifecycle events of the underlying ValueAnimator object.
*/
private Animator.AnimatorListener mListener = null;
@@ -332,6 +338,7 @@ public class ViewPropertyAnimator {
* @return This object, allowing calls to methods in this class to be chained.
*/
public ViewPropertyAnimator setInterpolator(TimeInterpolator interpolator) {
+ mInterpolatorSet = true;
mInterpolator = interpolator;
return this;
}
@@ -342,7 +349,7 @@ public class ViewPropertyAnimator {
* @return The timing interpolator for this animation.
*/
public TimeInterpolator getInterpolator() {
- if (mInterpolator != null) {
+ if (mInterpolatorSet) {
return mInterpolator;
} else {
// Just return the default from ValueAnimator, since that's what we'd get if
@@ -890,7 +897,7 @@ public class ViewPropertyAnimator {
if (mDurationSet) {
animator.setDuration(mDuration);
}
- if (mInterpolator != null) {
+ if (mInterpolatorSet) {
animator.setInterpolator(mInterpolator);
}
animator.start();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e2f42db..8b57d96 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -663,6 +663,10 @@ public final class ViewRootImpl implements ViewParent,
return mWindowAttributes.flags;
}
+ public int getDisplayId() {
+ return mDisplay.getDisplayId();
+ }
+
public CharSequence getTitle() {
return mWindowAttributes.getTitle();
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 8ceb166..d06cd83 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -201,6 +201,17 @@ public abstract class ViewStructure {
public abstract void setChildCount(int num);
/**
+ * Add to this view's child count. This increases the current child count by
+ * <var>num</var> children beyond what was last set by {@link #setChildCount}
+ * or {@link #addChildCount}. The index at which the new child starts in the child
+ * array is returned.
+ *
+ * @param num The number of new children to add.
+ * @return Returns the index in the child array at which the new children start.
+ */
+ public abstract int addChildCount(int num);
+
+ /**
* Return the child count as set by {@link #setChildCount}.
*/
public abstract int getChildCount();
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index 382a266..410d39c 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -52,11 +52,9 @@ public class CaptioningManager {
/** Default scaling value for caption fonts. */
private static final float DEFAULT_FONT_SCALE = 1;
- private final ArrayList<CaptioningChangeListener>
- mListeners = new ArrayList<CaptioningChangeListener>();
- private final Handler mHandler = new Handler();
-
+ private final ArrayList<CaptioningChangeListener> mListeners = new ArrayList<>();
private final ContentResolver mContentResolver;
+ private final ContentObserver mContentObserver;
/**
* Creates a new captioning manager for the specified context.
@@ -65,6 +63,9 @@ public class CaptioningManager {
*/
public CaptioningManager(Context context) {
mContentResolver = context.getContentResolver();
+
+ final Handler handler = new Handler(context.getMainLooper());
+ mContentObserver = new MyContentObserver(handler);
}
/**
@@ -220,7 +221,15 @@ public class CaptioningManager {
}
}
- private final ContentObserver mContentObserver = new ContentObserver(mHandler) {
+ private class MyContentObserver extends ContentObserver {
+ private final Handler mHandler;
+
+ public MyContentObserver(Handler handler) {
+ super(handler);
+
+ mHandler = handler;
+ }
+
@Override
public void onChange(boolean selfChange, Uri uri) {
final String uriPath = uri.getPath();
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 195a335..e77dc0d 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -28,9 +28,6 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
-import android.view.textservice.SpellCheckerInfo;
-import android.view.textservice.SuggestionsInfo;
-import android.view.textservice.TextInfo;
import java.util.LinkedList;
import java.util.Queue;
@@ -226,17 +223,44 @@ public class SpellCheckerSession {
private static final int TASK_GET_SUGGESTIONS_MULTIPLE = 2;
private static final int TASK_CLOSE = 3;
private static final int TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE = 4;
- private final Queue<SpellCheckerParams> mPendingTasks =
- new LinkedList<SpellCheckerParams>();
+ private static String taskToString(int task) {
+ switch (task) {
+ case TASK_CANCEL:
+ return "TASK_CANCEL";
+ case TASK_GET_SUGGESTIONS_MULTIPLE:
+ return "TASK_GET_SUGGESTIONS_MULTIPLE";
+ case TASK_CLOSE:
+ return "TASK_CLOSE";
+ case TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE:
+ return "TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE";
+ default:
+ return "Unexpected task=" + task;
+ }
+ }
+
+ private final Queue<SpellCheckerParams> mPendingTasks = new LinkedList<>();
private Handler mHandler;
- private boolean mOpened;
+ private static final int STATE_WAIT_CONNECTION = 0;
+ private static final int STATE_CONNECTED = 1;
+ private static final int STATE_CLOSED_AFTER_CONNECTION = 2;
+ private static final int STATE_CLOSED_BEFORE_CONNECTION = 3;
+ private static String stateToString(int state) {
+ switch (state) {
+ case STATE_WAIT_CONNECTION: return "STATE_WAIT_CONNECTION";
+ case STATE_CONNECTED: return "STATE_CONNECTED";
+ case STATE_CLOSED_AFTER_CONNECTION: return "STATE_CLOSED_AFTER_CONNECTION";
+ case STATE_CLOSED_BEFORE_CONNECTION: return "STATE_CLOSED_BEFORE_CONNECTION";
+ default: return "Unexpected state=" + state;
+ }
+ }
+ private int mState = STATE_WAIT_CONNECTION;
+
private ISpellCheckerSession mISpellCheckerSession;
private HandlerThread mThread;
private Handler mAsyncHandler;
public SpellCheckerSessionListenerImpl(Handler handler) {
- mOpened = false;
mHandler = handler;
}
@@ -257,12 +281,18 @@ public class SpellCheckerSession {
private void processTask(ISpellCheckerSession session, SpellCheckerParams scp,
boolean async) {
+ if (DBG) {
+ synchronized (this) {
+ Log.d(TAG, "entering processTask:"
+ + " session.hashCode()=#" + Integer.toHexString(session.hashCode())
+ + " scp.mWhat=" + taskToString(scp.mWhat) + " async=" + async
+ + " mAsyncHandler=" + mAsyncHandler
+ + " mState=" + stateToString(mState));
+ }
+ }
if (async || mAsyncHandler == null) {
switch (scp.mWhat) {
case TASK_CANCEL:
- if (DBG) {
- Log.w(TAG, "Cancel spell checker tasks.");
- }
try {
session.onCancel();
} catch (RemoteException e) {
@@ -270,9 +300,6 @@ public class SpellCheckerSession {
}
break;
case TASK_GET_SUGGESTIONS_MULTIPLE:
- if (DBG) {
- Log.w(TAG, "Get suggestions from the spell checker.");
- }
try {
session.onGetSuggestionsMultiple(scp.mTextInfos,
scp.mSuggestionsLimit, scp.mSequentialWords);
@@ -281,9 +308,6 @@ public class SpellCheckerSession {
}
break;
case TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE:
- if (DBG) {
- Log.w(TAG, "Get sentence suggestions from the spell checker.");
- }
try {
session.onGetSentenceSuggestionsMultiple(
scp.mTextInfos, scp.mSuggestionsLimit);
@@ -292,9 +316,6 @@ public class SpellCheckerSession {
}
break;
case TASK_CLOSE:
- if (DBG) {
- Log.w(TAG, "Close spell checker tasks.");
- }
try {
session.onClose();
} catch (RemoteException e) {
@@ -313,21 +334,62 @@ public class SpellCheckerSession {
// If we are closing, we want to clean up our state now even
// if it is pending as an async operation.
synchronized (this) {
- mISpellCheckerSession = null;
- mHandler = null;
- if (mThread != null) {
- mThread.quit();
- }
- mThread = null;
- mAsyncHandler = null;
+ processCloseLocked();
}
}
}
+ private void processCloseLocked() {
+ if (DBG) Log.d(TAG, "entering processCloseLocked:"
+ + " session" + (mISpellCheckerSession != null ? ".hashCode()=#"
+ + Integer.toHexString(mISpellCheckerSession.hashCode()) : "=null")
+ + " mState=" + stateToString(mState));
+ mISpellCheckerSession = null;
+ if (mThread != null) {
+ mThread.quit();
+ }
+ mHandler = null;
+ mPendingTasks.clear();
+ mThread = null;
+ mAsyncHandler = null;
+ switch (mState) {
+ case STATE_WAIT_CONNECTION:
+ mState = STATE_CLOSED_BEFORE_CONNECTION;
+ break;
+ case STATE_CONNECTED:
+ mState = STATE_CLOSED_AFTER_CONNECTION;
+ break;
+ default:
+ Log.e(TAG, "processCloseLocked is called unexpectedly. mState=" +
+ stateToString(mState));
+ break;
+ }
+ }
+
public synchronized void onServiceConnected(ISpellCheckerSession session) {
synchronized (this) {
+ switch (mState) {
+ case STATE_WAIT_CONNECTION:
+ // OK, go ahead.
+ break;
+ case STATE_CLOSED_BEFORE_CONNECTION:
+ // This is possible, and not an error. The client no longer is interested
+ // in this connection. OK to ignore.
+ if (DBG) Log.i(TAG, "ignoring onServiceConnected since the session is"
+ + " already closed.");
+ return;
+ default:
+ Log.e(TAG, "ignoring onServiceConnected due to unexpected mState="
+ + stateToString(mState));
+ return;
+ }
+ if (session == null) {
+ Log.e(TAG, "ignoring onServiceConnected due to session=null");
+ return;
+ }
mISpellCheckerSession = session;
if (session.asBinder() instanceof Binder && mThread == null) {
+ if (DBG) Log.d(TAG, "starting HandlerThread in onServiceConnected.");
// If this is a local object, we need to do our own threading
// to make sure we handle it asynchronously.
mThread = new HandlerThread("SpellCheckerSession",
@@ -340,62 +402,65 @@ public class SpellCheckerSession {
}
};
}
- mOpened = true;
+ mState = STATE_CONNECTED;
+ if (DBG) {
+ Log.d(TAG, "processed onServiceConnected: mISpellCheckerSession.hashCode()=#"
+ + Integer.toHexString(mISpellCheckerSession.hashCode())
+ + " mPendingTasks.size()=" + mPendingTasks.size());
+ }
}
- if (DBG)
- Log.d(TAG, "onServiceConnected - Success");
while (!mPendingTasks.isEmpty()) {
processTask(session, mPendingTasks.poll(), false);
}
}
public void cancel() {
- if (DBG) {
- Log.w(TAG, "cancel");
- }
processOrEnqueueTask(new SpellCheckerParams(TASK_CANCEL, null, 0, false));
}
public void getSuggestionsMultiple(
TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
- if (DBG) {
- Log.w(TAG, "getSuggestionsMultiple");
- }
processOrEnqueueTask(
new SpellCheckerParams(TASK_GET_SUGGESTIONS_MULTIPLE, textInfos,
suggestionsLimit, sequentialWords));
}
public void getSentenceSuggestionsMultiple(TextInfo[] textInfos, int suggestionsLimit) {
- if (DBG) {
- Log.w(TAG, "getSentenceSuggestionsMultiple");
- }
processOrEnqueueTask(
new SpellCheckerParams(TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE,
textInfos, suggestionsLimit, false));
}
public void close() {
- if (DBG) {
- Log.w(TAG, "close");
- }
processOrEnqueueTask(new SpellCheckerParams(TASK_CLOSE, null, 0, false));
}
public boolean isDisconnected() {
- return mOpened && mISpellCheckerSession == null;
+ synchronized (this) {
+ return mState != STATE_CONNECTED;
+ }
}
private void processOrEnqueueTask(SpellCheckerParams scp) {
- if (DBG) {
- Log.d(TAG, "process or enqueue task: " + mISpellCheckerSession);
- }
ISpellCheckerSession session;
synchronized (this) {
- session = mISpellCheckerSession;
- if (session == null) {
+ if (mState != STATE_WAIT_CONNECTION && mState != STATE_CONNECTED) {
+ Log.e(TAG, "ignoring processOrEnqueueTask due to unexpected mState="
+ + taskToString(scp.mWhat)
+ + " scp.mWhat=" + taskToString(scp.mWhat));
+ return;
+ }
+
+ if (mState == STATE_WAIT_CONNECTION) {
+ // If we are still waiting for the connection. Need to pay special attention.
+ if (scp.mWhat == TASK_CLOSE) {
+ processCloseLocked();
+ return;
+ }
+ // Enqueue the task to task queue.
SpellCheckerParams closeTask = null;
if (scp.mWhat == TASK_CANCEL) {
+ if (DBG) Log.d(TAG, "canceling pending tasks in processOrEnqueueTask.");
while (!mPendingTasks.isEmpty()) {
final SpellCheckerParams tmp = mPendingTasks.poll();
if (tmp.mWhat == TASK_CLOSE) {
@@ -409,9 +474,15 @@ public class SpellCheckerSession {
if (closeTask != null) {
mPendingTasks.offer(closeTask);
}
+ if (DBG) Log.d(TAG, "queueing tasks in processOrEnqueueTask since the"
+ + " connection is not established."
+ + " mPendingTasks.size()=" + mPendingTasks.size());
return;
}
+
+ session = mISpellCheckerSession;
}
+ // session must never be null here.
processTask(session, scp, false);
}
@@ -467,9 +538,6 @@ public class SpellCheckerSession {
@Override
public void onServiceConnected(ISpellCheckerSession session) {
- if (DBG) {
- Log.w(TAG, "SpellCheckerSession connected.");
- }
mParentSpellCheckerSessionListenerImpl.onServiceConnected(session);
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 0001860..6454b57 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6575,13 +6575,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* @return A view from the ScrapViews collection. These are unordered.
*/
View getScrapView(int position) {
+ final int whichScrap = mAdapter.getItemViewType(position);
+ if (whichScrap < 0) {
+ return null;
+ }
if (mViewTypeCount == 1) {
return retrieveFromScrap(mCurrentScrap, position);
- } else {
- final int whichScrap = mAdapter.getItemViewType(position);
- if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
- return retrieveFromScrap(mScrapViews[whichScrap], position);
- }
+ } else if (whichScrap < mScrapViews.length) {
+ return retrieveFromScrap(mScrapViews[whichScrap], position);
}
return null;
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index cf6a018..238d6c4 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -122,6 +122,7 @@ public class Editor {
static final int BLINK = 500;
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
+ private static final float LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS = 0.5f;
// Tag used when the Editor maintains its own separate UndoManager.
private static final String UNDO_OWNER_TAG = "Editor";
@@ -244,15 +245,6 @@ public class Editor {
final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
- private final Runnable mHideFloatingToolbar = new Runnable() {
- @Override
- public void run() {
- if (mTextActionMode != null) {
- mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
- }
- }
- };
-
private final Runnable mShowFloatingToolbar = new Runnable() {
@Override
public void run() {
@@ -389,7 +381,6 @@ public class Editor {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
- mTextView.removeCallbacks(mHideFloatingToolbar);
mTextView.removeCallbacks(mShowFloatingToolbar);
destroyDisplayListsData();
@@ -1248,14 +1239,12 @@ public class Editor {
private void hideFloatingToolbar() {
if (mTextActionMode != null) {
mTextView.removeCallbacks(mShowFloatingToolbar);
- // Delay the "hide" a little bit just in case a "show" will happen almost immediately.
- mTextView.postDelayed(mHideFloatingToolbar, 100);
+ mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
}
}
private void showFloatingToolbar() {
if (mTextActionMode != null) {
- mTextView.removeCallbacks(mHideFloatingToolbar);
// Delay "show" so it doesn't interfere with click confirmations
// or double-clicks that could "dismiss" the floating toolbar.
int delay = ViewConfiguration.getDoubleTapTimeout();
@@ -3579,13 +3568,24 @@ public class Editor {
}
protected void updateDrawable() {
+ if (mIsDragging) {
+ // Don't update drawable during dragging.
+ return;
+ }
final int offset = getCurrentCursorOffset();
final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
final Drawable oldDrawable = mDrawable;
mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
- if (oldDrawable != mDrawable) {
+ final Layout layout = mTextView.getLayout();
+ if (layout != null && oldDrawable != mDrawable && isShowing()) {
+ // Update popup window position.
+ mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX -
+ getHorizontalOffset() + getCursorOffset());
+ mPositionX += mTextView.viewportToContentHorizontalOffset();
+ mPositionHasChanged = true;
+ updatePosition(mLastParentX, mLastParentY, false, false);
postInvalidate();
}
}
@@ -3859,10 +3859,12 @@ public class Editor {
case MotionEvent.ACTION_UP:
filterOnTouchUp();
mIsDragging = false;
+ updateDrawable();
break;
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
+ updateDrawable();
break;
}
return true;
@@ -4024,7 +4026,15 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
- positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
+ Layout layout = mTextView.getLayout();
+ int offset;
+ if (layout != null) {
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ offset = mTextView.getOffsetAtCoordinate(currLine, x);
+ } else {
+ offset = mTextView.getOffsetForPosition(x, y);
+ }
+ positionAtCursorOffset(offset, false);
if (mTextActionMode != null) {
mTextActionMode.invalidate();
}
@@ -4084,16 +4094,23 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
- final int selectionEnd = mTextView.getSelectionEnd();
final Layout layout = mTextView.getLayout();
- int initialOffset = mTextView.getOffsetForPosition(x, y);
- int currLine = mTextView.getLineAtCoordinate(y);
+ if (layout == null) {
+ // HandleView will deal appropriately in positionAtCursorOffset when
+ // layout is null.
+ positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
+ return;
+ }
+
boolean positionCursor = false;
+ final int selectionEnd = mTextView.getSelectionEnd();
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
if (initialOffset >= selectionEnd) {
// Handles have crossed, bound it to the last selected line and
// adjust by word / char as normal.
- currLine = layout != null ? layout.getLineForOffset(selectionEnd) : mPrevLine;
+ currLine = layout.getLineForOffset(selectionEnd);
initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
}
@@ -4211,16 +4228,23 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
- final int selectionStart = mTextView.getSelectionStart();
final Layout layout = mTextView.getLayout();
- int initialOffset = mTextView.getOffsetForPosition(x, y);
- int currLine = mTextView.getLineAtCoordinate(y);
+ if (layout == null) {
+ // HandleView will deal appropriately in positionAtCursorOffset when
+ // layout is null.
+ positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
+ return;
+ }
+
boolean positionCursor = false;
+ final int selectionStart = mTextView.getSelectionStart();
+ int currLine = getCurrentLineAdjustedForSlop(layout, mPrevLine, y);
+ int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
if (initialOffset <= selectionStart) {
// Handles have crossed, bound it to the first selected line and
// adjust by word / char as normal.
- currLine = layout != null ? layout.getLineForOffset(selectionStart) : mPrevLine;
+ currLine = layout.getLineForOffset(selectionStart);
initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
}
@@ -4240,7 +4264,7 @@ public class Editor {
offset = mPreviousOffset;
}
}
- if (layout != null && offset > initialOffset) {
+ if (offset > initialOffset) {
final float adjustedX = layout.getPrimaryHorizontal(offset);
mTouchWordDelta =
adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
@@ -4256,7 +4280,7 @@ public class Editor {
if (currLine < mPrevLine) {
// We're on a different line, so we'll snap to word boundaries.
offset = end;
- if (layout != null && offset > initialOffset) {
+ if (offset > initialOffset) {
final float adjustedX = layout.getPrimaryHorizontal(offset);
mTouchWordDelta =
adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
@@ -4297,6 +4321,37 @@ public class Editor {
}
}
+ private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
+ if (layout == null || prevLine > layout.getLineCount()
+ || layout.getLineCount() <= 0 || prevLine < 0) {
+ // Invalid parameters, just return whatever line is at y.
+ return mTextView.getLineAtCoordinate(y);
+ }
+
+ final float verticalOffset = mTextView.viewportToContentVerticalOffset();
+ final int lineCount = layout.getLineCount();
+ final float slop = mTextView.getLineHeight() * LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS;
+
+ final float firstLineTop = layout.getLineTop(0) + verticalOffset;
+ final float prevLineTop = layout.getLineTop(prevLine) + verticalOffset;
+ final float yTopBound = Math.max(prevLineTop - slop, firstLineTop + slop);
+
+ final float lastLineBottom = layout.getLineBottom(lineCount - 1) + verticalOffset;
+ final float prevLineBottom = layout.getLineBottom(prevLine) + verticalOffset;
+ final float yBottomBound = Math.min(prevLineBottom + slop, lastLineBottom - slop);
+
+ // Determine if we've moved lines based on y position and previous line.
+ int currLine;
+ if (y <= yTopBound) {
+ currLine = Math.max(prevLine - 1, 0);
+ } else if (y >= yBottomBound) {
+ currLine = Math.min(prevLine + 1, lineCount - 1);
+ } else {
+ currLine = prevLine;
+ }
+ return currLine;
+ }
+
/**
* A CursorController instance can be used to control a cursor in the text.
*/
@@ -4379,6 +4434,10 @@ public class Editor {
// Indicates whether the user is selecting text and using the drag accelerator.
private boolean mDragAcceleratorActive;
private boolean mHaventMovedEnoughToStartDrag;
+ // The line that a selection happened most recently with the drag accelerator.
+ private int mLineSelectionIsOn = -1;
+ // Whether the drag accelerator has selected past the initial line.
+ private boolean mSwitchedLines = false;
SelectionModifierCursorController() {
resetTouchOffsets();
@@ -4431,6 +4490,7 @@ public class Editor {
// Start location of selection.
mStartOffset = mTextView.getOffsetForPosition(mLastDownPositionX,
mLastDownPositionY);
+ mLineSelectionIsOn = mTextView.getLineAtCoordinate(mLastDownPositionY);
// Don't show the handles until user has lifted finger.
hide();
@@ -4514,17 +4574,35 @@ public class Editor {
break;
}
- if (mStartOffset != -1) {
+ if (mStartOffset != -1 && mTextView.getLayout() != null) {
if (!mHaventMovedEnoughToStartDrag) {
- // Offset the finger by the same vertical offset as the handles. This
- // improves visibility of the content being selected by shifting
- // the finger below the content.
- final float fingerOffset = (mStartHandle != null)
- ? mStartHandle.getIdealVerticalOffset()
- : touchSlop;
- int offset =
- mTextView.getOffsetForPosition(eventX, eventY - fingerOffset);
+
+ float y = eventY;
+ if (mSwitchedLines) {
+ // Offset the finger by the same vertical offset as the handles.
+ // This improves visibility of the content being selected by
+ // shifting the finger below the content, this is applied once
+ // the user has switched lines.
+ final float fingerOffset = (mStartHandle != null)
+ ? mStartHandle.getIdealVerticalOffset()
+ : touchSlop;
+ y = eventY - fingerOffset;
+ }
+
+ final int currLine = getCurrentLineAdjustedForSlop(
+ mTextView.getLayout(),
+ mLineSelectionIsOn, y);
+ if (!mSwitchedLines && currLine != mLineSelectionIsOn) {
+ // Break early here, we want to offset the finger position from
+ // the selection highlight, once the user moved their finger
+ // to a different line we should apply the offset and *not* switch
+ // lines until recomputing the position with the finger offset.
+ mSwitchedLines = true;
+ break;
+ }
+
int startOffset;
+ int offset = mTextView.getOffsetAtCoordinate(currLine, eventX);
// Snap to word boundaries.
if (mStartOffset < offset) {
// Expanding with end handle.
@@ -4535,6 +4613,7 @@ public class Editor {
offset = getWordStart(offset);
startOffset = getWordEnd(mStartOffset);
}
+ mLineSelectionIsOn = currLine;
Selection.setSelection((Spannable) mTextView.getText(),
startOffset, offset);
}
@@ -4571,6 +4650,7 @@ public class Editor {
startSelectionActionMode();
mDragAcceleratorActive = false;
mStartOffset = -1;
+ mSwitchedLines = false;
}
break;
}
@@ -4600,6 +4680,7 @@ public class Editor {
mMinTouchOffset = mMaxTouchOffset = -1;
mStartOffset = -1;
mDragAcceleratorActive = false;
+ mSwitchedLines = false;
}
/**
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 6b28f89..e0b2395 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -216,7 +216,7 @@ public class ImageView extends View {
protected boolean verifyDrawable(Drawable dr) {
return mDrawable == dr || super.verifyDrawable(dr);
}
-
+
@Override
public void jumpDrawablesToCurrentState() {
super.jumpDrawablesToCurrentState();
@@ -226,6 +226,15 @@ public class ImageView extends View {
@Override
public void invalidateDrawable(Drawable dr) {
if (dr == mDrawable) {
+ if (dr != null) {
+ // update cached drawable dimensions if they've changed
+ final int w = dr.getIntrinsicWidth();
+ final int h = dr.getIntrinsicHeight();
+ if (w != mDrawableWidth || h != mDrawableHeight) {
+ mDrawableWidth = w;
+ mDrawableHeight = h;
+ }
+ }
/* we invalidate the whole view in this case because it's very
* hard to know where the drawable actually is. This is made
* complicated because of the offsets and transformations that
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index affc5da..339038e 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -522,7 +522,7 @@ public class RelativeLayout extends ViewGroup {
View baselineView = null;
LayoutParams baselineParams = null;
for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
if (baselineView == null || baselineParams == null
@@ -548,9 +548,9 @@ public class RelativeLayout extends ViewGroup {
if (offsetHorizontalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) {
centerHorizontal(child, params, width);
@@ -578,9 +578,9 @@ public class RelativeLayout extends ViewGroup {
if (offsetVerticalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) {
centerVertical(child, params, height);
@@ -607,9 +607,9 @@ public class RelativeLayout extends ViewGroup {
final int verticalOffset = contentBounds.top - top;
if (horizontalOffset != 0 || verticalOffset != 0) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE && child != ignore) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
if (horizontalGravity) {
params.mLeft += horizontalOffset;
params.mRight += horizontalOffset;
@@ -626,9 +626,9 @@ public class RelativeLayout extends ViewGroup {
if (isLayoutRtl()) {
final int offsetWidth = myWidth - width;
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mLeft -= offsetWidth;
params.mRight -= offsetWidth;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 353901c..c538dc2 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -241,8 +241,6 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
* @attr ref android.R.styleable#TextView_fontFeatureSettings
* @attr ref android.R.styleable#TextView_breakStrategy
* @attr ref android.R.styleable#TextView_hyphenationFrequency
- * @attr ref android.R.styleable#TextView_leftIndents
- * @attr ref android.R.styleable#TextView_rightIndents
*/
@RemoteView
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -559,8 +557,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mBreakStrategy;
private int mHyphenationFrequency;
- private int[] mLeftIndents;
- private int[] mRightIndents;
private int mMaximum = Integer.MAX_VALUE;
private int mMaxMode = LINES;
@@ -1165,16 +1161,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case com.android.internal.R.styleable.TextView_hyphenationFrequency:
mHyphenationFrequency = a.getInt(attr, Layout.HYPHENATION_FREQUENCY_NONE);
break;
-
- case com.android.internal.R.styleable.TextView_leftIndents:
- TypedArray margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID));
- mLeftIndents = parseDimensionArray(margins);
- break;
-
- case com.android.internal.R.styleable.TextView_rightIndents:
- margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID));
- mRightIndents = parseDimensionArray(margins);
- break;
}
}
a.recycle();
@@ -3095,51 +3081,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
- * Set indents. Arguments are arrays holding an indent amount, one per line, measured in
- * pixels. For lines past the last element in the array, the last element repeats.
- *
- * @param leftIndents array of indent values for left margin, in pixels
- * @param rightIndents array of indent values for right margin, in pixels
- *
- * @see #getLeftIndents()
- * @see #getRightIndents()
- *
- * @attr ref android.R.styleable#TextView_leftIndents
- * @attr ref android.R.styleable#TextView_rightIndents
- */
- public void setIndents(@Nullable int[] leftIndents, @Nullable int[] rightIndents) {
- mLeftIndents = leftIndents;
- mRightIndents = rightIndents;
- if (mLayout != null) {
- nullLayouts();
- requestLayout();
- invalidate();
- }
- }
-
- /**
- * Get left indents. See {#link setMargins} for more details.
- *
- * @return left indents
- * @see #setIndents(int[], int[])
- * @attr ref android.R.styleable#TextView_leftIndents
- */
- public int[] getLeftIndents() {
- return mLeftIndents;
- }
-
- /**
- * Get right indents. See {#link setMargins} for more details.
- *
- * @return right indents
- * @see #setIndents(int[], int[])
- * @attr ref android.R.styleable#TextView_rightIndents
- */
- public int[] getRightIndents() {
- return mRightIndents;
- }
-
- /**
* Sets font feature settings. The format is the same as the CSS
* font-feature-settings attribute:
* http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings
@@ -6685,9 +6626,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
.setIncludePad(mIncludePad)
.setBreakStrategy(mBreakStrategy)
.setHyphenationFrequency(mHyphenationFrequency);
- if (mLeftIndents != null || mRightIndents != null) {
- builder.setIndents(mLeftIndents, mRightIndents);
- }
if (shouldEllipsize) {
builder.setEllipsize(mEllipsize)
.setEllipsizedWidth(ellipsisWidth)
@@ -6776,9 +6714,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
.setIncludePad(mIncludePad)
.setBreakStrategy(mBreakStrategy)
.setHyphenationFrequency(mHyphenationFrequency);
- if (mLeftIndents != null || mRightIndents != null) {
- builder.setIndents(mLeftIndents, mRightIndents);
- }
if (shouldEllipsize) {
builder.setEllipsize(effectiveEllipsize)
.setEllipsizedWidth(ellipsisWidth)
@@ -8790,7 +8725,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public void onProvideStructure(ViewStructure structure) {
super.onProvideStructure(structure);
- final boolean isPassword = hasPasswordTransformationMethod();
+ final boolean isPassword = hasPasswordTransformationMethod()
+ || isPasswordInputType(getInputType());
if (!isPassword) {
structure.setText(getText(), getSelectionStart(), getSelectionEnd());
@@ -9244,25 +9180,25 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* If provided, this ActionMode.Callback will be used to create the ActionMode when text
* insertion is initiated in this View.
- *
* The standard implementation populates the menu with a subset of Select All,
* Paste and Replace actions, depending on what this View supports.
*
- * A custom implementation can add new entries in the default menu in its
- * {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
- * default actions can also be removed from the menu using
+ * <p>A custom implementation can add new entries in the default menu in its
+ * {@link android.view.ActionMode.Callback#onPrepareActionMode(android.view.ActionMode,
+ * android.view.Menu)} method. The default actions can also be removed from the menu using
* {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll},
- * {@link android.R.id#paste} or {@link android.R.id#replaceText} ids as parameters.
+ * {@link android.R.id#paste} or {@link android.R.id#replaceText} ids as parameters.</p>
*
- * Returning false from
- * {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
- * the action mode from being started.
+ * <p>Returning false from
+ * {@link android.view.ActionMode.Callback#onCreateActionMode(android.view.ActionMode,
+ * android.view.Menu)} will prevent the action mode from being started.</p>
*
- * Action click events should be handled by the custom implementation of
- * {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
+ * <p>Action click events should be handled by the custom implementation of
+ * {@link android.view.ActionMode.Callback#onActionItemClicked(android.view.ActionMode,
+ * android.view.MenuItem)}.</p>
*
- * Note that text insertion mode is not started when a TextView receives focus and the
- * {@link android.R.attr#selectAllOnFocus} flag has been set.
+ * <p>Note that text insertion mode is not started when a TextView receives focus and the
+ * {@link android.R.attr#selectAllOnFocus} flag has been set.</p>
*/
public void setCustomInsertionActionModeCallback(ActionMode.Callback actionModeCallback) {
createEditorIfNeeded();
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 8ace0f3..471ea9b 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -26,7 +26,6 @@ import android.annotation.StyleRes;
import android.app.ActionBar;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -148,6 +147,9 @@ public class Toolbar extends ViewGroup {
// Clear me after use.
private final ArrayList<View> mTempViews = new ArrayList<View>();
+ // Used to hold views that will be removed while we have an expanded action view.
+ private final ArrayList<View> mHiddenViews = new ArrayList<>();
+
private final int[] mTempMargins = new int[2];
private OnMenuItemClickListener mOnMenuItemClickListener;
@@ -271,6 +273,24 @@ public class Toolbar extends ViewGroup {
if (!TextUtils.isEmpty(navDesc)) {
setNavigationContentDescription(navDesc);
}
+
+ final Drawable logo = a.getDrawable(R.styleable.Toolbar_logo);
+ if (logo != null) {
+ setLogo(logo);
+ }
+
+ final CharSequence logoDesc = a.getText(R.styleable.Toolbar_logoDescription);
+ if (!TextUtils.isEmpty(logoDesc)) {
+ setLogoDescription(logoDesc);
+ }
+
+ if (a.hasValue(R.styleable.Toolbar_titleTextColor)) {
+ setTitleTextColor(a.getColor(R.styleable.Toolbar_titleTextColor, 0xffffffff));
+ }
+
+ if (a.hasValue(R.styleable.Toolbar_subtitleTextColor)) {
+ setSubtitleTextColor(a.getColor(R.styleable.Toolbar_subtitleTextColor, 0xffffffff));
+ }
a.recycle();
}
@@ -435,12 +455,12 @@ public class Toolbar extends ViewGroup {
public void setLogo(Drawable drawable) {
if (drawable != null) {
ensureLogoView();
- if (mLogoView.getParent() == null) {
- addSystemView(mLogoView);
- updateChildVisibilityForExpandedActionView(mLogoView);
+ if (!isChildOrHidden(mLogoView)) {
+ addSystemView(mLogoView, true);
}
- } else if (mLogoView != null && mLogoView.getParent() != null) {
+ } else if (mLogoView != null && isChildOrHidden(mLogoView)) {
removeView(mLogoView);
+ mHiddenViews.remove(mLogoView);
}
if (mLogoView != null) {
mLogoView.setImageDrawable(drawable);
@@ -577,12 +597,12 @@ public class Toolbar extends ViewGroup {
mTitleTextView.setTextColor(mTitleTextColor);
}
}
- if (mTitleTextView.getParent() == null) {
- addSystemView(mTitleTextView);
- updateChildVisibilityForExpandedActionView(mTitleTextView);
+ if (!isChildOrHidden(mTitleTextView)) {
+ addSystemView(mTitleTextView, true);
}
- } else if (mTitleTextView != null && mTitleTextView.getParent() != null) {
+ } else if (mTitleTextView != null && isChildOrHidden(mTitleTextView)) {
removeView(mTitleTextView);
+ mHiddenViews.remove(mTitleTextView);
}
if (mTitleTextView != null) {
mTitleTextView.setText(title);
@@ -631,12 +651,12 @@ public class Toolbar extends ViewGroup {
mSubtitleTextView.setTextColor(mSubtitleTextColor);
}
}
- if (mSubtitleTextView.getParent() == null) {
- addSystemView(mSubtitleTextView);
- updateChildVisibilityForExpandedActionView(mSubtitleTextView);
+ if (!isChildOrHidden(mSubtitleTextView)) {
+ addSystemView(mSubtitleTextView, true);
}
- } else if (mSubtitleTextView != null && mSubtitleTextView.getParent() != null) {
+ } else if (mSubtitleTextView != null && isChildOrHidden(mSubtitleTextView)) {
removeView(mSubtitleTextView);
+ mHiddenViews.remove(mSubtitleTextView);
}
if (mSubtitleTextView != null) {
mSubtitleTextView.setText(subtitle);
@@ -772,12 +792,12 @@ public class Toolbar extends ViewGroup {
public void setNavigationIcon(@Nullable Drawable icon) {
if (icon != null) {
ensureNavButtonView();
- if (mNavButtonView.getParent() == null) {
- addSystemView(mNavButtonView);
- updateChildVisibilityForExpandedActionView(mNavButtonView);
+ if (!isChildOrHidden(mNavButtonView)) {
+ addSystemView(mNavButtonView, true);
}
- } else if (mNavButtonView != null && mNavButtonView.getParent() != null) {
+ } else if (mNavButtonView != null && isChildOrHidden(mNavButtonView)) {
removeView(mNavButtonView);
+ mHiddenViews.remove(mNavButtonView);
}
if (mNavButtonView != null) {
mNavButtonView.setImageDrawable(icon);
@@ -866,7 +886,7 @@ public class Toolbar extends ViewGroup {
final LayoutParams lp = generateDefaultLayoutParams();
lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mMenuView.setLayoutParams(lp);
- addSystemView(mMenuView);
+ addSystemView(mMenuView, false);
}
}
@@ -1041,7 +1061,7 @@ public class Toolbar extends ViewGroup {
}
}
- private void addSystemView(View v) {
+ private void addSystemView(View v, boolean allowHide) {
final ViewGroup.LayoutParams vlp = v.getLayoutParams();
final LayoutParams lp;
if (vlp == null) {
@@ -1052,7 +1072,13 @@ public class Toolbar extends ViewGroup {
lp = (LayoutParams) vlp;
}
lp.mViewType = LayoutParams.SYSTEM;
- addView(v, lp);
+
+ if (allowHide && mExpandedActionView != null) {
+ v.setLayoutParams(lp);
+ mHiddenViews.add(v);
+ } else {
+ addView(v, lp);
+ }
}
@Override
@@ -1741,22 +1767,30 @@ public class Toolbar extends ViewGroup {
return mWrapper;
}
- private void setChildVisibilityForExpandedActionView(boolean expand) {
+ void removeChildrenForExpandedActionView() {
final int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
+ // Go backwards since we're removing from the list
+ for (int i = childCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
- child.setVisibility(expand ? GONE : VISIBLE);
+ removeViewAt(i);
+ mHiddenViews.add(child);
}
}
}
- private void updateChildVisibilityForExpandedActionView(View child) {
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
- child.setVisibility(mExpandedActionView != null ? GONE : VISIBLE);
+ void addChildrenForExpandedActionView() {
+ final int count = mHiddenViews.size();
+ // Re-add in reverse order since we removed in reverse order
+ for (int i = count - 1; i >= 0; i--) {
+ addView(mHiddenViews.get(i));
}
+ mHiddenViews.clear();
+ }
+
+ private boolean isChildOrHidden(View child) {
+ return child.getParent() == this || mHiddenViews.contains(child);
}
/**
@@ -1971,7 +2005,7 @@ public class Toolbar extends ViewGroup {
addView(mExpandedActionView);
}
- setChildVisibilityForExpandedActionView(true);
+ removeChildrenForExpandedActionView();
requestLayout();
item.setActionViewExpanded(true);
@@ -1994,7 +2028,7 @@ public class Toolbar extends ViewGroup {
removeView(mCollapseButtonView);
mExpandedActionView = null;
- setChildVisibilityForExpandedActionView(false);
+ addChildrenForExpandedActionView();
mCurrentExpandedItem = null;
requestLayout();
item.setActionViewExpanded(false);