summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/AppOpsManager.java25
-rw-r--r--core/java/android/app/ApplicationPackageManager.java27
-rw-r--r--core/java/android/app/KeyguardManager.java20
-rw-r--r--core/java/android/app/StatusBarManager.java12
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java72
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl5
-rw-r--r--core/java/android/content/ContentProviderNative.java3
-rw-r--r--core/java/android/content/pm/IPackageMoveObserver.aidl3
-rw-r--r--core/java/android/content/pm/PackageManager.java17
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java161
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java22
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java86
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java35
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java46
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java7
-rw-r--r--core/java/android/hardware/usb/UsbDevice.java19
-rw-r--r--core/java/android/net/INetworkPolicyManager.aidl2
-rw-r--r--core/java/android/net/NetworkPolicyManager.java20
-rw-r--r--core/java/android/os/IDeviceIdleController.aidl26
-rw-r--r--core/java/android/os/INetworkManagementService.aidl2
-rw-r--r--core/java/android/os/IPermissionController.aidl1
-rw-r--r--core/java/android/os/PowerManager.java8
-rw-r--r--core/java/android/os/storage/IMountService.java84
-rw-r--r--core/java/android/os/storage/IMountServiceListener.java10
-rw-r--r--core/java/android/os/storage/StorageEventListener.java2
-rw-r--r--core/java/android/os/storage/StorageManager.java101
-rw-r--r--core/java/android/os/storage/VolumeInfo.java25
-rw-r--r--core/java/android/os/storage/VolumeRecord.java139
-rw-r--r--core/java/android/security/keymaster/KeyCharacteristics.java8
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java22
-rw-r--r--core/java/android/speech/RecognizerIntent.java8
-rw-r--r--core/java/android/transition/TransitionInflater.java2
-rw-r--r--core/java/android/util/EventLog.java18
-rw-r--r--core/java/android/view/DisplayListCanvas.java18
-rw-r--r--core/java/android/view/PhoneWindow.java2
-rw-r--r--core/java/android/view/TextureView.java5
-rw-r--r--core/java/android/view/View.java112
-rw-r--r--core/java/android/view/ViewGroup.java3
-rw-r--r--core/java/android/widget/DayPickerPagerAdapter.java6
-rw-r--r--core/java/android/widget/DayPickerView.java20
-rw-r--r--core/java/android/widget/Editor.java100
-rw-r--r--core/java/android/widget/SimpleMonthView.java49
-rw-r--r--core/java/android/widget/Switch.java2
-rw-r--r--core/java/android/widget/TextView.java12
44 files changed, 918 insertions, 449 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 223d528..48e380b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -726,6 +726,16 @@ public class AppOpsManager {
false
};
+ /**
+ * This is a mapping from a permission name to public app op name.
+ */
+ private static final ArrayMap<String, String> sPermToOp = new ArrayMap<>();
+ static {
+ sPermToOp.put(Manifest.permission.ACCESS_COARSE_LOCATION, OPSTR_COARSE_LOCATION);
+ sPermToOp.put(Manifest.permission.ACCESS_FINE_LOCATION, OPSTR_FINE_LOCATION);
+ sPermToOp.put(Manifest.permission.PACKAGE_USAGE_STATS, OPSTR_GET_USAGE_STATS);
+ }
+
private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
static {
@@ -1066,6 +1076,21 @@ public class AppOpsManager {
}
/**
+ * Gets the app op name associated with a given permission.
+ * The app op name is one of the public constants defined
+ * in this class such as {@link #OPSTR_COARSE_LOCATION}.
+ *
+ * @param permission The permission.
+ * @return The app op associated with the permission or null.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static String permissionToOp(String permission) {
+ return sPermToOp.get(permission);
+ }
+
+ /**
* Monitor for changes to the operating mode for the given op in the given app package.
* @param op The operation to monitor, one of OPSTR_*.
* @param packageName The name of the application to monitor.
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 16a2430..6e511f3 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -79,6 +79,7 @@ import android.view.Display;
import dalvik.system.VMRuntime;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
import com.android.internal.util.UserIcons;
@@ -2054,8 +2055,7 @@ final class ApplicationPackageManager extends PackageManager {
/** {@hide} */
private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
Handler.Callback {
- private static final int MSG_STARTED = 1;
- private static final int MSG_STATUS_CHANGED = 2;
+ private static final int MSG_STATUS_CHANGED = 1;
final MoveCallback mCallback;
final Handler mHandler;
@@ -2067,26 +2067,25 @@ final class ApplicationPackageManager extends PackageManager {
@Override
public boolean handleMessage(Message msg) {
- final int moveId = msg.arg1;
switch (msg.what) {
- case MSG_STARTED:
- mCallback.onStarted(moveId, (String) msg.obj);
- return true;
case MSG_STATUS_CHANGED:
- mCallback.onStatusChanged(moveId, msg.arg2, (long) msg.obj);
+ final SomeArgs args = (SomeArgs) msg.obj;
+ mCallback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
+ (long) args.arg4);
+ args.recycle();
return true;
}
return false;
}
@Override
- public void onStarted(int moveId, String title) {
- mHandler.obtainMessage(MSG_STARTED, moveId, 0, title).sendToTarget();
- }
-
- @Override
- public void onStatusChanged(int moveId, int status, long estMillis) {
- mHandler.obtainMessage(MSG_STATUS_CHANGED, moveId, status, estMillis).sendToTarget();
+ public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
+ final SomeArgs args = SomeArgs.obtain();
+ args.argi1 = moveId;
+ args.arg2 = moveTitle;
+ args.argi3 = status;
+ args.arg4 = estMillis;
+ mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
}
}
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index ebb3c43..2c12317 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -199,9 +199,12 @@ public class KeyguardManager {
}
/**
- * Return whether the keyguard requires a password to unlock.
+ * Return whether the keyguard is secured by a PIN, pattern or password or a SIM card
+ * is currently locked.
*
- * @return true if keyguard is secure.
+ * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states.
+ *
+ * @return true if a PIN, pattern or password is set or a SIM card is locked.
*/
public boolean isKeyguardSecure() {
try {
@@ -240,12 +243,8 @@ public class KeyguardManager {
}
/**
- * Returns whether the device is currently locked and requires a PIN, pattern or
- * password to unlock.
+ * Per-user version of {@link #isDeviceLocked()}.
*
- * @param userId the user for which the locked state should be reported.
- * @return true if unlocking the device currently requires a PIN, pattern or
- * password.
* @hide
*/
public boolean isDeviceLocked(int userId) {
@@ -260,6 +259,8 @@ public class KeyguardManager {
* Returns whether the device is secured with a PIN, pattern or
* password.
*
+ * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure.
+ *
* @return true if a PIN, pattern or password was set.
*/
public boolean isDeviceSecure() {
@@ -267,11 +268,8 @@ public class KeyguardManager {
}
/**
- * Returns whether the device is secured with a PIN, pattern or
- * password.
+ * Per-user version of {@link #isDeviceSecure()}.
*
- * @param userId the user for which the secure state should be reported.
- * @return true if a PIN, pattern or password was set.
* @hide
*/
public boolean isDeviceSecure(int userId) {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 207519c..31d1ab7 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -63,12 +63,20 @@ public class StatusBarManager {
| DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK
| DISABLE_SEARCH;
+ /**
+ * Flag to disable quick settings.
+ *
+ * Setting this flag disables quick settings completely, but does not disable expanding the
+ * notification shade.
+ */
+ public static final int DISABLE2_QUICK_SETTINGS = 0x00000001;
+
public static final int DISABLE2_NONE = 0x00000000;
- public static final int DISABLE2_MASK = 0x00000000;
+ public static final int DISABLE2_MASK = DISABLE2_QUICK_SETTINGS;
@IntDef(flag = true,
- value = {DISABLE2_NONE, DISABLE2_MASK})
+ value = {DISABLE2_NONE, DISABLE2_MASK, DISABLE2_QUICK_SETTINGS})
@Retention(RetentionPolicy.SOURCE)
public @interface Disable2Flags {}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ed814c3..cf9813f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -807,6 +807,24 @@ public class DevicePolicyManager {
public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED
= "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
+ /**
+ * Permission policy to prompt user for new permission requests for runtime permissions.
+ * Already granted or denied permissions are not affected by this.
+ */
+ public static final int PERMISSION_POLICY_PROMPT = 0;
+
+ /**
+ * Permission policy to always grant new permission requests for runtime permissions.
+ * Already granted or denied permissions are not affected by this.
+ */
+ public static final int PERMISSION_POLICY_AUTO_GRANT = 1;
+
+ /**
+ * Permission policy to always deny new permission requests for runtime permissions.
+ * Already granted or denied permissions are not affected by this.
+ */
+ public static final int PERMISSION_POLICY_AUTO_DENY = 2;
+
/**
* Return true if the given administrator component is currently
@@ -4342,4 +4360,58 @@ public class DevicePolicyManager {
Log.w(TAG, "Failed talking with device policy service", re);
}
}
+
+ /**
+ * Called by profile or device owners to set the default response for future runtime permission
+ * requests by applications. The policy can allow for normal operation which prompts the
+ * user to grant a permission, or can allow automatic granting or denying of runtime
+ * permission requests by an application. This also applies to new permissions declared by app
+ * updates.
+ * @param admin Which profile or device owner this request is associated with.
+ * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
+ * {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}.
+ */
+ public void setPermissionPolicy(ComponentName admin, int policy) {
+ try {
+ mService.setPermissionPolicy(admin, policy);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed talking with device policy service", re);
+ }
+ }
+
+ /**
+ * Returns the current runtime permission policy set by the device or profile owner. The
+ * default is {@link #PERMISSION_POLICY_PROMPT}.
+ * @param admin Which profile or device owner this request is associated with.
+ * @return the current policy for future permission requests.
+ */
+ public int getPermissionPolicy(ComponentName admin) {
+ try {
+ return mService.getPermissionPolicy(admin);
+ } catch (RemoteException re) {
+ return PERMISSION_POLICY_PROMPT;
+ }
+ }
+
+ /**
+ * Grants or revokes a runtime permission to a specific application so that the user
+ * does not have to be prompted. This might affect all permissions in a group that the
+ * runtime permission belongs to. This method can only be called by a profile or device
+ * owner.
+ * @param admin Which profile or device owner this request is associated with.
+ * @param packageName The application to grant or revoke a permission to.
+ * @param permission The permission to grant or revoke.
+ * @param granted Whether or not to grant the permission. If false, all permissions in the
+ * associated permission group will be denied.
+ * @return whether the permission was successfully granted or revoked
+ */
+ public boolean setPermissionGranted(ComponentName admin, String packageName,
+ String permission, boolean granted) {
+ try {
+ return mService.setPermissionGranted(admin, packageName, permission, granted);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed talking with device policy service", re);
+ return false;
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index a678c51..833bc00 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -229,4 +229,9 @@ interface IDevicePolicyManager {
boolean getDoNotAskCredentialsOnBoot();
void notifyPendingSystemUpdate(in long updateReceivedTime);
+
+ void setPermissionPolicy(in ComponentName admin, int policy);
+ int getPermissionPolicy(in ComponentName admin);
+ boolean setPermissionGranted(in ComponentName admin, String packageName, String permission,
+ boolean granted);
}
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index f2e7fc4..4769bd0 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -593,7 +593,8 @@ final class ContentProviderProxy implements IContentProvider
DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
int has = reply.readInt();
- ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
+ ParcelFileDescriptor fd = has != 0 ? ParcelFileDescriptor.CREATOR
+ .createFromParcel(reply) : null;
return fd;
} finally {
data.recycle();
diff --git a/core/java/android/content/pm/IPackageMoveObserver.aidl b/core/java/android/content/pm/IPackageMoveObserver.aidl
index 50ab3b5..155ed0b 100644
--- a/core/java/android/content/pm/IPackageMoveObserver.aidl
+++ b/core/java/android/content/pm/IPackageMoveObserver.aidl
@@ -22,6 +22,5 @@ package android.content.pm;
* @hide
*/
oneway interface IPackageMoveObserver {
- void onStarted(int moveId, String title);
- void onStatusChanged(int moveId, int status, long estMillis);
+ void onStatusChanged(int moveId, String moveTitle, int status, long estMillis);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e1c271d..a1ee7fc 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -209,7 +209,14 @@ public abstract class PackageManager {
* matching. This is a synonym for including the CATEGORY_DEFAULT in your
* supplied Intent.
*/
- public static final int MATCH_DEFAULT_ONLY = 0x00010000;
+ public static final int MATCH_DEFAULT_ONLY = 0x00010000;
+
+ /**
+ * Querying flag: if set and if the platform is doing any filtering of the results, then
+ * the filtering will not happen. This is a synonym for saying that all results should
+ * be returned.
+ */
+ public static final int MATCH_ALL = 0x00020000;
/**
* Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
@@ -2637,6 +2644,8 @@ public abstract class PackageManager {
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
*
+ * You can also set {@link #MATCH_ALL} for preventing the filtering of the results.
+ *
* @return A List&lt;ResolveInfo&gt; containing one entry for each matching
* Activity. These are ordered from best to worst match -- that
* is, the first item in the list is what is returned by
@@ -2658,6 +2667,8 @@ public abstract class PackageManager {
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
*
+ * You can also set {@link #MATCH_ALL} for preventing the filtering of the results.
+ *
* @return A List&lt;ResolveInfo&gt; containing one entry for each matching
* Activity. These are ordered from best to worst match -- that
* is, the first item in the list is what is returned by
@@ -4201,8 +4212,8 @@ public abstract class PackageManager {
/** {@hide} */
public static abstract class MoveCallback {
- public abstract void onStarted(int moveId, String title);
- public abstract void onStatusChanged(int moveId, int status, long estMillis);
+ public abstract void onStatusChanged(int moveId, String moveTitle, int status,
+ long estMillis);
}
/** {@hide} */
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 87a1ca9..19e821c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -603,10 +603,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>List of available high speed video size and fps range configurations
* supported by the camera device, in the format of (width, height, fps_min, fps_max).</p>
- * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes},
- * this metadata will list the supported high speed video size and fps range
- * configurations. All the sizes listed in this configuration will be a subset
- * of the sizes reported by StreamConfigurationMap#getOutputSizes for processed
+ * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}, this metadata
+ * will list the supported high speed video size and fps range configurations. All the sizes
+ * listed in this configuration will be a subset of the sizes reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } for processed
* non-stalling formats.</p>
* <p>For the high speed video use case, where the application will set
* {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the application must
@@ -1116,11 +1115,12 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* into the 3 stream types as below:</p>
* <ul>
* <li>Processed (but stalling): any non-RAW format with a stallDurations &gt; 0.
- * Typically JPEG format (ImageFormat#JPEG).</li>
- * <li>Raw formats: ImageFormat#RAW_SENSOR, ImageFormat#RAW10, ImageFormat#RAW12,
- * and ImageFormat#RAW_OPAQUE.</li>
+ * Typically {@link android.graphics.ImageFormat#JPEG JPEG format}.</li>
+ * <li>Raw formats: {@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}, {@link android.graphics.ImageFormat#RAW10 RAW10}, or {@link android.graphics.ImageFormat#RAW12 RAW12}.</li>
* <li>Processed (but not-stalling): any non-RAW format without a stall duration.
- * Typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12.</li>
+ * Typically {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888},
+ * {@link android.graphics.ImageFormat#NV21 NV21}, or
+ * {@link android.graphics.ImageFormat#YV12 YV12}.</li>
* </ul>
* <p><b>Range of valid values:</b><br></p>
* <p>For processed (and stalling) format streams, &gt;= 1.</p>
@@ -1148,10 +1148,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* be any <code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
* <p>In particular, a <code>RAW</code> format is typically one of:</p>
* <ul>
- * <li>ImageFormat#RAW_SENSOR</li>
- * <li>ImageFormat#RAW10</li>
- * <li>ImageFormat#RAW12</li>
- * <li>Opaque <code>RAW</code></li>
+ * <li>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</li>
+ * <li>{@link android.graphics.ImageFormat#RAW10 RAW10}</li>
+ * <li>{@link android.graphics.ImageFormat#RAW12 RAW12}</li>
* </ul>
* <p>LEGACY mode devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> LEGACY)
* never support raw streams.</p>
@@ -1180,13 +1179,13 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>Processed (but not-stalling) is defined as any non-RAW format without a stall duration.
* Typically:</p>
* <ul>
- * <li>ImageFormat#YUV_420_888</li>
- * <li>ImageFormat#NV21</li>
- * <li>ImageFormat#YV12</li>
- * <li>Implementation-defined formats, i.e. StreamConfiguration#isOutputSupportedFor(Class)</li>
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</li>
+ * <li>{@link android.graphics.ImageFormat#NV21 NV21}</li>
+ * <li>{@link android.graphics.ImageFormat#YV12 YV12}</li>
+ * <li>Implementation-defined formats, i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#isOutputSupportedFor(Class) }</li>
* </ul>
- * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
- * a processed format -- it will return 0 for a non-stalling stream.</p>
+ * <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
+ * processed format -- it will return 0 for a non-stalling stream.</p>
* <p>LEGACY devices will support at least 2 processing/non-stalling streams.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>&gt;= 3
@@ -1212,10 +1211,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* the camera device. Using more streams simultaneously may require more hardware and
* CPU resources that will consume more power. The image format for this kind of an output stream can
* be any non-<code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
- * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations &gt; 0.
- * Typically only the <code>JPEG</code> format (ImageFormat#JPEG) is a stalling format.</p>
- * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
- * a processed format -- it will return a non-0 value for a stalling stream.</p>
+ * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations
+ * &gt; 0. Typically only the {@link android.graphics.ImageFormat#JPEG JPEG format} is a
+ * stalling format.</p>
+ * <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
+ * processed format -- it will return a non-0 value for a stalling stream.</p>
* <p>LEGACY devices will support up to 1 processing/stalling stream.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>&gt;= 1</p>
@@ -1232,10 +1232,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>The maximum numbers of any type of input streams
* that can be configured and used simultaneously by a camera device.</p>
* <p>When set to 0, it means no input stream is supported.</p>
- * <p>The image format for a input stream can be any supported
- * format returned by StreamConfigurationMap#getInputFormats. When using an
- * input stream, there must be at least one output stream
- * configured to to receive the reprocessed images.</p>
+ * <p>The image format for a input stream can be any supported format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }. When using an
+ * input stream, there must be at least one output stream configured to to receive the
+ * reprocessed images.</p>
* <p>When an input stream and some output streams are used in a reprocessing request,
* only the input buffer will be used to produce these output stream buffers, and a
* new sensor image will not be captured.</p>
@@ -1352,7 +1351,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>A list of all keys that the camera device has available
- * to use with CaptureRequest.</p>
+ * to use with {@link android.hardware.camera2.CaptureRequest }.</p>
* <p>Attempting to set a key into a CaptureRequest that is not
* listed here will result in an invalid request and will be rejected
* by the camera device.</p>
@@ -1370,7 +1369,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>A list of all keys that the camera device has available
- * to use with CaptureResult.</p>
+ * to use with {@link android.hardware.camera2.CaptureResult }.</p>
* <p>Attempting to get a key from a CaptureResult that is not
* listed here will always return a <code>null</code> value. Getting a key from
* a CaptureResult that is listed here will generally never return a <code>null</code>
@@ -1396,7 +1395,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>A list of all keys that the camera device has available
- * to use with CameraCharacteristics.</p>
+ * to use with {@link android.hardware.camera2.CameraCharacteristics }.</p>
* <p>This entry follows the same rules as
* android.request.availableResultKeys (except that it applies for
* CameraCharacteristics instead of CaptureResult). See above for more
@@ -1535,34 +1534,31 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* </thead>
* <tbody>
* <tr>
- * <td align="left">PRIVATE (ImageFormat#PRIVATE)</td>
- * <td align="left">JPEG</td>
+ * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="left">OPAQUE_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">PRIVATE</td>
- * <td align="left">YUV_420_888</td>
+ * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="left">OPAQUE_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">YUV_420_888</td>
- * <td align="left">JPEG</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="left">YUV_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">YUV_420_888</td>
- * <td align="left">YUV_420_888</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="left">YUV_REPROCESSING</td>
* </tr>
* </tbody>
* </table>
- * <p>PRIVATE refers to a device-internal format that is not directly application-visible.
- * A PRIVATE input surface can be acquired by
- * ImageReader.newOpaqueInstance(width, height, maxImages).
- * For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format
- * as either input or output will never hurt maximum frame rate (i.e.
- * StreamConfigurationMap#getOutputStallDuration(format, size) is always 0),
- * where format is ImageFormat#PRIVATE.</p>
+ * <p>PRIVATE refers to a device-internal format that is not directly application-visible. A
+ * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newOpaqueInstance }.</p>
+ * <p>For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format as either input
+ * or output will never hurt maximum frame rate (i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration getOutputStallDuration(ImageFormat.PRIVATE, size)} is always 0),</p>
* <p>Attempting to configure an input stream with output streams not
* listed as available in this map is not valid.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
@@ -1680,7 +1676,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* android.scaler.availableStallDurations for more details about
* calculating the max frame rate.</p>
* <p>(Keep in sync with
- * StreamConfigurationMap#getOutputMinFrameDuration)</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration })</p>
* <p><b>Units</b>: (format, width, height, ns) x n</p>
* <p>This key is available on all devices.</p>
*
@@ -1692,7 +1688,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>This lists the maximum stall duration for each
- * format/size combination.</p>
+ * output format/size combination.</p>
* <p>A stall duration is how much extra time would get added
* to the normal minimum frame duration for a repeating request
* that has streams with non-zero stall.</p>
@@ -1734,12 +1730,13 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* ignored).</p>
* <p>The following formats may always have a stall duration:</p>
* <ul>
- * <li>ImageFormat#JPEG</li>
- * <li>ImageFormat#RAW_SENSOR</li>
+ * <li>{@link android.graphics.ImageFormat#JPEG }</li>
+ * <li>{@link android.graphics.ImageFormat#RAW_SENSOR }</li>
* </ul>
* <p>The following formats will never have a stall duration:</p>
* <ul>
- * <li>ImageFormat#YUV_420_888</li>
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 }</li>
+ * <li>{@link android.graphics.ImageFormat#RAW10 }</li>
* </ul>
* <p>All other formats may or may not have an allowed stall duration on
* a per-capability basis; refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
@@ -1747,7 +1744,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} for more information about
* calculating the max frame rate (absent stalls).</p>
* <p>(Keep up to date with
- * StreamConfigurationMap#getOutputStallDuration(int, Size) )</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } )</p>
* <p><b>Units</b>: (format, width, height, ns) x n</p>
* <p>This key is available on all devices.</p>
*
@@ -1786,57 +1783,57 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* </thead>
* <tbody>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</td>
* <td align="center">Any</td>
* <td align="center"></td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">1920x1080 (1080p)</td>
* <td align="center">Any</td>
* <td align="center">if 1080p &lt;= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">1280x720 (720)</td>
* <td align="center">Any</td>
* <td align="center">if 720p &lt;= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">640x480 (480p)</td>
* <td align="center">Any</td>
* <td align="center">if 480p &lt;= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">320x240 (240p)</td>
* <td align="center">Any</td>
* <td align="center">if 240p &lt;= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">YUV_420_888</td>
+ * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="center">all output sizes available for JPEG</td>
* <td align="center">FULL</td>
* <td align="center"></td>
* </tr>
* <tr>
- * <td align="center">YUV_420_888</td>
+ * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="center">all output sizes available for JPEG, up to the maximum video size</td>
* <td align="center">LIMITED</td>
* <td align="center"></td>
* </tr>
* <tr>
- * <td align="center">IMPLEMENTATION_DEFINED</td>
+ * <td align="center">{@link android.graphics.ImageFormat#PRIVATE }</td>
* <td align="center">same as YUV_420_888</td>
* <td align="center">Any</td>
* <td align="center"></td>
* </tr>
* </tbody>
* </table>
- * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} for additional
- * mandatory stream configurations on a per-capability basis.</p>
+ * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} and {@link android.hardware.camera2.CameraDevice#createCaptureSession } for additional mandatory
+ * stream configurations on a per-capability basis.</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
@@ -1973,8 +1970,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>Attempting to use frame durations beyond the maximum will result in the frame
* duration being clipped to the maximum. See that control for a full definition of frame
* durations.</p>
- * <p>Refer to StreamConfigurationMap#getOutputMinFrameDuration(int,Size) for the minimum
- * frame duration values.</p>
+ * <p>Refer to {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+ * for the minimum frame duration values.</p>
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* For FULL capability devices
@@ -2634,6 +2631,41 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<Integer>("android.sync.maxLatency", int.class);
/**
+ * <p>The maximal camera capture pipeline stall (in unit of frame count) introduced by a
+ * reprocess capture request.</p>
+ * <p>The key describes the maximal interference that one reprocess (input) request
+ * can introduce to the camera simultaneous streaming of regular (output) capture
+ * requests, including repeating requests.</p>
+ * <p>When a reprocessing capture request is submitted while a camera output repeating request
+ * (e.g. preview) is being served by the camera device, it may preempt the camera capture
+ * pipeline for at least one frame duration so that the camera device is unable to process
+ * the following capture request in time for the next sensor start of exposure boundary.
+ * When this happens, the application may observe a capture time gap (longer than one frame
+ * duration) between adjacent capture output frames, which usually exhibits as preview
+ * glitch if the repeating request output targets include a preview surface. This key gives
+ * the worst-case number of frame stall introduced by one reprocess request with any kind of
+ * formats/sizes combination.</p>
+ * <p>If this key reports 0, it means a reprocess request doesn't introduce any glitch to the
+ * ongoing camera repeating request outputs, as if this reprocess request is never issued.</p>
+ * <p>This key is supported if the camera device supports OPAQUE or YUV reprocessing (
+ * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains OPAQUE_REPROCESSING or
+ * YUV_REPROCESSING).</p>
+ * <p><b>Units</b>: Number of frames.</p>
+ * <p><b>Range of valid values:</b><br>
+ * &lt;= 4</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ */
+ @PublicKey
+ public static final Key<Integer> REPROCESS_MAX_CAPTURE_STALL =
+ new Key<Integer>("android.reprocess.maxCaptureStall", int.class);
+
+ /**
* <p>The available depth dataspace stream
* configurations that this camera device supports
* (i.e. format, width, height, output/input stream).</p>
@@ -2672,8 +2704,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
* android.scaler.availableStallDurations for more details about
* calculating the max frame rate.</p>
- * <p>(Keep in sync with
- * StreamConfigurationMap#getOutputMinFrameDuration)</p>
+ * <p>(Keep in sync with {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration })</p>
* <p><b>Units</b>: (format, width, height, ns) x n</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Limited capability</b> -
@@ -2689,7 +2720,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>This lists the maximum stall duration for each
- * format/size combination for depth streams.</p>
+ * output format/size combination for depth streams.</p>
* <p>A stall duration is how much extra time would get added
* to the normal minimum frame duration for a repeating request
* that has streams with non-zero stall.</p>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 51b326b..f6791a4 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -54,6 +54,7 @@ public abstract class CameraDevice implements AutoCloseable {
* means that high frame rate is given priority over the highest-quality
* post-processing. These requests would normally be used with the
* {@link CameraCaptureSession#setRepeatingRequest} method.
+ * This template is guaranteed to be supported on all camera devices.
*
* @see #createCaptureRequest
*/
@@ -63,6 +64,7 @@ public abstract class CameraDevice implements AutoCloseable {
* Create a request suitable for still image capture. Specifically, this
* means prioritizing image quality over frame rate. These requests would
* commonly be used with the {@link CameraCaptureSession#capture} method.
+ * This template is guaranteed to be supported on all camera devices.
*
* @see #createCaptureRequest
*/
@@ -73,6 +75,7 @@ public abstract class CameraDevice implements AutoCloseable {
* that a stable frame rate is used, and post-processing is set for
* recording quality. These requests would commonly be used with the
* {@link CameraCaptureSession#setRepeatingRequest} method.
+ * This template is guaranteed to be supported on all camera devices.
*
* @see #createCaptureRequest
*/
@@ -84,6 +87,9 @@ public abstract class CameraDevice implements AutoCloseable {
* disrupting the ongoing recording. These requests would commonly be used
* with the {@link CameraCaptureSession#capture} method while a request based on
* {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
+ * This template is guaranteed to be supported on all camera devices except
+ * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
*
* @see #createCaptureRequest
*/
@@ -93,6 +99,11 @@ public abstract class CameraDevice implements AutoCloseable {
* Create a request suitable for zero shutter lag still capture. This means
* means maximizing image quality without compromising preview frame rate.
* AE/AWB/AF should be on auto mode.
+ * This template is guaranteed to be supported on camera devices that support the
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}
+ * capability or the
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}
+ * capability.
*
* @see #createCaptureRequest
*/
@@ -105,6 +116,9 @@ public abstract class CameraDevice implements AutoCloseable {
* quality. The manual capture parameters (exposure, sensitivity, and so on)
* are set to reasonable defaults, but should be overriden by the
* application depending on the intended use case.
+ * This template is guaranteed to be supported on camera devices that support the
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}
+ * capability.
*
* @see #createCaptureRequest
*/
@@ -473,12 +487,14 @@ public abstract class CameraDevice implements AutoCloseable {
* settings as desired, instead.</p>
*
* @param templateType An enumeration selecting the use case for this
- * request; one of the CameraDevice.TEMPLATE_ values.
+ * request; one of the CameraDevice.TEMPLATE_ values. Not all template
+ * types are supported on every device. See the documentation for each
+ * template type for details.
* @return a builder for a capture request, initialized with default
* settings for that template, and no output streams
*
- * @throws IllegalArgumentException if the templateType is not in the list
- * of supported templates.
+ * @throws IllegalArgumentException if the templateType is not supported by
+ * this device.
* @throws CameraAccessException if the camera device is no longer connected or has
* encountered a fatal error
* @throws IllegalStateException if the camera device has been closed
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e3f1d73..ca9439b 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -461,22 +461,21 @@ public abstract class CameraMetadata<TKey> {
* <p>The camera device supports the Zero Shutter Lag reprocessing use case.</p>
* <ul>
* <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
- * <li>ImageFormat#PRIVATE is supported as an output/input format, that is,
- * ImageFormat#PRIVATE is included in the lists of formats returned by
- * StreamConfigurationMap#getInputFormats and
- * StreamConfigurationMap#getOutputFormats.</li>
- * <li>StreamConfigurationMap#getValidOutputFormatsForInput returns non empty int[] for
- * each supported input format returned by StreamConfigurationMap#getInputFormats.</li>
- * <li>Each size returned by StreamConfigurationMap#getInputSizes(ImageFormat#PRIVATE)
- * is also included in StreamConfigurationMap#getOutputSizes(ImageFormat#PRIVATE)</li>
- * <li>Using ImageFormat#PRIVATE does not cause a frame rate drop
- * relative to the sensor's maximum capture rate (at that
- * resolution).</li>
- * <li>ImageFormat#PRIVATE will be reprocessable into both YUV_420_888
- * and JPEG formats.</li>
+ * <li>{@link android.graphics.ImageFormat#PRIVATE } is supported as an output/input format,
+ * that is, {@link android.graphics.ImageFormat#PRIVATE } is included in the lists of
+ * formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+ * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+ * returns non empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+ * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.PRIVATE)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.PRIVATE)}</li>
+ * <li>Using {@link android.graphics.ImageFormat#PRIVATE } does not cause a frame rate drop
+ * relative to the sensor's maximum capture rate (at that resolution).</li>
+ * <li>{@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into both
+ * {@link android.graphics.ImageFormat#YUV_420_888 } and
+ * {@link android.graphics.ImageFormat#JPEG } formats.</li>
* <li>The maximum available resolution for OPAQUE streams
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
+ * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
* <li>Only below controls are effective for reprocessing requests and
* will be present in capture results, other controls in reprocess
* requests will be ignored by the camera device.<ul>
@@ -489,6 +488,7 @@ public abstract class CameraMetadata<TKey> {
*
* @see CaptureRequest#EDGE_MODE
* @see CaptureRequest#NOISE_REDUCTION_MODE
+ * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
@@ -569,25 +569,25 @@ public abstract class CameraMetadata<TKey> {
* following:</p>
* <ul>
* <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
- * <li>YUV_420_888 is supported as an output/input format, that is,
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 } is supported as an output/input format, that is,
* YUV_420_888 is included in the lists of formats returned by
- * StreamConfigurationMap#getInputFormats and
- * StreamConfigurationMap#getOutputFormats.</li>
- * <li>StreamConfigurationMap#getValidOutputFormatsForInput returns non empty int[] for
- * each supported input format returned by StreamConfigurationMap#getInputFormats.</li>
- * <li>Each size returned by StreamConfigurationMap#getInputSizes(YUV_420_888)
- * is also included in StreamConfigurationMap#getOutputSizes(YUV_420_888)</li>
- * <li>Using YUV_420_888 does not cause a frame rate drop
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+ * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+ * returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+ * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(YUV_420_888)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(YUV_420_888)}</li>
+ * <li>Using {@link android.graphics.ImageFormat#YUV_420_888 } does not cause a frame rate drop
* relative to the sensor's maximum capture rate (at that resolution).</li>
- * <li>YUV_420_888 will be reprocessable into both YUV_420_888
- * and JPEG formats.</li>
- * <li>The maximum available resolution for YUV_420_888 streams
- * (both input/output) will match the maximum available
- * resolution of JPEG streams.</li>
- * <li>Only the below controls are effective for reprocessing requests and will be
- * present in capture results. The reprocess requests are from the original capture
- * results that are assocaited with the intermidate YUV_420_888 output buffers.
- * All other controls in the reprocess requests will be ignored by the camera device.<ul>
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 } will be reprocessable into both
+ * {@link android.graphics.ImageFormat#YUV_420_888 } and {@link android.graphics.ImageFormat#JPEG } formats.</li>
+ * <li>The maximum available resolution for {@link android.graphics.ImageFormat#YUV_420_888 } streams (both input/output) will match the
+ * maximum available resolution of {@link android.graphics.ImageFormat#JPEG } streams.</li>
+ * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
+ * <li>Only the below controls are effective for reprocessing requests and will be present
+ * in capture results. The reprocess requests are from the original capture results that
+ * are associated with the intermediate {@link android.graphics.ImageFormat#YUV_420_888 }
+ * output buffers. All other controls in the reprocess requests will be ignored by the
+ * camera device.<ul>
* <li>android.jpeg.*</li>
* <li>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}</li>
* <li>{@link CaptureRequest#EDGE_MODE android.edge.mode}</li>
@@ -599,6 +599,7 @@ public abstract class CameraMetadata<TKey> {
* @see CaptureRequest#EDGE_MODE
* @see CaptureRequest#NOISE_REDUCTION_MODE
* @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
+ * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
@@ -608,11 +609,13 @@ public abstract class CameraMetadata<TKey> {
* <p>The camera device can produce depth measurements from its field of view.</p>
* <p>This capability requires the camera device to support the following:</p>
* <ul>
- * <li>DEPTH16 is supported as an output format.</li>
- * <li>DEPTH_POINT_CLOUD is optionally supported as an output format.</li>
- * <li>This camera device, and all camera devices with the same android.lens.info.facing,
- * will list the following calibration entries in both CameraCharacteristics and
- * CaptureResults:<ul>
+ * <li>{@link android.graphics.ImageFormat#DEPTH16 } is supported as an output format.</li>
+ * <li>{@link android.graphics.ImageFormat#DEPTH_POINT_CLOUD } is optionally supported as an
+ * output format.</li>
+ * <li>This camera device, and all camera devices with the same {@link CameraCharacteristics#LENS_FACING android.lens.facing},
+ * will list the following calibration entries in both
+ * {@link android.hardware.camera2.CameraCharacteristics } and
+ * {@link android.hardware.camera2.CaptureResult }:<ul>
* <li>{@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}</li>
* <li>{@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}</li>
* <li>android.lens.intrinsicCalibration</li>
@@ -627,13 +630,14 @@ public abstract class CameraMetadata<TKey> {
* <p>Generally, depth output operates at a slower frame rate than standard color capture,
* so the DEPTH16 and DEPTH_POINT_CLOUD formats will commonly have a stall duration that
* should be accounted for (see
- * android.hardware.camera2.StreamConfigurationMap#getOutputStallDuration). On a device
- * that supports both depth and color-based output, to enable smooth preview, using a
- * repeating burst is recommended, where a depth-output target is only included once
- * every N frames, where N is the ratio between preview output rate and depth output
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }).
+ * On a device that supports both depth and color-based output, to enable smooth preview,
+ * using a repeating burst is recommended, where a depth-output target is only included
+ * once every N frames, where N is the ratio between preview output rate and depth output
* rate, including depth stall time.</p>
*
* @see CameraCharacteristics#DEPTH_DEPTH_IS_EXCLUSIVE
+ * @see CameraCharacteristics#LENS_FACING
* @see CameraCharacteristics#LENS_POSE_ROTATION
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
@@ -707,7 +711,7 @@ public abstract class CameraMetadata<TKey> {
/**
* <p>Timestamps from {@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp} are in the same timebase as
- * android.os.SystemClock#elapsedRealtimeNanos(),
+ * {@link android.os.SystemClock#elapsedRealtimeNanos },
* and they can be compared to other timestamps using that base.</p>
*
* @see CaptureResult#SENSOR_TIMESTAMP
@@ -866,7 +870,7 @@ public abstract class CameraMetadata<TKey> {
/**
* <p>Every frame has the requests immediately applied.</p>
* <p>Furthermore for all results,
- * <code>android.sync.frameNumber == CaptureResult#getFrameNumber()</code></p>
+ * <code>android.sync.frameNumber == {@link android.hardware.camera2.CaptureResult#getFrameNumber }</code></p>
* <p>Changing controls over multiple requests one after another will
* produce results that have those controls applied atomically
* each frame.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 19d17b1..ab6ce91 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1275,8 +1275,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains MANUAL_SENSOR. Other intent values are always supported.</p>
+ * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
+ * always supported.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2039,8 +2040,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* cannot process more than 1 capture at a time.</li>
* </ul>
* <p>The necessary information for the application, given the model above,
- * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field
- * using StreamConfigurationMap#getOutputMinFrameDuration(int, Size).
+ * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field using
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.
* These are used to determine the maximum frame rate / minimum frame
* duration that is possible for a given stream configuration.</p>
* <p>Specifically, the application can use the following rules to
@@ -2049,21 +2050,19 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <ol>
* <li>Let the set of currently configured input/output streams
* be called <code>S</code>.</li>
- * <li>Find the minimum frame durations for each stream in <code>S</code>, by
- * looking it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using
- * StreamConfigurationMap#getOutputMinFrameDuration(int, Size) (with
- * its respective size/format). Let this set of frame durations be called
- * <code>F</code>.</li>
+ * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+ * it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+ * (with its respective size/format). Let this set of frame durations be
+ * called <code>F</code>.</li>
* <li>For any given request <code>R</code>, the minimum frame duration allowed
* for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
* used in <code>R</code> be called <code>S_r</code>.</li>
* </ol>
- * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
- * StreamConfigurationMap#getOutputStallDuration(int,Size) using its
- * respective size/format), then the frame duration in
- * <code>F</code> determines the steady state frame rate that the application will
- * get if it uses <code>R</code> as a repeating request. Let this special kind
- * of request be called <code>Rsimple</code>.</p>
+ * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }
+ * using its respective size/format), then the frame duration in <code>F</code>
+ * determines the steady state frame rate that the application will get
+ * if it uses <code>R</code> as a repeating request. Let this special kind of
+ * request be called <code>Rsimple</code>.</p>
* <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
* by a single capture of a new request <code>Rstall</code> (which has at least
* one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
@@ -2071,7 +2070,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* if all buffers from the previous <code>Rstall</code> have already been
* delivered.</p>
* <p>For more details about stalling, see
- * StreamConfigurationMap#getOutputStallDuration(int,Size).</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
* OFF; otherwise the auto-exposure algorithm will override this value.</p>
* <p><b>Units</b>: Nanoseconds</p>
@@ -2647,8 +2646,12 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <p><b>Range of valid values:</b><br>
* &gt;= 1.0</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CaptureRequest#EDGE_MODE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#NOISE_REDUCTION_MODE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ef5d75c..3dc8970 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1698,8 +1698,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains MANUAL_SENSOR. Other intent values are always supported.</p>
+ * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
+ * always supported.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2885,8 +2886,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* cannot process more than 1 capture at a time.</li>
* </ul>
* <p>The necessary information for the application, given the model above,
- * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field
- * using StreamConfigurationMap#getOutputMinFrameDuration(int, Size).
+ * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field using
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.
* These are used to determine the maximum frame rate / minimum frame
* duration that is possible for a given stream configuration.</p>
* <p>Specifically, the application can use the following rules to
@@ -2895,21 +2896,19 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <ol>
* <li>Let the set of currently configured input/output streams
* be called <code>S</code>.</li>
- * <li>Find the minimum frame durations for each stream in <code>S</code>, by
- * looking it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using
- * StreamConfigurationMap#getOutputMinFrameDuration(int, Size) (with
- * its respective size/format). Let this set of frame durations be called
- * <code>F</code>.</li>
+ * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+ * it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+ * (with its respective size/format). Let this set of frame durations be
+ * called <code>F</code>.</li>
* <li>For any given request <code>R</code>, the minimum frame duration allowed
* for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
* used in <code>R</code> be called <code>S_r</code>.</li>
* </ol>
- * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
- * StreamConfigurationMap#getOutputStallDuration(int,Size) using its
- * respective size/format), then the frame duration in
- * <code>F</code> determines the steady state frame rate that the application will
- * get if it uses <code>R</code> as a repeating request. Let this special kind
- * of request be called <code>Rsimple</code>.</p>
+ * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }
+ * using its respective size/format), then the frame duration in <code>F</code>
+ * determines the steady state frame rate that the application will get
+ * if it uses <code>R</code> as a repeating request. Let this special kind of
+ * request be called <code>Rsimple</code>.</p>
* <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
* by a single capture of a new request <code>Rstall</code> (which has at least
* one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
@@ -2917,7 +2916,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* if all buffers from the previous <code>Rstall</code> have already been
* delivered.</p>
* <p>For more details about stalling, see
- * StreamConfigurationMap#getOutputStallDuration(int,Size).</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
* OFF; otherwise the auto-exposure algorithm will override this value.</p>
* <p><b>Units</b>: Nanoseconds</p>
@@ -2979,11 +2978,10 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* and are monotonically increasing. They can be compared with the
* timestamps for other captures from the same camera device, but are
* not guaranteed to be comparable to any other time source.</p>
- * <p>When {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} <code>==</code> REALTIME,
- * the timestamps measure time in the same timebase as
- * android.os.SystemClock#elapsedRealtimeNanos(), and they can be
- * compared to other timestamps from other subsystems that are using
- * that base.</p>
+ * <p>When {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} <code>==</code> REALTIME, the
+ * timestamps measure time in the same timebase as {@link android.os.SystemClock#elapsedRealtimeNanos }, and they can
+ * be compared to other timestamps from other subsystems that
+ * are using that base.</p>
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* &gt; 0</p>
@@ -3141,7 +3139,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* &gt;= 0 and &lt;
- * StreamConfigurationMap#getOutputMinFrameDuration(int, Size).</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Limited capability</b> -
* Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -3966,8 +3964,12 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p><b>Range of valid values:</b><br>
* &gt;= 1.0</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CaptureRequest#EDGE_MODE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#NOISE_REDUCTION_MODE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index adab9be..02793f1 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -182,6 +182,10 @@ public abstract class DisplayManagerInternal {
// The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter).
public float screenAutoBrightnessAdjustment;
+ // Set to true if screenBrightness and screenAutoBrightnessAdjustment were both
+ // set by the user as opposed to being programmatically controlled by apps.
+ public boolean brightnessSetByUser;
+
// If true, enables automatic brightness control.
public boolean useAutoBrightness;
@@ -229,6 +233,7 @@ public abstract class DisplayManagerInternal {
useProximitySensor = other.useProximitySensor;
screenBrightness = other.screenBrightness;
screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
+ brightnessSetByUser = other.brightnessSetByUser;
useAutoBrightness = other.useAutoBrightness;
blockScreenOn = other.blockScreenOn;
lowPowerMode = other.lowPowerMode;
@@ -249,6 +254,7 @@ public abstract class DisplayManagerInternal {
&& useProximitySensor == other.useProximitySensor
&& screenBrightness == other.screenBrightness
&& screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
+ && brightnessSetByUser == other.brightnessSetByUser
&& useAutoBrightness == other.useAutoBrightness
&& blockScreenOn == other.blockScreenOn
&& lowPowerMode == other.lowPowerMode
@@ -268,6 +274,7 @@ public abstract class DisplayManagerInternal {
+ ", useProximitySensor=" + useProximitySensor
+ ", screenBrightness=" + screenBrightness
+ ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+ + ", brightnessSetByUser=" + brightnessSetByUser
+ ", useAutoBrightness=" + useAutoBrightness
+ ", blockScreenOn=" + blockScreenOn
+ ", lowPowerMode=" + lowPowerMode
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 1a42319..410d550 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -45,6 +45,7 @@ public class UsbDevice implements Parcelable {
private final String mName;
private final String mManufacturerName;
private final String mProductName;
+ private final String mVersion;
private final String mSerialNumber;
private final int mVendorId;
private final int mProductId;
@@ -62,7 +63,7 @@ public class UsbDevice implements Parcelable {
*/
public UsbDevice(String name, int vendorId, int productId,
int Class, int subClass, int protocol,
- String manufacturerName, String productName, String serialNumber) {
+ String manufacturerName, String productName, String version, String serialNumber) {
mName = name;
mVendorId = vendorId;
mProductId = productId;
@@ -71,6 +72,7 @@ public class UsbDevice implements Parcelable {
mProtocol = protocol;
mManufacturerName = manufacturerName;
mProductName = productName;
+ mVersion = version;
mSerialNumber = serialNumber;
}
@@ -104,6 +106,15 @@ public class UsbDevice implements Parcelable {
}
/**
+ * Returns the version number of the device.
+ *
+ * @return the device version
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ /**
* Returns the serial number of the device.
*
* @return the serial number name
@@ -263,7 +274,7 @@ public class UsbDevice implements Parcelable {
",mVendorId=" + mVendorId + ",mProductId=" + mProductId +
",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName +
- ",mSerialNumber=" + mSerialNumber + ",mConfigurations=[");
+ ",mVersion=" + mVersion + ",mSerialNumber=" + mSerialNumber + ",mConfigurations=[");
for (int i = 0; i < mConfigurations.length; i++) {
builder.append("\n");
builder.append(mConfigurations[i].toString());
@@ -283,10 +294,11 @@ public class UsbDevice implements Parcelable {
int protocol = in.readInt();
String manufacturerName = in.readString();
String productName = in.readString();
+ String version = in.readString();
String serialNumber = in.readString();
Parcelable[] configurations = in.readParcelableArray(UsbInterface.class.getClassLoader());
UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
- manufacturerName, productName, serialNumber);
+ manufacturerName, productName, version, serialNumber);
device.setConfigurations(configurations);
return device;
}
@@ -309,6 +321,7 @@ public class UsbDevice implements Parcelable {
parcel.writeInt(mProtocol);
parcel.writeString(mManufacturerName);
parcel.writeString(mProductName);
+ parcel.writeString(mVersion);
parcel.writeString(mSerialNumber);
parcel.writeParcelableArray(mConfigurations, 0);
}
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index c722fbc..7f5f377 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -38,8 +38,6 @@ interface INetworkPolicyManager {
boolean isUidForeground(int uid);
- int[] getPowerSaveAppIdWhitelist();
-
void registerListener(INetworkPolicyListener listener);
void unregisterListener(INetworkPolicyListener listener);
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index bc03637..ecc3fb4 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -41,6 +41,7 @@ import java.util.HashSet;
*/
public class NetworkPolicyManager {
+ /* POLICY_* are masks and can be ORed */
/** No specific network policy, use system default. */
public static final int POLICY_NONE = 0x0;
/** Reject network usage on metered networks when application in background. */
@@ -48,10 +49,17 @@ public class NetworkPolicyManager {
/** Allow network use (metered or not) in the background in battery save mode. */
public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
+ /* RULE_* are not masks and they must be exclusive */
/** All network traffic should be allowed. */
public static final int RULE_ALLOW_ALL = 0x0;
/** Reject traffic on metered networks. */
public static final int RULE_REJECT_METERED = 0x1;
+ /** Reject traffic on all networks. */
+ public static final int RULE_REJECT_ALL = 0x2;
+
+ public static final int FIREWALL_RULE_DEFAULT = 0;
+ public static final int FIREWALL_RULE_ALLOW = 1;
+ public static final int FIREWALL_RULE_DENY = 2;
private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
@@ -80,7 +88,7 @@ public class NetworkPolicyManager {
* Set policy flags for specific UID.
*
* @param policy {@link #POLICY_NONE} or combination of flags like
- * {@link #POLICY_REJECT_METERED_BACKGROUND}, {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
+ * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
*/
public void setUidPolicy(int uid, int policy) {
try {
@@ -129,14 +137,6 @@ public class NetworkPolicyManager {
}
}
- public int[] getPowerSaveAppIdWhitelist() {
- try {
- return mService.getPowerSaveAppIdWhitelist();
- } catch (RemoteException e) {
- return new int[0];
- }
- }
-
public void registerListener(INetworkPolicyListener listener) {
try {
mService.registerListener(listener);
@@ -330,6 +330,8 @@ public class NetworkPolicyManager {
fout.write("[");
if ((rules & RULE_REJECT_METERED) != 0) {
fout.write("REJECT_METERED");
+ } else if ((rules & RULE_REJECT_ALL) != 0) {
+ fout.write("REJECT_ALL");
}
fout.write("]");
}
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
new file mode 100644
index 0000000..3cb29ff
--- /dev/null
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -0,0 +1,26 @@
+/**
+ * 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.os;
+
+/** @hide */
+interface IDeviceIdleController {
+ void addPowerSaveWhitelistApp(String name);
+ void removePowerSaveWhitelistApp(String name);
+ String[] getSystemPowerWhitelist();
+ String[] getFullPowerWhitelist();
+ int[] getAppIdWhitelist();
+}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index f93550a..b29e8d0 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -342,7 +342,7 @@ 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, boolean allow);
+ void setFirewallUidRule(int uid, int rule);
/**
* Set all packets from users in ranges to go through VPN specified by netId.
diff --git a/core/java/android/os/IPermissionController.aidl b/core/java/android/os/IPermissionController.aidl
index 73a68f1..0cc1603 100644
--- a/core/java/android/os/IPermissionController.aidl
+++ b/core/java/android/os/IPermissionController.aidl
@@ -20,4 +20,5 @@ package android.os;
/** @hide */
interface IPermissionController {
boolean checkPermission(String permission, int pid, int uid);
+ String[] getPackagesForUid(int uid);
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 01c9a21..1d9d7d2 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -920,6 +920,14 @@ public final class PowerManager {
= "android.os.action.DEVICE_IDLE_MODE_CHANGED";
/**
+ * @hide Intent that is broadcast when the set of power save whitelist apps has changed.
+ * This broadcast is only sent to registered receivers.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_POWER_SAVE_WHITELIST_CHANGED
+ = "android.os.action.POWER_SAVE_WHITELIST_CHANGED";
+
+ /**
* Intent that is broadcast when the state of {@link #isPowerSaveMode()} is about to change.
* This broadcast is only sent to registered receivers.
*
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 16e0bf7..fcde3f4 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -942,6 +942,24 @@ public interface IMountService extends IInterface {
}
@Override
+ public VolumeRecord[] getVolumeRecords(int _flags) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ VolumeRecord[] _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(_flags);
+ mRemote.transact(Stub.TRANSACTION_getVolumeRecords, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.createTypedArray(VolumeRecord.CREATOR);
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ @Override
public void mount(String volId) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -1033,12 +1051,12 @@ public interface IMountService extends IInterface {
}
@Override
- public void setVolumeNickname(String volId, String nickname) throws RemoteException {
+ public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volId);
+ _data.writeString(fsUuid);
_data.writeString(nickname);
mRemote.transact(Stub.TRANSACTION_setVolumeNickname, _data, _reply, 0);
_reply.readException();
@@ -1049,12 +1067,12 @@ public interface IMountService extends IInterface {
}
@Override
- public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException {
+ public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volId);
+ _data.writeString(fsUuid);
_data.writeInt(flags);
_data.writeInt(mask);
mRemote.transact(Stub.TRANSACTION_setVolumeUserFlags, _data, _reply, 0);
@@ -1066,6 +1084,21 @@ public interface IMountService extends IInterface {
}
@Override
+ public void forgetVolume(String fsUuid) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(fsUuid);
+ mRemote.transact(Stub.TRANSACTION_forgetVolume, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
public String getPrimaryStorageUuid() throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -1192,20 +1225,22 @@ public interface IMountService extends IInterface {
static final int TRANSACTION_getDisks = IBinder.FIRST_CALL_TRANSACTION + 44;
static final int TRANSACTION_getVolumes = IBinder.FIRST_CALL_TRANSACTION + 45;
+ static final int TRANSACTION_getVolumeRecords = IBinder.FIRST_CALL_TRANSACTION + 46;
- static final int TRANSACTION_mount = IBinder.FIRST_CALL_TRANSACTION + 46;
- static final int TRANSACTION_unmount = IBinder.FIRST_CALL_TRANSACTION + 47;
- static final int TRANSACTION_format = IBinder.FIRST_CALL_TRANSACTION + 48;
+ static final int TRANSACTION_mount = IBinder.FIRST_CALL_TRANSACTION + 47;
+ static final int TRANSACTION_unmount = IBinder.FIRST_CALL_TRANSACTION + 48;
+ static final int TRANSACTION_format = IBinder.FIRST_CALL_TRANSACTION + 49;
- static final int TRANSACTION_partitionPublic = IBinder.FIRST_CALL_TRANSACTION + 49;
- static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 50;
- static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 51;
+ static final int TRANSACTION_partitionPublic = IBinder.FIRST_CALL_TRANSACTION + 50;
+ static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 51;
+ static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 52;
- static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 52;
- static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 53;
+ static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 53;
+ static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 54;
+ static final int TRANSACTION_forgetVolume = IBinder.FIRST_CALL_TRANSACTION + 55;
- static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 54;
- static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 55;
+ static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 56;
+ static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
/**
* Cast an IBinder object into an IMountService interface, generating a
@@ -1647,6 +1682,14 @@ public interface IMountService extends IInterface {
reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
}
+ case TRANSACTION_getVolumeRecords: {
+ data.enforceInterface(DESCRIPTOR);
+ int _flags = data.readInt();
+ VolumeRecord[] volumes = getVolumeRecords(_flags);
+ reply.writeNoException();
+ reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+ return true;
+ }
case TRANSACTION_mount: {
data.enforceInterface(DESCRIPTOR);
String volId = data.readString();
@@ -1707,6 +1750,13 @@ public interface IMountService extends IInterface {
reply.writeNoException();
return true;
}
+ case TRANSACTION_forgetVolume: {
+ data.enforceInterface(DESCRIPTOR);
+ String fsUuid = data.readString();
+ forgetVolume(fsUuid);
+ reply.writeNoException();
+ return true;
+ }
case TRANSACTION_getPrimaryStorageUuid: {
data.enforceInterface(DESCRIPTOR);
String volumeUuid = getPrimaryStorageUuid();
@@ -2012,6 +2062,7 @@ public interface IMountService extends IInterface {
public DiskInfo[] getDisks() throws RemoteException;
public VolumeInfo[] getVolumes(int flags) throws RemoteException;
+ public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException;
public void mount(String volId) throws RemoteException;
public void unmount(String volId) throws RemoteException;
@@ -2021,8 +2072,9 @@ public interface IMountService extends IInterface {
public void partitionPrivate(String diskId) throws RemoteException;
public void partitionMixed(String diskId, int ratio) throws RemoteException;
- public void setVolumeNickname(String volId, String nickname) throws RemoteException;
- public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException;
+ public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException;
+ public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException;
+ public void forgetVolume(String fsUuid) throws RemoteException;
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
index fcb4779..2d13e49 100644
--- a/core/java/android/os/storage/IMountServiceListener.java
+++ b/core/java/android/os/storage/IMountServiceListener.java
@@ -93,8 +93,8 @@ public interface IMountServiceListener extends IInterface {
}
case TRANSACTION_onVolumeMetadataChanged: {
data.enforceInterface(DESCRIPTOR);
- final VolumeInfo vol = (VolumeInfo) data.readParcelable(null);
- onVolumeMetadataChanged(vol);
+ final String fsUuid = data.readString();
+ onVolumeMetadataChanged(fsUuid);
reply.writeNoException();
return true;
}
@@ -192,12 +192,12 @@ public interface IMountServiceListener extends IInterface {
}
@Override
- public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException {
+ public void onVolumeMetadataChanged(String fsUuid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
- _data.writeParcelable(vol, 0);
+ _data.writeString(fsUuid);
mRemote.transact(Stub.TRANSACTION_onVolumeMetadataChanged, _data, _reply,
android.os.IBinder.FLAG_ONEWAY);
_reply.readException();
@@ -253,7 +253,7 @@ public interface IMountServiceListener extends IInterface {
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
throws RemoteException;
- public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException;
+ public void onVolumeMetadataChanged(String fsUuid) throws RemoteException;
public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
}
diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java
index 6a0140e..536aca9 100644
--- a/core/java/android/os/storage/StorageEventListener.java
+++ b/core/java/android/os/storage/StorageEventListener.java
@@ -41,7 +41,7 @@ public class StorageEventListener {
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
}
- public void onVolumeMetadataChanged(VolumeInfo vol) {
+ public void onVolumeMetadataChanged(String fsUuid) {
}
public void onDiskScanned(DiskInfo disk, int volumeCount) {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 6116aef..29da4f1 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -34,6 +34,7 @@ import android.os.ServiceManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.os.SomeArgs;
@@ -79,9 +80,6 @@ public class StorageManager {
/** {@hide} */
public static final String UUID_PRIMARY_PHYSICAL = "primary_physical";
- /** {@hide} */
- public static final int FLAG_ALL_METADATA = 1 << 0;
-
private final Context mContext;
private final ContentResolver mResolver;
@@ -120,7 +118,7 @@ public class StorageManager {
args.recycle();
return true;
case MSG_VOLUME_METADATA_CHANGED:
- mCallback.onVolumeMetadataChanged((VolumeInfo) args.arg1);
+ mCallback.onVolumeMetadataChanged((String) args.arg1);
args.recycle();
return true;
case MSG_DISK_SCANNED:
@@ -156,9 +154,9 @@ public class StorageManager {
}
@Override
- public void onVolumeMetadataChanged(VolumeInfo vol) {
+ public void onVolumeMetadataChanged(String fsUuid) {
final SomeArgs args = SomeArgs.obtain();
- args.arg1 = vol;
+ args.arg1 = fsUuid;
mHandler.obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
}
@@ -516,6 +514,18 @@ public class StorageManager {
}
/** {@hide} */
+ public @Nullable VolumeRecord findRecordByUuid(String fsUuid) {
+ Preconditions.checkNotNull(fsUuid);
+ // TODO; go directly to service to make this faster
+ for (VolumeRecord rec : getVolumeRecords()) {
+ if (Objects.equals(rec.fsUuid, fsUuid)) {
+ return rec;
+ }
+ }
+ return null;
+ }
+
+ /** {@hide} */
public @Nullable VolumeInfo findPrivateForEmulated(VolumeInfo emulatedVol) {
return findVolumeById(emulatedVol.getId().replace("emulated", "private"));
}
@@ -527,13 +537,17 @@ public class StorageManager {
/** {@hide} */
public @NonNull List<VolumeInfo> getVolumes() {
- return getVolumes(0);
+ try {
+ return Arrays.asList(mMountService.getVolumes(0));
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
}
/** {@hide} */
- public @NonNull List<VolumeInfo> getVolumes(int flags) {
+ public @NonNull List<VolumeRecord> getVolumeRecords() {
try {
- return Arrays.asList(mMountService.getVolumes(flags));
+ return Arrays.asList(mMountService.getVolumeRecords(0));
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -541,13 +555,23 @@ public class StorageManager {
/** {@hide} */
public @Nullable String getBestVolumeDescription(VolumeInfo vol) {
- String descrip = vol.getDescription();
- if (vol.disk != null) {
- if (TextUtils.isEmpty(descrip)) {
- descrip = vol.disk.getDescription();
+ // Nickname always takes precedence when defined
+ if (!TextUtils.isEmpty(vol.fsUuid)) {
+ final VolumeRecord rec = findRecordByUuid(vol.fsUuid);
+ if (!TextUtils.isEmpty(rec.nickname)) {
+ return rec.nickname;
}
}
- return descrip;
+
+ if (!TextUtils.isEmpty(vol.getDescription())) {
+ return vol.getDescription();
+ }
+
+ if (vol.disk != null) {
+ return vol.disk.getDescription();
+ }
+
+ return null;
}
/** {@hide} */
@@ -616,29 +640,62 @@ public class StorageManager {
}
/** {@hide} */
- public void setVolumeNickname(String volId, String nickname) {
+ public void wipeAdoptableDisks() {
+ // We only wipe devices in "adoptable" locations, which are in a
+ // long-term stable slot/location on the device, where apps have a
+ // reasonable chance of storing sensitive data. (Apps need to go through
+ // SAF to write to transient volumes.)
+ final List<DiskInfo> disks = getDisks();
+ for (DiskInfo disk : disks) {
+ final String diskId = disk.getId();
+ if (disk.isAdoptable()) {
+ Slog.d(TAG, "Found adoptable " + diskId + "; wiping");
+ try {
+ // TODO: switch to explicit wipe command when we have it,
+ // for now rely on the fact that vfat format does a wipe
+ mMountService.partitionPublic(diskId);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failed to wipe " + diskId + ", but soldiering onward", e);
+ }
+ } else {
+ Slog.d(TAG, "Ignorning non-adoptable disk " + disk.getId());
+ }
+ }
+ }
+
+ /** {@hide} */
+ public void setVolumeNickname(String fsUuid, String nickname) {
+ try {
+ mMountService.setVolumeNickname(fsUuid, nickname);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
+ public void setVolumeInited(String fsUuid, boolean inited) {
try {
- mMountService.setVolumeNickname(volId, nickname);
+ mMountService.setVolumeUserFlags(fsUuid, inited ? VolumeRecord.USER_FLAG_INITED : 0,
+ VolumeRecord.USER_FLAG_INITED);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
/** {@hide} */
- public void setVolumeInited(String volId, boolean inited) {
+ public void setVolumeSnoozed(String fsUuid, boolean snoozed) {
try {
- mMountService.setVolumeUserFlags(volId, inited ? VolumeInfo.USER_FLAG_INITED : 0,
- VolumeInfo.USER_FLAG_INITED);
+ mMountService.setVolumeUserFlags(fsUuid, snoozed ? VolumeRecord.USER_FLAG_SNOOZED : 0,
+ VolumeRecord.USER_FLAG_SNOOZED);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
/** {@hide} */
- public void setVolumeSnoozed(String volId, boolean snoozed) {
+ public void forgetVolume(String fsUuid) {
try {
- mMountService.setVolumeUserFlags(volId, snoozed ? VolumeInfo.USER_FLAG_SNOOZED : 0,
- VolumeInfo.USER_FLAG_SNOOZED);
+ mMountService.forgetVolume(fsUuid);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 4e9cfc7..fd10cae 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -78,9 +78,6 @@ public class VolumeInfo implements Parcelable {
public static final int MOUNT_FLAG_PRIMARY = 1 << 0;
public static final int MOUNT_FLAG_VISIBLE = 1 << 1;
- public static final int USER_FLAG_INITED = 1 << 0;
- public static final int USER_FLAG_SNOOZED = 1 << 1;
-
private static SparseArray<String> sStateToEnvironment = new SparseArray<>();
private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>();
@@ -135,8 +132,6 @@ public class VolumeInfo implements Parcelable {
/** Framework state */
public final int mtpIndex;
- public String nickname;
- public int userFlags = 0;
public VolumeInfo(String id, int type, DiskInfo disk, int mtpIndex) {
this.id = Preconditions.checkNotNull(id);
@@ -161,8 +156,6 @@ public class VolumeInfo implements Parcelable {
fsLabel = parcel.readString();
path = parcel.readString();
mtpIndex = parcel.readInt();
- nickname = parcel.readString();
- userFlags = parcel.readInt();
}
public static @NonNull String getEnvironmentForState(int state) {
@@ -210,10 +203,6 @@ public class VolumeInfo implements Parcelable {
return fsUuid;
}
- public @Nullable String getNickname() {
- return nickname;
- }
-
public int getMountUserId() {
return mountUserId;
}
@@ -221,8 +210,6 @@ public class VolumeInfo implements Parcelable {
public @Nullable String getDescription() {
if (ID_PRIVATE_INTERNAL.equals(id)) {
return Resources.getSystem().getString(com.android.internal.R.string.storage_internal);
- } else if (!TextUtils.isEmpty(nickname)) {
- return nickname;
} else if (!TextUtils.isEmpty(fsLabel)) {
return fsLabel;
} else {
@@ -250,14 +237,6 @@ public class VolumeInfo implements Parcelable {
return (mountFlags & MOUNT_FLAG_VISIBLE) != 0;
}
- public boolean isInited() {
- return (userFlags & USER_FLAG_INITED) != 0;
- }
-
- public boolean isSnoozed() {
- return (userFlags & USER_FLAG_SNOOZED) != 0;
- }
-
public boolean isVisibleToUser(int userId) {
if (type == TYPE_PUBLIC && userId == this.mountUserId) {
return isVisible();
@@ -394,8 +373,6 @@ public class VolumeInfo implements Parcelable {
pw.println();
pw.printPair("path", path);
pw.printPair("mtpIndex", mtpIndex);
- pw.printPair("nickname", nickname);
- pw.printPair("userFlags", DebugUtils.flagsToString(getClass(), "USER_FLAG_", userFlags));
pw.decreaseIndent();
pw.println();
}
@@ -461,7 +438,5 @@ public class VolumeInfo implements Parcelable {
parcel.writeString(fsLabel);
parcel.writeString(path);
parcel.writeInt(mtpIndex);
- parcel.writeString(nickname);
- parcel.writeInt(userFlags);
}
}
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
new file mode 100644
index 0000000..096e2dd
--- /dev/null
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -0,0 +1,139 @@
+/*
+ * 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.os.storage;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.DebugUtils;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Metadata for a storage volume which may not be currently present.
+ *
+ * @hide
+ */
+public class VolumeRecord implements Parcelable {
+ public static final String EXTRA_FS_UUID =
+ "android.os.storage.extra.FS_UUID";
+
+ public static final int USER_FLAG_INITED = 1 << 0;
+ public static final int USER_FLAG_SNOOZED = 1 << 1;
+
+ public final int type;
+ public final String fsUuid;
+ public String nickname;
+ public int userFlags;
+
+ public VolumeRecord(int type, String fsUuid) {
+ this.type = type;
+ this.fsUuid = Preconditions.checkNotNull(fsUuid);
+ }
+
+ public VolumeRecord(Parcel parcel) {
+ type = parcel.readInt();
+ fsUuid = parcel.readString();
+ nickname = parcel.readString();
+ userFlags = parcel.readInt();
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getFsUuid() {
+ return fsUuid;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public boolean isInited() {
+ return (userFlags & USER_FLAG_INITED) != 0;
+ }
+
+ public boolean isSnoozed() {
+ return (userFlags & USER_FLAG_SNOOZED) != 0;
+ }
+
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("VolumeRecord:");
+ pw.increaseIndent();
+ pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type));
+ pw.printPair("fsUuid", fsUuid);
+ pw.printPair("nickname", nickname);
+ pw.printPair("userFlags",
+ DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
+ pw.decreaseIndent();
+ pw.println();
+ }
+
+ @Override
+ public VolumeRecord clone() {
+ final Parcel temp = Parcel.obtain();
+ try {
+ writeToParcel(temp, 0);
+ temp.setDataPosition(0);
+ return CREATOR.createFromParcel(temp);
+ } finally {
+ temp.recycle();
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof VolumeRecord) {
+ return Objects.equals(fsUuid, ((VolumeRecord) o).fsUuid);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return fsUuid.hashCode();
+ }
+
+ public static final Creator<VolumeRecord> CREATOR = new Creator<VolumeRecord>() {
+ @Override
+ public VolumeRecord createFromParcel(Parcel in) {
+ return new VolumeRecord(in);
+ }
+
+ @Override
+ public VolumeRecord[] newArray(int size) {
+ return new VolumeRecord[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(type);
+ parcel.writeString(fsUuid);
+ parcel.writeString(nickname);
+ parcel.writeInt(userFlags);
+ }
+}
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index b3a3aad..458f153 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -105,11 +105,11 @@ public class KeyCharacteristics implements Parcelable {
}
}
- public boolean getBoolean(KeyCharacteristics keyCharacteristics, int tag) {
- if (keyCharacteristics.hwEnforced.containsTag(tag)) {
- return keyCharacteristics.hwEnforced.getBoolean(tag, false);
+ public boolean getBoolean(int tag) {
+ if (hwEnforced.containsTag(tag)) {
+ return hwEnforced.getBoolean(tag, false);
} else {
- return keyCharacteristics.swEnforced.getBoolean(tag, false);
+ return swEnforced.getBoolean(tag, false);
}
}
}
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 14e947c..dc8f3ea 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -62,7 +62,7 @@ public class ZenModeConfig implements Parcelable {
Calendar.WEDNESDAY, Calendar.THURSDAY };
public static final int[] WEEKEND_DAYS = { Calendar.FRIDAY, Calendar.SATURDAY };
- public static final int[] MINUTE_BUCKETS = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
+ public static final int[] MINUTE_BUCKETS = generateMinuteBuckets();
private static final int SECONDS_MS = 1000;
private static final int MINUTES_MS = 60 * SECONDS_MS;
private static final int ZERO_VALUE_MS = 10 * SECONDS_MS;
@@ -201,6 +201,18 @@ public class ZenModeConfig implements Parcelable {
}
}
+ private static int[] generateMinuteBuckets() {
+ final int maxHrs = 12;
+ final int[] buckets = new int[maxHrs + 3];
+ buckets[0] = 15;
+ buckets[1] = 30;
+ buckets[2] = 45;
+ for (int i = 1; i <= maxHrs; i++) {
+ buckets[2 + i] = 60 * i;
+ }
+ return buckets;
+ }
+
public static String sourceToString(int source) {
switch (source) {
case SOURCE_ANYONE:
@@ -298,10 +310,10 @@ public class ZenModeConfig implements Parcelable {
throw new IndexOutOfBoundsException("bad source in config:" + rt.allowFrom);
}
} else if (MANUAL_TAG.equals(tag)) {
- rt.manualRule = readRuleXml(parser);
+ rt.manualRule = readRuleXml(parser, false /*conditionRequired*/);
} else if (AUTOMATIC_TAG.equals(tag)) {
final String id = parser.getAttributeValue(null, RULE_ATT_ID);
- final ZenRule automaticRule = readRuleXml(parser);
+ final ZenRule automaticRule = readRuleXml(parser, true /*conditionRequired*/);
if (id != null && automaticRule != null) {
rt.automaticRules.put(id, automaticRule);
}
@@ -341,7 +353,7 @@ public class ZenModeConfig implements Parcelable {
out.endTag(null, ZEN_TAG);
}
- public static ZenRule readRuleXml(XmlPullParser parser) {
+ public static ZenRule readRuleXml(XmlPullParser parser, boolean conditionRequired) {
final ZenRule rt = new ZenRule();
rt.enabled = safeBoolean(parser, RULE_ATT_ENABLED, true);
rt.snoozing = safeBoolean(parser, RULE_ATT_SNOOZING, false);
@@ -355,7 +367,7 @@ public class ZenModeConfig implements Parcelable {
rt.conditionId = safeUri(parser, RULE_ATT_CONDITION_ID);
rt.component = safeComponentName(parser, RULE_ATT_COMPONENT);
rt.condition = readConditionXml(parser);
- return rt.condition != null ? rt : null;
+ return rt.condition != null || !conditionRequired ? rt : null;
}
public static void writeRuleXml(ZenRule rule, XmlSerializer out) throws IOException {
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index e991d84..ce94315 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -403,4 +403,12 @@ public class RecognizerIntent {
*/
public static final String EXTRA_SUPPORTED_LANGUAGES =
"android.speech.extra.SUPPORTED_LANGUAGES";
+
+ /**
+ * Optional boolean, to be used with {@link #ACTION_RECOGNIZE_SPEECH},
+ * {@link #ACTION_VOICE_SEARCH_HANDS_FREE}, {@link #ACTION_WEB_SEARCH} to indicate whether to
+ * only use an offline speech recognition engine. The default is false, meaning that either
+ * network or offline recognition engines may be used.
+ */
+ public static final String EXTRA_PREFER_OFFLINE = "android.speech.extra.PREFER_OFFLINE";
}
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index a7d9503..ca37d49 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -214,7 +214,7 @@ public class TransitionInflater {
sConstructors.put(className, constructor);
}
}
-
+ constructor.setAccessible(true);
return constructor.newInstance(mContext, attrs);
}
} catch (InstantiationException e) {
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index aefced8..558b8f5 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -74,6 +74,7 @@ public class EventLog {
private static final byte LONG_TYPE = 1;
private static final byte STRING_TYPE = 2;
private static final byte LIST_TYPE = 3;
+ private static final byte FLOAT_TYPE = 4;
/** @param data containing event, read from the system */
/*package*/ Event(byte[] data) {
@@ -106,7 +107,7 @@ public class EventLog {
return mBuffer.getInt(offset);
}
- /** @return one of Integer, Long, String, null, or Object[] of same. */
+ /** @return one of Integer, Long, Float, String, null, or Object[] of same. */
public synchronized Object getData() {
try {
int offset = mBuffer.getShort(HEADER_SIZE_OFFSET);
@@ -130,10 +131,13 @@ public class EventLog {
byte type = mBuffer.get();
switch (type) {
case INT_TYPE:
- return (Integer) mBuffer.getInt();
+ return mBuffer.getInt();
case LONG_TYPE:
- return (Long) mBuffer.getLong();
+ return mBuffer.getLong();
+
+ case FLOAT_TYPE:
+ return mBuffer.getFloat();
case STRING_TYPE:
try {
@@ -180,6 +184,14 @@ public class EventLog {
/**
* Record an event log message.
* @param tag The event type tag code
+ * @param value A value to log
+ * @return The number of bytes written
+ */
+ public static native int writeEvent(int tag, float value);
+
+ /**
+ * Record an event log message.
+ * @param tag The event type tag code
* @param str A value to log
* @return The number of bytes written
*/
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index eedbc70..46dd857 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -234,25 +234,13 @@ public class DisplayListCanvas extends Canvas {
* Draws the specified display list onto this canvas. The display list can only
* be drawn if {@link android.view.RenderNode#isValid()} returns true.
*
- * @param renderNode The RenderNode to replay.
+ * @param renderNode The RenderNode to draw.
*/
public void drawRenderNode(RenderNode renderNode) {
- drawRenderNode(renderNode, RenderNode.FLAG_CLIP_CHILDREN);
+ nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
}
- /**
- * Draws the specified display list onto this canvas.
- *
- * @param renderNode The RenderNode to replay.
- * @param flags Optional flags about drawing, see {@link RenderNode} for
- * the possible flags.
- */
- public void drawRenderNode(RenderNode renderNode, int flags) {
- nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList(), flags);
- }
-
- private static native void nDrawRenderNode(long renderer, long renderNode,
- int flags);
+ private static native void nDrawRenderNode(long renderer, long renderNode);
///////////////////////////////////////////////////////////////////////////
// Hardware layer
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index 794c8e7..a3e7a10 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -3599,7 +3599,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (!mForcedNavigationBarColor) {
mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
}
- if (a.getBoolean(R.styleable.Window_windowHasLightStatusBar, false)) {
+ if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
decor.setSystemUiVisibility(
decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index ad34f02..6db46e9 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -284,11 +284,6 @@ public class TextureView extends View {
return LAYER_TYPE_HARDWARE;
}
- @Override
- boolean hasStaticLayer() {
- return true;
- }
-
/**
* Calling this method has no effect.
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7da2da4..b5b7f0f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -30,6 +30,7 @@ import android.annotation.Nullable;
import android.annotation.Size;
import android.content.ClipData;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -2591,7 +2592,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS
* FLAG_TRANSLUCENT_STATUS}.
*
- * @see android.R.attr#windowHasLightStatusBar
+ * @see android.R.attr#windowLightStatusBar
*/
public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
@@ -4016,37 +4017,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final String handlerName = a.getString(attr);
if (handlerName != null) {
- setOnClickListener(new OnClickListener() {
- private Method mHandler;
-
- public void onClick(View v) {
- if (mHandler == null) {
- try {
- mHandler = getContext().getClass().getMethod(handlerName,
- View.class);
- } catch (NoSuchMethodException e) {
- int id = getId();
- String idText = id == NO_ID ? "" : " with id '"
- + getContext().getResources().getResourceEntryName(
- id) + "'";
- throw new IllegalStateException("Could not find a method " +
- handlerName + "(View) in the activity "
- + getContext().getClass() + " for onClick handler"
- + " on view " + View.this.getClass() + idText, e);
- }
- }
-
- try {
- mHandler.invoke(getContext(), View.this);
- } catch (IllegalAccessException e) {
- throw new IllegalStateException("Could not execute non "
- + "public method of the activity", e);
- } catch (InvocationTargetException e) {
- throw new IllegalStateException("Could not execute "
- + "method of the activity", e);
- }
- }
- });
+ setOnClickListener(new DeclaredOnClickListener(this, handlerName));
}
break;
case R.styleable.View_overScrollMode:
@@ -4238,6 +4209,66 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * An implementation of OnClickListener that attempts to lazily load a
+ * named click handling method from a parent or ancestor context.
+ */
+ private static class DeclaredOnClickListener implements OnClickListener {
+ private final View mHostView;
+ private final String mMethodName;
+
+ private Method mMethod;
+
+ public DeclaredOnClickListener(@NonNull View hostView, @NonNull String methodName) {
+ mHostView = hostView;
+ mMethodName = methodName;
+ }
+
+ @Override
+ public void onClick(@NonNull View v) {
+ if (mMethod == null) {
+ mMethod = resolveMethod(mHostView.getContext(), mMethodName);
+ }
+
+ try {
+ mMethod.invoke(mHostView.getContext(), v);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException(
+ "Could not execute non-public method for android:onClick", e);
+ } catch (InvocationTargetException e) {
+ throw new IllegalStateException(
+ "Could not execute method for android:onClick", e);
+ }
+ }
+
+ @NonNull
+ private Method resolveMethod(@Nullable Context context, @NonNull String name) {
+ while (context != null) {
+ try {
+ if (!context.isRestricted()) {
+ return context.getClass().getMethod(mMethodName, View.class);
+ }
+ } catch (NoSuchMethodException e) {
+ // Failed to find method, keep searching up the hierarchy.
+ }
+
+ if (context instanceof ContextWrapper) {
+ context = ((ContextWrapper) context).getBaseContext();
+ } else {
+ // Can't search up the hierarchy, null out and fail.
+ context = null;
+ }
+ }
+
+ final int id = mHostView.getId();
+ final String idText = id == NO_ID ? "" : " with id '"
+ + mHostView.getContext().getResources().getResourceEntryName(id) + "'";
+ throw new IllegalStateException("Could not find method " + mMethodName
+ + "(View) in a parent or ancestor Context for android:onClick "
+ + "attribute defined on view " + mHostView.getClass() + idText);
+ }
+ }
+
+ /**
* Non-public constructor for use in testing
*/
View() {
@@ -14342,15 +14373,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Indicates whether this view has a static layer. A view with layer type
- * {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are
- * dynamic.
- */
- boolean hasStaticLayer() {
- return true;
- }
-
- /**
* Indicates what type of layer is currently associated with this view. By default
* a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
* Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
@@ -15468,12 +15490,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (drawingWithRenderNode) {
renderNode.setAlpha(alpha * getAlpha() * getTransitionAlpha());
} else if (layerType == LAYER_TYPE_NONE) {
- int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
- if ((parentFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0) {
- layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
- }
canvas.saveLayerAlpha(sx, sy, sx + getWidth(), sy + getHeight(),
- multipliedAlpha, layerFlags);
+ multipliedAlpha);
}
} else {
// Alpha is handled by the child directly, clobber the layer's alpha
@@ -15509,7 +15527,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!drawingWithDrawingCache) {
if (drawingWithRenderNode) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
- ((DisplayListCanvas) canvas).drawRenderNode(renderNode, parentFlags);
+ ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
} else {
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 4324e75..d0d4201 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3505,8 +3505,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
final View child = children[i];
- if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) &&
- child.hasStaticLayer()) {
+ if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null)) {
recreateChildDisplayList(child);
}
}
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 478fa00..d271af2 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -286,14 +286,10 @@ class DayPickerPagerAdapter extends PagerAdapter {
return null;
}
- private boolean isCalendarInRange(Calendar value) {
- return value.compareTo(mMinDate) >= 0 && value.compareTo(mMaxDate) <= 0;
- }
-
private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
@Override
public void onDayClick(SimpleMonthView view, Calendar day) {
- if (day != null && isCalendarInRange(day)) {
+ if (day != null) {
setSelectedDay(day);
if (mOnDaySelectedListener != null) {
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 113e597..334afab 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -178,6 +178,13 @@ class DayPickerView extends ViewGroup {
});
}
+ private void updateButtonVisibility(int position) {
+ final boolean hasPrev = position > 0;
+ final boolean hasNext = position < (mAdapter.getCount() - 1);
+ mPrevButton.setVisibility(hasPrev ? View.VISIBLE : View.INVISIBLE);
+ mNextButton.setVisibility(hasNext ? View.VISIBLE : View.INVISIBLE);
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final ViewPager viewPager = mViewPager;
@@ -218,12 +225,6 @@ class DayPickerView extends ViewGroup {
final int height = bottom - top;
mViewPager.layout(0, 0, width, height);
- if (mViewPager.getChildCount() < 1) {
- leftButton.setVisibility(View.INVISIBLE);
- rightButton.setVisibility(View.INVISIBLE);
- return;
- }
-
final SimpleMonthView monthView = (SimpleMonthView) mViewPager.getChildAt(0);
final int monthHeight = monthView.getMonthHeight();
final int cellWidth = monthView.getCellWidth();
@@ -235,7 +236,6 @@ class DayPickerView extends ViewGroup {
final int leftIconTop = monthView.getPaddingTop() + (monthHeight - leftDH) / 2;
final int leftIconLeft = monthView.getPaddingLeft() + (cellWidth - leftDW) / 2;
leftButton.layout(leftIconLeft, leftIconTop, leftIconLeft + leftDW, leftIconTop + leftDH);
- leftButton.setVisibility(View.VISIBLE);
final int rightDW = rightButton.getMeasuredWidth();
final int rightDH = rightButton.getMeasuredHeight();
@@ -243,7 +243,6 @@ class DayPickerView extends ViewGroup {
final int rightIconRight = width - monthView.getPaddingRight() - (cellWidth - rightDW) / 2;
rightButton.layout(rightIconRight - rightDW, rightIconTop,
rightIconRight, rightIconTop + rightDH);
- rightButton.setVisibility(View.VISIBLE);
}
public void setDayOfWeekTextAppearance(int resId) {
@@ -399,10 +398,7 @@ class DayPickerView extends ViewGroup {
@Override
public void onPageSelected(int position) {
- mPrevButton.setVisibility(
- position > 0 ? View.VISIBLE : View.INVISIBLE);
- mNextButton.setVisibility(
- position < (mAdapter.getCount() - 1) ? View.VISIBLE : View.INVISIBLE);
+ updateButtonVisibility(position);
}
};
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 39b9907..35e7389 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -62,7 +62,6 @@ import android.text.TextUtils;
import android.text.method.KeyListener;
import android.text.method.MetaKeyKeyListener;
import android.text.method.MovementMethod;
-import android.text.method.PasswordTransformationMethod;
import android.text.method.WordIterator;
import android.text.style.EasyEditSpan;
import android.text.style.SuggestionRangeSpan;
@@ -145,16 +144,16 @@ public class Editor {
InputContentType mInputContentType;
InputMethodState mInputMethodState;
- private static class TextDisplayList {
- RenderNode displayList;
+ private static class TextRenderNode {
+ RenderNode renderNode;
boolean isDirty;
- public TextDisplayList(String name) {
+ public TextRenderNode(String name) {
isDirty = true;
- displayList = RenderNode.create(name, null);
+ renderNode = RenderNode.create(name, null);
}
- boolean needsRecord() { return isDirty || !displayList.isValid(); }
+ boolean needsRecord() { return isDirty || !renderNode.isValid(); }
}
- TextDisplayList[] mTextDisplayLists;
+ TextRenderNode[] mTextRenderNodes;
boolean mFrozenWithFocus;
boolean mSelectionMoved;
@@ -360,10 +359,10 @@ public class Editor {
}
private void destroyDisplayListsData() {
- if (mTextDisplayLists != null) {
- for (int i = 0; i < mTextDisplayLists.length; i++) {
- RenderNode displayList = mTextDisplayLists[i] != null
- ? mTextDisplayLists[i].displayList : null;
+ if (mTextRenderNodes != null) {
+ for (int i = 0; i < mTextRenderNodes.length; i++) {
+ RenderNode displayList = mTextRenderNodes[i] != null
+ ? mTextRenderNodes[i].renderNode : null;
if (displayList != null && displayList.isValid()) {
displayList.destroyDisplayListData();
}
@@ -682,34 +681,6 @@ public class Editor {
}
}
- /**
- * Unlike {@link TextView#textCanBeSelected()}, this method is based on the <i>current</i> state
- * of the TextView. textCanBeSelected() has to be true (this is one of the conditions to have
- * a selection controller (see {@link #prepareCursorControllers()}), but this is not sufficient.
- */
- private boolean canSelectText() {
- return hasSelectionController() && mTextView.getText().length() != 0;
- }
-
- /**
- * It would be better to rely on the input type for everything. A password inputType should have
- * a password transformation. We should hence use isPasswordInputType instead of this method.
- *
- * We should:
- * - Call setInputType in setKeyListener instead of changing the input type directly (which
- * would install the correct transformation).
- * - Refuse the installation of a non-password transformation in setTransformation if the input
- * type is password.
- *
- * However, this is like this for legacy reasons and we cannot break existing apps. This method
- * is useful since it matches what the user can see (obfuscated text or not).
- *
- * @return true if the current transformation method is of the password type.
- */
- private boolean hasPasswordTransformationMethod() {
- return mTextView.getTransformationMethod() instanceof PasswordTransformationMethod;
- }
-
private int getWordStart(int offset) {
// FIXME - For this and similar methods we're not doing anything to check if there's
// a LocaleSpan in the text, this may be something we should try handling or checking for.
@@ -758,11 +729,11 @@ public class Editor {
* successfully performed.
*/
private boolean selectCurrentWord() {
- if (!canSelectText()) {
+ if (!mTextView.canSelectText()) {
return false;
}
- if (hasPasswordTransformationMethod()) {
+ if (mTextView.hasPasswordTransformationMethod()) {
// Always select all on a password field.
// Cut/copy menu entries are not available for passwords, but being able to select all
// is however useful to delete or paste to replace the entire content.
@@ -1467,8 +1438,8 @@ public class Editor {
firstLine, lastLine);
if (layout instanceof DynamicLayout) {
- if (mTextDisplayLists == null) {
- mTextDisplayLists = ArrayUtils.emptyArray(TextDisplayList.class);
+ if (mTextRenderNodes == null) {
+ mTextRenderNodes = ArrayUtils.emptyArray(TextRenderNode.class);
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
@@ -1489,19 +1460,19 @@ public class Editor {
searchStartIndex);
// Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
- if (mTextDisplayLists[blockIndex] != null) {
- mTextDisplayLists[blockIndex].isDirty = true;
+ if (mTextRenderNodes[blockIndex] != null) {
+ mTextRenderNodes[blockIndex].isDirty = true;
}
searchStartIndex = blockIndex + 1;
}
- if (mTextDisplayLists[blockIndex] == null) {
- mTextDisplayLists[blockIndex] =
- new TextDisplayList("Text " + blockIndex);
+ if (mTextRenderNodes[blockIndex] == null) {
+ mTextRenderNodes[blockIndex] =
+ new TextRenderNode("Text " + blockIndex);
}
- final boolean blockDisplayListIsInvalid = mTextDisplayLists[blockIndex].needsRecord();
- RenderNode blockDisplayList = mTextDisplayLists[blockIndex].displayList;
+ final boolean blockDisplayListIsInvalid = mTextRenderNodes[blockIndex].needsRecord();
+ RenderNode blockDisplayList = mTextRenderNodes[blockIndex].renderNode;
if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
final int blockBeginLine = endOfPreviousBlock + 1;
final int top = layout.getLineTop(blockBeginLine);
@@ -1528,7 +1499,7 @@ public class Editor {
// brings this range of text back to the top left corner of the viewport
displayListCanvas.translate(-left, -top);
layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
- mTextDisplayLists[blockIndex].isDirty = false;
+ mTextRenderNodes[blockIndex].isDirty = false;
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
@@ -1543,8 +1514,7 @@ public class Editor {
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
}
- ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList,
- 0 /* no child clipping, our TextView parent enforces it */);
+ ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
endOfPreviousBlock = blockEndLine;
}
@@ -1558,7 +1528,7 @@ public class Editor {
private int getAvailableDisplayListIndex(int[] blockIndices, int numberOfBlocks,
int searchStartIndex) {
- int length = mTextDisplayLists.length;
+ int length = mTextRenderNodes.length;
for (int i = searchStartIndex; i < length; i++) {
boolean blockIndexFound = false;
for (int j = 0; j < numberOfBlocks; j++) {
@@ -1572,7 +1542,7 @@ public class Editor {
}
// No available index found, the pool has to grow
- mTextDisplayLists = GrowingArrayUtils.append(mTextDisplayLists, length, null);
+ mTextRenderNodes = GrowingArrayUtils.append(mTextRenderNodes, length, null);
return length;
}
@@ -1589,7 +1559,7 @@ public class Editor {
* Invalidates all the sub-display lists that overlap the specified character range
*/
void invalidateTextDisplayList(Layout layout, int start, int end) {
- if (mTextDisplayLists != null && layout instanceof DynamicLayout) {
+ if (mTextRenderNodes != null && layout instanceof DynamicLayout) {
final int firstLine = layout.getLineForOffset(start);
final int lastLine = layout.getLineForOffset(end);
@@ -1609,7 +1579,7 @@ public class Editor {
while (i < numberOfBlocks) {
final int blockIndex = blockIndices[i];
if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) {
- mTextDisplayLists[blockIndex].isDirty = true;
+ mTextRenderNodes[blockIndex].isDirty = true;
}
if (blockEndLines[i] >= lastLine) break;
i++;
@@ -1618,9 +1588,9 @@ public class Editor {
}
void invalidateTextDisplayList() {
- if (mTextDisplayLists != null) {
- for (int i = 0; i < mTextDisplayLists.length; i++) {
- if (mTextDisplayLists[i] != null) mTextDisplayLists[i].isDirty = true;
+ if (mTextRenderNodes != null) {
+ for (int i = 0; i < mTextRenderNodes.length; i++) {
+ if (mTextRenderNodes[i] != null) mTextRenderNodes[i].isDirty = true;
}
}
}
@@ -1718,7 +1688,7 @@ public class Editor {
return false;
}
- if (!canSelectText() || !mTextView.requestFocus()) {
+ if (!mTextView.canSelectText() || !mTextView.requestFocus()) {
Log.w(TextView.LOG_TAG,
"TextView does not support text selection. Action mode cancelled.");
return false;
@@ -3090,7 +3060,7 @@ public class Editor {
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
- if (canSelectText() && !hasPasswordTransformationMethod()) {
+ if (mTextView.canSelectAllText()) {
menu.add(0, TextView.ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setAlphabeticShortcut('a').
setShowAsAction(
@@ -3847,6 +3817,10 @@ public class Editor {
startSelectionActionModeWithoutSelection();
}
}
+ } else {
+ if (mSelectionActionMode != null) {
+ mSelectionActionMode.invalidateContentRect();
+ }
}
hideAfterDelay();
break;
@@ -4491,7 +4465,7 @@ public class Editor {
private class CorrectionHighlighter {
private final Path mPath = new Path();
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Paint mPaint = new Paint();
private int mStart, mEnd;
private long mFadingStartTime;
private RectF mTempRectF;
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 2778f0f..acf1df9 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -31,6 +31,7 @@ import android.text.TextPaint;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.IntArray;
+import android.util.MathUtils;
import android.util.StateSet;
import android.view.MotionEvent;
import android.view.View;
@@ -422,7 +423,8 @@ class SimpleMonthView extends View {
int stateMask = 0;
- if (day >= mEnabledDayStart && day <= mEnabledDayEnd) {
+ final boolean isDayEnabled = isDayEnabled(day);
+ if (isDayEnabled) {
stateMask |= StateSet.VIEW_STATE_ENABLED;
}
@@ -435,8 +437,11 @@ class SimpleMonthView extends View {
} else if (mTouchedItem == day) {
stateMask |= StateSet.VIEW_STATE_PRESSED;
- // Adjust the circle to be centered on the row.
- canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, mDayHighlightPaint);
+ if (isDayEnabled) {
+ // Adjust the circle to be centered on the row.
+ canvas.drawCircle(colCenterRtl, rowCenter,
+ mDaySelectorRadius, mDayHighlightPaint);
+ }
}
final boolean isDayToday = mToday == day;
@@ -460,6 +465,14 @@ class SimpleMonthView extends View {
}
}
+ private boolean isDayEnabled(int day) {
+ return day >= mEnabledDayStart && day <= mEnabledDayEnd;
+ }
+
+ private boolean isValidDayOfMonth(int day) {
+ return day >= 1 && day <= mDaysInMonth;
+ }
+
private static boolean isValidDayOfWeek(int day) {
return day >= Calendar.SUNDAY && day <= Calendar.SATURDAY;
}
@@ -536,13 +549,6 @@ class SimpleMonthView extends View {
mWeekStart = mCalendar.getFirstDayOfWeek();
}
- if (enabledDayStart > 0 && enabledDayEnd < 32) {
- mEnabledDayStart = enabledDayStart;
- }
- if (enabledDayEnd > 0 && enabledDayEnd < 32 && enabledDayEnd >= enabledDayStart) {
- mEnabledDayEnd = enabledDayEnd;
- }
-
// Figure out what day today is.
final Calendar today = Calendar.getInstance();
mToday = -1;
@@ -554,6 +560,9 @@ class SimpleMonthView extends View {
}
}
+ mEnabledDayStart = MathUtils.constrain(enabledDayStart, 1, mDaysInMonth);
+ mEnabledDayEnd = MathUtils.constrain(enabledDayEnd, mEnabledDayStart, mDaysInMonth);
+
// Invalidate the old title.
mTitle = null;
@@ -694,7 +703,7 @@ class SimpleMonthView extends View {
final int col = (paddedXRtl * DAYS_IN_WEEK) / mPaddedWidth;
final int index = col + row * DAYS_IN_WEEK;
final int day = index + 1 - findDayOffset();
- if (day < 1 || day > mDaysInMonth) {
+ if (!isValidDayOfMonth(day)) {
return -1;
}
@@ -708,7 +717,7 @@ class SimpleMonthView extends View {
* @param outBounds the rect to populate with bounds
*/
private boolean getBoundsForDay(int id, Rect outBounds) {
- if (id < 1 || id > mDaysInMonth) {
+ if (!isValidDayOfMonth(id)) {
return false;
}
@@ -742,7 +751,7 @@ class SimpleMonthView extends View {
* @param day the day that was clicked
*/
private boolean onDayClicked(int day) {
- if (day < 0 || day > mDaysInMonth) {
+ if (!isValidDayOfMonth(day) || !isDayEnabled(day)) {
return false;
}
@@ -774,7 +783,7 @@ class SimpleMonthView extends View {
@Override
protected int getVirtualViewAt(float x, float y) {
final int day = getDayAtLocation((int) (x + 0.5f), (int) (y + 0.5f));
- if (day >= 0) {
+ if (day != -1) {
return day;
}
return ExploreByTouchHelper.INVALID_ID;
@@ -808,7 +817,13 @@ class SimpleMonthView extends View {
node.setText(getDayText(virtualViewId));
node.setContentDescription(getDayDescription(virtualViewId));
node.setBoundsInParent(mTempRect);
- node.addAction(AccessibilityAction.ACTION_CLICK);
+
+ final boolean isDayEnabled = isDayEnabled(virtualViewId);
+ if (isDayEnabled) {
+ node.addAction(AccessibilityAction.ACTION_CLICK);
+ }
+
+ node.setEnabled(isDayEnabled);
if (virtualViewId == mActivatedDay) {
// TODO: This should use activated once that's supported.
@@ -835,7 +850,7 @@ class SimpleMonthView extends View {
* @return a description of the virtual view
*/
private CharSequence getDayDescription(int id) {
- if (id >= 1 && id <= mDaysInMonth) {
+ if (isValidDayOfMonth(id)) {
mTempCalendar.set(mYear, mMonth, id);
return DateFormat.format(DATE_FORMAT, mTempCalendar.getTimeInMillis());
}
@@ -850,7 +865,7 @@ class SimpleMonthView extends View {
* @return the visible text of the virtual view
*/
private CharSequence getDayText(int id) {
- if (id >= 1 && id <= mDaysInMonth) {
+ if (isValidDayOfMonth(id)) {
return Integer.toString(id);
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index ae779fe..f94f97c 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -216,7 +216,7 @@ public class Switch extends CompoundButton {
public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new TextPaint();
final Resources res = getResources();
mTextPaint.density = res.getDisplayMetrics().density;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3e8df08..774a864 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -668,11 +668,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final Resources res = getResources();
final CompatibilityInfo compat = res.getCompatibilityInfo();
- mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new TextPaint();
mTextPaint.density = res.getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling(compat.applicationScale);
- mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mHighlightPaint = new Paint();
mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
mMovement = getDefaultMovementMethod();
@@ -4569,7 +4569,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @return true if the current transformation method is of the password type.
*/
- private boolean hasPasswordTransformationMethod() {
+ boolean hasPasswordTransformationMethod() {
return mTransformation instanceof PasswordTransformationMethod;
}
@@ -8583,7 +8583,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* a selection controller (see {@link Editor#prepareCursorControllers()}), but this is not
* sufficient.
*/
- private boolean canSelectText() {
+ boolean canSelectText() {
return mText.length() != 0 && mEditor != null && mEditor.hasSelectionController();
}
@@ -9199,6 +9199,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return false;
}
+ boolean canSelectAllText() {
+ return canSelectText() && !hasPasswordTransformationMethod();
+ }
+
boolean selectAllText() {
// Need to hide insert point cursor controller before settings selection, otherwise insert
// point cursor controller obtains cursor update event and update cursor with cancelling