Merge "Fix flaky ScheduleCalendarTest"
diff --git a/Android.bp b/Android.bp
index e9fb93e..4d2e5e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1251,6 +1251,9 @@
local_sourcepaths: frameworks_base_subdirs,
installable: false,
metalava_enabled: true,
+ metalava_annotations_enabled: true,
+ metalava_previous_api: ":public-api-for-metalava-annotations",
+ metalava_merge_annotations_dir: "tools/metalava/manual",
}
droiddoc {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 950070e..a58db64 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2206,10 +2206,10 @@
com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
if (val != null) {
if (val.type == TypedValue.TYPE_STRING && val.string != null) {
- targetCode = minCode = val.string.toString();
+ minCode = val.string.toString();
} else {
// If it's not a string, it's an integer.
- targetVers = minVers = val.data;
+ minVers = val.data;
}
}
@@ -2225,6 +2225,9 @@
// If it's not a string, it's an integer.
targetVers = val.data;
}
+ } else {
+ targetVers = minVers;
+ targetCode = minCode;
}
sa.recycle();
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 87c64cd..32c6898 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -2365,13 +2365,25 @@
* {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, is defined relative to the active array rectangle given in
* this field, with <code>(0, 0)</code> being the top-left of this rectangle.</p>
* <p>The active array may be smaller than the full pixel array, since the full array may
- * include black calibration pixels or other inactive regions, and geometric correction
- * resulting in scaling or cropping may have been applied.</p>
+ * include black calibration pixels or other inactive regions.</p>
+ * <p>For devices that do not support {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the active
+ * array must be the same as {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.</p>
+ * <p>For devices that support {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the active array must
+ * be enclosed by {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}. The difference between
+ * pre-correction active array and active array accounts for scaling or cropping caused
+ * by lens geometric distortion correction.</p>
+ * <p>In general, application should always refer to active array size for controls like
+ * metering regions or crop region. Two exceptions are when the application is dealing with
+ * RAW image buffers (RAW_SENSOR, RAW10, RAW12 etc), or when application explicitly set
+ * {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} to OFF. In these cases, application should refer
+ * to {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.</p>
* <p><b>Units</b>: Pixel coordinates on the image sensor</p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE =
@@ -2616,9 +2628,9 @@
* <ol>
* <li>{@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion}.</li>
* </ol>
- * <p>If all of the geometric distortion fields are no-ops, this rectangle will be the same
- * as the post-distortion-corrected rectangle given in
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+ * <p>If the camera device doesn't support geometric distortion correction, or all of the
+ * geometric distortion fields are no-ops, this rectangle will be the same as the
+ * post-distortion-corrected rectangle given in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
* <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
* the full pixel array, and the size of the full pixel array is given by
* {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 411a97e..aca77a5 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1269,11 +1269,26 @@
* Otherwise will always be present.</p>
* <p>The maximum number of regions supported by the device is determined by the value
* of {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe}.</p>
- * <p>The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left pixel in the active pixel array, and
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with (0,0) being
+ * the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
- * bottom-right pixel in the active pixel array.</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.height - 1) being the bottom-right
+ * pixel in the pre-correction active pixel array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
* <p>The weight must be within <code>[0, 1000]</code>, and represents a weight
* for every pixel in the area. This means that a large metering area
* with the same weight as a smaller area will have more effect in
@@ -1289,15 +1304,20 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
- * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
+ * distortion correction capability and mode</p>
* <p><b>Range of valid values:</b><br>
* Coordinates must be between <code>[(0,0), (width, height))</code> of
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * depending on distortion correction capability and mode</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AE_REGIONS =
@@ -1443,11 +1463,26 @@
* Otherwise will always be present.</p>
* <p>The maximum number of focus areas supported by the device is determined by the value
* of {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf}.</p>
- * <p>The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left pixel in the active pixel array, and
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with (0,0) being
+ * the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
- * bottom-right pixel in the active pixel array.</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.height - 1) being the bottom-right
+ * pixel in the pre-correction active pixel array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
* <p>The weight must be within <code>[0, 1000]</code>, and represents a weight
* for every pixel in the area. This means that a large metering area
* with the same weight as a smaller area will have more effect in
@@ -1464,15 +1499,20 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
- * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
+ * distortion correction capability and mode</p>
* <p><b>Range of valid values:</b><br>
* Coordinates must be between <code>[(0,0), (width, height))</code> of
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * depending on distortion correction capability and mode</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AF_REGIONS =
@@ -1612,11 +1652,26 @@
* Otherwise will always be present.</p>
* <p>The maximum number of regions supported by the device is determined by the value
* of {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb}.</p>
- * <p>The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left pixel in the active pixel array, and
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with (0,0) being
+ * the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
- * bottom-right pixel in the active pixel array.</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.height - 1) being the bottom-right
+ * pixel in the pre-correction active pixel array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
* <p>The weight must range from 0 to 1000, and represents a weight
* for every pixel in the area. This means that a large metering area
* with the same weight as a smaller area will have more effect in
@@ -1632,15 +1687,20 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
- * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
+ * distortion correction capability and mode</p>
* <p><b>Range of valid values:</b><br>
* Coordinates must be between <code>[(0,0), (width, height))</code> of
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * depending on distortion correction capability and mode</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AWB_REGIONS =
@@ -2433,9 +2493,17 @@
/**
* <p>The desired region of the sensor to read out for this capture.</p>
* <p>This control can be used to implement digital zoom.</p>
- * <p>The crop region coordinate system is based off
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being the
- * top-left corner of the sensor active array.</p>
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being
+ * the top-left pixel of the active array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
* <p>Output streams use this rectangle to produce their output,
* cropping to a smaller region if necessary to maintain the
* stream's aspect ratio, then scaling the sensor input to
@@ -2454,20 +2522,30 @@
* outputs will crop horizontally (pillarbox), and 16:9
* streams will match exactly. These additional crops will
* be centered within the crop region.</p>
- * <p>The width and height of the crop region cannot
- * be set to be smaller than
+ * <p>If the coordinate system is android.sensor.info.activeArraysSize, the width and height
+ * of the crop region cannot be set to be smaller than
* <code>floor( activeArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code> and
* <code>floor( activeArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>, respectively.</p>
+ * <p>If the coordinate system is {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, the width
+ * and height of the crop region cannot be set to be smaller than
+ * <code>floor( preCorrectionActiveArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>
+ * and
+ * <code>floor( preCorrectionActiveArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>,
+ * respectively.</p>
* <p>The camera device may adjust the crop region to account
* for rounding and other hardware requirements; the final
* crop region used will be included in the output capture
* result.</p>
* <p><b>Units</b>: Pixel coordinates relative to
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on distortion correction
+ * capability and mode</p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
@@ -3186,15 +3264,14 @@
* any correction at all would slow down capture rate. Every output stream will have a
* similar amount of enhancement applied.</p>
* <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
- * applied to any RAW output. Metadata coordinates such as face rectangles or metering
+ * applied to any RAW output. Metadata coordinates such as face rectangles or metering
* regions are also not affected by correction.</p>
- * <p>Applications enabling distortion correction need to pay extra attention when converting
- * image coordinates between corrected output buffers and the sensor array. For example, if
- * the app supports tap-to-focus and enables correction, it then has to apply the distortion
- * model described in {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} to the image buffer tap coordinates to properly
- * calculate the tap position on the sensor active array to be used with
- * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}. The same applies in reverse to detected face rectangles if
- * they need to be drawn on top of the corrected output buffers.</p>
+ * <p>This control will be on by default on devices that support this control. Applications
+ * disabling distortion correction need to pay extra attention with the coordinate system of
+ * metering regions, crop region, and face rectangles. When distortion correction is OFF,
+ * metadata coordinates follow the coordinate system of
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}. When distortion is not OFF, metadata
+ * coordinates follow the coordinate system of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li>
@@ -3205,9 +3282,10 @@
* {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
- * @see CaptureRequest#CONTROL_AF_REGIONS
* @see CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES
* @see CameraCharacteristics#LENS_DISTORTION
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see #DISTORTION_CORRECTION_MODE_OFF
* @see #DISTORTION_CORRECTION_MODE_FAST
* @see #DISTORTION_CORRECTION_MODE_HIGH_QUALITY
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 361d83d..d003f9a 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -730,11 +730,26 @@
* Otherwise will always be present.</p>
* <p>The maximum number of regions supported by the device is determined by the value
* of {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe}.</p>
- * <p>The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left pixel in the active pixel array, and
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with (0,0) being
+ * the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
- * bottom-right pixel in the active pixel array.</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.height - 1) being the bottom-right
+ * pixel in the pre-correction active pixel array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
* <p>The weight must be within <code>[0, 1000]</code>, and represents a weight
* for every pixel in the area. This means that a large metering area
* with the same weight as a smaller area will have more effect in
@@ -750,15 +765,20 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
- * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
+ * distortion correction capability and mode</p>
* <p><b>Range of valid values:</b><br>
* Coordinates must be between <code>[(0,0), (width, height))</code> of
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * depending on distortion correction capability and mode</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AE_REGIONS =
@@ -1152,11 +1172,26 @@
* Otherwise will always be present.</p>
* <p>The maximum number of focus areas supported by the device is determined by the value
* of {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf}.</p>
- * <p>The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left pixel in the active pixel array, and
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with (0,0) being
+ * the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
- * bottom-right pixel in the active pixel array.</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.height - 1) being the bottom-right
+ * pixel in the pre-correction active pixel array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
* <p>The weight must be within <code>[0, 1000]</code>, and represents a weight
* for every pixel in the area. This means that a large metering area
* with the same weight as a smaller area will have more effect in
@@ -1173,15 +1208,20 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
- * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
+ * distortion correction capability and mode</p>
* <p><b>Range of valid values:</b><br>
* Coordinates must be between <code>[(0,0), (width, height))</code> of
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * depending on distortion correction capability and mode</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AF_REGIONS =
@@ -1730,11 +1770,26 @@
* Otherwise will always be present.</p>
* <p>The maximum number of regions supported by the device is determined by the value
* of {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb}.</p>
- * <p>The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left pixel in the active pixel array, and
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with (0,0) being
+ * the top-left pixel in the active pixel array, and
* ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
- * bottom-right pixel in the active pixel array.</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.height - 1) being the bottom-right
+ * pixel in the pre-correction active pixel array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array, and
+ * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the bottom-right pixel in the
+ * active pixel array.</p>
* <p>The weight must range from 0 to 1000, and represents a weight
* for every pixel in the area. This means that a large metering area
* with the same weight as a smaller area will have more effect in
@@ -1750,15 +1805,20 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
- * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
+ * distortion correction capability and mode</p>
* <p><b>Range of valid values:</b><br>
* Coordinates must be between <code>[(0,0), (width, height))</code> of
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}
+ * depending on distortion correction capability and mode</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.hardware.camera2.params.MeteringRectangle[]> CONTROL_AWB_REGIONS =
@@ -3099,9 +3159,17 @@
/**
* <p>The desired region of the sensor to read out for this capture.</p>
* <p>This control can be used to implement digital zoom.</p>
- * <p>The crop region coordinate system is based off
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being the
- * top-left corner of the sensor active array.</p>
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being
+ * the top-left pixel of the active array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
* <p>Output streams use this rectangle to produce their output,
* cropping to a smaller region if necessary to maintain the
* stream's aspect ratio, then scaling the sensor input to
@@ -3120,20 +3188,30 @@
* outputs will crop horizontally (pillarbox), and 16:9
* streams will match exactly. These additional crops will
* be centered within the crop region.</p>
- * <p>The width and height of the crop region cannot
- * be set to be smaller than
+ * <p>If the coordinate system is android.sensor.info.activeArraysSize, the width and height
+ * of the crop region cannot be set to be smaller than
* <code>floor( activeArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code> and
* <code>floor( activeArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>, respectively.</p>
+ * <p>If the coordinate system is {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, the width
+ * and height of the crop region cannot be set to be smaller than
+ * <code>floor( preCorrectionActiveArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>
+ * and
+ * <code>floor( preCorrectionActiveArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>,
+ * respectively.</p>
* <p>The camera device may adjust the crop region to account
* for rounding and other hardware requirements; the final
* crop region used will be included in the output capture
* result.</p>
* <p><b>Units</b>: Pixel coordinates relative to
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</p>
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on distortion correction
+ * capability and mode</p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
*/
@PublicKey
public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
@@ -3624,12 +3702,23 @@
/**
* <p>List of landmarks for detected
* faces.</p>
- * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being
+ * the top-left pixel of the active array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
* <code>(0, 0)</code> being the top-left pixel of the active array.</p>
* <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL
* This key is available on all devices.</p>
*
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
@@ -3639,12 +3728,23 @@
/**
* <p>List of the bounding rectangles for detected
* faces.</p>
- * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <p>For devices not supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system always follows that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being
+ * the top-left pixel of the active array.</p>
+ * <p>For devices supporting {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} control, the coordinate
+ * system depends on the mode being set.
+ * When the distortion correction mode is OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the pre-correction active array.
+ * When the distortion correction mode is not OFF, the coordinate system follows
+ * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
* <code>(0, 0)</code> being the top-left pixel of the active array.</p>
* <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF
* This key is available on all devices.</p>
*
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
@@ -4478,15 +4578,14 @@
* any correction at all would slow down capture rate. Every output stream will have a
* similar amount of enhancement applied.</p>
* <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
- * applied to any RAW output. Metadata coordinates such as face rectangles or metering
+ * applied to any RAW output. Metadata coordinates such as face rectangles or metering
* regions are also not affected by correction.</p>
- * <p>Applications enabling distortion correction need to pay extra attention when converting
- * image coordinates between corrected output buffers and the sensor array. For example, if
- * the app supports tap-to-focus and enables correction, it then has to apply the distortion
- * model described in {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} to the image buffer tap coordinates to properly
- * calculate the tap position on the sensor active array to be used with
- * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}. The same applies in reverse to detected face rectangles if
- * they need to be drawn on top of the corrected output buffers.</p>
+ * <p>This control will be on by default on devices that support this control. Applications
+ * disabling distortion correction need to pay extra attention with the coordinate system of
+ * metering regions, crop region, and face rectangles. When distortion correction is OFF,
+ * metadata coordinates follow the coordinate system of
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}. When distortion is not OFF, metadata
+ * coordinates follow the coordinate system of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li>
@@ -4497,9 +4596,10 @@
* {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
- * @see CaptureRequest#CONTROL_AF_REGIONS
* @see CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES
* @see CameraCharacteristics#LENS_DISTORTION
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see #DISTORTION_CORRECTION_MODE_OFF
* @see #DISTORTION_CORRECTION_MODE_FAST
* @see #DISTORTION_CORRECTION_MODE_HIGH_QUALITY
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index e989e1a..8f28102 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1435,7 +1435,9 @@
// set the EXTRA_AUTHENTICATION_RESULT extra, but it could cause weird results if the
// service set the extra and returned RESULT_CANCELED...
- if (sDebug) Log.d(TAG, "onAuthenticationResult(): d=" + data);
+ if (sDebug) {
+ Log.d(TAG, "onAuthenticationResult(): id= " + authenticationId + ", data=" + data);
+ }
synchronized (mLock) {
if (!isActiveLocked()) {
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 1b816fe..c195a8e 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -142,7 +142,7 @@
LOG_ALWAYS_FATAL_IF(!mProjectedDisplayList->mProjectedOutline);
const bool shouldClip = mProjectedDisplayList->mProjectedOutline->getPath();
SkAutoCanvasRestore acr2(canvas, shouldClip);
- canvas->setMatrix(mProjectedDisplayList->mProjectedReceiverParentMatrix);
+ canvas->setMatrix(mProjectedDisplayList->mParentMatrix);
if (shouldClip) {
clipOutline(*mProjectedDisplayList->mProjectedOutline, canvas, nullptr);
}
@@ -200,9 +200,7 @@
setViewProperties(properties, canvas, &alphaMultiplier);
}
SkiaDisplayList* displayList = (SkiaDisplayList*)mRenderNode->getDisplayList();
- if (displayList->containsProjectionReceiver()) {
- displayList->mProjectedReceiverParentMatrix = canvas->getTotalMatrix();
- }
+ displayList->mParentMatrix = canvas->getTotalMatrix();
// TODO should we let the bound of the drawable do this for us?
const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 6292a6c..dba97fe 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -55,6 +55,11 @@
if (casterZ >= -NON_ZERO_EPSILON) { // draw only children with negative Z
return;
}
+ SkAutoCanvasRestore acr(canvas, true);
+ // Since we're drawing out of recording order, the child's matrix needs to be applied to the
+ // canvas. In in-order drawing, the canvas already has the child's matrix applied.
+ canvas->setMatrix(mDisplayList->mParentMatrix);
+ canvas->concat(childNode->getRecordedMatrix());
childNode->forceDraw(canvas);
drawIndex++;
}
@@ -102,6 +107,11 @@
RenderNodeDrawable* childNode = zChildren[drawIndex];
SkASSERT(childNode);
+ SkAutoCanvasRestore acr(canvas, true);
+ // Since we're drawing out of recording order, the child's matrix needs to be applied to the
+ // canvas. In in-order drawing, the canvas already has the child's matrix applied.
+ canvas->setMatrix(mStartBarrier->mDisplayList->mParentMatrix);
+ canvas->concat(childNode->getRecordedMatrix());
childNode->forceDraw(canvas);
drawIndex++;
@@ -153,10 +163,15 @@
}
SkAutoCanvasRestore acr(canvas, true);
+ // Since we're drawing out of recording order, the child's matrix needs to be applied to the
+ // canvas. In in-order drawing, the canvas already has the child's matrix applied.
+ canvas->setMatrix(mStartBarrier->mDisplayList->mParentMatrix);
SkMatrix shadowMatrix;
- mat4 hwuiMatrix;
+ mat4 hwuiMatrix(caster->getRecordedMatrix());
// TODO we don't pass the optional boolean to treat it as a 4x4 matrix
+ // applyViewPropertyTransforms gets the same matrix, which render nodes apply with
+ // RenderNodeDrawable::setViewProperties as a part if their draw.
caster->getRenderNode()->applyViewPropertyTransforms(hwuiMatrix);
hwuiMatrix.copyTo(shadowMatrix);
canvas->concat(shadowMatrix);
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 58b9242..6eff589 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -173,12 +173,12 @@
// node is drawn.
const Outline* mProjectedOutline = nullptr;
- // mProjectedReceiverParentMatrix is valid when render node tree is traversed during the draw
- // pass. Render nodes that have a child receiver node, will store their matrix in
- // mProjectedReceiverParentMatrix. Child receiver node will set the matrix and then clip with
- // the
- // outline of their parent.
- SkMatrix mProjectedReceiverParentMatrix;
+ // mParentMatrix is set and valid when render node tree is traversed during the draw
+ // pass. Render nodes, which draw in a order different than recording order (e.g. nodes with a
+ // child receiver node or Z elevation), can use mParentMatrix to calculate the final transform
+ // without replaying the matrix transform OPs from the display list.
+ // Child receiver node will set the matrix and then clip with the outline of their parent.
+ SkMatrix mParentMatrix;
};
}; // namespace skiapipeline
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index 15c0ab1..eb67e6c 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -1094,7 +1094,7 @@
class ShadowTestCanvas : public SkCanvas {
public:
ShadowTestCanvas(int width, int height) : SkCanvas(width, height) {}
- int getIndex() { return mDrawCounter; }
+ int getDrawCounter() { return mDrawCounter; }
virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
// expect to draw 2 RenderNodeDrawable, 1 StartReorderBarrierDrawable,
@@ -1109,17 +1109,36 @@
EXPECT_EQ(dy, TRANSLATE_Y);
}
- virtual void didConcat(const SkMatrix& matrix) override {
- // This function is invoked by EndReorderBarrierDrawable::drawShadow to apply shadow
- // matrix.
+ virtual void didSetMatrix(const SkMatrix& matrix) override {
mDrawCounter++;
- EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X, CASTER_Y), matrix);
- EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
- getTotalMatrix());
+ // First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix.
+ // Second invocation is preparing the matrix for an elevated RenderNodeDrawable.
+ EXPECT_TRUE(matrix.isIdentity());
+ EXPECT_TRUE(getTotalMatrix().isIdentity());
+ }
+
+ virtual void didConcat(const SkMatrix& matrix) override {
+ mDrawCounter++;
+ if (mFirstDidConcat) {
+ // First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix.
+ mFirstDidConcat = false;
+ EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
+ matrix);
+ EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
+ getTotalMatrix());
+ } else {
+ // Second invocation is preparing the matrix for an elevated RenderNodeDrawable.
+ EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y),
+ matrix);
+ EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y),
+ getTotalMatrix());
+ }
}
protected:
int mDrawCounter = 0;
+ private:
+ bool mFirstDidConcat = true;
};
auto parent = TestUtils::createSkiaNode(
@@ -1143,7 +1162,7 @@
ShadowTestCanvas canvas(CANVAS_WIDTH, CANVAS_HEIGHT);
RenderNodeDrawable drawable(parent.get(), &canvas, false);
canvas.drawDrawable(&drawable);
- EXPECT_EQ(6, canvas.getIndex());
+ EXPECT_EQ(9, canvas.getDrawCounter());
}
// Draw a vector drawable twice but with different bounds and verify correct bounds are used.
diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
index 8473c06..a18600a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java
@@ -40,9 +40,6 @@
public class AccessibilityUtils {
public static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
- final static TextUtils.SimpleStringSplitter sStringColonSplitter =
- new TextUtils.SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
-
/**
* @return the set of enabled accessibility services. If there are no services,
* it returns the unmodifiable {@link Collections#emptySet()}.
@@ -72,16 +69,16 @@
final String enabledServicesSetting = Settings.Secure.getStringForUser(
context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
userId);
- if (enabledServicesSetting == null) {
+ if (TextUtils.isEmpty(enabledServicesSetting)) {
return Collections.emptySet();
}
final Set<ComponentName> enabledServices = new HashSet<>();
- final TextUtils.SimpleStringSplitter colonSplitter = sStringColonSplitter;
+ final TextUtils.StringSplitter colonSplitter =
+ new TextUtils.SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
colonSplitter.setString(enabledServicesSetting);
- while (colonSplitter.hasNext()) {
- final String componentNameString = colonSplitter.next();
+ for (String componentNameString : colonSplitter) {
final ComponentName enabledService = ComponentName.unflattenFromString(
componentNameString);
if (enabledService != null) {
@@ -168,8 +165,7 @@
* an OEM-configurable default if the setting has never been set.
*
* @param context A valid context
- * @param userId The user whose settings should be checked
- *
+ * @param userId The user whose settings should be checked
* @return The component name, flattened to a string, of the target service.
*/
public static String getShortcutTargetServiceComponentNameString(
@@ -187,9 +183,9 @@
* Check if the accessibility shortcut is enabled for a user
*
* @param context A valid context
- * @param userId The user of interest
+ * @param userId The user of interest
* @return {@code true} if the shortcut is enabled for the user. {@code false} otherwise.
- * Note that the shortcut may be enabled, but no action associated with it.
+ * Note that the shortcut may be enabled, but no action associated with it.
*/
public static boolean isShortcutEnabled(Context context, int userId) {
return Settings.Secure.getIntForUser(context.getContentResolver(),
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index 0f0e4e57..3549abc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -34,7 +34,6 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
-import android.widget.RemoteViews;
import java.util.ArrayList;
import java.util.Collections;
@@ -96,11 +95,7 @@
/**
* The key used to get the category from metadata of activities of action
* {@link #EXTRA_SETTINGS_ACTION}
- * The value must be one of:
- * <li>com.android.settings.category.wireless</li>
- * <li>com.android.settings.category.device</li>
- * <li>com.android.settings.category.personal</li>
- * <li>com.android.settings.category.system</li>
+ * The value must be from {@link CategoryKey}.
*/
private static final String EXTRA_CATEGORY_KEY = "com.android.settings.category";
@@ -171,17 +166,6 @@
public static final String META_DATA_PREFERENCE_SUMMARY_URI =
"com.android.settings.summary_uri";
- /**
- * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the
- * custom view which should be displayed for the preference. The custom view will be inflated
- * as a remote view.
- *
- * This also can be used with {@link #META_DATA_PREFERENCE_SUMMARY_URI}, by setting the id
- * of the summary TextView to '@android:id/summary'.
- */
- public static final String META_DATA_PREFERENCE_CUSTOM_VIEW =
- "com.android.settings.custom_view";
-
public static final String SETTING_PKG = "com.android.settings";
/**
@@ -442,11 +426,6 @@
keyHint = metaData.getString(META_DATA_PREFERENCE_KEYHINT);
}
}
- if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
- int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
- tile.remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
- updateSummaryAndTitle(context, providerMap, tile);
- }
}
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
if (DEBUG) Log.d(LOG_TAG, "Couldn't find info", e);
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java
deleted file mode 100644
index 19e556a..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.settingslib.suggestions;
-
-public class SuggestionCategory {
- public String category;
- public String pkg;
- public boolean multiple;
- public boolean exclusive;
- public long exclusiveExpireDaysInMillis;
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java
deleted file mode 100644
index a890920..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.settingslib.suggestions;
-
-import android.content.Intent;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-
-import com.android.settingslib.drawer.Tile;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class SuggestionList {
- // Category -> list of suggestion map
- private final Map<SuggestionCategory, List<Tile>> mSuggestions;
-
- // A flatten list of all suggestions.
- private List<Tile> mSuggestionList;
-
- public SuggestionList() {
- mSuggestions = new ArrayMap<>();
- }
-
- public void addSuggestions(SuggestionCategory category, List<Tile> suggestions) {
- mSuggestions.put(category, suggestions);
- }
-
- public List<Tile> getSuggestions() {
- if (mSuggestionList != null) {
- return mSuggestionList;
- }
- mSuggestionList = new ArrayList<>();
- for (List<Tile> suggestions : mSuggestions.values()) {
- mSuggestionList.addAll(suggestions);
- }
- dedupeSuggestions(mSuggestionList);
- return mSuggestionList;
- }
-
- public boolean isExclusiveSuggestionCategory() {
- if (mSuggestions.size() != 1) {
- // If there is no category, or more than 1 category, it's not exclusive by definition.
- return false;
- }
- for (SuggestionCategory category : mSuggestions.keySet()) {
- if (category.exclusive) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Filter suggestions list so they are all unique.
- */
- private void dedupeSuggestions(List<Tile> suggestions) {
- final Set<String> intents = new ArraySet<>();
- for (int i = suggestions.size() - 1; i >= 0; i--) {
- final Tile suggestion = suggestions.get(i);
- final String intentUri = suggestion.intent.toUri(Intent.URI_INTENT_SCHEME);
- if (intents.contains(intentUri)) {
- suggestions.remove(i);
- } else {
- intents.add(intentUri);
- }
- }
- }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
deleted file mode 100644
index 8705c98..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.settingslib.suggestions;
-
-import android.Manifest;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.annotation.RequiresPermission;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Xml;
-import android.view.InflateException;
-
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class SuggestionParser {
-
- private static final String TAG = "SuggestionParser";
-
- // If defined, only returns this suggestion if the feature is supported.
- public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
-
- // If defined, only display this optional step if an account of that type exists.
- private static final String META_DATA_REQUIRE_ACCOUNT = "com.android.settings.require_account";
-
- // If defined and not true, do not should optional step.
- private static final String META_DATA_IS_SUPPORTED = "com.android.settings.is_supported";
-
- // If defined, only display this optional step if the current user is of that type.
- private static final String META_DATA_REQUIRE_USER_TYPE =
- "com.android.settings.require_user_type";
-
- // If defined, only display this optional step if a connection is available.
- private static final String META_DATA_IS_CONNECTION_REQUIRED =
- "com.android.settings.require_connection";
-
- // The valid values that setup wizard recognizes for differentiating user types.
- private static final String META_DATA_PRIMARY_USER_TYPE_VALUE = "primary";
- private static final String META_DATA_ADMIN_USER_TYPE_VALUE = "admin";
- private static final String META_DATA_GUEST_USER_TYPE_VALUE = "guest";
- private static final String META_DATA_RESTRICTED_USER_TYPE_VALUE = "restricted";
-
- /**
- * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
- * For instance:
- * 0,10
- * Will appear immediately, but if the user removes it, it will come back after 10 days.
- *
- * Another example:
- * 10,30
- * Will only show up after 10 days, and then again after 30.
- */
- public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
-
- // Shared prefs keys for storing dismissed state.
- // Index into current dismissed state.
- public static final String SETUP_TIME = "_setup_time";
- private static final String IS_DISMISSED = "_is_dismissed";
-
- // Default dismiss control for smart suggestions.
- private static final String DEFAULT_SMART_DISMISS_CONTROL = "0";
-
- private final Context mContext;
- private final List<SuggestionCategory> mSuggestionList;
- private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
- private final SharedPreferences mSharedPrefs;
- private final String mDefaultDismissControl;
-
- public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml,
- String defaultDismissControl) {
- this(
- context,
- sharedPrefs,
- (List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml),
- defaultDismissControl);
- }
-
- public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
- this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
- }
-
- @VisibleForTesting
- public SuggestionParser(
- Context context,
- SharedPreferences sharedPrefs,
- List<SuggestionCategory> suggestionList,
- String defaultDismissControl) {
- mContext = context;
- mSuggestionList = suggestionList;
- mSharedPrefs = sharedPrefs;
- mDefaultDismissControl = defaultDismissControl;
- }
-
- public SuggestionList getSuggestions(boolean isSmartSuggestionEnabled) {
- final SuggestionList suggestionList = new SuggestionList();
- final int N = mSuggestionList.size();
- for (int i = 0; i < N; i++) {
- final SuggestionCategory category = mSuggestionList.get(i);
- if (category.exclusive && !isExclusiveCategoryExpired(category)) {
- // If suggestions from an exclusive category are present, parsing is stopped
- // and only suggestions from that category are displayed. Note that subsequent
- // exclusive categories are also ignored.
- final List<Tile> exclusiveSuggestions = new ArrayList<>();
-
- // Read suggestion and force isSmartSuggestion to be false so the rule defined
- // from each suggestion itself is used.
- readSuggestions(category, exclusiveSuggestions, false /* isSmartSuggestion */);
- if (!exclusiveSuggestions.isEmpty()) {
- final SuggestionList exclusiveList = new SuggestionList();
- exclusiveList.addSuggestions(category, exclusiveSuggestions);
- return exclusiveList;
- }
- } else {
- // Either the category is not exclusive, or the exclusiveness expired so we should
- // treat it as a normal category.
- final List<Tile> suggestions = new ArrayList<>();
- readSuggestions(category, suggestions, isSmartSuggestionEnabled);
- suggestionList.addSuggestions(category, suggestions);
- }
- }
- return suggestionList;
- }
-
- /**
- * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
- * be disabled.
- */
- public boolean dismissSuggestion(Tile suggestion) {
- final String keyBase = suggestion.intent.getComponent().flattenToShortString();
- mSharedPrefs.edit()
- .putBoolean(keyBase + IS_DISMISSED, true)
- .commit();
- return true;
- }
-
- @VisibleForTesting
- public void filterSuggestions(
- List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
- for (int i = countBefore; i < suggestions.size(); i++) {
- if (!isAvailable(suggestions.get(i)) ||
- !isSupported(suggestions.get(i)) ||
- !satisifesRequiredUserType(suggestions.get(i)) ||
- !satisfiesRequiredAccount(suggestions.get(i)) ||
- !satisfiesConnectivity(suggestions.get(i)) ||
- isDismissed(suggestions.get(i), isSmartSuggestionEnabled)) {
- suggestions.remove(i--);
- }
- }
- }
-
- @VisibleForTesting
- void readSuggestions(
- SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
- int countBefore = suggestions.size();
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(category.category);
- if (category.pkg != null) {
- intent.setPackage(category.pkg);
- }
- TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
- mAddCache, null, suggestions, true, false, false, true /* shouldUpdateTiles */);
- filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
- if (!category.multiple && suggestions.size() > (countBefore + 1)) {
- // If there are too many, remove them all and only re-add the one with the highest
- // priority.
- Tile item = suggestions.remove(suggestions.size() - 1);
- while (suggestions.size() > countBefore) {
- Tile last = suggestions.remove(suggestions.size() - 1);
- if (last.priority > item.priority) {
- item = last;
- }
- }
- // If category is marked as done, do not add any item.
- if (!isCategoryDone(category.category)) {
- suggestions.add(item);
- }
- }
- }
-
- private boolean isAvailable(Tile suggestion) {
- final String featuresRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
- if (featuresRequired != null) {
- for (String feature : featuresRequired.split(",")) {
- if (TextUtils.isEmpty(feature)) {
- Log.w(TAG, "Found empty substring when parsing required features: "
- + featuresRequired);
- } else if (!mContext.getPackageManager().hasSystemFeature(feature)) {
- Log.i(TAG, suggestion.title + " requires unavailable feature " + feature);
- return false;
- }
- }
- }
- return true;
- }
-
- @RequiresPermission(Manifest.permission.MANAGE_USERS)
- private boolean satisifesRequiredUserType(Tile suggestion) {
- final String requiredUser = suggestion.metaData.getString(META_DATA_REQUIRE_USER_TYPE);
- if (requiredUser != null) {
- final UserManager userManager = mContext.getSystemService(UserManager.class);
- UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
- for (String userType : requiredUser.split("\\|")) {
- final boolean primaryUserCondtionMet = userInfo.isPrimary()
- && META_DATA_PRIMARY_USER_TYPE_VALUE.equals(userType);
- final boolean adminUserConditionMet = userInfo.isAdmin()
- && META_DATA_ADMIN_USER_TYPE_VALUE.equals(userType);
- final boolean guestUserCondtionMet = userInfo.isGuest()
- && META_DATA_GUEST_USER_TYPE_VALUE.equals(userType);
- final boolean restrictedUserCondtionMet = userInfo.isRestricted()
- && META_DATA_RESTRICTED_USER_TYPE_VALUE.equals(userType);
- if (primaryUserCondtionMet || adminUserConditionMet || guestUserCondtionMet
- || restrictedUserCondtionMet) {
- return true;
- }
- }
- Log.i(TAG, suggestion.title + " requires user type " + requiredUser);
- return false;
- }
- return true;
- }
-
- public boolean satisfiesRequiredAccount(Tile suggestion) {
- final String requiredAccountType = suggestion.metaData.getString(META_DATA_REQUIRE_ACCOUNT);
- if (requiredAccountType == null) {
- return true;
- }
- AccountManager accountManager = mContext.getSystemService(AccountManager.class);
- Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
- boolean satisfiesRequiredAccount = accounts.length > 0;
- if (!satisfiesRequiredAccount) {
- Log.i(TAG, suggestion.title + " requires unavailable account type "
- + requiredAccountType);
- }
- return satisfiesRequiredAccount;
- }
-
- public boolean isSupported(Tile suggestion) {
- final int isSupportedResource = suggestion.metaData.getInt(META_DATA_IS_SUPPORTED);
- try {
- if (suggestion.intent == null) {
- return false;
- }
- final Resources res = mContext.getPackageManager().getResourcesForActivity(
- suggestion.intent.getComponent());
- boolean isSupported =
- isSupportedResource != 0 ? res.getBoolean(isSupportedResource) : true;
- if (!isSupported) {
- Log.i(TAG, suggestion.title + " requires unsupported resource "
- + isSupportedResource);
- }
- return isSupported;
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent());
- return false;
- } catch (Resources.NotFoundException e) {
- Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent(), e);
- return false;
- }
- }
-
- private boolean satisfiesConnectivity(Tile suggestion) {
- final boolean isConnectionRequired =
- suggestion.metaData.getBoolean(META_DATA_IS_CONNECTION_REQUIRED);
- if (!isConnectionRequired) {
- return true;
- }
- ConnectivityManager cm =
- (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo netInfo = cm.getActiveNetworkInfo();
- boolean satisfiesConnectivity = netInfo != null && netInfo.isConnectedOrConnecting();
- if (!satisfiesConnectivity) {
- Log.i(TAG, suggestion.title + " is missing required connection.");
- }
- return satisfiesConnectivity;
- }
-
- public boolean isCategoryDone(String category) {
- String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
- return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
- }
-
- public void markCategoryDone(String category) {
- String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
- Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
- }
-
- /**
- * Whether or not the category's exclusiveness has expired.
- */
- private boolean isExclusiveCategoryExpired(SuggestionCategory category) {
- final String keySetupTime = category.category + SETUP_TIME;
- final long currentTime = System.currentTimeMillis();
- if (!mSharedPrefs.contains(keySetupTime)) {
- mSharedPrefs.edit()
- .putLong(keySetupTime, currentTime)
- .commit();
- }
- if (category.exclusiveExpireDaysInMillis < 0) {
- // negative means never expires
- return false;
- }
- final long setupTime = mSharedPrefs.getLong(keySetupTime, 0);
- final long elapsedTime = currentTime - setupTime;
- Log.d(TAG, "Day " + elapsedTime / DateUtils.DAY_IN_MILLIS + " for " + category.category);
- return elapsedTime > category.exclusiveExpireDaysInMillis;
- }
-
- @VisibleForTesting
- boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
- String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
- String keyBase = suggestion.intent.getComponent().flattenToShortString();
- if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
- mSharedPrefs.edit()
- .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
- .commit();
- }
- // Check if it's already manually dismissed
- final boolean isDismissed = mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, false);
- if (isDismissed) {
- return true;
- }
- if (dismissControl == null) {
- return false;
- }
- // Parse when suggestion should first appear. return true to artificially hide suggestion
- // before then.
- int firstAppearDay = parseDismissString(dismissControl);
- long firstAppearDayInMs = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0),
- firstAppearDay);
- if (System.currentTimeMillis() >= firstAppearDayInMs) {
- // Dismiss timeout has passed, undismiss it.
- mSharedPrefs.edit()
- .putBoolean(keyBase + IS_DISMISSED, false)
- .commit();
- return false;
- }
- return true;
- }
-
- private long getEndTime(long startTime, int daysDelay) {
- long days = daysDelay * DateUtils.DAY_IN_MILLIS;
- return startTime + days;
- }
-
- /**
- * Parse the first int from a string formatted as "0,1,2..."
- * The value means suggestion should first appear on Day X.
- */
- private int parseDismissString(String dismissControl) {
- final String[] dismissStrs = dismissControl.split(",");
- return Integer.parseInt(dismissStrs[0]);
- }
-
- private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
- if (isSmartSuggestionEnabled) {
- return mDefaultDismissControl;
- } else {
- return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
- }
- }
-
- private static class SuggestionOrderInflater {
- private static final String TAG_LIST = "optional-steps";
- private static final String TAG_ITEM = "step";
-
- private static final String ATTR_CATEGORY = "category";
- private static final String ATTR_PACKAGE = "package";
- private static final String ATTR_MULTIPLE = "multiple";
- private static final String ATTR_EXCLUSIVE = "exclusive";
- private static final String ATTR_EXCLUSIVE_EXPIRE_DAYS = "exclusiveExpireDays";
-
- private final Context mContext;
-
- public SuggestionOrderInflater(Context context) {
- mContext = context;
- }
-
- public Object parse(int resource) {
- XmlPullParser parser = mContext.getResources().getXml(resource);
- final AttributeSet attrs = Xml.asAttributeSet(parser);
- try {
- // Look for the root node.
- int type;
- do {
- type = parser.next();
- } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
-
- if (type != XmlPullParser.START_TAG) {
- throw new InflateException(parser.getPositionDescription()
- + ": No start tag found!");
- }
-
- // Temp is the root that was found in the xml
- Object xmlRoot = onCreateItem(parser.getName(), attrs);
-
- // Inflate all children under temp
- rParse(parser, xmlRoot, attrs);
- return xmlRoot;
- } catch (XmlPullParserException | IOException e) {
- Log.w(TAG, "Problem parser resource " + resource, e);
- return null;
- }
- }
-
- /**
- * Recursive method used to descend down the xml hierarchy and instantiate
- * items, instantiate their children.
- */
- private void rParse(XmlPullParser parser, Object parent, final AttributeSet attrs)
- throws XmlPullParserException, IOException {
- final int depth = parser.getDepth();
-
- int type;
- while (((type = parser.next()) != XmlPullParser.END_TAG ||
- parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- final String name = parser.getName();
-
- Object item = onCreateItem(name, attrs);
- onAddChildItem(parent, item);
- rParse(parser, item, attrs);
- }
- }
-
- protected void onAddChildItem(Object parent, Object child) {
- if (parent instanceof List<?> && child instanceof SuggestionCategory) {
- ((List<SuggestionCategory>) parent).add((SuggestionCategory) child);
- } else {
- throw new IllegalArgumentException("Parent was not a list");
- }
- }
-
- protected Object onCreateItem(String name, AttributeSet attrs) {
- if (name.equals(TAG_LIST)) {
- return new ArrayList<SuggestionCategory>();
- } else if (name.equals(TAG_ITEM)) {
- SuggestionCategory category = new SuggestionCategory();
- category.category = attrs.getAttributeValue(null, ATTR_CATEGORY);
- category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
- String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
- category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
- String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE);
- category.exclusive =
- !TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive);
- String expireDaysAttr = attrs.getAttributeValue(null,
- ATTR_EXCLUSIVE_EXPIRE_DAYS);
- long expireDays = !TextUtils.isEmpty(expireDaysAttr)
- ? Integer.parseInt(expireDaysAttr)
- : -1;
- category.exclusiveExpireDaysInMillis = DateUtils.DAY_IN_MILLIS * expireDays;
- return category;
- } else {
- throw new IllegalArgumentException("Unknown item " + name);
- }
- }
- }
-}
-
diff --git a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
deleted file mode 100644
index f02ac15..0000000
--- a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<optional-steps>
- <step category="com.android.settings.suggested.category.DEFERRED_SETUP"
- exclusive="true" />
- <step category="com.android.settings.suggested.category.LOCK_SCREEN" />
- <step category="com.android.settings.suggested.category.TRUST_AGENT" />
- <step category="com.android.settings.suggested.category.EMAIL" />
- <step category="com.android.settings.suggested.category.PARTNER_ACCOUNT"
- multiple="true" />
- <step category="com.android.settings.suggested.category.GESTURE" />
- <step category="com.android.settings.suggested.category.HOTWORD" />
- <step category="com.android.settings.suggested.category.DEFAULT"
- multiple="true" />
- <step category="com.android.settings.suggested.category.SETTINGS_ONLY"
- multiple="true" />
-</optional-steps>
diff --git a/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java b/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java
deleted file mode 100644
index 14b0d59..0000000
--- a/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 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.bluetooth;
-
-/**
- * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility.
- */
-public class BluetoothCodecConfig {
- public boolean isMandatoryCodec() { return true; }
- public String getCodecName() { return null; }
- public int getCodecType() { return -1; }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecStatus.java b/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecStatus.java
deleted file mode 100644
index 919ec3f..0000000
--- a/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecStatus.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.bluetooth;
-
-/**
- * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility.
- */
-public class BluetoothCodecStatus {
- public BluetoothCodecConfig getCodecConfig() { return null; }
- public BluetoothCodecConfig[] getCodecsSelectableCapabilities() { return null; }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java
new file mode 100644
index 0000000..152d024
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/accessibility/AccessibilityUtilsTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 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 com.android.settingslib.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class AccessibilityUtilsTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ }
+
+ @Test
+ public void getEnabledServicesFromSettings_noService_emptyResult() {
+ assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext)).isEmpty();
+ }
+
+ @Test
+ public void getEnabledServicesFromSettings_badFormat_emptyResult() {
+ Settings.Secure.putStringForUser(
+ mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ ":",
+ UserHandle.myUserId());
+
+ assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext)).isEmpty();
+ }
+
+ @Test
+ public void getEnabledServicesFromSettings_1Service_1result() {
+ final ComponentName cn = new ComponentName("pkg", "serv");
+ Settings.Secure.putStringForUser(
+ mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ cn.flattenToString() + ":",
+ UserHandle.myUserId());
+
+ assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext))
+ .containsExactly(cn);
+ }
+
+ @Test
+ public void getEnabledServicesFromSettings_2Services_2results() {
+ final ComponentName cn1 = new ComponentName("pkg", "serv");
+ final ComponentName cn2 = new ComponentName("pkg", "serv2");
+ Settings.Secure.putStringForUser(
+ mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ cn1.flattenToString() + ":" + cn2.flattenToString(),
+ UserHandle.myUserId());
+
+ assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext))
+ .containsExactly(cn1, cn2);
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index fc1b2238..6e66805 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -28,7 +28,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
-import static org.robolectric.shadow.api.Shadow.extract;
import android.app.ActivityManager;
import android.content.ContentResolver;
@@ -52,9 +51,6 @@
import android.util.Pair;
import android.widget.RemoteViews;
-import com.android.settingslib.R;
-import com.android.settingslib.suggestions.SuggestionParser;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -67,7 +63,6 @@
import org.robolectric.annotation.Implements;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -164,35 +159,6 @@
}
@Test
- public void getTilesForIntent_shouldSkipFilteredApps() {
- Intent intent = new Intent();
- Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
- List<Tile> outTiles = new ArrayList<>();
- List<ResolveInfo> info = new ArrayList<>();
- ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
- URI_GET_SUMMARY);
- addMetadataToInfo(resolveInfo, "com.android.settings.require_account", "com.google");
- addMetadataToInfo(resolveInfo, "com.android.settings.require_connection", "true");
- info.add(resolveInfo);
-
- when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
- .thenReturn(info);
-
- TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
- null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */, true /* forceTintExternalIcon */);
-
- assertThat(outTiles.size()).isEqualTo(1);
- SuggestionParser parser = new SuggestionParser(
- mContext,
- null,
- Collections.emptyList(),
- "0,10");
- parser.filterSuggestions(outTiles, 0, false);
- assertThat(outTiles.size()).isEqualTo(0);
- }
-
- @Test
public void getCategories_shouldHandleExtraIntentAction() {
final String testCategory = "category1";
final String testAction = "action1";
@@ -392,108 +358,6 @@
assertThat(outTiles.size()).isEqualTo(1);
}
- @Test
- public void getTilesForIntent_shouldShowRemoteViewIfSpecified() {
- Intent intent = new Intent();
- Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
- List<Tile> outTiles = new ArrayList<>();
- List<ResolveInfo> info = new ArrayList<>();
- ResolveInfo resolveInfo = newInfo(true, null /* category */);
- resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
- R.layout.user_preference);
- info.add(resolveInfo);
-
- when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
- .thenReturn(info);
-
- TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
- null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */, true /* forceTintExternalIcon */);
-
- assertThat(outTiles.size()).isEqualTo(1);
- Tile tile = outTiles.get(0);
- assertThat(tile.remoteViews).isNotNull();
- assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
- }
-
- @Test
- public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
- throws RemoteException {
- Intent intent = new Intent();
- Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
- List<Tile> outTiles = new ArrayList<>();
- List<ResolveInfo> info = new ArrayList<>();
- ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
- null, URI_GET_SUMMARY);
- resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
- R.layout.user_preference);
- info.add(resolveInfo);
-
- when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
- .thenReturn(info);
-
- // Mock the content provider interaction.
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
- when(mIContentProvider.call(anyString(),
- eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
- any())).thenReturn(bundle);
- when(mContentResolver.acquireUnstableProvider(anyString()))
- .thenReturn(mIContentProvider);
- when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
- .thenReturn(mIContentProvider);
-
- TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
- null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */, true /* forceTintExternalIcon */);
-
- assertThat(outTiles.size()).isEqualTo(1);
- Tile tile = outTiles.get(0);
- assertThat(tile.remoteViews).isNotNull();
- assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
- // Make sure the summary TextView got a new text string.
- TileUtilsShadowRemoteViews shadowRemoteViews = extract(tile.remoteViews);
- assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
- assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
- }
-
- @Test
- public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
- throws RemoteException {
- Intent intent = new Intent();
- Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
- List<Tile> outTiles = new ArrayList<>();
- List<ResolveInfo> info = new ArrayList<>();
- ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
- null, URI_GET_SUMMARY);
- resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
- R.layout.user_preference);
- info.add(resolveInfo);
-
- when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
- .thenReturn(info);
-
- // Mock the content provider interaction.
- Bundle bundle = new Bundle();
- bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
- when(mIContentProvider.call(anyString(),
- eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
- any())).thenReturn(bundle);
-
- TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
- null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */, true /* forceTintExternalIcon */);
-
- assertThat(outTiles.size()).isEqualTo(1);
- Tile tile = outTiles.get(0);
- assertThat(tile.remoteViews).isNotNull();
- assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
- // Make sure the summary TextView didn't get any text view updates.
- TileUtilsShadowRemoteViews shadowRemoteViews = extract(tile.remoteViews);
- assertThat(shadowRemoteViews.overrideViewId).isNull();
- assertThat(shadowRemoteViews.overrideText).isNull();
- }
-
public static ResolveInfo newInfo(boolean systemApp, String category) {
return newInfo(systemApp, category, null);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
deleted file mode 100644
index d05bcfd..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.settingslib.suggestions;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.robolectric.RuntimeEnvironment.application;
-import static org.robolectric.shadow.api.Shadow.extract;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-
-import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtilsTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.shadows.ShadowPackageManager;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(SettingsLibRobolectricTestRunner.class)
-public class SuggestionParserTest {
-
- private ShadowPackageManager mPackageManager;
- private SuggestionParser mSuggestionParser;
- private SuggestionCategory mMultipleCategory;
- private SuggestionCategory mExclusiveCategory;
- private SuggestionCategory mExpiredExclusiveCategory;
- private List<Tile> mSuggestionsBeforeDismiss;
- private List<Tile> mSuggestionsAfterDismiss;
- private SharedPreferences mPrefs;
- private Tile mSuggestion;
-
- @Before
- public void setUp() {
- mPackageManager = extract(application.getPackageManager());
- mPrefs = PreferenceManager.getDefaultSharedPreferences(application);
- mSuggestion = new Tile();
- mSuggestion.intent = new Intent("action");
- mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
- mSuggestion.metaData = new Bundle();
- mMultipleCategory = new SuggestionCategory();
- mMultipleCategory.category = "category1";
- mMultipleCategory.multiple = true;
- mExclusiveCategory = new SuggestionCategory();
- mExclusiveCategory.category = "category2";
- mExclusiveCategory.exclusive = true;
- mExpiredExclusiveCategory = new SuggestionCategory();
- mExpiredExclusiveCategory.category = "category3";
- mExpiredExclusiveCategory.exclusive = true;
- mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0;
-
- mSuggestionParser = new SuggestionParser(application, mPrefs,
- Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
- "0");
-
- ResolveInfo info1 = TileUtilsTest.newInfo(true, null);
- info1.activityInfo.packageName = "pkg";
- ResolveInfo infoDupe1 = TileUtilsTest.newInfo(true, null);
- infoDupe1.activityInfo.packageName = "pkg";
-
- ResolveInfo info2 = TileUtilsTest.newInfo(true, null);
- info2.activityInfo.packageName = "pkg2";
- ResolveInfo info3 = TileUtilsTest.newInfo(true, null);
- info3.activityInfo.packageName = "pkg3";
- ResolveInfo info4 = TileUtilsTest.newInfo(true, null);
- info4.activityInfo.packageName = "pkg4";
-
- Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
- Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
- Intent intent3 = new Intent(Intent.ACTION_MAIN).addCategory("category3");
-
- mPackageManager.addResolveInfoForIntent(intent1, info1);
- mPackageManager.addResolveInfoForIntent(intent1, info2);
- mPackageManager.addResolveInfoForIntent(intent1, infoDupe1);
- mPackageManager.addResolveInfoForIntent(intent2, info3);
- mPackageManager.addResolveInfoForIntent(intent3, info4);
- }
-
- @Test
- public void dismissSuggestion_shouldDismiss() {
- assertThat(mSuggestionParser.dismissSuggestion(mSuggestion)).isTrue();
- }
-
- @Test
- public void testGetSuggestions_withoutSmartSuggestions_shouldDismiss() {
- readAndDismissSuggestion(false);
- mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
- assertThat(mSuggestionsBeforeDismiss).hasSize(2);
- assertThat(mSuggestionsAfterDismiss).hasSize(1);
- assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
- }
-
- @Test
- public void testGetSuggestions_withSmartSuggestions_shouldDismiss() {
- readAndDismissSuggestion(true);
- assertThat(mSuggestionsBeforeDismiss).hasSize(2);
- assertThat(mSuggestionsAfterDismiss).hasSize(1);
- }
-
- @Test
- public void testGetSuggestion_exclusiveNotAvailable_onlyRegularCategoryAndNoDupe() {
- mPackageManager.removeResolveInfosForIntent(
- new Intent(Intent.ACTION_MAIN).addCategory("category2"),
- "pkg3");
- mPackageManager.removeResolveInfosForIntent(
- new Intent(Intent.ACTION_MAIN).addCategory("category3"),
- "pkg4");
-
- // If exclusive item is not available, the other categories should be shown
- final SuggestionList sl =
- mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
- final List<Tile> suggestions = sl.getSuggestions();
- assertThat(suggestions).hasSize(2);
-
- assertThat(suggestions.get(0).intent.getComponent().getPackageName()).isEqualTo("pkg");
- assertThat(suggestions.get(1).intent.getComponent().getPackageName()).isEqualTo("pkg2");
- }
-
- @Test
- public void testGetSuggestion_exclusiveExpiredAvailable_shouldLoadWithRegularCategory() {
- // First remove permanent exclusive
- mPackageManager.removeResolveInfosForIntent(
- new Intent(Intent.ACTION_MAIN).addCategory("category2"),
- "pkg3");
- // Set the other exclusive to be expired.
- mPrefs.edit()
- .putLong(mExpiredExclusiveCategory.category + "_setup_time",
- System.currentTimeMillis() - 1000)
- .commit();
-
- // If exclusive is expired, they should be shown together with the other categories
- final SuggestionList sl =
- mSuggestionParser.getSuggestions(true /* isSmartSuggestionEnabled */);
- final List<Tile> suggestions = sl.getSuggestions();
-
- assertThat(suggestions).hasSize(3);
- }
-
- @Test
- public void testGetSuggestions_exclusive() {
- final SuggestionList sl =
- mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
- final List<Tile> suggestions = sl.getSuggestions();
-
- assertThat(suggestions).hasSize(1);
- }
-
- @Test
- public void isSuggestionDismissed_dismissedSuggestion_shouldReturnTrue() {
- final Tile suggestion = new Tile();
- suggestion.metaData = new Bundle();
- suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3");
- suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
-
- // Dismiss suggestion when smart suggestion is not enabled.
- mSuggestionParser.dismissSuggestion(suggestion);
-
- assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */))
- .isTrue();
- }
-
- private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
- mSuggestionsBeforeDismiss = new ArrayList<>();
- mSuggestionsAfterDismiss = new ArrayList<>();
- mSuggestionParser.readSuggestions(
- mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
-
- final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
- if (mSuggestionParser.dismissSuggestion(suggestion)) {
- mPackageManager.removeResolveInfosForIntent(
- new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category),
- suggestion.intent.getComponent().getPackageName());
- }
- mSuggestionParser.readSuggestions(
- mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
- }
-}
diff --git a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
index 8b56b68..42d541e3 100644
--- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
@@ -58,6 +58,7 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
+ android:paddingStart="2.5dp"
android:paddingEnd="1dp"
android:visibility="gone" />
<Space
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index de69c6b..eed1df0 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -55,7 +55,7 @@
<dimen name="status_bar_left_clock_end_padding">7dp</dimen>
<!-- Spacing after the wifi signals that is present if there are any icons following it. -->
- <dimen name="status_bar_wifi_signal_spacer_width">4dp</dimen>
+ <dimen name="status_bar_wifi_signal_spacer_width">2.5dp</dimen>
<!-- Spacing before the airplane mode icon if there are any icons preceding it. -->
<dimen name="status_bar_airplane_spacer_width">4dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 4e060f6..d5d96fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -73,6 +73,7 @@
private ArraySet<View> mVisibleInDoze;
private boolean mPulsing;
+ private boolean mWasPulsing;
private float mDarkAmount = 0;
private int mTextColor;
private float mWidgetPadding;
@@ -224,7 +225,8 @@
boolean hasHeader = mKeyguardSlice.hasHeader();
boolean smallClock = hasHeader || mPulsing;
long duration = KeyguardSliceView.DEFAULT_ANIM_DURATION;
- long delay = smallClock ? 0 : duration / 4;
+ long delay = smallClock || mWasPulsing ? 0 : duration / 4;
+ mWasPulsing = false;
boolean shouldAnimate = mKeyguardSlice.getLayoutTransition() != null
&& mKeyguardSlice.getLayoutTransition().isRunning();
@@ -448,6 +450,12 @@
}
public void setPulsing(boolean pulsing, boolean animate) {
+ if (mPulsing == pulsing) {
+ return;
+ }
+ if (mPulsing) {
+ mWasPulsing = true;
+ }
mPulsing = pulsing;
mKeyguardSlice.setPulsing(pulsing, animate);
updateDozeVisibleViews();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index d9a1b11..075faa1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1590,6 +1590,10 @@
}
}
+ public boolean isKeyguardVisible() {
+ return mKeyguardIsVisible;
+ }
+
/**
* Notifies that the visibility state of Keyguard has changed.
*
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 9a43d9e..3c8a461d 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
-import android.os.Trace;
import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
@@ -46,7 +45,7 @@
public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
private static final String TAG = "SysuiColorExtractor";
private boolean mWallpaperVisible;
- private boolean mMediaBackdropVisible;
+ private boolean mHasBackdrop;
// Colors to return when the wallpaper isn't visible
private final GradientColors mWpHiddenColors;
@@ -165,7 +164,7 @@
return mWpHiddenColors;
}
} else {
- if (mMediaBackdropVisible) {
+ if (mHasBackdrop) {
return mWpHiddenColors;
} else {
return super.getColors(which, type);
@@ -181,9 +180,9 @@
}
}
- public void setMediaBackdropVisible(boolean visible) {
- if (mMediaBackdropVisible != visible) {
- mMediaBackdropVisible = visible;
+ public void setHasBackdrop(boolean hasBackdrop) {
+ if (mHasBackdrop != hasBackdrop) {
+ mHasBackdrop = hasBackdrop;
triggerColorsChanged(WallpaperManager.FLAG_LOCK);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index af88911..83db6aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -37,6 +37,7 @@
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
+import android.os.SystemClock;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
@@ -108,6 +109,7 @@
private static final int COLORED_DIVIDER_ALPHA = 0x7B;
private static final int MENU_VIEW_INDEX = 0;
private static final String TAG = "ExpandableNotifRow";
+ public static final float DEFAULT_HEADER_VISIBLE_AMOUNT = 1.0f;
/**
* Listener for when {@link ExpandableNotificationRow} is laid out.
@@ -157,7 +159,7 @@
private boolean mSensitiveHiddenInGeneral;
private boolean mShowingPublicInitialized;
private boolean mHideSensitiveForIntrinsicHeight;
- private float mHeaderVisibleAmount = 1.0f;
+ private float mHeaderVisibleAmount = DEFAULT_HEADER_VISIBLE_AMOUNT;
/**
* Is this notification expanded by the system. The expansion state can be overridden by the
@@ -992,6 +994,7 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ mEntry.setInitializationTime(SystemClock.elapsedRealtime());
Dependency.get(PluginManager.class).addPluginListener(this,
NotificationMenuRowPlugin.class, false /* Allow multiple */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
index 39485c3..ac289d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
@@ -21,6 +21,8 @@
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.Display;
import android.view.DisplayCutout;
@@ -38,6 +40,12 @@
* The view in the statusBar that contains part of the heads-up information
*/
public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
+ private static final String HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE =
+ "heads_up_status_bar_view_super_parcelable";
+ private static final String FIRST_LAYOUT = "first_layout";
+ private static final String PUBLIC_MODE = "public_mode";
+ private static final String VISIBILITY = "visibility";
+ private static final String ALPHA = "alpha";
private int mAbsoluteStartPadding;
private int mEndMargin;
private View mIconPlaceholder;
@@ -107,6 +115,39 @@
updateMaxWidth();
}
+ @Override
+ public Bundle onSaveInstanceState() {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE,
+ super.onSaveInstanceState());
+ bundle.putBoolean(FIRST_LAYOUT, mFirstLayout);
+ bundle.putBoolean(PUBLIC_MODE, mPublicMode);
+ bundle.putInt(VISIBILITY, getVisibility());
+ bundle.putFloat(ALPHA, getAlpha());
+
+ return bundle;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !(state instanceof Bundle)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ Bundle bundle = (Bundle) state;
+ Parcelable superState = bundle.getParcelable(HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE);
+ super.onRestoreInstanceState(superState);
+ mFirstLayout = bundle.getBoolean(FIRST_LAYOUT, true);
+ mPublicMode = bundle.getBoolean(PUBLIC_MODE, false);
+ if (bundle.containsKey(VISIBILITY)) {
+ setVisibility(bundle.getInt(VISIBILITY));
+ }
+ if (bundle.containsKey(ALPHA)) {
+ setAlpha(bundle.getFloat(ALPHA));
+ }
+ }
+
@VisibleForTesting
public HeadsUpStatusBarView(Context context, View iconPlaceholder, TextView textView) {
this(context);
@@ -178,11 +219,7 @@
* @param translationX how to translate the horizontal position
*/
public void setPanelTranslation(float translationX) {
- if (isLayoutRtl()) {
- setTranslationX(translationX + mCutOutInset);
- } else {
- setTranslationX(translationX - mCutOutInset);
- }
+ setTranslationX(translationX);
updateDrawingRect();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 1a645d1..a58752c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -84,6 +84,7 @@
public static final class Entry {
private static final long LAUNCH_COOLDOWN = 2000;
private static final long REMOTE_INPUT_COOLDOWN = 500;
+ private static final long INITIALIZATION_DELAY = 400;
private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN;
private static final int COLOR_INVALID = 1;
public String key;
@@ -114,6 +115,9 @@
public ArraySet<Integer> mActiveAppOps = new ArraySet<>(3);
public CharSequence headsUpStatusBarText;
public CharSequence headsUpStatusBarTextPublic;
+
+ private long initializationTime = -1;
+
/**
* Whether or not this row represents a system notification. Note that if this is
* {@code null}, that means we were either unable to retrieve the info or have yet to
@@ -169,6 +173,11 @@
return SystemClock.elapsedRealtime() < lastRemoteInputSent + REMOTE_INPUT_COOLDOWN;
}
+ public boolean hasFinishedInitialization() {
+ return initializationTime == -1 ||
+ SystemClock.elapsedRealtime() > initializationTime + INITIALIZATION_DELAY;
+ }
+
/**
* Create the icons for a notification
* @param context the context to create the icons with
@@ -341,6 +350,12 @@
}
return false;
}
+
+ public void setInitializationTime(long time) {
+ if (initializationTime == -1) {
+ initializationTime = time;
+ }
+ }
}
private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 2fc2cdb..ade27f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification;
+import static com.android.systemui.statusbar.ExpandableNotificationRow
+ .DEFAULT_HEADER_VISIBLE_AMOUNT;
import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
import android.app.Notification;
@@ -123,6 +125,9 @@
// Reinspect the notification.
resolveHeaderViews();
+ if (row.getHeaderVisibleAmount() != DEFAULT_HEADER_VISIBLE_AMOUNT) {
+ setHeaderVisibleAmount(row.getHeaderVisibleAmount());
+ }
updateTransformedTypes();
addRemainingTransformTypes();
updateCropToPaddingForImageViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index f7b7eeb..ea70ebb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -22,6 +22,8 @@
import android.app.Fragment;
import android.app.StatusBarManager;
import android.os.Bundle;
+import android.os.Parcelable;
+import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -89,7 +91,8 @@
super.onViewCreated(view, savedInstanceState);
mStatusBar = (PhoneStatusBarView) view;
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {
- mStatusBar.go(savedInstanceState.getInt(EXTRA_PANEL_STATE));
+ mStatusBar.restoreHierarchyState(
+ savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
}
mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
mDarkIconManager.setShouldLog(true);
@@ -105,7 +108,9 @@
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- outState.putInt(EXTRA_PANEL_STATE, mStatusBar.getState());
+ SparseArray<Parcelable> states = new SparseArray<>();
+ mStatusBar.saveHierarchyState(states);
+ outState.putSparseParcelableArray(EXTRA_PANEL_STATE, states);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 409a783..e1936fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -18,6 +18,7 @@
import android.graphics.Point;
import android.graphics.Rect;
+import android.view.DisplayCutout;
import android.view.View;
import android.view.WindowInsets;
@@ -53,9 +54,12 @@
mSetTrackingHeadsUp = this::setTrackingHeadsUp;
private final Runnable mUpdatePanelTranslation = this::updatePanelTranslation;
private final BiConsumer<Float, Float> mSetExpandedHeight = this::setExpandedHeight;
- private float mExpandedHeight;
- private boolean mIsExpanded;
- private float mExpandFraction;
+ @VisibleForTesting
+ float mExpandedHeight;
+ @VisibleForTesting
+ boolean mIsExpanded;
+ @VisibleForTesting
+ float mExpandFraction;
private ExpandableNotificationRow mTrackedChild;
private boolean mShown;
private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
@@ -99,6 +103,20 @@
mClockView = clockView;
mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
mDarkIconDispatcher.addDarkReceiver(this);
+
+ mHeadsUpStatusBarView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (shouldBeVisible()) {
+ updateTopEntry();
+
+ // trigger scroller to notify the latest panel translation
+ mStackScroller.requestLayout();
+ }
+ mHeadsUpStatusBarView.removeOnLayoutChangeListener(this);
+ }
+ });
}
@@ -159,8 +177,15 @@
}
WindowInsets windowInset = mStackScroller.getRootWindowInsets();
- return windowInset.getSystemWindowInsetLeft() + mStackScroller.getRight()
- + windowInset.getSystemWindowInsetRight() - realDisplaySize;
+ DisplayCutout cutout = (windowInset != null) ? windowInset.getDisplayCutout() : null;
+ int sysWinLeft = (windowInset != null) ? windowInset.getStableInsetLeft() : 0;
+ int sysWinRight = (windowInset != null) ? windowInset.getStableInsetRight() : 0;
+ int cutoutLeft = (cutout != null) ? cutout.getSafeInsetLeft() : 0;
+ int cutoutRight = (cutout != null) ? cutout.getSafeInsetRight() : 0;
+ int leftInset = Math.max(sysWinLeft, cutoutLeft);
+ int rightInset = Math.max(sysWinRight, cutoutRight);
+
+ return leftInset + mStackScroller.getRight() + rightInset - realDisplaySize;
}
public void updatePanelTranslation() {
@@ -293,4 +318,13 @@
mHeadsUpStatusBarView.setPublicMode(publicMode);
updateTopEntry();
}
+
+ void readFrom(HeadsUpAppearanceController oldController) {
+ if (oldController != null) {
+ mTrackedChild = oldController.mTrackedChild;
+ mExpandedHeight = oldController.mExpandedHeight;
+ mIsExpanded = oldController.mIsExpanded;
+ mExpandFraction = oldController.mExpandFraction;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 46d9827..e2f3319 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -367,10 +367,10 @@
}
}
- private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable,
+ private void startFinishingCircleAnimation(float velocity, Runnable animationEndRunnable,
boolean right) {
KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
- targetView.finishAnimation(velocity, mAnimationEndRunnable);
+ targetView.finishAnimation(velocity, animationEndRunnable);
}
private void setTranslation(float translation, boolean isReset, boolean animateReset) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 3ad207a..165b9b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2738,13 +2738,14 @@
public void setPulsing(boolean pulsing) {
mPulsing = pulsing;
- final boolean canAnimatePulse =
- !DozeParameters.getInstance(mContext).getDisplayNeedsBlanking();
- if (canAnimatePulse) {
+ DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
+ final boolean animatePulse = !dozeParameters.getDisplayNeedsBlanking()
+ && dozeParameters.getAlwaysOn();
+ if (animatePulse) {
mAnimateNextPositionUpdate = true;
}
- mNotificationStackScroller.setPulsing(pulsing, canAnimatePulse);
- mKeyguardStatusView.setPulsing(pulsing, canAnimatePulse);
+ mNotificationStackScroller.setPulsing(pulsing, animatePulse);
+ mKeyguardStatusView.setPulsing(pulsing, animatePulse);
}
public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index c4d7e72..18bc4e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -17,6 +17,8 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.os.Bundle;
+import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -27,6 +29,8 @@
public static final boolean DEBUG = false;
public static final String TAG = PanelBar.class.getSimpleName();
private static final boolean SPEW = false;
+ private static final String PANEL_BAR_SUPER_PARCELABLE = "panel_bar_super_parcelable";
+ private static final String STATE = "state";
private boolean mBouncerShowing;
private boolean mExpanded;
@@ -48,8 +52,26 @@
mState = state;
}
- public int getState() {
- return mState;
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(PANEL_BAR_SUPER_PARCELABLE, super.onSaveInstanceState());
+ bundle.putInt(STATE, mState);
+ return bundle;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !(state instanceof Bundle)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ Bundle bundle = (Bundle) state;
+ super.onRestoreInstanceState(bundle.getParcelable(PANEL_BAR_SUPER_PARCELABLE));
+ if (((Bundle) state).containsKey(STATE)) {
+ go(bundle.getInt(STATE, STATE_CLOSED));
+ }
}
public PanelBar(Context context, AttributeSet attrs) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 5477f88..075883a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -331,30 +331,25 @@
// or letterboxing from the right or left sides.
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- if (mDisplayCutout == null) {
+ if (mDisplayCutout == null || mDisplayCutout.isEmpty()
+ || mLastOrientation != ORIENTATION_PORTRAIT || cornerCutoutMargins == null) {
lp.leftMargin = 0;
lp.rightMargin = 0;
return;
}
- lp.leftMargin = mDisplayCutout.getSafeInsetLeft();
- lp.rightMargin = mDisplayCutout.getSafeInsetRight();
+ lp.leftMargin = Math.max(lp.leftMargin, cornerCutoutMargins.first);
+ lp.rightMargin = Math.max(lp.rightMargin, cornerCutoutMargins.second);
- if (cornerCutoutMargins != null) {
- lp.leftMargin = Math.max(lp.leftMargin, cornerCutoutMargins.first);
- lp.rightMargin = Math.max(lp.rightMargin, cornerCutoutMargins.second);
-
- // If we're already inset enough (e.g. on the status bar side), we can have 0 margin
- WindowInsets insets = getRootWindowInsets();
- int leftInset = insets.getSystemWindowInsetLeft();
- int rightInset = insets.getSystemWindowInsetRight();
- if (lp.leftMargin <= leftInset) {
- lp.leftMargin = 0;
- }
- if (lp.rightMargin <= rightInset) {
- lp.rightMargin = 0;
- }
-
+ // If we're already inset enough (e.g. on the status bar side), we can have 0 margin
+ WindowInsets insets = getRootWindowInsets();
+ int leftInset = insets.getSystemWindowInsetLeft();
+ int rightInset = insets.getSystemWindowInsetRight();
+ if (lp.leftMargin <= leftInset) {
+ lp.leftMargin = 0;
+ }
+ if (lp.rightMargin <= rightInset) {
+ lp.rightMargin = 0;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index de499d6..fe141661 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -29,9 +29,7 @@
import android.os.Trace;
import android.util.Log;
import android.util.MathUtils;
-import android.view.Choreographer;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -43,12 +41,11 @@
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.function.TriConsumer;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.stack.ViewState;
import com.android.systemui.util.AlarmTimeout;
@@ -482,21 +479,13 @@
// Make sure we have the right gradients and their opacities will satisfy GAR.
if (mNeedsDrawableColorUpdate) {
mNeedsDrawableColorUpdate = false;
- final GradientColors currentScrimColors;
- if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER_SCRIMMED
- || mState == ScrimState.BOUNCER) {
- // Always animate color changes if we're seeing the keyguard
- mScrimInFront.setColors(mLockColors, true /* animated */);
- mScrimBehind.setColors(mLockColors, true /* animated */);
- currentScrimColors = mLockColors;
- } else {
- // Only animate scrim color if the scrim view is actually visible
- boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
- boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
- mScrimInFront.setColors(mSystemColors, animateScrimInFront);
- mScrimBehind.setColors(mSystemColors, animateScrimBehind);
- currentScrimColors = mSystemColors;
- }
+ boolean isKeyguard = mKeyguardUpdateMonitor.isKeyguardVisible() && !mKeyguardOccluded;
+ GradientColors currentScrimColors = isKeyguard ? mLockColors : mSystemColors;
+ // Only animate scrim color if the scrim view is actually visible
+ boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0 && !mBlankScreen;
+ boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0 && !mBlankScreen;
+ mScrimInFront.setColors(currentScrimColors, animateScrimInFront);
+ mScrimBehind.setColors(currentScrimColors, animateScrimBehind);
// Calculate minimum scrim opacity for white or black text.
int textColor = currentScrimColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
@@ -899,6 +888,13 @@
updateScrims();
}
+ public void setHasBackdrop(boolean hasBackdrop) {
+ ScrimState[] states = ScrimState.values();
+ for (int i = 0; i < states.length; i++) {
+ states[i].setHasBackdrop(hasBackdrop);
+ }
+ }
+
public interface Callback {
default void onStart() {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 713356b..ec6ada4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -20,7 +20,6 @@
import android.os.Trace;
import android.util.MathUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -106,8 +105,7 @@
public void prepare(ScrimState previousState) {
final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
mBlankScreen = mDisplayRequiresBlanking;
- mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
- && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
+ mCurrentBehindAlpha = mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f;
mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
mCurrentInFrontTint = Color.BLACK;
mCurrentBehindTint = Color.BLACK;
@@ -131,8 +129,7 @@
public void prepare(ScrimState previousState) {
mCurrentInFrontAlpha = 0;
mCurrentInFrontTint = Color.BLACK;
- mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
- && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
+ mCurrentBehindAlpha = mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f;
mCurrentBehindTint = Color.BLACK;
mBlankScreen = mDisplayRequiresBlanking;
}
@@ -178,8 +175,8 @@
DozeParameters mDozeParameters;
boolean mDisplayRequiresBlanking;
boolean mWallpaperSupportsAmbientMode;
- KeyguardUpdateMonitor mKeyguardUpdateMonitor;
int mIndex;
+ boolean mHasBackdrop;
ScrimState(int index) {
mIndex = index;
@@ -190,7 +187,6 @@
mScrimBehind = scrimBehind;
mDozeParameters = dozeParameters;
mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
- mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(scrimInFront.getContext());
}
public void prepare(ScrimState previousState) {
@@ -256,4 +252,8 @@
public boolean isLowPowerState() {
return false;
}
+
+ public void setHasBackdrop(boolean hasBackdrop) {
+ mHasBackdrop = hasBackdrop;
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a7d27c5..4e984e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -843,13 +843,27 @@
mStatusBarView.setBar(this);
mStatusBarView.setPanel(mNotificationPanel);
mStatusBarView.setScrimController(mScrimController);
+
+ // CollapsedStatusBarFragment re-inflated PhoneStatusBarView and both of
+ // mStatusBarView.mExpanded and mStatusBarView.mBouncerShowing are false.
+ // PhoneStatusBarView's new instance will set to be gone in
+ // PanelBar.updateVisibility after calling mStatusBarView.setBouncerShowing
+ // that will trigger PanelBar.updateVisibility. If there is a heads up showing,
+ // it needs to notify PhoneStatusBarView's new instance to update the correct
+ // status by calling mNotificationPanel.notifyBarPanelExpansionChanged().
+ if (mHeadsUpManager.hasPinnedHeadsUp()) {
+ mNotificationPanel.notifyBarPanelExpansionChanged();
+ }
mStatusBarView.setBouncerShowing(mBouncerShowing);
+
+ HeadsUpAppearanceController oldController = mHeadsUpAppearanceController;
if (mHeadsUpAppearanceController != null) {
// This view is being recreated, let's destroy the old one
mHeadsUpAppearanceController.destroy();
}
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow);
+ mHeadsUpAppearanceController.readFrom(oldController);
setAreThereNotifications();
checkBarModes();
}).getFragmentManager()
@@ -1656,8 +1670,12 @@
&& mStatusBarKeyguardViewManager.isOccluded();
final boolean hasArtwork = artworkDrawable != null;
+ mColorExtractor.setHasBackdrop(hasArtwork);
+ if (mScrimController != null) {
+ mScrimController.setHasBackdrop(hasArtwork);
+ }
- if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && !mDozing
+ if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
&& (mState != StatusBarState.SHADE || allowWhenShade)
&& mFingerprintUnlockController.getMode()
!= FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
@@ -1673,7 +1691,6 @@
mBackdrop.setAlpha(1f);
}
mStatusBarWindowManager.setBackdropShowing(true);
- mColorExtractor.setMediaBackdropVisible(true);
metaDataChanged = true;
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
@@ -1725,7 +1742,6 @@
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
}
- mColorExtractor.setMediaBackdropVisible(false);
boolean cannotAnimateDoze = mDozing && !ScrimState.AOD.getAnimateChange();
if (mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
@@ -3857,7 +3873,7 @@
* Switches theme from light to dark and vice-versa.
*/
protected void updateTheme() {
- final boolean inflated = mStackScroller != null;
+ final boolean inflated = mStackScroller != null && mStatusBarWindowManager != null;
// The system wallpaper defines if QS should be light or dark.
WallpaperColors systemColors = mColorExtractor
@@ -4738,10 +4754,8 @@
// Bouncer needs the front scrim when it's on top of an activity,
// tapping on a notification, editing QS or being dismissed by
// FLAG_DISMISS_KEYGUARD_ACTIVITY.
- ScrimState state = mIsOccluded || mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
- || mStatusBarKeyguardViewManager.willDismissWithAction()
- || mStatusBarKeyguardViewManager.isFullscreenBouncer() ?
- ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
+ ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
+ ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
mScrimController.transitionTo(state);
} else if (mLaunchCameraOnScreenTurningOn || isInLaunchTransition()) {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 914bba2..affc424 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -170,8 +170,7 @@
// • Full-screen user switcher is displayed.
if (mNotificationPanelView.isUnlockHintRunning()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
- } else if (mOccluded || mBouncer.willDismissWithAction() || mBouncer.isShowingScrimmed()
- || mStatusBar.isFullScreenUserSwitcherState()) {
+ } else if (bouncerNeedsScrimming()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
} else if (mShowing && !mDozing) {
if (!isWakeAndUnlocking() && !mStatusBar.isInLaunchTransition()) {
@@ -731,12 +730,9 @@
}
}
- public boolean willDismissWithAction() {
- return mBouncer.willDismissWithAction();
- }
-
public boolean bouncerNeedsScrimming() {
- return mBouncer.isShowingScrimmed();
+ return mOccluded || mBouncer.willDismissWithAction() || mBouncer.needsFullscreenBouncer()
+ || mStatusBar.isFullScreenUserSwitcherState() || mBouncer.isShowingScrimmed();
}
public void dump(PrintWriter pw) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 0390f60..237ca25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -37,6 +37,7 @@
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.ActionMode;
+import android.view.DisplayCutout;
import android.view.InputDevice;
import android.view.InputQueue;
import android.view.KeyEvent;
@@ -118,10 +119,21 @@
boolean paddingChanged = insets.top != getPaddingTop()
|| insets.bottom != getPaddingBottom();
+ int rightCutout = 0;
+ int leftCutout = 0;
+ DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
+ if (displayCutout != null) {
+ leftCutout = displayCutout.getSafeInsetLeft();
+ rightCutout = displayCutout.getSafeInsetRight();
+ }
+
+ int targetLeft = Math.max(insets.left, leftCutout);
+ int targetRight = Math.max(insets.right, rightCutout);
+
// Super-special right inset handling, because scrims and backdrop need to ignore it.
- if (insets.right != mRightInset || insets.left != mLeftInset) {
- mRightInset = insets.right;
- mLeftInset = insets.left;
+ if (targetRight != mRightInset || targetLeft != mLeftInset) {
+ mRightInset = targetRight;
+ mLeftInset = targetLeft;
applyMargins();
}
// Drop top inset, and pass through bottom inset.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 9aa8044..8517d90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -25,6 +25,7 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Parcelable;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.Spannable;
@@ -65,6 +66,12 @@
DarkReceiver, ConfigurationListener {
public static final String CLOCK_SECONDS = "clock_seconds";
+ private static final String CLOCK_SUPER_PARCELABLE = "clock_super_parcelable";
+ private static final String CURRENT_USER_ID = "current_user_id";
+ private static final String VISIBLE_BY_POLICY = "visible_by_policy";
+ private static final String VISIBLE_BY_USER = "visible_by_user";
+ private static final String SHOW_SECONDS = "show_seconds";
+ private static final String VISIBILITY = "visibility";
private final CurrentUserTracker mCurrentUserTracker;
private int mCurrentUserId;
@@ -129,6 +136,40 @@
}
@Override
+ public Parcelable onSaveInstanceState() {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(CLOCK_SUPER_PARCELABLE, super.onSaveInstanceState());
+ bundle.putInt(CURRENT_USER_ID, mCurrentUserId);
+ bundle.putBoolean(VISIBLE_BY_POLICY, mClockVisibleByPolicy);
+ bundle.putBoolean(VISIBLE_BY_USER, mClockVisibleByUser);
+ bundle.putBoolean(SHOW_SECONDS, mShowSeconds);
+ bundle.putInt(VISIBILITY, getVisibility());
+
+ return bundle;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (state == null || !(state instanceof Bundle)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ Bundle bundle = (Bundle) state;
+ Parcelable superState = bundle.getParcelable(CLOCK_SUPER_PARCELABLE);
+ super.onRestoreInstanceState(superState);
+ if (bundle.containsKey(CURRENT_USER_ID)) {
+ mCurrentUserId = bundle.getInt(CURRENT_USER_ID);
+ }
+ mClockVisibleByPolicy = bundle.getBoolean(VISIBLE_BY_POLICY, true);
+ mClockVisibleByUser = bundle.getBoolean(VISIBLE_BY_USER, true);
+ mShowSeconds = bundle.getBoolean(SHOW_SECONDS, false);
+ if (bundle.containsKey(VISIBILITY)) {
+ setVisibility(bundle.getInt(VISIBILITY));
+ }
+ }
+
+ @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index a8464b3..fd49b26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -137,6 +137,10 @@
// to look nice
customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP_CLICKED
+ StackStateAnimator.ANIMATION_DELAY_HEADS_UP;
+ } else if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
+ .ANIMATION_TYPE_PULSE_APPEAR || ev.animationType ==
+ NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_PULSE_DISAPPEAR) {
+ customDelay = StackStateAnimator.ANIMATION_DURATION_PULSE_APPEAR / 2;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 75e527c..7bed01b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2053,11 +2053,9 @@
}
private int getScrollRange() {
- int contentHeight = getContentHeight();
- int scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight);
+ int scrollRange = Math.max(0, mContentHeight - mMaxLayoutHeight);
int imeInset = getImeInset();
- scrollRange += Math.min(imeInset, Math.max(0,
- getContentHeight() - (getHeight() - imeInset)));
+ scrollRange += Math.min(imeInset, Math.max(0, mContentHeight - (getHeight() - imeInset)));
return scrollRange;
}
@@ -2158,10 +2156,6 @@
return count;
}
- public int getContentHeight() {
- return mContentHeight;
- }
-
private void updateContentHeight() {
int height = 0;
float previousPaddingRequest = mPaddingBetweenElements;
@@ -2225,7 +2219,11 @@
}
}
mIntrinsicContentHeight = height;
- mContentHeight = height + mTopPadding + mBottomMargin;
+
+ // We don't want to use the toppadding since that might be interpolated and we want
+ // to take the final value of the animation.
+ int topPadding = mAmbientState.isFullyDark() ? mDarkTopPadding : mRegularTopPadding;
+ mContentHeight = height + topPadding + mBottomMargin;
updateScrollability();
clampScrollPosition();
mAmbientState.setLayoutMaxHeight(mContentHeight);
@@ -4717,10 +4715,13 @@
if (currView instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) currView;
- mCurrMenuRow = row.createMenu();
- mCurrMenuRow.setSwipeActionHelper(NotificationSwipeHelper.this);
- mCurrMenuRow.setMenuClickListener(NotificationStackScrollLayout.this);
- mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
+
+ if (row.getEntry().hasFinishedInitialization()) {
+ mCurrMenuRow = row.createMenu();
+ mCurrMenuRow.setSwipeActionHelper(NotificationSwipeHelper.this);
+ mCurrMenuRow.setMenuClickListener(NotificationStackScrollLayout.this);
+ mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
+ }
}
}
@@ -5067,11 +5068,13 @@
// ANIMATION_TYPE_PULSE_APPEAR
new AnimationFilter()
.animateAlpha()
+ .hasDelays()
.animateY(),
// ANIMATION_TYPE_PULSE_DISAPPEAR
new AnimationFilter()
.animateAlpha()
+ .hasDelays()
.animateY(),
};
@@ -5135,10 +5138,10 @@
StackStateAnimator.ANIMATION_DURATION_STANDARD,
// ANIMATION_TYPE_PULSE_APPEAR
- KeyguardSliceView.DEFAULT_ANIM_DURATION,
+ StackStateAnimator.ANIMATION_DURATION_PULSE_APPEAR,
// ANIMATION_TYPE_PULSE_DISAPPEAR
- KeyguardSliceView.DEFAULT_ANIM_DURATION / 2,
+ StackStateAnimator.ANIMATION_DURATION_PULSE_APPEAR / 2,
};
static final int ANIMATION_TYPE_ADD = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 0d50f5a..ee006d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -178,7 +178,7 @@
return false;
}
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- if (row.areGutsExposed()) {
+ if (row.areGutsExposed() || !row.getEntry().hasFinishedInitialization()) {
return false;
}
return row.canViewBeDismissed();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index a75d40f..b83a09d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -24,6 +24,7 @@
import android.view.ViewGroup;
import android.view.animation.Interpolator;
+import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -51,6 +52,8 @@
= (int) (ANIMATION_DURATION_HEADS_UP_APPEAR
* HeadsUpAppearInterpolator.getFractionUntilOvershoot());
public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 300;
+ public static final int ANIMATION_DURATION_PULSE_APPEAR =
+ KeyguardSliceView.DEFAULT_ANIM_DURATION;
public static final int ANIMATION_DURATION_BLOCKING_HELPER_FADE = 240;
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
@@ -430,15 +433,26 @@
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_PULSE_APPEAR) {
ExpandableViewState viewState = finalState.getViewStateForView(changingView);
- mTmpState.copyFrom(viewState);
- mTmpState.yTranslation += mPulsingAppearingTranslation;
- mTmpState.alpha = 0;
- mTmpState.applyToView(changingView);
+ if (viewState != null) {
+ mTmpState.copyFrom(viewState);
+ mTmpState.yTranslation += mPulsingAppearingTranslation;
+ mTmpState.alpha = 0;
+ mTmpState.applyToView(changingView);
+ }
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_PULSE_DISAPPEAR) {
ExpandableViewState viewState = finalState.getViewStateForView(changingView);
- viewState.yTranslation += mPulsingAppearingTranslation;
- viewState.alpha = 0;
+ if (viewState != null) {
+ viewState.alpha = 0;
+ // We want to animate the alpha away before the view starts translating,
+ // otherwise everything will overlap and look xtra ugly.
+ float originalYTranslation = viewState.yTranslation;
+ viewState.yTranslation = changingView.getTranslationY();
+ mAnimationFilter.animateAlpha = true;
+ mAnimationProperties.duration = ANIMATION_DURATION_PULSE_APPEAR / 2;
+ viewState.animateTo(changingView, mAnimationProperties);
+ viewState.yTranslation = originalYTranslation;
+ }
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR) {
// This item is added, initialize it's properties.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index 8153953..13dc36d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -93,7 +93,7 @@
SysuiColorExtractor extractor = getTestableExtractor(colors);
simulateEvent(extractor);
extractor.setWallpaperVisible(true);
- extractor.setMediaBackdropVisible(true);
+ extractor.setHasBackdrop(true);
ColorExtractor.GradientColors fallbackColors = extractor.getFallbackColors();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 537bfd4..fe7bf25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -123,6 +123,27 @@
}
@Test
+ public void testHeaderReadFromOldController() {
+ mHeadsUpAppearanceController.setExpandedHeight(1.0f, 1.0f);
+
+ HeadsUpAppearanceController newController = new HeadsUpAppearanceController(
+ mock(NotificationIconAreaController.class),
+ mHeadsUpManager,
+ mHeadsUpStatusBarView,
+ mStackScroller,
+ mPanelView,
+ new View(mContext));
+ newController.readFrom(mHeadsUpAppearanceController);
+
+ Assert.assertEquals(mHeadsUpAppearanceController.mExpandedHeight,
+ newController.mExpandedHeight, 0.0f);
+ Assert.assertEquals(mHeadsUpAppearanceController.mExpandFraction,
+ newController.mExpandFraction, 0.0f);
+ Assert.assertEquals(mHeadsUpAppearanceController.mIsExpanded,
+ newController.mIsExpanded);
+ }
+
+ @Test
public void testDestroy() {
reset(mHeadsUpManager);
reset(mDarkIconDispatcher);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index e95702c..89d562a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -44,7 +44,6 @@
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.util.function.TriConsumer;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.util.wakelock.WakeLock;
@@ -94,6 +93,7 @@
mScrimInFrontColor = scrimInFrontColor;
},
visible -> mScrimVisibility = visible, mDozeParamenters, mAlarmManager);
+ mScrimController.setHasBackdrop(false);
}
@Test
@@ -140,12 +140,7 @@
@Test
public void transitionToAod_withAodWallpaperAndLockScreenWallpaper() {
- ScrimState.AOD.mKeyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
- @Override
- public boolean hasLockscreenWallpaper() {
- return true;
- }
- };
+ mScrimController.setHasBackdrop(true);
mScrimController.setWallpaperSupportsAmbientMode(true);
mScrimController.transitionTo(ScrimState.AOD);
mScrimController.finishAnimationsImmediately();
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 72f11e0..a23c6d3 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -457,6 +457,8 @@
// Identifier for experimental scoring parameter settings.
optional string score_experiment_id = 117;
+ // Data on wifi radio usage
+ optional WifiRadioUsage wifi_radio_usage = 118;
}
// Information that gets logged for every WiFi connection.
@@ -1503,3 +1505,12 @@
optional int32 count = 2;
}
}
+
+// Usage data for the wifi radio while device is running on battery.
+message WifiRadioUsage {
+ // Duration of log (ms)
+ optional int64 logging_duration_ms = 1;
+
+ // Total time for which the radio is awake due to scan.
+ optional int64 scan_time_ms = 2;
+}
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 79fd29a..48f27d8 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -993,6 +993,7 @@
final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
final FillResponse authenticatedResponse = mResponses.get(requestId);
if (authenticatedResponse == null || data == null) {
+ Slog.w(TAG, "no authenticated response");
removeSelf();
return;
}
@@ -1003,6 +1004,7 @@
if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
final Dataset dataset = authenticatedResponse.getDatasets().get(datasetIdx);
if (dataset == null) {
+ Slog.w(TAG, "no dataset with index " + datasetIdx + " on fill response");
removeSelf();
return;
}
@@ -1012,7 +1014,7 @@
final Bundle newClientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE);
if (sDebug) {
Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result
- + ", clientState=" + newClientState);
+ + ", clientState=" + newClientState + ", authenticationId=" + authenticationId);
}
if (result instanceof FillResponse) {
logAuthenticationStatusLocked(requestId, MetricsEvent.AUTOFILL_AUTHENTICATED);
@@ -1029,6 +1031,8 @@
authenticatedResponse.getDatasets().set(datasetIdx, dataset);
autoFill(requestId, datasetIdx, dataset, false);
} else {
+ Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id "
+ + authenticationId);
logAuthenticationStatusLocked(requestId,
MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION);
}
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 786d757..1167e1d 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -198,7 +198,7 @@
@VisibleForTesting
final SparseArray<UidState> mUidStates = new SparseArray<>();
- long mLastUptime;
+ long mLastRealtime;
/*
* These are app op restrictions imposed per user from various parties.
@@ -770,7 +770,7 @@
} else {
settleTime = mConstants.BG_STATE_SETTLE_TIME;
}
- uidState.pendingStateCommitTime = SystemClock.uptimeMillis() + settleTime;
+ uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime;
}
if (uidState.startNesting != 0) {
// There is some actively running operation... need to find it
@@ -1881,11 +1881,11 @@
mUidStates.put(uid, uidState);
} else {
if (uidState.pendingStateCommitTime != 0) {
- if (uidState.pendingStateCommitTime < mLastUptime) {
+ if (uidState.pendingStateCommitTime < mLastRealtime) {
commitUidPendingStateLocked(uidState);
} else {
- mLastUptime = SystemClock.uptimeMillis();
- if (uidState.pendingStateCommitTime < mLastUptime) {
+ mLastRealtime = SystemClock.elapsedRealtime();
+ if (uidState.pendingStateCommitTime < mLastRealtime) {
commitUidPendingStateLocked(uidState);
}
}
@@ -3284,7 +3284,7 @@
}
if (uidState.pendingStateCommitTime != 0) {
pw.print(" pendingStateCommitTime=");
- TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowUptime, pw);
+ TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowElapsed, pw);
pw.println();
}
if (uidState.startNesting != 0) {
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 732ea8d..0941bc8 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -57,8 +57,6 @@
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.SpellCheckerSubtype;
@@ -71,6 +69,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.function.Predicate;
public class TextServicesManagerService extends ITextServicesManager.Stub {
@@ -537,52 +536,39 @@
&& !allowImplicitlySelectedSubtype) {
return null;
}
- String candidateLocale = null;
- if (subtypeHashCode == 0) {
- // Spell checker language settings == "auto"
- final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
- if (imm != null) {
- final InputMethodSubtype currentInputMethodSubtype =
- imm.getCurrentInputMethodSubtype();
- if (currentInputMethodSubtype != null) {
- final String localeString = currentInputMethodSubtype.getLocale();
- if (!TextUtils.isEmpty(localeString)) {
- // 1. Use keyboard locale if available in the spell checker
- candidateLocale = localeString;
- }
+
+ final int numSubtypes = sci.getSubtypeCount();
+ if (subtypeHashCode != 0) {
+ // Use the user specified spell checker subtype
+ for (int i = 0; i < numSubtypes; ++i) {
+ final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
+ if (scs.hashCode() == subtypeHashCode) {
+ return scs;
}
}
- if (candidateLocale == null) {
- // 2. Use System locale if available in the spell checker
- candidateLocale = systemLocale.toString();
- }
+ return null;
}
- SpellCheckerSubtype candidate = null;
+
+ // subtypeHashCode == 0 means spell checker language settings is "auto"
+
+ if (systemLocale == null) {
+ return null;
+ }
+ SpellCheckerSubtype firstLanguageMatchingSubtype = null;
for (int i = 0; i < sci.getSubtypeCount(); ++i) {
final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
- if (subtypeHashCode == 0) {
- final String scsLocale = scs.getLocale();
- if (candidateLocale.equals(scsLocale)) {
- return scs;
- } else if (candidate == null) {
- if (candidateLocale.length() >= 2 && scsLocale.length() >= 2
- && candidateLocale.startsWith(scsLocale)) {
- // Fall back to the applicable language
- candidate = scs;
- }
- }
- } else if (scs.hashCode() == subtypeHashCode) {
- if (DBG) {
- Slog.w(TAG, "Return subtype " + scs.hashCode() + ", " + scs.getLocale());
- }
- // 3. Use the user specified spell check language
+ final Locale scsLocale = scs.getLocaleObject();
+ if (Objects.equals(scsLocale, systemLocale)) {
+ // Exact match wins.
return scs;
}
+ if (firstLanguageMatchingSubtype == null && scsLocale != null
+ && TextUtils.equals(systemLocale.getLanguage(), scsLocale.getLanguage())) {
+ // Remember as a fall back candidate
+ firstLanguageMatchingSubtype = scs;
+ }
}
- // 4. Fall back to the applicable language and return it if not null
- // 5. Simply just return it even if it's null which means we could find no suitable
- // spell check languages
- return candidate;
+ return firstLanguageMatchingSubtype;
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 6de43de..ee93fc8 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -140,7 +140,7 @@
+ " to displayId=" + mDisplayId + " position=" + position);
addStackReferenceIfNeeded(stack);
positionChildAt(stack, position);
- mSupervisor.mService.updateSleepIfNeededLocked();
+ mSupervisor.mService.mAm.updateSleepIfNeededLocked();
}
void removeChild(ActivityStack stack) {
@@ -148,7 +148,7 @@
+ " from displayId=" + mDisplayId);
mStacks.remove(stack);
removeStackReferenceIfNeeded(stack);
- mSupervisor.mService.updateSleepIfNeededLocked();
+ mSupervisor.mService.mAm.updateSleepIfNeededLocked();
onStackOrderChanged();
}
@@ -300,7 +300,7 @@
}
}
- final ActivityManagerService service = mSupervisor.mService;
+ final ActivityManagerService service = mSupervisor.mService.mAm;
if (!isWindowingModeSupported(windowingMode, service.mSupportsMultiWindow,
service.mSupportsSplitScreenMultiWindow, service.mSupportsFreeformWindowManagement,
service.mSupportsPictureInPicture, activityType)) {
@@ -536,7 +536,7 @@
}
// Make sure the windowing mode we are trying to use makes sense for what is supported.
- final ActivityManagerService service = mSupervisor.mService;
+ final ActivityManagerService service = mSupervisor.mService.mAm;
boolean supportsMultiWindow = service.mSupportsMultiWindow;
boolean supportsSplitScreen = service.mSupportsSplitScreenMultiWindow;
boolean supportsFreeform = service.mSupportsFreeformWindowManagement;
@@ -714,7 +714,7 @@
boolean shouldSleep() {
return (mStacks.isEmpty() || !mAllSleepTokens.isEmpty())
- && (mSupervisor.mService.mRunningVoice == null);
+ && (mSupervisor.mService.mAm.mRunningVoice == null);
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7417326..ac4f6ab 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -615,10 +615,7 @@
private Installer mInstaller;
/** Run all ActivityStacks through this */
- final ActivityStackSupervisor mStackSupervisor;
- final KeyguardController mKeyguardController;
-
- private final ActivityStartController mActivityStartController;
+ ActivityStackSupervisor mStackSupervisor;
final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
@@ -680,11 +677,6 @@
*/
String mDeviceOwnerName;
- /**
- * The controller for all operations related to locktask.
- */
- private final LockTaskController mLockTaskController;
-
final UserController mUserController;
/**
@@ -741,7 +733,7 @@
public boolean canShowErrorDialogs() {
return mShowDialogs && !mSleeping && !mShuttingDown
- && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
+ && !mActivityTaskManager.mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
&& !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
mUserController.getCurrentUserId())
&& !(UserManager.isDeviceInDemoMode(mContext)
@@ -1293,16 +1285,6 @@
*/
final AppOpsService mAppOpsService;
- /** Current sequencing integer of the configuration, for skipping old configurations. */
- private int mConfigurationSeq;
-
- /**
- * Temp object used when global and/or display override configuration is updated. It is also
- * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
- * anyone...
- */
- private Configuration mTempConfig = new Configuration();
-
/**
* Hardware-reported OpenGLES version.
*/
@@ -2596,15 +2578,14 @@
mWindowManager = wm;
mActivityTaskManager.setWindowManager(wm);
mStackSupervisor.setWindowManager(wm);
- mLockTaskController.setWindowManager(wm);
}
}
public void setActivityTaskManager(ActivityTaskManagerService atm) {
synchronized (this) {
mActivityTaskManager = atm;
- mStackSupervisor.setActivityTaskManager(atm);
mActivityTaskManager.setActivityManagerService(this);
+ mStackSupervisor = mActivityTaskManager.mStackSupervisor;
}
}
@@ -2843,7 +2824,6 @@
mContext = mInjector.getContext();
mUiContext = null;
GL_ES_VERSION = 0;
- mActivityStartController = null;
mAppErrors = null;
mAppWarnings = null;
mAppOpsService = mInjector.getAppOpsService(null, null);
@@ -2854,17 +2834,14 @@
mHandler = null;
mHandlerThread = null;
mIntentFirewall = null;
- mKeyguardController = null;
mPermissionReviewRequired = false;
mProcessCpuThread = null;
mProcessStats = null;
mProviderMap = null;
mServices = null;
- mStackSupervisor = null;
mSystemThread = null;
mUiHandler = injector.getUiHandler(null);
mUserController = null;
- mLockTaskController = null;
mProcStartHandlerThread = null;
mProcStartHandler = null;
mHiddenApiBlacklist = null;
@@ -2948,16 +2925,8 @@
}
mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
- mTempConfig.setToDefaults();
- mTempConfig.setLocales(LocaleList.getDefault());
- mConfigurationSeq = mTempConfig.seq = 1;
- mStackSupervisor = createStackSupervisor();
- mStackSupervisor.onConfigurationChanged(mTempConfig);
- mKeyguardController = mStackSupervisor.getKeyguardController();
mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
- mActivityStartController = new ActivityStartController(this);
- mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
mProcessCpuThread = new Thread("CpuTracker") {
@Override
@@ -3011,12 +2980,6 @@
}
- protected ActivityStackSupervisor createStackSupervisor() {
- final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
- supervisor.initialize();
- return supervisor;
- }
-
public void setSystemServiceManager(SystemServiceManager mgr) {
mSystemServiceManager = mgr;
}
@@ -4405,7 +4368,7 @@
// For ANR debugging to verify if the user activity is the one that actually
// launched.
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
- mActivityStartController.startHomeActivity(intent, aInfo, myReason);
+ mActivityTaskManager.getActivityStartController().startHomeActivity(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
@@ -6196,7 +6159,7 @@
ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
packageName == null ? ("stop user " + userId) : ("stop " + packageName));
- didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
+ didSomething |= mActivityTaskManager.getActivityStartController().clearPendingActivityLaunches(packageName);
if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
packageName, null, doit, evenPersistent, userId)) {
@@ -9366,7 +9329,7 @@
synchronized (this) {
if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
Arrays.toString(packages));
- mLockTaskController.updateLockTaskPackages(userId, packages);
+ mActivityTaskManager.getLockTaskController().updateLockTaskPackages(userId, packages);
}
}
@@ -10138,18 +10101,6 @@
return AppGlobals.getPackageManager();
}
- ActivityStartController getActivityStartController() {
- return mActivityStartController;
- }
-
- LockTaskController getLockTaskController() {
- return mLockTaskController;
- }
-
- ClientLifecycleManager getLifecycleManager() {
- return mActivityTaskManager.getLifecycleManager();
- }
-
PackageManagerInternal getPackageManagerInternalLocked() {
if (mPackageManagerInt == null) {
mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
@@ -10913,11 +10864,6 @@
}
}
- /** Pokes the task persister. */
- void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
- mActivityTaskManager.getRecentTasks().notifyTaskPersisterLocked(task, flush);
- }
-
@Override
public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
@@ -10947,7 +10893,7 @@
mBatteryStatsService.shutdown();
synchronized (this) {
mProcessStats.shutdownLocked();
- notifyTaskPersisterLocked(null, true);
+ mActivityTaskManager.notifyTaskPersisterLocked(null, true);
}
return timedout;
@@ -10992,7 +10938,7 @@
final long ident = Binder.clearCallingIdentity();
try {
if (mUserController.shouldConfirmCredentials(userId)) {
- if (mKeyguardController.isKeyguardLocked()) {
+ if (mActivityTaskManager.mKeyguardController.isKeyguardLocked()) {
// Showing launcher to avoid user entering credential twice.
final int currentUserId = mUserController.getCurrentUserId();
startHomeActivityLocked(currentUserId, "notifyLockedProfile");
@@ -11034,7 +10980,7 @@
mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
+ APP_SWITCH_DELAY_TIME;
mDidAppSwitch = false;
- mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
+ mActivityTaskManager.getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
}
}
@@ -13602,7 +13548,7 @@
private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
- mActivityStartController.dump(pw, "", dumpPackage);
+ mActivityTaskManager.getActivityStartController().dump(pw, "", dumpPackage);
}
void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
@@ -19554,8 +19500,8 @@
/** Update default (global) configuration and notify listeners about changes. */
private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
boolean persistent, int userId, boolean deferResume) {
- mTempConfig.setTo(getGlobalConfiguration());
- final int changes = mTempConfig.updateFrom(values);
+ mActivityTaskManager.mTempConfig.setTo(getGlobalConfiguration());
+ final int changes = mActivityTaskManager.mTempConfig.updateFrom(values);
if (changes == 0) {
// Since calling to Activity.setRequestedOrientation leads to freezing the window with
// setting WindowManagerService.mWaitingForConfig to true, it is important that we call
@@ -19605,34 +19551,34 @@
locales.get(bestLocaleIndex)));
}
- mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
- mTempConfig.seq = mConfigurationSeq;
+ mActivityTaskManager.mConfigurationSeq = Math.max(++mActivityTaskManager.mConfigurationSeq, 1);
+ mActivityTaskManager.mTempConfig.seq = mActivityTaskManager.mConfigurationSeq;
// Update stored global config and notify everyone about the change.
- mStackSupervisor.onConfigurationChanged(mTempConfig);
+ mStackSupervisor.onConfigurationChanged(mActivityTaskManager.mTempConfig);
- Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
+ Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mActivityTaskManager.mTempConfig);
// TODO(multi-display): Update UsageEvents#Event to include displayId.
- mUsageStatsService.reportConfigurationChange(mTempConfig,
+ mUsageStatsService.reportConfigurationChange(mActivityTaskManager.mTempConfig,
mUserController.getCurrentUserId());
// TODO: If our config changes, should we auto dismiss any currently showing dialogs?
- updateShouldShowDialogsLocked(mTempConfig);
+ updateShouldShowDialogsLocked(mActivityTaskManager.mTempConfig);
AttributeCache ac = AttributeCache.instance();
if (ac != null) {
- ac.updateConfiguration(mTempConfig);
+ ac.updateConfiguration(mActivityTaskManager.mTempConfig);
}
// Make sure all resources in our process are updated right now, so that anyone who is going
// to retrieve resource values after we return will be sure to get the new ones. This is
// especially important during boot, where the first config change needs to guarantee all
// resources have that config before following boot code is executed.
- mSystemThread.applyConfigurationToResources(mTempConfig);
+ mSystemThread.applyConfigurationToResources(mActivityTaskManager.mTempConfig);
// We need another copy of global config because we're scheduling some calls instead of
// running them in place. We need to be sure that object we send will be handled unchanged.
- final Configuration configCopy = new Configuration(mTempConfig);
+ final Configuration configCopy = new Configuration(mActivityTaskManager.mTempConfig);
if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
msg.obj = configCopy;
@@ -19646,7 +19592,7 @@
if (app.thread != null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
+ app.processName + " new config " + configCopy);
- getLifecycleManager().scheduleTransaction(app.thread,
+ mActivityTaskManager.getLifecycleManager().scheduleTransaction(app.thread,
ConfigurationChangeItem.obtain(configCopy));
}
} catch (Exception e) {
@@ -19743,12 +19689,12 @@
private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
int displayId) {
- mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
- final int changes = mTempConfig.updateFrom(values);
+ mActivityTaskManager.mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
+ final int changes = mActivityTaskManager.mTempConfig.updateFrom(values);
if (changes != 0) {
Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
- + mTempConfig + " for displayId=" + displayId);
- mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
+ + mActivityTaskManager.mTempConfig + " for displayId=" + displayId);
+ mStackSupervisor.setDisplayOverrideConfiguration(mActivityTaskManager.mTempConfig, displayId);
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange && displayId == DEFAULT_DISPLAY) {
@@ -19765,7 +19711,7 @@
// ensureActivityConfiguration().
if (mWindowManager != null) {
final int[] resizedStacks =
- mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
+ mWindowManager.setNewDisplayOverrideConfiguration(mActivityTaskManager.mTempConfig, displayId);
if (resizedStacks != null) {
for (int stackId : resizedStacks) {
resizeStackWithBoundsFromWindowManager(stackId, deferResume);
@@ -21807,7 +21753,8 @@
}
private final ActivityRecord resumedAppLocked() {
- ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
+ final ActivityRecord act =
+ mStackSupervisor != null ? mStackSupervisor.getResumedActivityLocked() : null;
String pkg;
int uid;
if (act != null) {
@@ -21889,7 +21836,9 @@
uidRec.reset();
}
- mStackSupervisor.rankTaskLayersIfNeeded();
+ if (mStackSupervisor != null) {
+ mStackSupervisor.rankTaskLayersIfNeeded();
+ }
mAdjSeq++;
mNewNumServiceProcs = 0;
@@ -23455,7 +23404,7 @@
pw.println(" Reason: " + reason);
}
pw.println();
- mActivityStartController.dump(pw, " ", null);
+ mActivityTaskManager.getActivityStartController().dump(pw, " ", null);
pw.println();
pw.println("-------------------------------------------------------------------------------");
dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 9e9f638..1611a38 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -185,6 +185,10 @@
mWindowState = WINDOW_STATE_INVALID;
ActivityStack stack = mSupervisor.getFocusedStack();
+ if (stack == null) {
+ return;
+ }
+
if (stack.isActivityTypeAssistant()) {
mWindowState = WINDOW_STATE_ASSISTANT;
return;
@@ -407,7 +411,7 @@
}
private void checkVisibility(TaskRecord t, ActivityRecord r) {
- synchronized (mSupervisor.mService) {
+ synchronized (mSupervisor.mService.mGlobalLock) {
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
r.getWindowingMode());
@@ -663,8 +667,8 @@
private ProcessRecord findProcessForActivity(ActivityRecord launchedActivity) {
return launchedActivity != null
- ? mSupervisor.mService.mProcessNames.get(launchedActivity.processName,
- launchedActivity.appInfo.uid)
+ ? mSupervisor.mService.mAm.mProcessNames.get(
+ launchedActivity.processName, launchedActivity.appInfo.uid)
: null;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index a55ffdb..0e427d6 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1098,7 +1098,7 @@
return true;
}
// Allow the recents component to launch the home activity.
- final RecentTasks recentTasks = mStackSupervisor.mService.mActivityTaskManager.getRecentTasks();
+ final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
return true;
}
@@ -2930,16 +2930,16 @@
throw new XmlPullParserException("restoreActivity error intent=" + intent);
}
- final ActivityManagerService service = stackSupervisor.mService;
+ final ActivityTaskManagerService service = stackSupervisor.mService;
final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
userId, Binder.getCallingUid());
if (aInfo == null) {
throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
" resolvedType=" + resolvedType);
}
- final ActivityRecord r = new ActivityRecord(service.mActivityTaskManager, null /* caller */,
+ final ActivityRecord r = new ActivityRecord(service, null /* caller */,
0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
- aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
+ aInfo, service.mAm.getConfiguration(), null /* resultTo */, null /* resultWho */,
0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
stackSupervisor, null /* options */, null /* sourceRecord */);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 3869f83..6118131 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -271,7 +271,7 @@
// the input bounds right or bottom side minus the width or height divided by this value.
private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
- final ActivityManagerService mService;
+ final ActivityTaskManagerService mService;
private final WindowManagerService mWindowManager;
T mWindowContainerController;
@@ -391,18 +391,18 @@
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
Slog.w(TAG, "Activity pause timeout for " + r);
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
if (r.app != null) {
- mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
+ mService.mAm.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
}
activityPausedLocked(r.appToken, true);
}
} break;
case LAUNCH_TICK_MSG: {
ActivityRecord r = (ActivityRecord)msg.obj;
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
if (r.continueLaunchTickingLocked()) {
- mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
+ mService.mAm.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
}
}
} break;
@@ -411,7 +411,7 @@
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
Slog.w(TAG, "Activity destroy timeout for " + r);
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
activityDestroyedLocked(r != null ? r.appToken : null, "destroyTimeout");
}
} break;
@@ -420,7 +420,7 @@
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
Slog.w(TAG, "Activity stop timeout for " + r);
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
if (r.isInHistory()) {
r.activityStoppedLocked(null /* icicle */,
null /* persistentState */, null /* description */);
@@ -429,12 +429,12 @@
} break;
case DESTROY_ACTIVITIES_MSG: {
ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
destroyActivitiesLocked(args.mOwner, args.mReason);
}
} break;
case TRANSLUCENT_TIMEOUT_MSG: {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
notifyActivityDrawnLocked(null);
}
} break;
@@ -454,10 +454,10 @@
int windowingMode, int activityType, boolean onTop) {
mStackSupervisor = supervisor;
mService = supervisor.mService;
- mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
+ mHandler = new ActivityStackHandler(supervisor.mLooper);
mWindowManager = mService.mWindowManager;
mStackId = stackId;
- mCurrentUser = mService.mUserController.getCurrentUserId();
+ mCurrentUser = mService.mAm.mUserController.getCurrentUserId();
mTmpRect2.setEmpty();
// Set display id before setting activity and window type to make sure it won't affect
// stacks on a wrong display.
@@ -495,7 +495,7 @@
if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
+ reason);
setResumedActivity(record, reason + " - onActivityStateChanged");
- mService.setResumedActivityUncheckLocked(record, reason);
+ mService.mAm.setResumedActivityUncheckLocked(record, reason);
mStackSupervisor.mRecentTasks.add(record.getTask());
}
}
@@ -552,7 +552,7 @@
// Looks like we can't launch in split screen mode or the stack we are launching
// doesn't support split-screen mode, go ahead an dismiss split-screen and display a
// warning toast about it.
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
+ mService.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
display.getSplitScreenPrimaryStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN,
false /* animate */, false /* showRecents */,
false /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */);
@@ -573,7 +573,7 @@
// Inform the user that they are starting an app that may not work correctly in
// multi-window mode.
final String packageName = topActivity.appInfo.packageName;
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyActivityForcedResizable(
+ mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
topTask.taskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName);
}
@@ -1451,14 +1451,14 @@
mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
- mService.updateCpuStats();
+ mService.mAm.updateCpuStats();
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
- mService.updateUsageStats(prev, false);
+ mService.mAm.updateUsageStats(prev, false);
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
@@ -1478,7 +1478,7 @@
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
- if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
+ if (!uiSleeping && !mService.mAm.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
@@ -1621,11 +1621,11 @@
prev.resumeKeyDispatchingLocked();
if (prev.app != null && prev.cpuTimeAtResume > 0
- && mService.mBatteryStatsService.isOnBattery()) {
- long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
+ && mService.mAm.mBatteryStatsService.isOnBattery()) {
+ long diff = mService.mAm.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
- prev.cpuTimeAtResume;
if (diff > 0) {
- BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
+ BatteryStatsImpl bsi = mService.mAm.mBatteryStatsService.getActiveStatistics();
synchronized (bsi) {
BatteryStatsImpl.Uid.Proc ps =
bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
@@ -1644,7 +1644,7 @@
// task stack changes, because its positioning may depend on it.
if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
|| getDisplay().hasPinnedStack()) {
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskStackChanged();
+ mService.getTaskChangeNotificationController().notifyTaskStackChanged();
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
}
@@ -2328,7 +2328,7 @@
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
- if (!mService.mBooting && !mService.mBooted) {
+ if (!mService.mAm.mBooting && !mService.mAm.mBooted) {
// Not ready yet!
return false;
}
@@ -2388,7 +2388,7 @@
// Make sure that the user who owns this activity is started. If not,
// we will just leave it as is because someone should be bringing
// another user's activities to the top of the stack.
- if (!mService.mUserController.hasStartedUserState(next.userId)) {
+ if (!mService.mAm.mUserController.hasStartedUserState(next.userId)) {
Slog.w(TAG, "Skipping resume of top activity " + next
+ ": user " + next.userId + " is stopped");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -2452,7 +2452,7 @@
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.app != null && next.app.thread != null) {
- mService.updateLruProcessLocked(next.app, true, null);
+ mService.mAm.updateLruProcessLocked(next.app, true, null);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
if (lastResumed != null) {
@@ -2611,16 +2611,16 @@
lastStack == null ? null :lastStack.mResumedActivity;
final ActivityState lastState = next.getState();
- mService.updateCpuStats();
+ mService.mAm.updateCpuStats();
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
+ " (in existing)");
next.setState(RESUMED, "resumeTopActivityInnerLocked");
- mService.updateLruProcessLocked(next.app, true, null);
+ mService.mAm.updateLruProcessLocked(next.app, true, null);
updateLRUListLocked(next);
- mService.updateOomAdjLocked();
+ mService.mAm.updateOomAdjLocked();
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order.
@@ -2689,14 +2689,14 @@
next.shortComponentName);
next.sleeping = false;
- mService.getAppWarningsLocked().onResumeActivity(next);
- mService.showAskCompatModeDialogLocked(next);
+ mService.mAm.getAppWarningsLocked().onResumeActivity(next);
+ mService.mAm.showAskCompatModeDialogLocked(next);
next.app.pendingUiClean = true;
- next.app.forceProcessStateUpTo(mService.mTopProcessState);
+ next.app.forceProcessStateUpTo(mService.mAm.mTopProcessState);
next.clearOptionsLocked();
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.repProcState,
- mService.mActivityTaskManager.isNextTransitionForward()));
+ mService.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
@@ -3338,7 +3338,7 @@
String resultWho, int requestCode, int resultCode, Intent data) {
if (callingUid > 0) {
- mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
+ mService.mAm.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
data, r.getUriPermissionsLocked(), r.userId);
}
@@ -3535,7 +3535,7 @@
}
}
}
- mService.updateOomAdjLocked();
+ mService.mAm.updateOomAdjLocked();
}
/**
@@ -3578,7 +3578,7 @@
if (activityNdx >= 0) {
r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
if (r.isState(RESUMED, PAUSING, PAUSED)) {
- if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
+ if (!r.isActivityTypeHome() || mService.mAm.mHomeProcess != r.app) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
@@ -3616,7 +3616,7 @@
} catch (RemoteException re) {
// Ok
}
- mService.finishRunningVoiceLocked();
+ mService.mAm.finishRunningVoiceLocked();
break;
}
}
@@ -3624,7 +3624,7 @@
}
if (didOne) {
- mService.updateOomAdjLocked();
+ mService.mAm.updateOomAdjLocked();
}
}
@@ -3653,12 +3653,11 @@
}
}
if (r.info.applicationInfo.uid > 0) {
- mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
+ mService.mAm.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.userId);
}
- resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
- resultData);
+ resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, resultData);
r.resultTo = null;
}
else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
@@ -3723,7 +3722,7 @@
if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare close transition: finishing " + r);
if (endTask) {
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskRemovalStarted(
+ mService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
task.taskId);
}
mWindowManager.prepareAppTransition(transit, false);
@@ -3814,7 +3813,7 @@
"Moving to STOPPING: "+ r + " (finish requested)");
r.setState(STOPPING, "finishCurrentActivityLocked");
if (oomAdj) {
- mService.updateOomAdjLocked();
+ mService.mAm.updateOomAdjLocked();
}
return r;
}
@@ -3957,7 +3956,7 @@
}
}
- IActivityController controller = mService.mController;
+ IActivityController controller = mService.mAm.mController;
if (controller != null) {
ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
if (next != null) {
@@ -3966,7 +3965,7 @@
try {
resumeOK = controller.activityResuming(next.packageName);
} catch (RemoteException e) {
- mService.mController = null;
+ mService.mAm.mController = null;
Watchdog.getInstance().setActivityController(null);
}
@@ -4075,7 +4074,7 @@
for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
PendingIntentRecord rec = apr.get();
if (rec != null) {
- mService.cancelIntentSenderLocked(rec, false);
+ mService.mAm.cancelIntentSenderLocked(rec, false);
}
}
r.pendingResults = null;
@@ -4162,7 +4161,7 @@
Iterator<ConnectionRecord> it = r.connections.iterator();
while (it.hasNext()) {
ConnectionRecord c = it.next();
- mService.mServices.removeConnectionLocked(c, null, r);
+ mService.mAm.mServices.removeConnectionLocked(c, null, r);
}
r.connections = null;
}
@@ -4294,18 +4293,18 @@
if (hadApp) {
if (removeFromApp) {
r.app.activities.remove(r);
- if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
- mService.mHeavyWeightProcess = null;
- mService.mHandler.sendEmptyMessage(
+ if (mService.mAm.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
+ mService.mAm.mHeavyWeightProcess = null;
+ mService.mAm.mHandler.sendEmptyMessage(
ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
}
if (r.app.activities.isEmpty()) {
// Update any services we are bound to that might care about whether
// their client may have activities.
- mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
+ mService.mAm.mServices.updateServiceConnectionActivitiesLocked(r.app);
// No longer have activities, so update LRU list and oom adj.
- mService.updateLruProcessLocked(r.app, false, null);
- mService.updateOomAdjLocked();
+ mService.mAm.updateLruProcessLocked(r.app, false, null);
+ mService.mAm.updateOomAdjLocked();
}
}
@@ -4483,7 +4482,7 @@
r.getTask().taskId, r.shortComponentName,
"proc died without state saved");
if (r.getState() == RESUMED) {
- mService.updateUsageStats(r, false);
+ mService.mAm.updateUsageStats(r, false);
}
}
} else {
@@ -4629,7 +4628,7 @@
mStackSupervisor.resumeFocusedStackTopActivityLocked();
EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.taskId);
+ mService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.taskId);
} finally {
getDisplay().continueUpdateImeTarget();
}
@@ -4663,7 +4662,7 @@
// If we have a watcher, preflight the move before committing to it. First check
// for *other* available tasks, but if none are available, then try again allowing the
// current task to be selected.
- if (isTopStackOnDisplay() && mService.mController != null) {
+ if (isTopStackOnDisplay() && mService.mAm.mController != null) {
ActivityRecord next = topRunningActivityLocked(null, taskId);
if (next == null) {
next = topRunningActivityLocked(null, 0);
@@ -4672,9 +4671,9 @@
// ask watcher if this is allowed
boolean moveOK = true;
try {
- moveOK = mService.mController.activityResuming(next.packageName);
+ moveOK = mService.mAm.mController.activityResuming(next.packageName);
} catch (RemoteException e) {
- mService.mController = null;
+ mService.mAm.mController = null;
Watchdog.getInstance().setActivityController(null);
}
if (!moveOK) {
@@ -4751,7 +4750,7 @@
// TODO: Figure-out a way to consolidate with resize() method below.
@Override
public void requestResize(Rect bounds) {
- mService.mActivityTaskManager.resizeStack(mStackId, bounds,
+ mService.resizeStack(mStackId, bounds,
true /* allowResizeInDockedMode */, false /* preserveWindows */,
false /* animate */, -1 /* animationDuration */);
}
@@ -5160,7 +5159,7 @@
// Notify if a task from the pinned stack is being removed (or moved depending on the mode)
if (inPinnedWindowingMode()) {
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyActivityUnpinned();
+ mService.getTaskChangeNotificationController().notifyActivityUnpinned();
}
}
@@ -5337,11 +5336,11 @@
return false;
}
- return display != null ? display.isSleeping() : mService.isSleepingLocked();
+ return display != null ? display.isSleeping() : mService.mAm.isSleepingLocked();
}
boolean shouldSleepOrShutDownActivities() {
- return shouldSleepActivities() || mService.isShuttingDownLocked();
+ return shouldSleepActivities() || mService.mAm.isShuttingDownLocked();
}
public void writeToProto(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index df09b4a..a77d734 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -304,7 +304,7 @@
/** The number of distinct task ids that can be assigned to the tasks of a single user */
private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
- ActivityManagerService mService;
+ ActivityTaskManagerService mService;
/** The historial list of recent tasks including inactive tasks */
RecentTasks mRecentTasks;
@@ -318,7 +318,6 @@
/** Short cut */
WindowManagerService mWindowManager;
DisplayManager mDisplayManager;
- ActivityTaskManagerService mAtm;
private LaunchParamsController mLaunchParamsController;
@@ -489,7 +488,7 @@
// No restrictions for the default display.
return true;
}
- if (!mService.mSupportsMultiDisplay) {
+ if (!mService.mAm.mSupportsMultiDisplay) {
// Can't launch on secondary displays if feature is not supported.
return false;
}
@@ -604,14 +603,14 @@
}
}
- public ActivityStackSupervisor(ActivityManagerService service, Looper looper) {
+ public ActivityStackSupervisor(ActivityTaskManagerService service, Looper looper) {
mService = service;
mLooper = looper;
mHandler = new ActivityStackSupervisorHandler(looper);
}
@VisibleForTesting
- void setService(ActivityManagerService service) {
+ void setService(ActivityTaskManagerService service) {
mService = service;
}
@@ -622,11 +621,10 @@
mInitialized = true;
mRunningTasks = createRunningTasks();
- mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext,
- mHandler.getLooper());
- mKeyguardController = new KeyguardController(mService, this);
+ mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, mHandler.getLooper());
+ mKeyguardController = new KeyguardController(mService.mAm, this);
- mLaunchParamsController = new LaunchParamsController(mService);
+ mLaunchParamsController = new LaunchParamsController(mService.mAm);
mLaunchParamsController.registerDefaultModifiers(this);
}
@@ -665,10 +663,6 @@
mLaunchingActivity.setReferenceCounted(false);
}
- void setActivityTaskManager(ActivityTaskManagerService atm) {
- mAtm = atm;
- }
-
void setWindowManager(WindowManagerService wm) {
mWindowManager = wm;
getKeyguardController().setWindowManager(wm);
@@ -715,6 +709,11 @@
if (!focusCandidate.isFocusable()) {
// The focus candidate isn't focusable. Move focus to the top stack that is focusable.
focusCandidate = getNextFocusableStackLocked(focusCandidate, false /* ignoreCurrent */);
+ if (focusCandidate == null) {
+ Slog.w(TAG,
+ "setFocusStackUnchecked: No focusable stack found, focus home as default");
+ focusCandidate = mHomeStack;
+ }
}
if (focusCandidate != mFocusedStack) {
@@ -727,7 +726,7 @@
}
final ActivityRecord r = topRunningActivityLocked();
- if (mService.mBooting || !mService.mBooted) {
+ if (mService.mAm.mBooting || !mService.mAm.mBooted) {
if (r != null && r.idle) {
checkFinishBootingLocked();
}
@@ -759,7 +758,7 @@
}
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
- if (!mService.mBooting && !mService.mBooted) {
+ if (!mService.mAm.mBooting && !mService.mAm.mBooted) {
// Not ready yet!
return false;
}
@@ -773,7 +772,7 @@
moveFocusableActivityStackToFrontLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
- return mService.startHomeActivityLocked(mCurrentUser, myReason);
+ return mService.mAm.startHomeActivityLocked(mCurrentUser, myReason);
}
TaskRecord anyTaskForIdLocked(int id) {
@@ -911,7 +910,7 @@
// result to an activity belonging to userId. Example case: a document
// picker for personal files, opened by a work app, should still get locked.
if (taskTopActivityIsUser(task, userId)) {
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskProfileLocked(
+ mService.mAm.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskProfileLocked(
task.taskId, userId);
}
}
@@ -1166,7 +1165,7 @@
}
}
if (changed) {
- mService.notifyAll();
+ mService.mAm.notifyAll();
}
}
@@ -1196,7 +1195,7 @@
}
if (changed) {
- mService.notifyAll();
+ mService.mAm.notifyAll();
}
}
@@ -1217,7 +1216,7 @@
}
}
if (changed) {
- mService.notifyAll();
+ mService.mAm.notifyAll();
}
}
@@ -1322,19 +1321,19 @@
// Don't debug things in the system process
if (!aInfo.processName.equals("system")) {
if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
- mService.setDebugApp(aInfo.processName, true, false);
+ mService.mAm.setDebugApp(aInfo.processName, true, false);
}
if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
- mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
+ mService.mAm.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
}
if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
- mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
+ mService.mAm.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
}
if (profilerInfo != null) {
- mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+ mService.mAm.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
}
}
final String intentLaunchToken = intent.getLaunchToken();
@@ -1347,7 +1346,7 @@
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
int filterCallingUid) {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
try {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "resolveIntent");
int modifiedFlags = flags
@@ -1364,7 +1363,7 @@
// (e.g. AMS.startActivityAsUser).
final long token = Binder.clearCallingIdentity();
try {
- return mService.getPackageManagerInternalLocked().resolveIntent(
+ return mService.mAm.getPackageManagerInternalLocked().resolveIntent(
intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
} finally {
Binder.restoreCallingIdentity(token);
@@ -1453,8 +1452,8 @@
if (idx < 0) {
app.activities.add(r);
}
- mService.updateLruProcessLocked(app, true, null);
- mService.updateOomAdjLocked();
+ mService.mAm.updateLruProcessLocked(app, true, null);
+ mService.mAm.updateOomAdjLocked();
final LockTaskController lockTaskController = mService.getLockTaskController();
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
@@ -1484,20 +1483,20 @@
System.identityHashCode(r), task.taskId, r.shortComponentName);
if (r.isActivityTypeHome()) {
// Home process is the root process of the task.
- mService.mHomeProcess = task.mActivities.get(0).app;
+ mService.mAm.mHomeProcess = task.mActivities.get(0).app;
}
- mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
+ mService.mAm.notifyPackageUse(r.intent.getComponent().getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
r.sleeping = false;
r.forceNewConfig = false;
- mService.getAppWarningsLocked().onStartActivity(r);
- mService.showAskCompatModeDialogLocked(r);
- r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
+ mService.mAm.getAppWarningsLocked().onStartActivity(r);
+ mService.mAm.showAskCompatModeDialogLocked(r);
+ r.compat = mService.mAm.compatibilityInfoForPackageLocked(r.info.applicationInfo);
ProfilerInfo profilerInfo = null;
- if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
- if (mService.mProfileProc == null || mService.mProfileProc == app) {
- mService.mProfileProc = app;
- ProfilerInfo profilerInfoSvc = mService.mProfilerInfo;
+ if (mService.mAm.mProfileApp != null && mService.mAm.mProfileApp.equals(app.processName)) {
+ if (mService.mAm.mProfileProc == null || mService.mAm.mProfileProc == app) {
+ mService.mAm.mProfileProc = app;
+ ProfilerInfo profilerInfoSvc = mService.mAm.mProfilerInfo;
if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
if (profilerInfoSvc.profileFd != null) {
try {
@@ -1514,13 +1513,13 @@
app.hasShownUi = true;
app.pendingUiClean = true;
- app.forceProcessStateUpTo(mService.mTopProcessState);
+ app.forceProcessStateUpTo(mService.mAm.mTopProcessState);
// Because we could be starting an Activity in the system process this may not go
// across a Binder interface which would create a new Configuration. Consequently
// we have to always create a new Configuration here.
final MergedConfiguration mergedConfiguration = new MergedConfiguration(
- mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
+ mService.mAm.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
r.setLastReportedConfiguration(mergedConfiguration);
logIfTransactionTooLarge(r.intent, r.icicle);
@@ -1536,13 +1535,13 @@
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
- r.persistentState, results, newIntents, mService.mActivityTaskManager.isNextTransitionForward(),
+ r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
- lifecycleItem = ResumeActivityItem.obtain(mService.mActivityTaskManager.isNextTransitionForward());
+ lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
@@ -1551,25 +1550,24 @@
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
-
if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
- && mService.mHasHeavyWeightFeature) {
+ && mService.mAm.mHasHeavyWeightFeature) {
// This may be a heavy-weight process! Note that the package
// manager will ensure that only activity can run in the main
// process of the .apk, which is the only thing that will be
// considered heavy-weight.
if (app.processName.equals(app.info.packageName)) {
- if (mService.mHeavyWeightProcess != null
- && mService.mHeavyWeightProcess != app) {
+ if (mService.mAm.mHeavyWeightProcess != null
+ && mService.mAm.mHeavyWeightProcess != app) {
Slog.w(TAG, "Starting new heavy weight process " + app
+ " when already running "
- + mService.mHeavyWeightProcess);
+ + mService.mAm.mHeavyWeightProcess);
}
- mService.mHeavyWeightProcess = app;
- Message msg = mService.mHandler.obtainMessage(
+ mService.mAm.mHeavyWeightProcess = app;
+ Message msg = mService.mAm.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
- mService.mHandler.sendMessage(msg);
+ mService.mAm.mHandler.sendMessage(msg);
}
}
@@ -1580,7 +1578,7 @@
Slog.e(TAG, "Second failure launching "
+ r.intent.getComponent().flattenToShortString()
+ ", giving up", e);
- mService.appDiedLocked(app);
+ mService.mAm.appDiedLocked(app);
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
@@ -1627,7 +1625,7 @@
// Update any services we are bound to that might care about whether
// their client may have activities.
if (r.app != null) {
- mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
+ mService.mAm.mServices.updateServiceConnectionActivitiesLocked(r.app);
}
return true;
@@ -1663,7 +1661,7 @@
}
// Update the configuration of the activities on the display.
- return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
+ return mService.mAm.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
displayId);
}
@@ -1685,7 +1683,7 @@
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
- ProcessRecord app = mService.getProcessRecordLocked(r.processName,
+ ProcessRecord app = mService.mAm.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
@@ -1699,7 +1697,7 @@
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
- mService.mProcessStats);
+ mService.mAm.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
@@ -1712,7 +1710,7 @@
// restart the application.
}
- mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
+ mService.mAm.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
@@ -1728,16 +1726,16 @@
|| !resumedActivity.app.equals(targetActivity.app);
}
- if (sendHint && mService.mLocalPowerManager != null) {
- mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 1);
+ if (sendHint && mService.mAm.mLocalPowerManager != null) {
+ mService.mAm.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 1);
mPowerHintSent = true;
}
}
void sendPowerHintForLaunchEndIfNeeded() {
// Trigger launch power hint if activity is launched
- if (mPowerHintSent && mService.mLocalPowerManager != null) {
- mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 0);
+ if (mPowerHintSent && mService.mAm.mLocalPowerManager != null) {
+ mService.mAm.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 0);
mPowerHintSent = false;
}
}
@@ -1746,9 +1744,9 @@
String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, boolean ignoreTargetSecurity, boolean launchingInTask,
ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack) {
- final boolean isCallerRecents = mService.mActivityTaskManager.getRecentTasks() != null
- && mService.mActivityTaskManager.getRecentTasks().isCallerRecents(callingUid);
- final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
+ final boolean isCallerRecents = mService.getRecentTasks() != null
+ && mService.getRecentTasks().isCallerRecents(callingUid);
+ final int startAnyPerm = mService.mAm.checkPermission(START_ANY_ACTIVITY, callingPid,
callingUid);
if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) {
// If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the
@@ -1827,7 +1825,7 @@
// Check if the caller has enough privileges to embed activities and launch to private
// displays.
- final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+ final int startAnyPerm = mService.mAm.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
callingUid);
if (startAnyPerm == PERMISSION_GRANTED) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1849,7 +1847,7 @@
return false;
}
// Check if the caller is allowed to embed activities from other apps.
- if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid)
+ if (mService.mAm.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid)
== PERMISSION_DENIED && !uidPresentOnDisplay) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ " disallow activity embedding without permission.");
@@ -1907,7 +1905,7 @@
private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
- if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
+ if (!ignoreTargetSecurity && mService.mAm.checkComponentPermission(activityInfo.permission,
callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
== PERMISSION_DENIED) {
return ACTIVITY_RESTRICTION_PERMISSION;
@@ -1922,7 +1920,7 @@
return ACTIVITY_RESTRICTION_NONE;
}
- if (mService.mAppOpsService.noteOperation(opCode, callingUid,
+ if (mService.mAm.mAppOpsService.noteOperation(opCode, callingUid,
callingPackage) != AppOpsManager.MODE_ALLOWED) {
if (!ignoreTargetSecurity) {
return ACTIVITY_RESTRICTION_APPOP;
@@ -1956,7 +1954,7 @@
return ACTIVITY_RESTRICTION_NONE;
}
- if (mService.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) {
+ if (mService.mAm.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) {
return ACTIVITY_RESTRICTION_PERMISSION;
}
@@ -1965,7 +1963,7 @@
return ACTIVITY_RESTRICTION_NONE;
}
- if (mService.mAppOpsService.noteOperation(opCode, callingUid,
+ if (mService.mAm.mAppOpsService.noteOperation(opCode, callingUid,
callingPackage) != AppOpsManager.MODE_ALLOWED) {
return ACTIVITY_RESTRICTION_APPOP;
}
@@ -1990,19 +1988,19 @@
/**
* Called when the frontmost task is idle.
- * @return the state of mService.mBooting before this was called.
+ * @return the state of mService.mAm.mBooting before this was called.
*/
@GuardedBy("mService")
private boolean checkFinishBootingLocked() {
- final boolean booting = mService.mBooting;
+ final boolean booting = mService.mAm.mBooting;
boolean enableScreen = false;
- mService.mBooting = false;
- if (!mService.mBooted) {
- mService.mBooted = true;
+ mService.mAm.mBooting = false;
+ if (!mService.mAm.mBooted) {
+ mService.mAm.mBooted = true;
enableScreen = true;
}
if (booting || enableScreen) {
- mService.postFinishBooting(booting, enableScreen);
+ mService.mAm.postFinishBooting(booting, enableScreen);
}
return booting;
}
@@ -2051,7 +2049,7 @@
if (allResumedActivitiesIdle()) {
if (r != null) {
- mService.scheduleAppGcsLocked();
+ mService.mAm.scheduleAppGcsLocked();
}
if (mLaunchingActivity.isHeld()) {
@@ -2108,12 +2106,12 @@
// Complete user switch
if (startingUsers != null) {
for (int i = 0; i < startingUsers.size(); i++) {
- mService.mUserController.finishUserSwitch(startingUsers.get(i));
+ mService.mAm.mUserController.finishUserSwitch(startingUsers.get(i));
}
}
}
- mService.trimApplications();
+ mService.mAm.trimApplications();
//dump();
//mWindowManager.dump();
@@ -2207,10 +2205,10 @@
// Now set this one as the previous process, only if that really
// makes sense to.
if (r.app != null && fgApp != null && r.app != fgApp
- && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
- && r.app != mService.mHomeProcess) {
- mService.mPreviousProcess = r.app;
- mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
+ && r.lastVisibleTime > mService.mAm.mPreviousProcessVisibleTime
+ && r.app != mService.mAm.mHomeProcess) {
+ mService.mAm.mPreviousProcess = r.app;
+ mService.mAm.mPreviousProcessVisibleTime = r.lastVisibleTime;
}
}
@@ -2349,9 +2347,9 @@
if (options == null || options.getLaunchBounds() == null) {
return false;
}
- return (mService.mSupportsPictureInPicture
+ return (mService.mAm.mSupportsPictureInPicture
&& options.getLaunchWindowingMode() == WINDOWING_MODE_PINNED)
- || mService.mSupportsFreeformWindowManagement;
+ || mService.mAm.mSupportsFreeformWindowManagement;
}
LaunchParamsController getLaunchParamsController() {
@@ -3098,7 +3096,7 @@
}
// Find any running services associated with this app and stop if needed.
- mService.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
+ mService.mAm.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
if (!killProcess) {
return;
@@ -3107,7 +3105,7 @@
// Determine if the process(es) for this task should be killed.
final String pkg = component.getPackageName();
ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
- ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mProcessNames.getMap();
+ ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mAm.mProcessNames.getMap();
for (int i = 0; i < pmap.size(); i++) {
SparseArray<ProcessRecord> uids = pmap.valueAt(i);
@@ -3117,7 +3115,7 @@
// Don't kill process for a different user.
continue;
}
- if (proc == mService.mHomeProcess) {
+ if (proc == mService.mAm.mHomeProcess) {
// Don't kill the home process along with tasks from the same package.
continue;
}
@@ -3260,21 +3258,21 @@
// Ensure that we aren't trying to move into a multi-window stack without multi-window
// support
- if (inMultiWindowMode && !mService.mSupportsMultiWindow) {
+ if (inMultiWindowMode && !mService.mAm.mSupportsMultiWindow) {
throw new IllegalArgumentException("Device doesn't support multi-window, can not"
+ " reparent task=" + task + " to stack=" + stack);
}
// Ensure that we're not moving a task to a dynamic stack if device doesn't support
// multi-display.
- if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
+ if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mAm.mSupportsMultiDisplay) {
throw new IllegalArgumentException("Device doesn't support multi-display, can not"
+ " reparent task=" + task + " to stackId=" + stackId);
}
// Ensure that we aren't trying to move into a freeform stack without freeform support
if (stack.getWindowingMode() == WINDOWING_MODE_FREEFORM
- && !mService.mSupportsFreeformWindowManagement) {
+ && !mService.mAm.mSupportsFreeformWindowManagement) {
throw new IllegalArgumentException("Device doesn't support freeform, can not reparent"
+ " task=" + task);
}
@@ -3307,7 +3305,7 @@
return false;
}
- if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
+ if (!mService.mAm.mForceResizableActivities && !r.supportsPictureInPicture()) {
Slog.w(TAG,
"moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
+ " r=" + r);
@@ -3388,7 +3386,7 @@
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyActivityPinned(r);
+ mService.getTaskChangeNotificationController().notifyActivityPinned(r);
}
/** Move activity with its stack to front and make the stack focused. */
@@ -3495,7 +3493,7 @@
throw new IllegalStateException("Calling must be system uid");
}
mLaunchingActivity.release();
- mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+ mService.mAm.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
}
}
@@ -3520,7 +3518,7 @@
long timeRemaining = endTime - System.currentTimeMillis();
if (timeRemaining > 0) {
try {
- mService.wait(timeRemaining);
+ mService.mAm.wait(timeRemaining);
} catch (InterruptedException e) {
}
} else {
@@ -3602,7 +3600,7 @@
}
void checkReadyForSleepLocked(boolean allowDelay) {
- if (!mService.isSleepingOrShuttingDownLocked()) {
+ if (!mService.mAm.isSleepingOrShuttingDownLocked()) {
// Do not care.
return;
}
@@ -3619,8 +3617,8 @@
if (mGoingToSleep.isHeld()) {
mGoingToSleep.release();
}
- if (mService.mShuttingDown) {
- mService.notifyAll();
+ if (mService.mAm.mShuttingDown) {
+ mService.mAm.notifyAll();
}
}
@@ -3648,7 +3646,7 @@
final ActivityStack stack = r.getStack();
if (isFocusedStack(stack)) {
- mService.updateUsageStats(r, true);
+ mService.mAm.updateUsageStats(r, true);
}
if (allResumedActivitiesComplete()) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
@@ -3675,7 +3673,7 @@
r.mLaunchTaskBehind = false;
mRecentTasks.add(task);
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskStackChanged();
+ mService.getTaskChangeNotificationController().notifyTaskStackChanged();
r.setVisibility(false);
// When launching tasks behind, update the last active time of the top task after the new
@@ -3875,7 +3873,7 @@
/** Checks whether the userid is a profile of the current user. */
boolean isCurrentProfileLocked(int userId) {
if (userId == mCurrentUser) return true;
- return mService.mUserController.isCurrentProfile(userId);
+ return mService.mAm.mUserController.isCurrentProfile(userId);
}
/**
@@ -3922,7 +3920,7 @@
final ActivityStack stack = s.getStack();
final boolean shouldSleepOrShutDown = stack != null
? stack.shouldSleepOrShutDownActivities()
- : mService.isSleepingOrShuttingDownLocked();
+ : mService.mAm.isSleepingOrShuttingDownLocked();
if (!waitingVisible || shouldSleepOrShutDown) {
if (!processPausingActivities && s.isState(PAUSING)) {
// Defer processing pausing activities in this iteration and reschedule
@@ -4276,7 +4274,7 @@
}
private void handleDisplayAdded(int displayId) {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
getActivityDisplayOrCreateLocked(displayId);
}
}
@@ -4339,7 +4337,7 @@
throw new IllegalArgumentException("Can't remove the primary display.");
}
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
return;
@@ -4354,7 +4352,7 @@
}
private void handleDisplayChanged(int displayId) {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
// TODO: The following code block should be moved into {@link ActivityDisplay}.
if (activityDisplay != null) {
@@ -4363,7 +4361,7 @@
int displayState = activityDisplay.mDisplay.getState();
if (displayState == Display.STATE_OFF && activityDisplay.mOffToken == null) {
activityDisplay.mOffToken =
- mService.acquireSleepToken("Display-off", displayId);
+ mService.mAm.acquireSleepToken("Display-off", displayId);
} else if (displayState == Display.STATE_ON
&& activityDisplay.mOffToken != null) {
activityDisplay.mOffToken.release();
@@ -4396,7 +4394,7 @@
if (display != null) {
display.mAllSleepTokens.remove(token);
if (display.mAllSleepTokens.isEmpty()) {
- mService.updateSleepIfNeededLocked();
+ mService.mAm.updateSleepIfNeededLocked();
}
}
}
@@ -4410,7 +4408,7 @@
}
display.mAllSleepTokens.clear();
- mService.updateSleepIfNeededLocked();
+ mService.mAm.updateSleepIfNeededLocked();
}
private StackInfo getStackInfo(ActivityStack stack) {
@@ -4503,12 +4501,12 @@
}
// The task might have landed on a display different from requested.
// TODO(multi-display): Find proper stack for the task on the default display.
- mAtm.setTaskWindowingMode(task.taskId,
+ mService.setTaskWindowingMode(task.taskId,
WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
if (preferredDisplayId != actualDisplayId) {
// Display a warning toast that we tried to put a non-resizeable task on a secondary
// display with config different from global config.
- mService.mActivityTaskManager.getTaskChangeNotificationController()
+ mService.getTaskChangeNotificationController()
.notifyActivityLaunchOnSecondaryDisplayFailed();
return;
}
@@ -4517,7 +4515,7 @@
if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) {
// Display a warning toast that we tried to put an app that doesn't support split-screen
// in split-screen.
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
+ mService.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
// Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
// we need to move it to top of fullscreen stack, otherwise it will be covered.
@@ -4537,7 +4535,7 @@
final int reason = isSecondaryDisplayPreferred
? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY
: FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyActivityForcedResizable(
+ mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
task.taskId, reason, packageName);
}
}
@@ -4661,7 +4659,7 @@
}
void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
processPausingActivities, null);
}
@@ -4671,7 +4669,7 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
r.updateMultiWindowMode();
@@ -4679,7 +4677,7 @@
}
} break;
case REPORT_PIP_MODE_CHANGED_MSG: {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mPipModeChangedActivities.remove(i);
r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds,
@@ -4701,20 +4699,20 @@
false /* processPausingActivities */);
} break;
case RESUME_TOP_ACTIVITY_MSG: {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
resumeFocusedStackTopActivityLocked();
}
} break;
case SLEEP_TIMEOUT_MSG: {
- synchronized (mService) {
- if (mService.isSleepingOrShuttingDownLocked()) {
+ synchronized (mService.mGlobalLock) {
+ if (mService.mAm.isSleepingOrShuttingDownLocked()) {
Slog.w(TAG, "Sleep timeout! Sleeping now.");
checkReadyForSleepLocked(false /* allowDelay */);
}
}
} break;
case LAUNCH_TIMEOUT_MSG: {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
if (mLaunchingActivity.isHeld()) {
Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
if (VALIDATE_WAKE_LOCK_CALLER
@@ -4735,7 +4733,7 @@
handleDisplayRemoved(msg.arg1);
} break;
case LAUNCH_TASK_BEHIND_COMPLETE: {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
if (r != null) {
handleLaunchTaskBehindCompleteLocked(r);
@@ -4823,14 +4821,14 @@
// If the user must confirm credentials (e.g. when first launching a work app and the
// Work Challenge is present) let startActivityInPackage handle the intercepting.
- if (!mService.mUserController.shouldConfirmCredentials(task.userId)
+ if (!mService.mAm.mUserController.shouldConfirmCredentials(task.userId)
&& task.getRootActivity() != null) {
final ActivityRecord targetActivity = task.getTopActivity();
sendPowerHintForLaunchStartIfNeeded(true /* forceSend */, targetActivity);
mActivityMetricsLogger.notifyActivityLaunching();
try {
- mService.mActivityTaskManager.moveTaskToFrontLocked(task.taskId, 0, options,
+ mService.moveTaskToFrontLocked(task.taskId, 0, options,
true /* fromRecents */);
} finally {
mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT,
@@ -4951,7 +4949,7 @@
@Override
public void release() {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
removeSleepTokenLocked(this);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index a7c3200..fa001df 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -65,7 +65,7 @@
private static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 1;
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
private final ActivityStackSupervisor mSupervisor;
/** Last home activity record we attempted to start. */
@@ -96,7 +96,7 @@
public void handleMessage(Message msg) {
switch(msg.what) {
case DO_PENDING_ACTIVITY_LAUNCHES_MSG:
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
doPendingActivityLaunches(true);
}
break;
@@ -111,22 +111,22 @@
*/
private ActivityStarter mLastStarter;
- ActivityStartController(ActivityManagerService service) {
+ ActivityStartController(ActivityTaskManagerService service) {
this(service, service.mStackSupervisor,
new DefaultFactory(service, service.mStackSupervisor,
new ActivityStartInterceptor(service, service.mStackSupervisor)));
}
@VisibleForTesting
- ActivityStartController(ActivityManagerService service, ActivityStackSupervisor supervisor,
+ ActivityStartController(ActivityTaskManagerService service, ActivityStackSupervisor supervisor,
Factory factory) {
mService = service;
mSupervisor = supervisor;
- mHandler = new StartHandler(mService.mHandlerThread.getLooper());
+ mHandler = new StartHandler(mService.mH.getLooper());
mFactory = factory;
mFactory.setController(this);
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service,
- service.mHandler);
+ service.mH);
}
/**
@@ -182,7 +182,7 @@
*/
void startSetupActivity() {
// Only do this once per boot.
- if (mService.getCheckedForSetup()) {
+ if (mService.mAm.getCheckedForSetup()) {
return;
}
@@ -190,10 +190,10 @@
// version than the last one shown, and we are not running in
// low-level factory test mode.
final ContentResolver resolver = mService.mContext.getContentResolver();
- if (mService.mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
+ if (mService.mAm.mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
Settings.Global.getInt(resolver,
Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
- mService.setCheckedForSetup(true);
+ mService.mAm.setCheckedForSetup(true);
// See if we should be showing the platform update setup UI.
final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
@@ -237,10 +237,10 @@
int checkTargetUser(int targetUserId, boolean validateIncomingUser,
int realCallingPid, int realCallingUid, String reason) {
if (validateIncomingUser) {
- return mService.mUserController.handleIncomingUser(realCallingPid, realCallingUid,
+ return mService.mAm.mUserController.handleIncomingUser(realCallingPid, realCallingUid,
targetUserId, false, ALLOW_FULL_ONLY, reason, null);
} else {
- mService.mUserController.ensureNotSpecialUser(targetUserId);
+ mService.mAm.mUserController.ensureNotSpecialUser(targetUserId);
return targetUserId;
}
}
@@ -320,7 +320,7 @@
}
final long origId = Binder.clearCallingIdentity();
try {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
ActivityRecord[] outActivity = new ActivityRecord[1];
for (int i=0; i < intents.length; i++) {
Intent intent = intents[i];
@@ -343,7 +343,7 @@
null, userId, ActivityStarter.computeResolveFilterUid(
callingUid, realCallingUid, UserHandle.USER_NULL));
// TODO: New, check if this is correct
- aInfo = mService.getActivityInfoForUser(aInfo, userId);
+ aInfo = mService.mAm.getActivityInfoForUser(aInfo, userId);
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index ff97db8..171c0bb 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -66,7 +66,7 @@
*/
class ActivityStartInterceptor {
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
private final ActivityStackSupervisor mSupervisor;
private final Context mServiceContext;
private final UserController mUserController;
@@ -99,12 +99,13 @@
TaskRecord mInTask;
ActivityOptions mActivityOptions;
- ActivityStartInterceptor(ActivityManagerService service, ActivityStackSupervisor supervisor) {
- this(service, supervisor, service.mContext, service.mUserController);
+ ActivityStartInterceptor(
+ ActivityTaskManagerService service, ActivityStackSupervisor supervisor) {
+ this(service, supervisor, service.mContext, service.mAm.mUserController);
}
@VisibleForTesting
- ActivityStartInterceptor(ActivityManagerService service, ActivityStackSupervisor supervisor,
+ ActivityStartInterceptor(ActivityTaskManagerService service, ActivityStackSupervisor supervisor,
Context context, UserController userController) {
mService = service;
mSupervisor = supervisor;
@@ -127,7 +128,7 @@
private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) {
Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary();
- final IIntentSender target = mService.getIntentSenderLocked(
+ final IIntentSender target = mService.mAm.getIntentSenderLocked(
INTENT_SENDER_ACTIVITY, mCallingPackage, callingUid, mUserId, null /*token*/,
null /*resultCode*/, 0 /*requestCode*/,
new Intent[] { mIntent }, new String[] { mResolvedType },
@@ -238,7 +239,7 @@
(mAInfo.applicationInfo.flags & FLAG_SUSPENDED) == 0) {
return false;
}
- final PackageManagerInternal pmi = mService.getPackageManagerInternalLocked();
+ final PackageManagerInternal pmi = mService.mAm.getPackageManagerInternalLocked();
if (pmi == null) {
return false;
}
@@ -319,7 +320,7 @@
private boolean interceptHarmfulAppIfNeeded() {
CharSequence harmfulAppWarning;
try {
- harmfulAppWarning = mService.getPackageManager()
+ harmfulAppWarning = mService.mAm.getPackageManager()
.getHarmfulAppWarning(mAInfo.packageName, mUserId);
} catch (RemoteException ex) {
return false;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 796018c..f50bb37 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -132,7 +132,7 @@
private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
private static final int INVALID_LAUNCH_MODE = -1;
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
private final ActivityStackSupervisor mSupervisor;
private final ActivityStartInterceptor mInterceptor;
private final ActivityStartController mController;
@@ -233,14 +233,14 @@
private final int MAX_STARTER_COUNT = 3;
private ActivityStartController mController;
- private ActivityManagerService mService;
+ private ActivityTaskManagerService mService;
private ActivityStackSupervisor mSupervisor;
private ActivityStartInterceptor mInterceptor;
private SynchronizedPool<ActivityStarter> mStarterPool =
new SynchronizedPool<>(MAX_STARTER_COUNT);
- DefaultFactory(ActivityManagerService service,
+ DefaultFactory(ActivityTaskManagerService service,
ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
mService = service;
mSupervisor = supervisor;
@@ -410,7 +410,7 @@
}
}
- ActivityStarter(ActivityStartController controller, ActivityManagerService service,
+ ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
mController = controller;
mService = service;
@@ -583,7 +583,7 @@
ProcessRecord callerApp = null;
if (caller != null) {
- callerApp = mService.getRecordForAppLocked(caller);
+ callerApp = mService.mAm.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
@@ -672,7 +672,7 @@
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
try {
intent.addCategory(Intent.CATEGORY_VOICE);
- if (!mService.getPackageManager().activitySupportsIntent(
+ if (!mService.mAm.getPackageManager().activitySupportsIntent(
intent.getComponent(), intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in current voice task does not support voice: "
@@ -690,7 +690,7 @@
// If the caller is starting a new voice session, just make sure the target
// is actually allowing it to run this way.
try {
- if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
+ if (!mService.mAm.getPackageManager().activitySupportsIntent(intent.getComponent(),
intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in new voice task does not support: "
@@ -717,7 +717,7 @@
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
inTask != null, callerApp, resultRecord, resultStack);
- abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
+ abort |= !mService.mAm.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
// Merge the two options bundles, while realCallerOptions takes precedence.
@@ -729,15 +729,15 @@
.getPendingRemoteAnimationRegistry()
.overrideOptionsIfNeeded(callingPackage, checkedOptions);
}
- if (mService.mController != null) {
+ if (mService.mAm.mController != null) {
try {
// The Intent we give to the watcher has the extra data
// stripped off, since it can contain private information.
Intent watchIntent = intent.cloneFilter();
- abort |= !mService.mController.activityStarting(watchIntent,
+ abort |= !mService.mAm.mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
- mService.mController = null;
+ mService.mAm.mController = null;
}
}
@@ -770,10 +770,10 @@
// If permissions need a review before any of the app components can run, we
// launch the review activity and pass a pending intent to start the activity
// we are to launching now after the review is completed.
- if (mService.mPermissionReviewRequired && aInfo != null) {
- if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
+ if (mService.mAm.mPermissionReviewRequired && aInfo != null) {
+ if (mService.mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
- IIntentSender target = mService.getIntentSenderLocked(
+ IIntentSender target = mService.mAm.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
callingUid, userId, null, null, 0, new Intent[]{intent},
new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
@@ -823,9 +823,9 @@
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
- ActivityRecord r = new ActivityRecord(mService.mActivityTaskManager, callerApp, callingPid,
+ ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid,
callingUid,
- callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
+ callingPackage, intent, resolvedType, aInfo, mService.mAm.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
@@ -844,7 +844,7 @@
// one, check whether app switches are allowed.
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
- if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
+ if (!mService.mAm.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
sourceRecord, startFlags, stack, callerApp));
@@ -853,15 +853,15 @@
}
}
- if (mService.mDidAppSwitch) {
+ if (mService.mAm.mDidAppSwitch) {
// This is the second allowed switch since we stopped switches,
// so now just generally allow switches. Use case: user presses
// home (switches disabled, switch to home, mDidAppSwitch now true);
// user taps a home icon (coming from home so allowed, we hit here
// and now allow anyone to switch again).
- mService.mAppSwitchesAllowedTime = 0;
+ mService.mAm.mAppSwitchesAllowedTime = 0;
} else {
- mService.mDidAppSwitch = true;
+ mService.mAm.mDidAppSwitch = true;
}
mController.doPendingActivityLaunches(false);
@@ -879,7 +879,7 @@
String resolvedType, int userId) {
if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
// request phase two resolution
- mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
+ mService.mAm.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
auxiliaryResponse, originalIntent, resolvedType, callingPackage,
verificationBundle, userId);
}
@@ -930,7 +930,7 @@
// anyone interested in this piece of information.
switch (startedActivityStack.getWindowingMode()) {
case WINDOWING_MODE_PINNED:
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
+ mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
clearedTask);
break;
case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
@@ -979,7 +979,7 @@
&& !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
&& !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
&& !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
- && mService.getPackageManagerInternalLocked()
+ && mService.mAm.getPackageManagerInternalLocked()
.isInstantAppInstallerComponent(intent.getComponent())) {
// intercept intents targeted directly to the ephemeral installer the
// ephemeral installer should never be started with a raw Intent; instead
@@ -1021,10 +1021,10 @@
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
final ActivityStack stack = mSupervisor.mFocusedStack;
stack.mConfigWillChange = globalConfig != null
- && mService.getGlobalConfiguration().diff(globalConfig) != 0;
+ && mService.mAm.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Starting activity when config will change = " + stack.mConfigWillChange);
@@ -1033,16 +1033,16 @@
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
- mService.mHasHeavyWeightFeature) {
+ mService.mAm.mHasHeavyWeightFeature) {
// This may be a heavy-weight process! Check to see if we already
// have another, different heavy-weight process running.
if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
- final ProcessRecord heavy = mService.mHeavyWeightProcess;
+ final ProcessRecord heavy = mService.mAm.mHeavyWeightProcess;
if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
|| !heavy.processName.equals(aInfo.processName))) {
int appCallingUid = callingUid;
if (caller != null) {
- ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
+ ProcessRecord callerApp = mService.mAm.getRecordForAppLocked(caller);
if (callerApp != null) {
appCallingUid = callerApp.info.uid;
} else {
@@ -1054,7 +1054,7 @@
}
}
- IIntentSender target = mService.getIntentSenderLocked(
+ IIntentSender target = mService.mAm.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, "android",
appCallingUid, userId, null, null, 0, new Intent[] { intent },
new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
@@ -1090,7 +1090,7 @@
callingUid, realCallingUid, mRequest.filterCallingUid));
aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
- aInfo = mService.getActivityInfoForUser(aInfo, userId);
+ aInfo = mService.mAm.getActivityInfoForUser(aInfo, userId);
}
}
}
@@ -1110,12 +1110,12 @@
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
- mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
+ mService.mAm.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
stack.mConfigWillChange = false;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Updating to new configuration after starting activity.");
- mService.updateConfigurationLocked(globalConfig, null, false);
+ mService.mAm.updateConfigurationLocked(globalConfig, null, false);
}
if (outResult != null) {
@@ -1128,7 +1128,7 @@
mSupervisor.mWaitingActivityLaunched.add(outResult);
do {
try {
- mService.wait();
+ mService.mGlobalLock.wait();
} catch (InterruptedException e) {
}
} while (outResult.result != START_TASK_TO_FRONT
@@ -1159,7 +1159,7 @@
// Note: the timeout variable is not currently not ever set.
do {
try {
- mService.wait();
+ mService.mGlobalLock.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
@@ -1423,9 +1423,9 @@
return result;
}
- mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
+ mService.mAm.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
- mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
+ mService.mAm.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
@@ -1821,7 +1821,7 @@
}
// Get the virtual display id from ActivityManagerService.
- int displayId = mService.mVr2dDisplayId;
+ int displayId = mService.mAm.mVr2dDisplayId;
if (displayId != INVALID_DISPLAY) {
if (DEBUG_STACK) {
Slog.d(TAG, "getSourceDisplayId :" + displayId);
@@ -2115,13 +2115,13 @@
// be not suitable. Let's check other displays.
if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
// Can't use target display, lets find a stack on the source display.
- mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
+ mTargetStack = mSupervisor.getValidLaunchStackOnDisplay(
sourceStack.mDisplayId, mStartActivity);
}
if (mTargetStack == null) {
// There are no suitable stacks on the target and source display(s). Look on all
// displays.
- mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
+ mTargetStack = mSupervisor.getNextValidLaunchStackLocked(
mStartActivity, -1 /* currentFocus */);
}
}
@@ -2252,7 +2252,7 @@
final ActivityStack stack = task.getStack();
if (stack != null && stack.resizeStackWithLaunchBounds()) {
- mService.mActivityTaskManager.resizeStack(
+ mService.resizeStack(
stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
} else {
task.updateOverrideConfiguration(bounds);
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 37ee3f7..90097fd 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -128,6 +128,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.LocaleList;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
@@ -222,6 +223,9 @@
KeyguardController mKeyguardController;
private final ClientLifecycleManager mLifecycleManager;
private TaskChangeNotificationController mTaskChangeNotificationController;
+ /** The controller for all operations related to locktask. */
+ private LockTaskController mLockTaskController;
+ private ActivityStartController mActivityStartController;
boolean mSuppressResizeConfigChanges;
@@ -240,6 +244,16 @@
}
}
+ /** Current sequencing integer of the configuration, for skipping old configurations. */
+ int mConfigurationSeq;
+
+ /**
+ * Temp object used when global and/or display override configuration is updated. It is also
+ * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
+ * anyone...
+ */
+ Configuration mTempConfig = new Configuration();
+
ActivityTaskManagerService(Context context) {
mContext = context;
mLifecycleManager = new ClientLifecycleManager();
@@ -256,17 +270,32 @@
mAm = am;
mGlobalLock = mAm;
mH = new H(mAm.mHandlerThread.getLooper());
- mStackSupervisor = mAm.mStackSupervisor;
+
+ mTempConfig.setToDefaults();
+ mTempConfig.setLocales(LocaleList.getDefault());
+ mConfigurationSeq = mTempConfig.seq = 1;
+ mStackSupervisor = createStackSupervisor();
+ mStackSupervisor.onConfigurationChanged(mTempConfig);
+
mTaskChangeNotificationController =
new TaskChangeNotificationController(mAm, mStackSupervisor, mH);
+ mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
+ mActivityStartController = new ActivityStartController(this);
mRecentTasks = createRecentTasks();
mStackSupervisor.setRecentTasks(mRecentTasks);
mVrController = new VrController(mAm);
mKeyguardController = mStackSupervisor.getKeyguardController();
}
+ protected ActivityStackSupervisor createStackSupervisor() {
+ final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper());
+ supervisor.initialize();
+ return supervisor;
+ }
+
void setWindowManager(WindowManagerService wm) {
mWindowManager = wm;
+ mLockTaskController.setWindowManager(wm);
}
protected RecentTasks createRecentTasks() {
@@ -281,10 +310,18 @@
return mLifecycleManager;
}
+ ActivityStartController getActivityStartController() {
+ return mActivityStartController;
+ }
+
TaskChangeNotificationController getTaskChangeNotificationController() {
return mTaskChangeNotificationController;
}
+ LockTaskController getLockTaskController() {
+ return mLockTaskController;
+ }
+
private void start() {
LocalServices.addService(ActivityTaskManagerInternal.class, new LocalService());
}
@@ -326,7 +363,7 @@
userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
// TODO: Switch to user app stacks here.
- return mAm.getActivityStartController().startActivities(caller, -1, callingPackage, intents,
+ return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
}
@@ -345,11 +382,11 @@
boolean validateIncomingUser) {
mAm.enforceNotIsolatedCaller("startActivityAsUser");
- userId = mAm.getActivityStartController().checkTargetUser(userId, validateIncomingUser,
+ userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
- return mAm.getActivityStartController().obtainStarter(intent, "startActivityAsUser")
+ return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
@@ -488,7 +525,7 @@
final long origId = Binder.clearCallingIdentity();
// TODO(b/64750076): Check if calling pid should really be -1.
- final int res = mAm.getActivityStartController()
+ final int res = getActivityStartController()
.obtainStarter(intent, "startNextMatchingActivity")
.setCaller(r.app.thread)
.setResolvedType(r.resolvedType)
@@ -524,7 +561,7 @@
Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
"startActivityAndWait", null);
// TODO: Switch to user app stacks here.
- mAm.getActivityStartController().obtainStarter(intent, "startActivityAndWait")
+ getActivityStartController().obtainStarter(intent, "startActivityAndWait")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
@@ -551,7 +588,7 @@
Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
"startActivityWithConfig", null);
// TODO: Switch to user app stacks here.
- return mAm.getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
+ return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
@@ -626,7 +663,7 @@
// TODO: Switch to user app stacks here.
try {
- return mAm.getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
+ return getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
.setCallingUid(targetUid)
.setCallingPackage(targetPackage)
.setResolvedType(resolvedType)
@@ -667,7 +704,7 @@
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
ALLOW_FULL_ONLY, "startVoiceActivity", null);
// TODO: Switch to user app stacks here.
- return mAm.getActivityStartController().obtainStarter(intent, "startVoiceActivity")
+ return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
.setCallingUid(callingUid)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
@@ -687,7 +724,7 @@
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
ALLOW_FULL_ONLY, "startAssistantActivity", null);
- return mAm.getActivityStartController().obtainStarter(intent, "startAssistantActivity")
+ return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
.setCallingUid(callingUid)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
@@ -709,7 +746,7 @@
// Start a new recents animation
final RecentsAnimation anim = new RecentsAnimation(mAm, mStackSupervisor,
- mAm.getActivityStartController(), mAm.mWindowManager, mAm.mUserController,
+ getActivityStartController(), mAm.mWindowManager, mAm.mUserController,
callingPid);
anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
recentsUid, assistDataReceiver);
@@ -769,7 +806,7 @@
}
// Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
// finish.
- if (mAm.getLockTaskController().activityBlockedFromFinish(r)) {
+ if (getLockTaskController().activityBlockedFromFinish(r)) {
return false;
}
@@ -836,7 +873,7 @@
// Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
// can finish.
final TaskRecord task = r.getTask();
- if (mAm.getLockTaskController().activityBlockedFromFinish(r)) {
+ if (getLockTaskController().activityBlockedFromFinish(r)) {
return false;
}
return task.getStack().finishActivityAffinityLocked(r);
@@ -1442,7 +1479,7 @@
Slog.d(TAG, "Could not find task for id: "+ taskId);
return;
}
- if (mAm.getLockTaskController().isLockTaskModeViolation(task)) {
+ if (getLockTaskController().isLockTaskModeViolation(task)) {
Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
return;
}
@@ -1812,7 +1849,7 @@
// When a task is locked, dismiss the pinned stack if it exists
mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
- mAm.getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
+ getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1823,7 +1860,7 @@
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- mAm.getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
+ getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
}
// Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
// task and jumping straight into a call in the case of emergency call back.
@@ -1844,7 +1881,7 @@
@Override
public int getLockTaskModeState() {
synchronized (mGlobalLock) {
- return mAm.getLockTaskController().getLockTaskModeState();
+ return getLockTaskController().getLockTaskModeState();
}
}
@@ -2601,7 +2638,7 @@
if (r == null) {
return;
}
- mAm.getLockTaskController().showLockTaskToast();
+ getLockTaskController().showLockTaskToast();
}
}
@@ -3319,7 +3356,7 @@
synchronized (mGlobalLock) {
if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
Integer.toHexString(flags));
- mAm.getLockTaskController().updateLockTaskFeatures(userId, flags);
+ getLockTaskController().updateLockTaskFeatures(userId, flags);
}
}
@@ -3383,7 +3420,7 @@
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
- mAm.getActivityStartController().registerRemoteAnimationForNextActivityStart(
+ getActivityStartController().registerRemoteAnimationForNextActivityStart(
packageName, adapter);
} finally {
Binder.restoreCallingIdentity(origId);
@@ -3595,7 +3632,7 @@
}
synchronized (mGlobalLock) {
- return mAm.getActivityStartController().startActivitiesInPackage(
+ return getActivityStartController().startActivitiesInPackage(
packageUid, packageName,
intents, resolvedTypes, null /* resultTo */,
SafeActivityOptions.fromBundle(bOptions), userId,
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 75090d4..eac3501 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -479,7 +479,7 @@
final Set<String> cats = task.intent != null
? task.intent.getCategories() : null;
if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
- mService.getActivityStartController().startActivityInPackage(
+ mService.mActivityTaskManager.getActivityStartController().startActivityInPackage(
task.mCallingUid, callingPid, callingUid, task.mCallingPackage,
task.intent, null, null, null, 0, 0,
new SafeActivityOptions(ActivityOptions.makeBasic()),
diff --git a/services/core/java/com/android/server/am/AppTaskImpl.java b/services/core/java/com/android/server/am/AppTaskImpl.java
index 4a7c21c..953d3b8 100644
--- a/services/core/java/com/android/server/am/AppTaskImpl.java
+++ b/services/core/java/com/android/server/am/AppTaskImpl.java
@@ -127,7 +127,7 @@
}
}
- return mService.mAm.getActivityStartController().obtainStarter(intent, "AppTaskImpl")
+ return mService.getActivityStartController().obtainStarter(intent, "AppTaskImpl")
.setCaller(appThread)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index e0aa2a2..db09165 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -343,12 +343,12 @@
allIntents[allIntents.length-1] = finalIntent;
allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
- res = owner.getActivityStartController().startActivitiesInPackage(
+ res = owner.mActivityTaskManager.getActivityStartController().startActivitiesInPackage(
uid, key.packageName, allIntents, allResolvedTypes,
resultTo, mergedOptions, userId,
false /* validateIncomingUser */);
} else {
- res = owner.getActivityStartController().startActivityInPackage(uid,
+ res = owner.mActivityTaskManager.getActivityStartController().startActivityInPackage(uid,
callingPid, callingUid, key.packageName, finalIntent,
resolvedType, resultTo, resultWho, requestCode, 0,
mergedOptions, userId, null, "PendingIntentRecord",
diff --git a/services/core/java/com/android/server/am/PendingRemoteAnimationRegistry.java b/services/core/java/com/android/server/am/PendingRemoteAnimationRegistry.java
index 77713f5..877d896 100644
--- a/services/core/java/com/android/server/am/PendingRemoteAnimationRegistry.java
+++ b/services/core/java/com/android/server/am/PendingRemoteAnimationRegistry.java
@@ -33,9 +33,9 @@
private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
private final Handler mHandler;
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
- PendingRemoteAnimationRegistry(ActivityManagerService service, Handler handler) {
+ PendingRemoteAnimationRegistry(ActivityTaskManagerService service, Handler handler) {
mService = service;
mHandler = handler;
}
@@ -74,7 +74,7 @@
this.packageName = packageName;
this.adapter = adapter;
mHandler.postDelayed(() -> {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
final Entry entry = mEntries.get(packageName);
if (entry == this) {
mEntries.remove(packageName);
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 29898b1..edc6e53 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -55,7 +55,7 @@
void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
boolean fromFullscreen) {
if (skipResizeAnimation(toBounds == null /* toFullscreen */)) {
- mService.mActivityTaskManager.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+ mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
} else {
getWindowContainerController().animateResizePinnedStack(toBounds, sourceHintBounds,
animationDuration, fromFullscreen);
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 5390127..749589b 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -529,7 +529,7 @@
}
for (int i = mTasks.size() - 1; i >= 0; --i) {
final TaskRecord tr = mTasks.get(i);
- if (tr.userId == userId && !mService.mAm.getLockTaskController().isTaskWhitelisted(tr)) {
+ if (tr.userId == userId && !mService.getLockTaskController().isTaskWhitelisted(tr)) {
remove(tr);
}
}
@@ -1162,7 +1162,7 @@
}
// If we're in lock task mode, ignore the root task
- if (task == mService.mAm.getLockTaskController().getRootTask()) {
+ if (task == mService.getLockTaskController().getRootTask()) {
return false;
}
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index 55d17a9..778990b 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -192,7 +192,7 @@
// component or has the START_TASKS_FROM_RECENTS permission
if (options.getLaunchTaskId() != INVALID_TASK_ID
&& !supervisor.mRecentTasks.isCallerRecents(callingUid)) {
- final int startInTaskPerm = supervisor.mService.checkPermission(
+ final int startInTaskPerm = supervisor.mService.mAm.checkPermission(
START_TASKS_FROM_RECENTS, callingPid, callingUid);
if (startInTaskPerm == PERMISSION_DENIED) {
final String msg = "Permission Denial: starting " + getIntentString(intent)
@@ -230,7 +230,7 @@
// Check permission for remote animations
final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
- if (adapter != null && supervisor.mService.checkPermission(
+ if (adapter != null && supervisor.mService.mAm.checkPermission(
CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, callingPid, callingUid)
!= PERMISSION_GRANTED) {
final String msg = "Permission Denial: starting " + getIntentString(intent)
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index 7896e2d..efb80be 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -52,7 +52,8 @@
// Delay in notifying task stack change listeners (in millis)
private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
- private final ActivityManagerService mService;
+ // Global lock used by the service the instantiate objects of this class.
+ private final Object mServiceLock;
private final ActivityStackSupervisor mStackSupervisor;
private final Handler mHandler;
@@ -149,7 +150,7 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case LOG_STACK_STATE_MSG: {
- synchronized (mService) {
+ synchronized (mServiceLock) {
mStackSupervisor.logStackState();
}
break;
@@ -209,15 +210,15 @@
}
}
- public TaskChangeNotificationController(ActivityManagerService service,
+ public TaskChangeNotificationController(Object serviceLock,
ActivityStackSupervisor stackSupervisor, Handler handler) {
- mService = service;
+ mServiceLock = serviceLock;
mStackSupervisor = stackSupervisor;
mHandler = new MainHandler(handler.getLooper());
}
public void registerTaskStackListener(ITaskStackListener listener) {
- synchronized (mService) {
+ synchronized (mServiceLock) {
if (listener != null) {
if (Binder.getCallingPid() == android.os.Process.myPid()) {
if (!mLocalTaskStackListeners.contains(listener)) {
@@ -231,7 +232,7 @@
}
public void unregisterTaskStackListener(ITaskStackListener listener) {
- synchronized (mService) {
+ synchronized (mServiceLock) {
if (listener != null) {
if (Binder.getCallingPid() == android.os.Process.myPid()) {
mLocalTaskStackListeners.remove(listener);
@@ -243,7 +244,7 @@
}
private void forAllRemoteListeners(TaskStackConsumer callback, Message message) {
- synchronized (mService) {
+ synchronized (mServiceLock) {
for (int i = mRemoteTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
try {
// Make a one-way callback to the listener
@@ -257,7 +258,7 @@
}
private void forAllLocalListeners(TaskStackConsumer callback, Message message) {
- synchronized (mService) {
+ synchronized (mServiceLock) {
for (int i = mLocalTaskStackListeners.size() - 1; i >= 0; i--) {
try {
callback.accept(mLocalTaskStackListeners.get(i), message);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index b363866..6eac4bc 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -295,7 +295,7 @@
int mCallingUid;
String mCallingPackage;
- final ActivityManagerService mService;
+ final ActivityTaskManagerService mService;
private final Rect mTmpStableBounds = new Rect();
private final Rect mTmpNonDecorBounds = new Rect();
@@ -320,10 +320,10 @@
private TaskWindowContainerController mWindowContainerController;
/**
- * Don't use constructor directly. Use {@link #create(ActivityManagerService, int, ActivityInfo,
- * Intent, TaskDescription)} instead.
+ * Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
+ * ActivityInfo, Intent, TaskDescription)} instead.
*/
- TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
+ TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
mService = service;
userId = UserHandle.getUserId(info.applicationInfo.uid);
@@ -339,14 +339,15 @@
setIntent(_intent, info);
setMinDimensions(info);
touchActiveTime();
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
+ mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
}
/**
- * Don't use constructor directly. Use {@link #create(ActivityManagerService, int, ActivityInfo,
+ * Don't use constructor directly.
+ * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
* Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
*/
- TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
+ TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
TaskDescription _taskDescription) {
mService = service;
userId = UserHandle.getUserId(info.applicationInfo.uid);
@@ -369,13 +370,13 @@
lastTaskDescription = _taskDescription;
touchActiveTime();
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
+ mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
}
/**
* Don't use constructor directly. This is only used by XML parser.
*/
- TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
+ TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
@@ -419,7 +420,7 @@
mSupportsPictureInPicture = supportsPictureInPicture;
mMinWidth = minWidth;
mMinHeight = minHeight;
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
+ mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
}
TaskWindowContainerController getWindowContainerController() {
@@ -460,13 +461,13 @@
// default configuration the next time it launches.
updateOverrideConfiguration(null);
}
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
+ mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
mWindowContainerController = null;
}
@Override
public void onSnapshotChanged(TaskSnapshot snapshot) {
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
+ mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
}
void setResizeMode(int resizeMode) {
@@ -486,7 +487,7 @@
// TODO: Consolidate this with the resize() method below.
@Override
public void requestResize(Rect bounds, int resizeMode) {
- mService.mActivityTaskManager.resizeTask(taskId, bounds, resizeMode);
+ mService.resizeTask(taskId, bounds, resizeMode);
}
boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
@@ -1302,7 +1303,7 @@
// We normally notify listeners of task stack changes on pause, however pinned stack
// activities are normally in the paused state so no notification will be sent there
// before the activity is removed. We send it here so instead.
- mService.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskStackChanged();
+ mService.getTaskChangeNotificationController().notifyTaskStackChanged();
}
if (mActivities.isEmpty()) {
@@ -1493,7 +1494,7 @@
}
private boolean isResizeable(boolean checkSupportsPip) {
- return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
+ return (mService.mAm.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
|| (checkSupportsPip && mSupportsPictureInPicture));
}
@@ -1506,8 +1507,8 @@
// A task can not be docked even if it is considered resizeable because it only supports
// picture-in-picture mode but has a non-resizeable resizeMode
return super.supportsSplitScreenWindowingMode()
- && mService.mSupportsSplitScreenMultiWindow
- && (mService.mForceResizableActivities
+ && mService.mAm.mSupportsSplitScreenMultiWindow
+ && (mService.mAm.mForceResizableActivities
|| (isResizeable(false /* checkSupportsPip */)
&& !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
}
@@ -2205,14 +2206,14 @@
sTaskRecordFactory = factory;
}
- static TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+ static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor) {
return getTaskRecordFactory().create(
service, taskId, info, intent, voiceSession, voiceInteractor);
}
- static TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+ static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, TaskDescription taskDescription) {
return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
}
@@ -2229,14 +2230,14 @@
*/
static class TaskRecordFactory {
- TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+ TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor) {
return new TaskRecord(
service, taskId, info, intent, voiceSession, voiceInteractor);
}
- TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+ TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, TaskDescription taskDescription) {
return new TaskRecord(service, taskId, info, intent, taskDescription);
}
@@ -2244,7 +2245,7 @@
/**
* Should only be used when we're restoring {@link TaskRecord} from storage.
*/
- TaskRecord create(ActivityManagerService service, int taskId, Intent intent,
+ TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Intent affinityIntent, String affinity, String rootAffinity,
ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
boolean autoRemoveRecents, boolean askedCompatMode, int userId,
@@ -2468,7 +2469,8 @@
}
}
- final TaskRecord task = create(stackSupervisor.mService, taskId, intent, affinityIntent,
+ final TaskRecord task = create(stackSupervisor.mService,
+ taskId, intent, affinityIntent,
affinity, rootAffinity, realActivity, origActivity, rootHasReset,
autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2fbe56b..b500bbf 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2248,7 +2248,7 @@
protected void clearAllLockedTasks(String reason) {
synchronized (mService) {
- mService.getLockTaskController().clearLockedTasks(reason);
+ mService.mActivityTaskManager.getLockTaskController().clearLockedTasks(reason);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0897b8a..32f1744 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3408,20 +3408,27 @@
@Override
public void applyEnqueuedAdjustmentFromAssistant(INotificationListener token,
- Adjustment adjustment) throws RemoteException {
+ Adjustment adjustment) {
+ boolean foundEnqueued = false;
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
mAssistants.checkServiceTokenLocked(token);
int N = mEnqueuedNotifications.size();
for (int i = 0; i < N; i++) {
- final NotificationRecord n = mEnqueuedNotifications.get(i);
- if (Objects.equals(adjustment.getKey(), n.getKey())
- && Objects.equals(adjustment.getUser(), n.getUserId())) {
- applyAdjustment(n, adjustment);
+ final NotificationRecord r = mEnqueuedNotifications.get(i);
+ if (Objects.equals(adjustment.getKey(), r.getKey())
+ && Objects.equals(adjustment.getUser(), r.getUserId())) {
+ applyAdjustment(r, adjustment);
+ r.applyAdjustments();
+ foundEnqueued = true;
break;
}
}
+ if (!foundEnqueued) {
+ // adjustment arrived too late to apply to enqueued; apply to posted
+ applyAdjustmentFromAssistant(token, adjustment);
+ }
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -3430,7 +3437,7 @@
@Override
public void applyAdjustmentFromAssistant(INotificationListener token,
- Adjustment adjustment) throws RemoteException {
+ Adjustment adjustment) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
@@ -3446,7 +3453,7 @@
@Override
public void applyAdjustmentsFromAssistant(INotificationListener token,
- List<Adjustment> adjustments) throws RemoteException {
+ List<Adjustment> adjustments) {
final long identity = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 08d0ae9..fa6079c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
@@ -1377,7 +1378,7 @@
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
// We can now show all of the drawn windows!
- if (!mService.mOpeningApps.contains(this)) {
+ if (!mService.mOpeningApps.contains(this) && canShowWindows()) {
showAllWindowsLocked();
}
}
@@ -2270,4 +2271,21 @@
boolean isClosingOrEnteringPip() {
return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
}
+
+ /**
+ * @return Whether we are allowed to show non-starting windows at the moment. We disallow
+ * showing windows during transitions in case we have windows that have wide-color-gamut
+ * color mode set to avoid jank in the middle of the transition.
+ */
+ boolean canShowWindows() {
+ return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
+ }
+
+ /**
+ * @return true if we have a window that has a non-default color mode set; false otherwise.
+ */
+ private boolean hasNonDefaultColorWindow() {
+ return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
+ true /* topToBottom */);
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f364753..0cbf8a7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -404,7 +404,7 @@
WindowStateAnimator winAnimator = w.mWinAnimator;
final AppWindowToken atoken = w.mAppToken;
if (winAnimator.mDrawState == READY_TO_SHOW) {
- if (atoken == null || atoken.allDrawn) {
+ if (atoken == null || atoken.canShowWindows()) {
if (w.performShowLocked()) {
pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
if (DEBUG_LAYOUT_REPEATS) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 26fe24b..14e0e13 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -41,11 +41,11 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
import static com.android.server.wm.WindowManagerService.logWithStack;
-import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT;
import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
import static com.android.server.wm.utils.CoordinateTransforms.transformToRotation;
import android.content.Context;
@@ -366,7 +366,8 @@
mDrawState = READY_TO_SHOW;
boolean result = false;
final AppWindowToken atoken = mWin.mAppToken;
- if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
+ if (atoken == null || atoken.canShowWindows()
+ || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
result = mWin.performShowLocked();
}
return result;
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index 1ce41a6..0674d85 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -174,7 +174,7 @@
// #notifyAll will be called on the ActivityManagerService. we must hold the object lock
// when this happens.
- synchronized (mSupervisor.mService) {
+ synchronized (mSupervisor.mService.mGlobalLock) {
final WaitResult taskToFrontWait = new WaitResult();
mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait);
mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_TASK_TO_FRONT);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
index 7948e4c..a86372a 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -59,8 +59,8 @@
super.setUp();
mService = createActivityManagerService();
mFactory = mock(Factory.class);
- mController = new ActivityStartController(mService, mService.mStackSupervisor, mFactory);
- mStarter = spy(new ActivityStarter(mController, mService, mService.mStackSupervisor,
+ mController = new ActivityStartController(mService.mActivityTaskManager, mService.mStackSupervisor, mFactory);
+ mStarter = spy(new ActivityStarter(mController, mService.mActivityTaskManager, mService.mStackSupervisor,
mock(ActivityStartInterceptor.class)));
doReturn(mStarter).when(mFactory).obtain();
}
@@ -96,7 +96,7 @@
@Test
public void testRecycling() throws Exception {
final Intent intent = new Intent();
- final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
+ final ActivityStarter optionStarter = new ActivityStarter(mController, mService.mActivityTaskManager,
mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
optionStarter
.setIntent(intent)
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
index 9d35ef1..7f55824 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -57,7 +57,7 @@
* Unit tests for {@link ActivityStartInterceptorTest}.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest
+ * atest FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest
*/
@Presubmit
@SmallTest
@@ -82,7 +82,9 @@
@Mock
private Context mContext;
@Mock
- private ActivityManagerService mService;
+ private ActivityManagerService mAm;
+ @Mock
+ private ActivityTaskManagerService mService;
@Mock
private ActivityStackSupervisor mSupervisor;
@Mock
@@ -104,6 +106,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mService.mAm = mAm;
mInterceptor = new ActivityStartInterceptor(mService, mSupervisor, mContext,
mUserController);
mInterceptor.setStates(TEST_USER_ID, TEST_REAL_CALLING_PID, TEST_REAL_CALLING_UID,
@@ -113,10 +116,9 @@
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
LocalServices.addService(DevicePolicyManagerInternal.class,
mDevicePolicyManager);
- when(mDevicePolicyManager
- .createShowAdminSupportIntent(TEST_USER_ID, true))
+ when(mDevicePolicyManager.createShowAdminSupportIntent(TEST_USER_ID, true))
.thenReturn(ADMIN_SUPPORT_INTENT);
- when(mService.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
+ when(mAm.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
// Mock UserManager
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -129,7 +131,7 @@
thenReturn(CONFIRM_CREDENTIALS_INTENT);
// Mock PackageManager
- when(mService.getPackageManager()).thenReturn(mPackageManager);
+ when(mAm.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(null);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 74e5816..10d255e7 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -109,7 +109,7 @@
super.setUp();
mService = createActivityManagerService();
mController = mock(ActivityStartController.class);
- mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor,
+ mStarter = new ActivityStarter(mController, mService.mActivityTaskManager, mService.mStackSupervisor,
mock(ActivityStartInterceptor.class));
}
@@ -193,7 +193,7 @@
final IPackageManager packageManager = mock(IPackageManager.class);
final ActivityStartController controller = mock(ActivityStartController.class);
- final ActivityStarter starter = new ActivityStarter(controller, service,
+ final ActivityStarter starter = new ActivityStarter(controller, service.mActivityTaskManager,
service.mStackSupervisor, mock(ActivityStartInterceptor.class));
final IApplicationThread caller = mock(IApplicationThread.class);
@@ -282,7 +282,7 @@
// Ensure that {@link ActivityOptions} are aborted with unsuccessful result.
if (expectedResult != START_SUCCESS) {
- final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
+ final ActivityStarter optionStarter = new ActivityStarter(mController, mService.mActivityTaskManager,
mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
final ActivityOptions options = spy(ActivityOptions.makeBasic());
@@ -336,7 +336,7 @@
info.applicationInfo = new ApplicationInfo();
info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName();
- return new ActivityStarter(mController, mService,
+ return new ActivityStarter(mController, mService.mActivityTaskManager,
mService.mStackSupervisor, mock(ActivityStartInterceptor.class))
.setIntent(intent)
.setActivityInfo(info);
@@ -456,7 +456,7 @@
final ActivityStarter starter = prepareStarter(0);
- final LockTaskController lockTaskController = mService.getLockTaskController();
+ final LockTaskController lockTaskController = mService.mActivityTaskManager.getLockTaskController();
doReturn(true).when(lockTaskController).isLockTaskModeViolation(any());
final int result = starter.setReason("testTaskModeViolation").execute();
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 47c4de2..06ac3b0 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -111,10 +111,11 @@
protected ActivityManagerService setupActivityManagerService(
ActivityManagerService service, ActivityTaskManagerService atm) {
service = spy(service);
+ // Makes sure activity task is created with the spy object.
atm = spy(atm);
- // Makes sure the supervisor is using with the spy object.
- service.mStackSupervisor.setService(service);
service.setActivityTaskManager(atm);
+ // Makes sure the supervisor is using with the spy object.
+ atm.mStackSupervisor.setService(atm);
doReturn(mock(IPackageManager.class)).when(service).getPackageManager();
doNothing().when(service).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
service.mWindowManager = prepareMockWindowManager();
@@ -328,7 +329,7 @@
}
private static class TestTaskRecord extends TaskRecord {
- TestTaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info,
+ TestTaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info,
Intent _intent, IVoiceInteractionSession _voiceSession,
IVoiceInteractor _voiceInteractor) {
super(service, _taskId, info, _intent, _voiceSession, _voiceInteractor);
@@ -346,37 +347,13 @@
}
protected static class TestActivityTaskManagerService extends ActivityTaskManagerService {
+ private LockTaskController mLockTaskController;
+
TestActivityTaskManagerService(Context context) {
super(context);
}
- }
-
- /**
- * An {@link ActivityManagerService} subclass which provides a test
- * {@link ActivityStackSupervisor}.
- */
- protected static class TestActivityManagerService extends ActivityManagerService {
- private ClientLifecycleManager mLifecycleManager;
- private LockTaskController mLockTaskController;
-
- TestActivityManagerService(Context context) {
- super(context);
- mSupportsMultiWindow = true;
- mSupportsMultiDisplay = true;
- mSupportsSplitScreenMultiWindow = true;
- mSupportsFreeformWindowManagement = true;
- mSupportsPictureInPicture = true;
- mWindowManager = WindowTestUtils.getMockWindowManagerService();
- }
@Override
- public ClientLifecycleManager getLifecycleManager() {
- if (mLifecycleManager == null) {
- return super.getLifecycleManager();
- }
- return mLifecycleManager;
- }
-
public LockTaskController getLockTaskController() {
if (mLockTaskController == null) {
mLockTaskController = spy(super.getLockTaskController());
@@ -411,12 +388,33 @@
}
protected ActivityStackSupervisor createTestSupervisor() {
- return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
+ return new TestActivityStackSupervisor(this, mH.getLooper());
+ }
+ }
+
+ /**
+ * An {@link ActivityManagerService} subclass which provides a test
+ * {@link ActivityStackSupervisor}.
+ */
+ protected static class TestActivityManagerService extends ActivityManagerService {
+
+ TestActivityManagerService(Context context) {
+ super(context);
+ mSupportsMultiWindow = true;
+ mSupportsMultiDisplay = true;
+ mSupportsSplitScreenMultiWindow = true;
+ mSupportsFreeformWindowManagement = true;
+ mSupportsPictureInPicture = true;
}
@Override
void updateUsageStats(ActivityRecord component, boolean resumed) {
}
+
+ @Override
+ Configuration getGlobalConfiguration() {
+ return mContext.getResources().getConfiguration();
+ }
}
/**
@@ -427,7 +425,7 @@
private ActivityDisplay mDisplay;
private KeyguardController mKeyguardController;
- public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
+ public TestActivityStackSupervisor(ActivityTaskManagerService service, Looper looper) {
super(service, looper);
mDisplayManager =
(DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
diff --git a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
index 2baf995..e73661b 100644
--- a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
@@ -62,7 +62,7 @@
mService.mHandlerThread.getThreadHandler().runWithScissors(() -> {
mHandler = new TestHandler(null, mClock);
}, 0);
- mRegistry = new PendingRemoteAnimationRegistry(mService, mHandler);
+ mRegistry = new PendingRemoteAnimationRegistry(mService.mActivityTaskManager, mHandler);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index f98c50a..cd70677 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -837,6 +837,12 @@
protected RecentTasks createRecentTasks() {
return new TestRecentTasks(this, mTaskPersister, new TestUserController(mAm));
}
+
+ @Override
+ protected ActivityStackSupervisor createTestSupervisor() {
+ return new MyTestActivityStackSupervisor(this, mH.getLooper());
+ }
+
}
private class MyTestActivityManagerService extends TestActivityManagerService {
@@ -845,18 +851,13 @@
}
@Override
- protected ActivityStackSupervisor createTestSupervisor() {
- return new MyTestActivityStackSupervisor(this, mHandlerThread.getLooper());
- }
-
- @Override
public boolean isUserRunning(int userId, int flags) {
return true;
}
}
private class MyTestActivityStackSupervisor extends TestActivityStackSupervisor {
- public MyTestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
+ public MyTestActivityStackSupervisor(ActivityTaskManagerService service, Looper looper) {
super(service, looper);
}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
index 057fdc8..72851d01 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
@@ -155,7 +155,8 @@
}
private TaskRecord createTaskRecord(int taskId) {
- return new TaskRecord(mService, taskId, new Intent(), null, null, null, null, null, false,
+ return new TaskRecord(mService.mActivityTaskManager, taskId, new Intent(), null, null, null,
+ null, null, false,
false, false, 0, 10050, null, new ArrayList<>(), 0, false, null, 0, 0, 0, 0, 0,
null, 0, false, false, false, 0, 0);
}
@@ -164,7 +165,7 @@
private boolean mCreated = false;
@Override
- TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+ TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
mCreated = true;
@@ -172,7 +173,7 @@
}
@Override
- TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+ TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent,
ActivityManager.TaskDescription taskDescription) {
mCreated = true;
@@ -180,7 +181,7 @@
}
@Override
- TaskRecord create(ActivityManagerService service, int taskId, Intent intent,
+ TaskRecord create(ActivityTaskManagerService service, int taskId, Intent intent,
Intent affinityIntent, String affinity, String rootAffinity,
ComponentName realActivity,
ComponentName origActivity, boolean rootWasReset, boolean autoRemoveRecents,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 3b21390..96c948f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -2405,6 +2405,45 @@
}
@Test
+ public void testTooLateAdjustmentTriggersUpdate() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addNotification(r);
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+ NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ Adjustment adjustment = new Adjustment(
+ r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+ waitForIdle();
+
+ verify(handler, timeout(300).times(1)).scheduleSendRankingUpdate();
+ }
+
+ @Test
+ public void testEnqueuedAdjustmentAppliesAdjustments() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+ NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ Adjustment adjustment = new Adjustment(
+ r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+ assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE,
+ r.getUserSentiment());
+ }
+
+ @Test
public void testRecents() throws Exception {
Set<NotifyingApp> expected = new HashSet<>();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 1d5eece..b8dfd38 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -866,7 +866,7 @@
final long token = Binder.clearCallingIdentity();
try {
return UsageStatsService.this.queryEventsForPackage(userId, beginTime,
- endTime, callingPackage);
+ endTime, pkg);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index aa832ad..6a1e97a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -68,6 +68,7 @@
private static final String SHORTCUT_ID_ATTR = "shortcutId";
private static final String STANDBY_BUCKET_ATTR = "standbyBucket";
private static final String APP_LAUNCH_COUNT_ATTR = "appLaunchCount";
+ private static final String NOTIFICATION_CHANNEL_ATTR = "notificationChannel";
// Time attributes stored as an offset of the beginTime.
private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive";
@@ -189,6 +190,11 @@
case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
event.mBucketAndReason = XmlUtils.readIntAttribute(parser, STANDBY_BUCKET_ATTR, 0);
break;
+ case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+ final String channelId =
+ XmlUtils.readStringAttribute(parser, NOTIFICATION_CHANNEL_ATTR);
+ event.mNotificationChannelId = (channelId != null) ? channelId.intern() : null;
+ break;
}
if (statsOut.events == null) {
@@ -307,6 +313,13 @@
if (event.mBucketAndReason != 0) {
XmlUtils.writeIntAttribute(xml, STANDBY_BUCKET_ATTR, event.mBucketAndReason);
}
+ break;
+ case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+ if (event.mNotificationChannelId != null) {
+ XmlUtils.writeStringAttribute(
+ xml, NOTIFICATION_CHANNEL_ATTR, event.mNotificationChannelId);
+ }
+ break;
}
xml.endTag(null, EVENT_TAG);
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 9cb98f3..4efe0b5 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -604,6 +604,9 @@
pw.printPair("standbyBucket", event.getStandbyBucket());
pw.printPair("reason", UsageStatsManager.reasonToString(event.getStandbyReason()));
}
+ if (event.mNotificationChannelId != null) {
+ pw.printPair("channelId", event.mNotificationChannelId);
+ }
pw.printHexPair("flags", event.mFlags);
pw.println();
}
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index f7e6840..4354314 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -36,8 +36,8 @@
/**
* Base class of network service. Services that extend NetworkService must register the service in
* their AndroidManifest to be detected by the framework. They must be protected by the permission
- * "android.permission.BIND_NETWORK_SERVICE". The network service definition in the manifest must
- * follow the following format:
+ * "android.permission.BIND_TELEPHONY_NETWORK_SERVICE". The network service definition in the
+ * manifest must follow the following format:
* ...
* <service android:name=".xxxNetworkService"
* android:permission="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" >
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d7568b4..0940738 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5432,23 +5432,6 @@
}
/**
- * @return true if the IMS resolver is busy resolving a binding and should not be considered
- * available, false if the IMS resolver is idle.
- * @hide
- */
- public boolean isResolvingImsBinding() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null) {
- return telephony.isResolvingImsBinding();
- }
- } catch (RemoteException e) {
- Rlog.e(TAG, "isResolvingImsBinding, RemoteException: " + e.getMessage());
- }
- return false;
- }
-
- /**
* Set IMS registration state
*
* @param Registration state
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 4ca5ce3..1db5850 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -44,11 +44,11 @@
/**
* Base class of data service. Services that extend DataService must register the service in
* their AndroidManifest to be detected by the framework. They must be protected by the permission
- * "android.permission.BIND_DATA_SERVICE". The data service definition in the manifest must follow
- * the following format:
+ * "android.permission.BIND_TELEPHONY_DATA_SERVICE". The data service definition in the manifest
+ * must follow the following format:
* ...
* <service android:name=".xxxDataService"
- * android:permission="android.permission.BIND_DATA_SERVICE" >
+ * android:permission="android.permission.BIND_TELEPHONY_DATA_SERVICE" >
* <intent-filter>
* <action android:name="android.telephony.data.DataService" />
* </intent-filter>
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 6ea8ccb..84a18b4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -817,12 +817,6 @@
IImsConfig getImsConfig(int slotId, int feature);
/**
- * @return true if the IMS resolver is busy resolving a binding and should not be considered
- * available, false if the IMS resolver is idle.
- */
- boolean isResolvingImsBinding();
-
- /**
* @return true if the ImsService to bind to for the slot id specified was set, false otherwise.
*/
boolean setImsService(int slotId, boolean isCarrierImsService, String packageName);
diff --git a/tools/aapt2/integration-tests/NamespaceTest/LibOne/Android.mk b/tools/aapt2/integration-tests/NamespaceTest/LibOne/Android.mk
index 021185f..c723d90 100644
--- a/tools/aapt2/integration-tests/NamespaceTest/LibOne/Android.mk
+++ b/tools/aapt2/integration-tests/NamespaceTest/LibOne/Android.mk
@@ -23,6 +23,7 @@
LOCAL_SDK_VERSION := current
LOCAL_MODULE_TAGS := tests
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MIN_SDK_VERSION := 21
# We need this to retain the R.java generated for this library.
LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/tools/aapt2/integration-tests/NamespaceTest/LibTwo/Android.mk b/tools/aapt2/integration-tests/NamespaceTest/LibTwo/Android.mk
index 39bd481..90a7f62 100644
--- a/tools/aapt2/integration-tests/NamespaceTest/LibTwo/Android.mk
+++ b/tools/aapt2/integration-tests/NamespaceTest/LibTwo/Android.mk
@@ -24,6 +24,7 @@
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MIN_SDK_VERSION := 21
# We need this to retain the R.java generated for this library.
LOCAL_JAR_EXCLUDE_FILES := none