Merge "Fix thread safety issue on clearing cache"
diff --git a/Android.bp b/Android.bp
index e756b34..eacf57c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -366,7 +366,8 @@
":framework-tethering-srcs",
":framework-wifi-updatable-sources",
":updatable-media-srcs",
- ]
+ ],
+ visibility: ["//visibility:private"],
}
java_library {
@@ -383,7 +384,31 @@
"framework-wifi.stubs.module_lib",
],
sdk_version: "module_current",
- visibility: [":__pkg__"],
+ visibility: ["//visibility:private"],
+}
+
+java_library {
+ name: "framework-all",
+ installable: false,
+ static_libs: [
+ "framework-minus-apex",
+ "framework-appsearch",
+ "framework-graphics.impl",
+ "framework-mediaprovider.impl",
+ "framework-permission.impl",
+ "framework-sdkextensions.impl",
+ "framework-statsd.impl",
+ "framework-tethering.impl",
+ "framework-wifi.impl",
+ "updatable-media",
+ ],
+ apex_available: ["//apex_available:platform"],
+ sdk_version: "core_platform",
+ visibility: [
+ // DO NOT ADD ANY MORE ENTRIES TO THIS LIST
+ "//external/robolectric-shadows:__subpackages__",
+ "//frameworks/layoutlib:__subpackages__",
+ ],
}
filegroup {
@@ -474,53 +499,6 @@
installable: false,
}
-java_defaults {
- name: "framework-defaults",
- defaults: ["framework-aidl-export-defaults"],
- installable: true,
-
- aidl: {
- generate_get_transaction_name: true,
- },
-
- srcs: ["core/java/**/*.logtags"],
-
- exclude_srcs: [
- // See comment on framework-atb-backward-compatibility module below
- "core/java/android/content/pm/AndroidTestBaseUpdater.java",
- ],
-
- sdk_version: "core_platform",
- libs: [
- "app-compat-annotations",
- "ext",
- "unsupportedappusage",
- ],
-
- jarjar_rules: ":framework-jarjar-rules",
-
- static_libs: [
- "framework-internal-utils",
- ],
-
- dxflags: [
- "--core-library",
- "--multi-dex",
- ],
-
- plugins: [
- "view-inspector-annotation-processor",
- "staledataclass-annotation-processor",
- "error_prone_android_framework",
- ],
-
- required: [
- // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly.
- "gps_debug.conf",
- "protolog.conf.json.gz",
- ],
-}
-
filegroup {
name: "framework-jarjar-rules",
srcs: ["framework-jarjar-rules.txt"],
@@ -560,19 +538,47 @@
java_library {
name: "framework-minus-apex",
- defaults: ["framework-defaults"],
- srcs: [":framework-non-updatable-sources"],
+ defaults: ["framework-aidl-export-defaults"],
+ srcs: [
+ ":framework-non-updatable-sources",
+ "core/java/**/*.logtags",
+ ],
+ // See comment on framework-atb-backward-compatibility module below
+ exclude_srcs: ["core/java/android/content/pm/AndroidTestBaseUpdater.java"],
+ aidl: {
+ generate_get_transaction_name: true,
+ },
+ dxflags: [
+ "--core-library",
+ "--multi-dex",
+ ],
installable: true,
+ jarjar_rules: ":framework-jarjar-rules",
javac_shard_size: 150,
+ plugins: [
+ "view-inspector-annotation-processor",
+ "staledataclass-annotation-processor",
+ "error_prone_android_framework",
+ ],
required: [
"framework-platform-compat-config",
+ // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly.
+ "gps_debug.conf",
"libcore-platform-compat-config",
+ "protolog.conf.json.gz",
"services-platform-compat-config",
"documents-ui-compat-config",
"calendar-provider-compat-config",
],
- libs: ["framework-updatable-stubs-module_libs_api"],
+ libs: [
+ "app-compat-annotations",
+ "ext",
+ "framework-updatable-stubs-module_libs_api",
+ "unsupportedappusage",
+ ],
+ sdk_version: "core_platform",
static_libs: [
+ "framework-internal-utils",
// If MimeMap ever becomes its own APEX, then this dependency would need to be removed
// in favor of an API stubs dependency in java_library "framework" below.
"mimemap",
@@ -615,32 +621,6 @@
apex_available: ["//apex_available:platform"],
}
-java_library {
- name: "framework-all",
- defaults: ["framework-defaults"],
- srcs: [":framework-all-sources"],
- installable: false,
- static_libs: [
- "exoplayer2-extractor",
- "android.hardware.wifi-V1.0-java-constants",
- "mediatranscoding_aidl_interface-java",
-
- // Additional dependencies needed to build the ike API classes.
- "ike-internals",
- ],
- plugins: [
- "intdef-annotation-processor",
- ],
- libs: ["icing-java-proto-lite"],
- apex_available: ["//apex_available:platform"],
- visibility: [
- // DO NOT ADD ANY MORE ENTRIES TO THIS LIST
- "//external/robolectric-shadows:__subpackages__",
- "//frameworks/base",
- "//frameworks/layoutlib:__subpackages__",
- ],
-}
-
platform_compat_config {
name: "framework-platform-compat-config",
src: ":framework-minus-apex",
diff --git a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
index 29721c5..9e519f7 100644
--- a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
+++ b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
@@ -184,11 +184,11 @@
override fun startParsingPackage(
packageName: String,
- baseCodePath: String,
- codePath: String,
+ baseApkPath: String,
+ path: String,
manifestArray: TypedArray,
isCoreApp: Boolean
- ) = ParsingPackageImpl(packageName, baseCodePath, codePath, manifestArray)
+ ) = ParsingPackageImpl(packageName, baseApkPath, path, manifestArray)
})
override fun parseImpl(file: File) =
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
index 2697428..a701f86 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
@@ -21,14 +21,12 @@
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
-import android.graphics.Rect;
import android.os.RemoteException;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.perftests.utils.PerfTestActivity;
import android.platform.test.annotations.Presubmit;
import android.util.MergedConfiguration;
-import android.view.DisplayCutout;
import android.view.IWindow;
import android.view.IWindowSession;
import android.view.InsetsSourceControl;
@@ -38,6 +36,7 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.widget.LinearLayout;
+import android.window.ClientWindowFrames;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
@@ -125,13 +124,7 @@
}
private static class RelayoutRunner {
- final Rect mOutFrame = new Rect();
- final Rect mOutContentInsets = new Rect();
- final Rect mOutVisibleInsets = new Rect();
- final Rect mOutStableInsets = new Rect();
- final Rect mOutBackDropFrame = new Rect();
- final DisplayCutout.ParcelableWrapper mOutDisplayCutout =
- new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT);
+ final ClientWindowFrames mOutFrames = new ClientWindowFrames();
final MergedConfiguration mOutMergedConfiguration = new MergedConfiguration();
final InsetsState mOutInsetsState = new InsetsState();
final InsetsSourceControl[] mOutControls = new InsetsSourceControl[0];
@@ -164,11 +157,9 @@
final IWindowSession session = WindowManagerGlobal.getWindowSession();
while (state.keepRunning()) {
session.relayout(mWindow, mSeq, mParams, mWidth, mHeight,
- mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame,
- mOutContentInsets, mOutVisibleInsets, mOutStableInsets,
- mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration,
- mOutSurfaceControl, mOutInsetsState, mOutControls, mOutSurfaceSize,
- mOutBlastSurfaceControl);
+ mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrames,
+ mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState, mOutControls,
+ mOutSurfaceSize, mOutBlastSurfaceControl);
}
}
}
diff --git a/apex/Android.bp b/apex/Android.bp
index 410e211..266e672 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -101,20 +101,16 @@
annotations_enabled: true,
- stubs_library_visibility: [
- "//visibility:public",
- ],
+ // Allow access to the stubs from anywhere
+ visibility: ["//visibility:public"],
+ stubs_library_visibility: ["//visibility:public"],
- // Set the visibility of the modules creating the stubs source.
- stubs_source_visibility: [
- // Ignore any visibility rules specified on the java_sdk_library when
- // setting the visibility of the stubs source modules.
- "//visibility:override",
-
- // Currently, the stub source is not required for anything other than building
- // the stubs library so is private to avoid misuse.
- "//visibility:private",
+ // Hide impl library and stub sources
+ impl_library_visibility: [
+ ":__package__",
+ "//frameworks/base", // For framework-all
],
+ stubs_source_visibility: ["//visibility:private"],
// Collates API usages from each module for further analysis.
plugins: ["java_api_finder"],
diff --git a/apex/OWNERS b/apex/OWNERS
new file mode 100644
index 0000000..9760013
--- /dev/null
+++ b/apex/OWNERS
@@ -0,0 +1,7 @@
+# Shared module build rule owners
+per-file *.bp=hansson@google.com
+per-file *.bp=jiyong@google.com
+
+# This file, and all other OWNERS files
+per-file OWNERS=dariofreni@google.com
+per-file OWNERS=hansson@google.com
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 6c3398f..d8386b5 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -21,14 +21,12 @@
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -63,11 +61,10 @@
import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.provider.Settings;
+import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
-import android.util.KeyValueListParser;
import android.util.MutableLong;
import android.util.Pair;
import android.util.Slog;
@@ -856,7 +853,7 @@
* global Settings. Any access to this class or its fields should be done while
* holding the DeviceIdleController lock.
*/
- public final class Constants extends ContentObserver {
+ public final class Constants implements DeviceConfig.OnPropertiesChangedListener {
// Key names stored in the settings value.
private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
= "light_after_inactive_to";
@@ -884,15 +881,15 @@
private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
private static final String KEY_IDLE_FACTOR = "idle_factor";
private static final String KEY_MIN_TIME_TO_ALARM = "min_time_to_alarm";
+ // TODO(166121524): update flag names
private static final String KEY_MAX_TEMP_APP_WHITELIST_DURATION =
"max_temp_app_whitelist_duration";
private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
"mms_temp_app_whitelist_duration";
private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
"sms_temp_app_whitelist_duration";
- // TODO(b/124466289): update value to match the name
- private static final String KEY_NOTIFICATION_ALLOWLIST_DURATION =
- "notification_whitelist_duration";
+ private static final String KEY_NOTIFICATION_ALLOWLIST_DURATION_MS =
+ "notification_allowlist_duration_ms";
/**
* Whether to wait for the user to unlock the device before causing screen-on to
* exit doze. Default = true
@@ -903,52 +900,106 @@
private static final String KEY_PRE_IDLE_FACTOR_SHORT =
"pre_idle_factor_short";
+ private static final long DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
+ !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L;
+ private static final long DEFAULT_LIGHT_PRE_IDLE_TIMEOUT =
+ !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L;
+ private static final long DEFAULT_LIGHT_IDLE_TIMEOUT =
+ !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L;
+ private static final float DEFAULT_LIGHT_IDLE_FACTOR = 2f;
+ private static final long DEFAULT_LIGHT_MAX_IDLE_TIMEOUT =
+ !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
+ private static final long DEFAULT_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET =
+ !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L;
+ private static final long DEFAULT_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET =
+ !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L;
+ private static final long DEFAULT_MIN_LIGHT_MAINTENANCE_TIME =
+ !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L;
+ private static final long DEFAULT_MIN_DEEP_MAINTENANCE_TIME =
+ !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L;
+ private static final long DEFAULT_INACTIVE_TIMEOUT =
+ (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
+ private static final long DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY =
+ (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
+ private static final long DEFAULT_SENSING_TIMEOUT =
+ !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L;
+ private static final long DEFAULT_LOCATING_TIMEOUT =
+ !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L;
+ private static final float DEFAULT_LOCATION_ACCURACY = 20f;
+ private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT =
+ !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L;
+ private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT =
+ (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
+ private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY =
+ (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
+ private static final long DEFAULT_IDLE_PENDING_TIMEOUT =
+ !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L;
+ private static final long DEFAULT_MAX_IDLE_PENDING_TIMEOUT =
+ !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L;
+ private static final float DEFAULT_IDLE_PENDING_FACTOR = 2f;
+ private static final long DEFAULT_QUICK_DOZE_DELAY_TIMEOUT =
+ !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L;
+ private static final long DEFAULT_IDLE_TIMEOUT =
+ !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L;
+ private static final long DEFAULT_MAX_IDLE_TIMEOUT =
+ !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L;
+ private static final float DEFAULT_IDLE_FACTOR = 2f;
+ private static final long DEFAULT_MIN_TIME_TO_ALARM =
+ !COMPRESS_TIME ? 30 * 60 * 1000L : 6 * 60 * 1000L;
+ private static final long DEFAULT_MAX_TEMP_APP_WHITELIST_DURATION = 5 * 60 * 1000L;
+ private static final long DEFAULT_MMS_TEMP_APP_WHITELIST_DURATION = 60 * 1000L;
+ private static final long DEFAULT_SMS_TEMP_APP_WHITELIST_DURATION = 20 * 1000L;
+ private static final long DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS = 30 * 1000L;
+ private static final boolean DEFAULT_WAIT_FOR_UNLOCK = true;
+ private static final float DEFAULT_PRE_IDLE_FACTOR_LONG = 1.67f;
+ private static final float DEFAULT_PRE_IDLE_FACTOR_SHORT = .33f;
+
/**
* This is the time, after becoming inactive, that we go in to the first
* light-weight idle mode.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
*/
- public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
+ public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
/**
* This is amount of time we will wait from the point where we decide we would
* like to go idle until we actually do, while waiting for jobs and other current
* activity to finish.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_PRE_IDLE_TIMEOUT
*/
- public long LIGHT_PRE_IDLE_TIMEOUT;
+ public long LIGHT_PRE_IDLE_TIMEOUT = DEFAULT_LIGHT_PRE_IDLE_TIMEOUT;
/**
* This is the initial time that we will run in idle maintenance mode.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_IDLE_TIMEOUT
*/
- public long LIGHT_IDLE_TIMEOUT;
+ public long LIGHT_IDLE_TIMEOUT = DEFAULT_LIGHT_IDLE_TIMEOUT;
/**
* Scaling factor to apply to the light idle mode time each time we complete a cycle.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_IDLE_FACTOR
*/
- public float LIGHT_IDLE_FACTOR;
+ public float LIGHT_IDLE_FACTOR = DEFAULT_LIGHT_IDLE_FACTOR;
/**
* This is the maximum time we will run in idle maintenance mode.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
*/
- public long LIGHT_MAX_IDLE_TIMEOUT;
+ public long LIGHT_MAX_IDLE_TIMEOUT = DEFAULT_LIGHT_MAX_IDLE_TIMEOUT;
/**
* This is the minimum amount of time we want to make available for maintenance mode
* when lightly idling. That is, we will always have at least this amount of time
* available maintenance before timing out and cutting off maintenance mode.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
*/
- public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
+ public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = DEFAULT_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
/**
* This is the maximum amount of time we want to make available for maintenance mode
@@ -956,10 +1007,10 @@
* budget and this time is being added to the budget reserve, this is the maximum
* reserve size we will allow to grow and thus the maximum amount of time we will
* allow for the maintenance window.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
*/
- public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
+ public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = DEFAULT_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
/**
* This is the minimum amount of time that we will stay in maintenance mode after
@@ -967,10 +1018,10 @@
* in to maintenance mode and scheduling their work -- otherwise we may
* see there is nothing to do (no jobs pending) and go out of maintenance
* mode immediately.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
*/
- public long MIN_LIGHT_MAINTENANCE_TIME;
+ public long MIN_LIGHT_MAINTENANCE_TIME = DEFAULT_MIN_LIGHT_MAINTENANCE_TIME;
/**
* This is the minimum amount of time that we will stay in maintenance mode after
@@ -978,271 +1029,323 @@
* in to maintenance mode and scheduling their work -- otherwise we may
* see there is nothing to do (no jobs pending) and go out of maintenance
* mode immediately.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MIN_DEEP_MAINTENANCE_TIME
*/
- public long MIN_DEEP_MAINTENANCE_TIME;
+ public long MIN_DEEP_MAINTENANCE_TIME = DEFAULT_MIN_DEEP_MAINTENANCE_TIME;
/**
* This is the time, after becoming inactive, at which we start looking at the
* motion sensor to determine if the device is being left alone. We don't do this
* immediately after going inactive just because we don't want to be continually running
* the motion sensor whenever the screen is off.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_INACTIVE_TIMEOUT
*/
- public long INACTIVE_TIMEOUT;
+ public long INACTIVE_TIMEOUT = DEFAULT_INACTIVE_TIMEOUT;
/**
* If we don't receive a callback from AnyMotion in this amount of time +
* {@link #LOCATING_TIMEOUT}, we will change from
* STATE_SENSING to STATE_INACTIVE, and any AnyMotion callbacks while not in STATE_SENSING
* will be ignored.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_SENSING_TIMEOUT
*/
- public long SENSING_TIMEOUT;
+ public long SENSING_TIMEOUT = DEFAULT_SENSING_TIMEOUT;
/**
* This is how long we will wait to try to get a good location fix before going in to
* idle mode.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_LOCATING_TIMEOUT
*/
- public long LOCATING_TIMEOUT;
+ public long LOCATING_TIMEOUT = DEFAULT_LOCATING_TIMEOUT;
/**
* The desired maximum accuracy (in meters) we consider the location to be good enough to go
* on to idle. We will be trying to get an accuracy fix at least this good or until
* {@link #LOCATING_TIMEOUT} expires.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_LOCATION_ACCURACY
*/
- public float LOCATION_ACCURACY;
+ public float LOCATION_ACCURACY = DEFAULT_LOCATION_ACCURACY;
/**
* This is the time, after seeing motion, that we wait after becoming inactive from
* that until we start looking for motion again.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MOTION_INACTIVE_TIMEOUT
*/
- public long MOTION_INACTIVE_TIMEOUT;
+ public long MOTION_INACTIVE_TIMEOUT = DEFAULT_MOTION_INACTIVE_TIMEOUT;
/**
* This is the time, after the inactive timeout elapses, that we will wait looking
* for motion until we truly consider the device to be idle.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
*/
- public long IDLE_AFTER_INACTIVE_TIMEOUT;
+ public long IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT;
/**
* This is the initial time, after being idle, that we will allow ourself to be back
* in the IDLE_MAINTENANCE state allowing the system to run normally until we return to
* idle.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_IDLE_PENDING_TIMEOUT
*/
- public long IDLE_PENDING_TIMEOUT;
+ public long IDLE_PENDING_TIMEOUT = DEFAULT_IDLE_PENDING_TIMEOUT;
/**
* Maximum pending idle timeout (time spent running) we will be allowed to use.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MAX_IDLE_PENDING_TIMEOUT
*/
- public long MAX_IDLE_PENDING_TIMEOUT;
+ public long MAX_IDLE_PENDING_TIMEOUT = DEFAULT_MAX_IDLE_PENDING_TIMEOUT;
/**
* Scaling factor to apply to current pending idle timeout each time we cycle through
* that state.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_IDLE_PENDING_FACTOR
*/
- public float IDLE_PENDING_FACTOR;
+ public float IDLE_PENDING_FACTOR = DEFAULT_IDLE_PENDING_FACTOR;
/**
* This is amount of time we will wait from the point where we go into
* STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs
* and other current activity to finish.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
*/
- public long QUICK_DOZE_DELAY_TIMEOUT;
+ public long QUICK_DOZE_DELAY_TIMEOUT = DEFAULT_QUICK_DOZE_DELAY_TIMEOUT;
/**
* This is the initial time that we want to sit in the idle state before waking up
* again to return to pending idle and allowing normal work to run.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_IDLE_TIMEOUT
*/
- public long IDLE_TIMEOUT;
+ public long IDLE_TIMEOUT = DEFAULT_IDLE_TIMEOUT;
/**
* Maximum idle duration we will be allowed to use.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MAX_IDLE_TIMEOUT
*/
- public long MAX_IDLE_TIMEOUT;
+ public long MAX_IDLE_TIMEOUT = DEFAULT_MAX_IDLE_TIMEOUT;
/**
* Scaling factor to apply to current idle timeout each time we cycle through that state.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_IDLE_FACTOR
*/
- public float IDLE_FACTOR;
+ public float IDLE_FACTOR = DEFAULT_IDLE_FACTOR;
/**
* This is the minimum time we will allow until the next upcoming alarm for us to
* actually go in to idle mode.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MIN_TIME_TO_ALARM
*/
- public long MIN_TIME_TO_ALARM;
+ public long MIN_TIME_TO_ALARM = DEFAULT_MIN_TIME_TO_ALARM;
/**
* Max amount of time to temporarily whitelist an app when it receives a high priority
* tickle.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ *
* @see #KEY_MAX_TEMP_APP_WHITELIST_DURATION
*/
- public long MAX_TEMP_APP_WHITELIST_DURATION;
+ public long MAX_TEMP_APP_WHITELIST_DURATION = DEFAULT_MAX_TEMP_APP_WHITELIST_DURATION;
/**
* Amount of time we would like to whitelist an app that is receiving an MMS.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_MMS_TEMP_APP_WHITELIST_DURATION
*/
- public long MMS_TEMP_APP_WHITELIST_DURATION;
+ public long MMS_TEMP_APP_WHITELIST_DURATION = DEFAULT_MMS_TEMP_APP_WHITELIST_DURATION;
/**
* Amount of time we would like to whitelist an app that is receiving an SMS.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
*/
- public long SMS_TEMP_APP_WHITELIST_DURATION;
+ public long SMS_TEMP_APP_WHITELIST_DURATION = DEFAULT_SMS_TEMP_APP_WHITELIST_DURATION;
/**
* Amount of time we would like to whitelist an app that is handling a
* {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
- * @see Settings.Global#DEVICE_IDLE_CONSTANTS
- * @see #KEY_NOTIFICATION_ALLOWLIST_DURATION
+ * @see #KEY_NOTIFICATION_ALLOWLIST_DURATION_MS
*/
- public long NOTIFICATION_ALLOWLIST_DURATION;
+ public long NOTIFICATION_ALLOWLIST_DURATION_MS = DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS;
/**
* Pre idle time factor use to make idle delay longer
*/
- public float PRE_IDLE_FACTOR_LONG;
+ public float PRE_IDLE_FACTOR_LONG = DEFAULT_PRE_IDLE_FACTOR_LONG;
/**
* Pre idle time factor use to make idle delay shorter
*/
- public float PRE_IDLE_FACTOR_SHORT;
+ public float PRE_IDLE_FACTOR_SHORT = DEFAULT_PRE_IDLE_FACTOR_SHORT;
- public boolean WAIT_FOR_UNLOCK;
+ public boolean WAIT_FOR_UNLOCK = DEFAULT_WAIT_FOR_UNLOCK;
- private final ContentResolver mResolver;
private final boolean mSmallBatteryDevice;
- private final KeyValueListParser mParser = new KeyValueListParser(',');
- public Constants(Handler handler, ContentResolver resolver) {
- super(handler);
- mResolver = resolver;
+ public Constants() {
mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
- mResolver.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
- false, this);
- updateConstants();
+ if (mSmallBatteryDevice) {
+ INACTIVE_TIMEOUT = DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY;
+ IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY;
+ }
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DEVICE_IDLE,
+ JobSchedulerBackgroundThread.getExecutor(), this);
+ // Load all the constants.
+ onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE));
}
+
@Override
- public void onChange(boolean selfChange, Uri uri) {
- updateConstants();
- }
-
- private void updateConstants() {
+ public void onPropertiesChanged(DeviceConfig.Properties properties) {
synchronized (DeviceIdleController.this) {
- try {
- mParser.setString(Settings.Global.getString(mResolver,
- Settings.Global.DEVICE_IDLE_CONSTANTS));
- } catch (IllegalArgumentException e) {
- // Failed to parse the settings string, log this and move on
- // with defaults.
- Slog.e(TAG, "Bad device idle settings", e);
+ for (String name : properties.getKeyset()) {
+ if (name == null) {
+ continue;
+ }
+ switch (name) {
+ case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT:
+ LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
+ KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
+ DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
+ break;
+ case KEY_LIGHT_PRE_IDLE_TIMEOUT:
+ LIGHT_PRE_IDLE_TIMEOUT = properties.getLong(
+ KEY_LIGHT_PRE_IDLE_TIMEOUT, DEFAULT_LIGHT_PRE_IDLE_TIMEOUT);
+ break;
+ case KEY_LIGHT_IDLE_TIMEOUT:
+ LIGHT_IDLE_TIMEOUT = properties.getLong(
+ KEY_LIGHT_IDLE_TIMEOUT, DEFAULT_LIGHT_IDLE_TIMEOUT);
+ break;
+ case KEY_LIGHT_IDLE_FACTOR:
+ LIGHT_IDLE_FACTOR = properties.getFloat(
+ KEY_LIGHT_IDLE_FACTOR, DEFAULT_LIGHT_IDLE_FACTOR);
+ break;
+ case KEY_LIGHT_MAX_IDLE_TIMEOUT:
+ LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
+ KEY_LIGHT_MAX_IDLE_TIMEOUT, DEFAULT_LIGHT_MAX_IDLE_TIMEOUT);
+ break;
+ case KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET:
+ LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = properties.getLong(
+ KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
+ DEFAULT_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
+ break;
+ case KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET:
+ LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = properties.getLong(
+ KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
+ DEFAULT_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET);
+ break;
+ case KEY_MIN_LIGHT_MAINTENANCE_TIME:
+ MIN_LIGHT_MAINTENANCE_TIME = properties.getLong(
+ KEY_MIN_LIGHT_MAINTENANCE_TIME,
+ DEFAULT_MIN_LIGHT_MAINTENANCE_TIME);
+ break;
+ case KEY_MIN_DEEP_MAINTENANCE_TIME:
+ MIN_DEEP_MAINTENANCE_TIME = properties.getLong(
+ KEY_MIN_DEEP_MAINTENANCE_TIME,
+ DEFAULT_MIN_DEEP_MAINTENANCE_TIME);
+ break;
+ case KEY_INACTIVE_TIMEOUT:
+ final long defaultInactiveTimeout = mSmallBatteryDevice
+ ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY
+ : DEFAULT_INACTIVE_TIMEOUT;
+ INACTIVE_TIMEOUT = properties.getLong(
+ KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout);
+ break;
+ case KEY_SENSING_TIMEOUT:
+ SENSING_TIMEOUT = properties.getLong(
+ KEY_SENSING_TIMEOUT, DEFAULT_SENSING_TIMEOUT);
+ break;
+ case KEY_LOCATING_TIMEOUT:
+ LOCATING_TIMEOUT = properties.getLong(
+ KEY_LOCATING_TIMEOUT, DEFAULT_LOCATING_TIMEOUT);
+ break;
+ case KEY_LOCATION_ACCURACY:
+ LOCATION_ACCURACY = properties.getFloat(
+ KEY_LOCATION_ACCURACY, DEFAULT_LOCATION_ACCURACY);
+ break;
+ case KEY_MOTION_INACTIVE_TIMEOUT:
+ MOTION_INACTIVE_TIMEOUT = properties.getLong(
+ KEY_MOTION_INACTIVE_TIMEOUT, DEFAULT_MOTION_INACTIVE_TIMEOUT);
+ break;
+ case KEY_IDLE_AFTER_INACTIVE_TIMEOUT:
+ final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
+ ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
+ : DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT;
+ IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
+ KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
+ defaultIdleAfterInactiveTimeout);
+ break;
+ case KEY_IDLE_PENDING_TIMEOUT:
+ IDLE_PENDING_TIMEOUT = properties.getLong(
+ KEY_IDLE_PENDING_TIMEOUT, DEFAULT_IDLE_PENDING_TIMEOUT);
+ break;
+ case KEY_MAX_IDLE_PENDING_TIMEOUT:
+ MAX_IDLE_PENDING_TIMEOUT = properties.getLong(
+ KEY_MAX_IDLE_PENDING_TIMEOUT, DEFAULT_MAX_IDLE_PENDING_TIMEOUT);
+ break;
+ case KEY_IDLE_PENDING_FACTOR:
+ IDLE_PENDING_FACTOR = properties.getFloat(
+ KEY_IDLE_PENDING_FACTOR, DEFAULT_IDLE_PENDING_FACTOR);
+ break;
+ case KEY_QUICK_DOZE_DELAY_TIMEOUT:
+ QUICK_DOZE_DELAY_TIMEOUT = properties.getLong(
+ KEY_QUICK_DOZE_DELAY_TIMEOUT, DEFAULT_QUICK_DOZE_DELAY_TIMEOUT);
+ break;
+ case KEY_IDLE_TIMEOUT:
+ IDLE_TIMEOUT = properties.getLong(
+ KEY_IDLE_TIMEOUT, DEFAULT_IDLE_TIMEOUT);
+ break;
+ case KEY_MAX_IDLE_TIMEOUT:
+ MAX_IDLE_TIMEOUT = properties.getLong(
+ KEY_MAX_IDLE_TIMEOUT, DEFAULT_MAX_IDLE_TIMEOUT);
+ break;
+ case KEY_IDLE_FACTOR:
+ IDLE_FACTOR = properties.getFloat(KEY_IDLE_FACTOR, DEFAULT_IDLE_FACTOR);
+ break;
+ case KEY_MIN_TIME_TO_ALARM:
+ MIN_TIME_TO_ALARM = properties.getLong(
+ KEY_MIN_TIME_TO_ALARM, DEFAULT_MIN_TIME_TO_ALARM);
+ break;
+ case KEY_MAX_TEMP_APP_WHITELIST_DURATION:
+ MAX_TEMP_APP_WHITELIST_DURATION = properties.getLong(
+ KEY_MAX_TEMP_APP_WHITELIST_DURATION,
+ DEFAULT_MAX_TEMP_APP_WHITELIST_DURATION);
+ break;
+ case KEY_MMS_TEMP_APP_WHITELIST_DURATION:
+ MMS_TEMP_APP_WHITELIST_DURATION = properties.getLong(
+ KEY_MMS_TEMP_APP_WHITELIST_DURATION,
+ DEFAULT_MMS_TEMP_APP_WHITELIST_DURATION);
+ break;
+ case KEY_SMS_TEMP_APP_WHITELIST_DURATION:
+ SMS_TEMP_APP_WHITELIST_DURATION = properties.getLong(
+ KEY_SMS_TEMP_APP_WHITELIST_DURATION,
+ DEFAULT_SMS_TEMP_APP_WHITELIST_DURATION);
+ break;
+ case KEY_NOTIFICATION_ALLOWLIST_DURATION_MS:
+ NOTIFICATION_ALLOWLIST_DURATION_MS = properties.getLong(
+ KEY_NOTIFICATION_ALLOWLIST_DURATION_MS,
+ DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS);
+ break;
+ case KEY_WAIT_FOR_UNLOCK:
+ WAIT_FOR_UNLOCK = properties.getBoolean(
+ KEY_WAIT_FOR_UNLOCK, DEFAULT_WAIT_FOR_UNLOCK);
+ break;
+ case KEY_PRE_IDLE_FACTOR_LONG:
+ PRE_IDLE_FACTOR_LONG = properties.getFloat(
+ KEY_PRE_IDLE_FACTOR_LONG, DEFAULT_PRE_IDLE_FACTOR_LONG);
+ break;
+ case KEY_PRE_IDLE_FACTOR_SHORT:
+ PRE_IDLE_FACTOR_SHORT = properties.getFloat(
+ KEY_PRE_IDLE_FACTOR_SHORT, DEFAULT_PRE_IDLE_FACTOR_SHORT);
+ break;
+ default:
+ Slog.e(TAG, "Unknown configuration key: " + name);
+ break;
+ }
}
-
- LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
- KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
- !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L);
- LIGHT_PRE_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_PRE_IDLE_TIMEOUT,
- !COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L);
- LIGHT_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_IDLE_TIMEOUT,
- !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L);
- LIGHT_IDLE_FACTOR = mParser.getFloat(KEY_LIGHT_IDLE_FACTOR,
- 2f);
- LIGHT_MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_LIGHT_MAX_IDLE_TIMEOUT,
- !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L);
- LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mParser.getDurationMillis(
- KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
- !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L);
- LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mParser.getDurationMillis(
- KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
- !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
- MIN_LIGHT_MAINTENANCE_TIME = mParser.getDurationMillis(
- KEY_MIN_LIGHT_MAINTENANCE_TIME,
- !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L);
- MIN_DEEP_MAINTENANCE_TIME = mParser.getDurationMillis(
- KEY_MIN_DEEP_MAINTENANCE_TIME,
- !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
- long inactiveTimeoutDefault = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
- INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_INACTIVE_TIMEOUT,
- !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
- SENSING_TIMEOUT = mParser.getDurationMillis(KEY_SENSING_TIMEOUT,
- !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L);
- LOCATING_TIMEOUT = mParser.getDurationMillis(KEY_LOCATING_TIMEOUT,
- !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L);
- LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
- MOTION_INACTIVE_TIMEOUT = mParser.getDurationMillis(KEY_MOTION_INACTIVE_TIMEOUT,
- !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
- long idleAfterInactiveTimeout = (mSmallBatteryDevice ? 15 : 30) * 60 * 1000L;
- IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getDurationMillis(
- KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
- !COMPRESS_TIME ? idleAfterInactiveTimeout
- : (idleAfterInactiveTimeout / 10));
- IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_PENDING_TIMEOUT,
- !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
- MAX_IDLE_PENDING_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_PENDING_TIMEOUT,
- !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
- IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
- 2f);
- QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis(
- KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L);
- IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
- !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
- MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
- !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
- IDLE_FACTOR = mParser.getFloat(KEY_IDLE_FACTOR,
- 2f);
- MIN_TIME_TO_ALARM = mParser.getDurationMillis(KEY_MIN_TIME_TO_ALARM,
- !COMPRESS_TIME ? 30 * 60 * 1000L : 6 * 60 * 1000L);
- MAX_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
- KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
- MMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
- KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
- SMS_TEMP_APP_WHITELIST_DURATION = mParser.getDurationMillis(
- KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
- NOTIFICATION_ALLOWLIST_DURATION = mParser.getDurationMillis(
- KEY_NOTIFICATION_ALLOWLIST_DURATION, 30 * 1000L);
- WAIT_FOR_UNLOCK = mParser.getBoolean(KEY_WAIT_FOR_UNLOCK, true);
- PRE_IDLE_FACTOR_LONG = mParser.getFloat(KEY_PRE_IDLE_FACTOR_LONG, 1.67f);
- PRE_IDLE_FACTOR_SHORT = mParser.getFloat(KEY_PRE_IDLE_FACTOR_SHORT, 0.33f);
}
}
void dump(PrintWriter pw) {
pw.println(" Settings:");
- pw.print(" "); pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
+ pw.print(" ");
+ pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
+ pw.print("=");
TimeUtils.formatDuration(LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, pw);
pw.println();
@@ -1344,8 +1447,8 @@
TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
pw.println();
- pw.print(" "); pw.print(KEY_NOTIFICATION_ALLOWLIST_DURATION); pw.print("=");
- TimeUtils.formatDuration(NOTIFICATION_ALLOWLIST_DURATION, pw);
+ pw.print(" "); pw.print(KEY_NOTIFICATION_ALLOWLIST_DURATION_MS); pw.print("=");
+ TimeUtils.formatDuration(NOTIFICATION_ALLOWLIST_DURATION_MS, pw);
pw.println();
pw.print(" "); pw.print(KEY_WAIT_FOR_UNLOCK); pw.print("=");
@@ -1794,7 +1897,7 @@
// duration in milliseconds
@Override
public long getNotificationAllowlistDuration() {
- return mConstants.NOTIFICATION_ALLOWLIST_DURATION;
+ return mConstants.NOTIFICATION_ALLOWLIST_DURATION_MS;
}
@Override
@@ -1871,10 +1974,9 @@
return mConnectivityManager;
}
- Constants getConstants(DeviceIdleController controller, Handler handler,
- ContentResolver resolver) {
+ Constants getConstants(DeviceIdleController controller) {
if (mConstants == null) {
- mConstants = controller.new Constants(handler, resolver);
+ mConstants = controller.new Constants();
}
return mConstants;
}
@@ -2023,7 +2125,7 @@
}
}
- mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
+ mConstants = mInjector.getConstants(this);
readConfigFileLocked();
updateWhitelistAppIdsLocked();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index f1c624d..67997cf 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -22,6 +22,7 @@
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
+import android.annotation.Nullable;
import android.app.job.JobInfo;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
@@ -86,9 +87,12 @@
@GuardedBy("mLock")
private final SparseArray<ArraySet<JobStatus>> mRequestedWhitelistJobs = new SparseArray<>();
- /** List of currently available networks. */
+ /**
+ * Set of currently available networks mapped to their latest network capabilities. Cache the
+ * latest capabilities to avoid unnecessary calls into ConnectivityManager.
+ */
@GuardedBy("mLock")
- private final ArraySet<Network> mAvailableNetworks = new ArraySet<>();
+ private final ArrayMap<Network, NetworkCapabilities> mAvailableNetworks = new ArrayMap<>();
private static final int MSG_DATA_SAVER_TOGGLED = 0;
private static final int MSG_UID_RULES_CHANGES = 1;
@@ -165,9 +169,8 @@
public boolean isNetworkAvailable(JobStatus job) {
synchronized (mLock) {
for (int i = 0; i < mAvailableNetworks.size(); ++i) {
- final Network network = mAvailableNetworks.valueAt(i);
- final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(
- network);
+ final Network network = mAvailableNetworks.keyAt(i);
+ final NetworkCapabilities capabilities = mAvailableNetworks.valueAt(i);
final boolean satisfied = isSatisfied(job, network, capabilities, mConstants);
if (DEBUG) {
Slog.v(TAG, "isNetworkAvailable(" + job + ") with network " + network
@@ -427,9 +430,33 @@
return false;
}
+ @Nullable
+ private NetworkCapabilities getNetworkCapabilities(@Nullable Network network) {
+ if (network == null) {
+ return null;
+ }
+ synchronized (mLock) {
+ // There is technically a race here if the Network object is reused. This can happen
+ // only if that Network disconnects and the auto-incrementing network ID in
+ // ConnectivityService wraps. This should no longer be a concern if/when we only make
+ // use of asynchronous calls.
+ if (mAvailableNetworks.get(network) != null) {
+ return mAvailableNetworks.get(network);
+ }
+
+ // This should almost never happen because any time a new network connects, the
+ // NetworkCallback would populate mAvailableNetworks. However, it's currently necessary
+ // because we also call synchronous methods such as getActiveNetworkForUid.
+ // TODO(134978280): remove after switching to callback-based APIs
+ final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
+ mAvailableNetworks.put(network, capabilities);
+ return capabilities;
+ }
+ }
+
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
final Network network = mConnManager.getActiveNetworkForUid(jobStatus.getSourceUid());
- final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
+ final NetworkCapabilities capabilities = getNetworkCapabilities(network);
return updateConstraintsSatisfied(jobStatus, network, capabilities);
}
@@ -470,19 +497,13 @@
*/
private void updateTrackedJobs(int filterUid, Network filterNetwork) {
synchronized (mLock) {
- // Since this is a really hot codepath, temporarily cache any
- // answers that we get from ConnectivityManager.
- final ArrayMap<Network, NetworkCapabilities> networkToCapabilities = new ArrayMap<>();
-
boolean changed = false;
if (filterUid == -1) {
for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
- changed |= updateTrackedJobsLocked(mTrackedJobs.valueAt(i),
- filterNetwork, networkToCapabilities);
+ changed |= updateTrackedJobsLocked(mTrackedJobs.valueAt(i), filterNetwork);
}
} else {
- changed = updateTrackedJobsLocked(mTrackedJobs.get(filterUid),
- filterNetwork, networkToCapabilities);
+ changed = updateTrackedJobsLocked(mTrackedJobs.get(filterUid), filterNetwork);
}
if (changed) {
mStateChangedListener.onControllerStateChanged();
@@ -490,18 +511,13 @@
}
}
- private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork,
- ArrayMap<Network, NetworkCapabilities> networkToCapabilities) {
+ private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) {
if (jobs == null || jobs.size() == 0) {
return false;
}
final Network network = mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid());
- NetworkCapabilities capabilities = networkToCapabilities.get(network);
- if (capabilities == null) {
- capabilities = mConnManager.getNetworkCapabilities(network);
- networkToCapabilities.put(network, capabilities);
- }
+ final NetworkCapabilities capabilities = getNetworkCapabilities(network);
final boolean networkMatch = (filterNetwork == null
|| Objects.equals(filterNetwork, network));
@@ -544,9 +560,9 @@
@Override
public void onAvailable(Network network) {
if (DEBUG) Slog.v(TAG, "onAvailable: " + network);
- synchronized (mLock) {
- mAvailableNetworks.add(network);
- }
+ // Documentation says not to call getNetworkCapabilities here but wait for
+ // onCapabilitiesChanged instead. onCapabilitiesChanged should be called immediately
+ // after this, so no need to update mAvailableNetworks here.
}
@Override
@@ -554,6 +570,9 @@
if (DEBUG) {
Slog.v(TAG, "onCapabilitiesChanged: " + network);
}
+ synchronized (mLock) {
+ mAvailableNetworks.put(network, capabilities);
+ }
updateTrackedJobs(-1, network);
}
@@ -630,6 +649,8 @@
pw.println("Available networks:");
pw.increaseIndent();
for (int i = 0; i < mAvailableNetworks.size(); i++) {
+ pw.print(mAvailableNetworks.keyAt(i));
+ pw.print(": ");
pw.println(mAvailableNetworks.valueAt(i));
}
pw.decreaseIndent();
@@ -667,7 +688,7 @@
mRequestedWhitelistJobs.keyAt(i));
}
for (int i = 0; i < mAvailableNetworks.size(); i++) {
- Network network = mAvailableNetworks.valueAt(i);
+ Network network = mAvailableNetworks.keyAt(i);
if (network != null) {
network.dumpDebug(proto,
StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS);
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 4417b68..ce4b030 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -44,7 +44,6 @@
plugins: ["java_api_finder"],
hostdex: true, // for hiddenapi check
- visibility: ["//frameworks/av/apex:__subpackages__"],
apex_available: [
"com.android.media",
"test_com.android.media",
@@ -83,7 +82,7 @@
"java/android/media/MediaParser.java"
],
path: "java",
-}
+}
java_sdk_library {
name: "framework-media",
@@ -99,15 +98,7 @@
libs: [
"framework_media_annotation",
],
-
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/av/apex:__subpackages__",
- ],
+ impl_library_visibility: ["//frameworks/av/apex:__subpackages__"],
}
diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp
index be553fe..c0560f6 100644
--- a/apex/permission/framework/Android.bp
+++ b/apex/permission/framework/Android.bp
@@ -25,14 +25,8 @@
name: "framework-permission",
defaults: ["framework-module-defaults"],
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
// Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/base/apex/permission:__subpackages__",
- ],
+ impl_library_visibility: ["//frameworks/base/apex/permission:__subpackages__"],
srcs: [
":framework-permission-sources",
diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp
index 7f31879..b7d8433 100644
--- a/apex/permission/service/Android.bp
+++ b/apex/permission/service/Android.bp
@@ -23,15 +23,7 @@
java_sdk_library {
name: "service-permission",
defaults: ["framework-system-server-module-defaults"],
- visibility: [
- "//frameworks/base/services/core",
- "//frameworks/base/apex/permission",
- "//frameworks/base/apex/permission/testing",
- "//frameworks/base/apex/permission/tests",
- "//frameworks/base/services/tests/mockingservicestests",
- ],
impl_library_visibility: [
- "//visibility:override",
"//frameworks/base/apex/permission/tests",
"//frameworks/base/services/tests/mockingservicestests",
"//frameworks/base/services/tests/servicestests",
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index b06f401..bf4323d 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -72,19 +72,7 @@
hostdex: true, // for hiddenapi check
- visibility: [
- "//frameworks/base", // Framework
- "//frameworks/base/apex/statsd:__subpackages__", // statsd apex
- "//frameworks/base/packages/Tethering", // Tethering
- "//frameworks/opt/net/wifi/service", // wifi service
- "//packages/providers/MediaProvider", // MediaProvider apk
- ],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/base/apex/statsd:__subpackages__", // statsd apex
- ],
+ impl_library_visibility: ["//frameworks/base/apex/statsd/framework/test:__subpackages__"],
apex_available: [
"com.android.os.statsd",
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
index 97846f2..1e3846b 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
@@ -27,6 +27,7 @@
import android.os.IPullAtomCallback;
import android.os.IStatsManagerService;
import android.os.IStatsd;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -412,8 +413,13 @@
@Override
public byte[] getData(long key, String packageName) throws IllegalStateException {
enforceDumpAndUsageStatsPermission(packageName);
+ PowerManager powerManager = (PowerManager)
+ mContext.getSystemService(Context.POWER_SERVICE);
+ PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ /*tag=*/ StatsManagerService.class.getCanonicalName());
int callingUid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
+ wl.acquire();
try {
IStatsd statsd = waitForStatsd();
if (statsd != null) {
@@ -423,6 +429,7 @@
Log.e(TAG, "Failed to getData with statsd");
throw new IllegalStateException(e.getMessage(), e);
} finally {
+ wl.release();
Binder.restoreCallingIdentity(token);
}
throw new IllegalStateException("Failed to connect to statsd to getData");
diff --git a/api/current.txt b/api/current.txt
index a1629f1..723ffec5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1005,7 +1005,7 @@
field public static final int numericModifiers = 16844111; // 0x101054f
field public static final int numericShortcut = 16843236; // 0x10101e4
field public static final int offset = 16844052; // 0x1010514
- field public static final int onClick = 16843375; // 0x101026f
+ field @Deprecated public static final int onClick = 16843375; // 0x101026f
field public static final int oneshot = 16843159; // 0x1010197
field public static final int opacity = 16843550; // 0x101031e
field public static final int opticalInsetBottom = 16844171; // 0x101058b
@@ -6188,6 +6188,7 @@
method public android.app.PictureInPictureParams build();
method public android.app.PictureInPictureParams.Builder setActions(java.util.List<android.app.RemoteAction>);
method public android.app.PictureInPictureParams.Builder setAspectRatio(android.util.Rational);
+ method @NonNull public android.app.PictureInPictureParams.Builder setAutoEnterAllowed(boolean);
method public android.app.PictureInPictureParams.Builder setSourceRectHint(android.graphics.Rect);
}
@@ -6531,6 +6532,7 @@
method public android.graphics.Bitmap takeScreenshot();
method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
field public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 1; // 0x1
+ field public static final int FLAG_DONT_USE_ACCESSIBILITY = 2; // 0x2
field public static final int ROTATION_FREEZE_0 = 0; // 0x0
field public static final int ROTATION_FREEZE_180 = 2; // 0x2
field public static final int ROTATION_FREEZE_270 = 3; // 0x3
@@ -31302,6 +31304,7 @@
@Deprecated public static class WifiConfiguration.GroupCipher {
field @Deprecated public static final int CCMP = 3; // 0x3
+ field @Deprecated public static final int GCMP_128 = 7; // 0x7
field @Deprecated public static final int GCMP_256 = 5; // 0x5
field @Deprecated public static final int SMS4 = 6; // 0x6
field @Deprecated public static final int TKIP = 2; // 0x2
@@ -31331,6 +31334,7 @@
@Deprecated public static class WifiConfiguration.PairwiseCipher {
field @Deprecated public static final int CCMP = 2; // 0x2
+ field @Deprecated public static final int GCMP_128 = 5; // 0x5
field @Deprecated public static final int GCMP_256 = 3; // 0x3
field @Deprecated public static final int NONE = 0; // 0x0
field @Deprecated public static final int SMS4 = 4; // 0x4
@@ -31737,6 +31741,7 @@
method public void onPublishStarted(@NonNull android.net.wifi.aware.PublishDiscoverySession);
method public void onServiceDiscovered(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>);
method public void onServiceDiscoveredWithinRange(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>, int);
+ method public void onServiceLost(@NonNull android.net.wifi.aware.PeerHandle);
method public void onSessionConfigFailed();
method public void onSessionConfigUpdated();
method public void onSessionTerminated();
@@ -31812,6 +31817,7 @@
method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
method public android.net.wifi.aware.Characteristics getCharacteristics();
method public boolean isAvailable();
+ method public boolean isDeviceAttached();
field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0
field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
@@ -48399,7 +48405,8 @@
method public boolean isVoiceCapable();
method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
method public boolean isWorldPhone();
- method public void listen(android.telephony.PhoneStateListener, int);
+ method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
+ method public void listen(long, @NonNull android.telephony.PhoneStateListener);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
method public void sendDialerSpecialCode(String);
@@ -52841,6 +52848,7 @@
method public final boolean isFunctionPressed();
method public static final boolean isGamepadButton(int);
method public final boolean isLongPress();
+ method public static final boolean isMediaSessionKey(int);
method public final boolean isMetaPressed();
method public static boolean isModifierKey(int);
method public final boolean isNumLockOn();
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 17545a4..c12d897 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -35,17 +35,32 @@
package android.media {
public class AudioManager {
+ method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
+ method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
+ method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
field public static final int FLAG_FROM_KEY = 4096; // 0x1000
}
+ public static final class MediaMetadata.Builder {
+ ctor public MediaMetadata.Builder(@NonNull android.media.MediaMetadata, @IntRange(from=1) int);
+ }
+
}
package android.media.session {
+ public static final class MediaController.PlaybackInfo implements android.os.Parcelable {
+ ctor public MediaController.PlaybackInfo(int, int, @IntRange(from=0) int, @IntRange(from=0) int, @NonNull android.media.AudioAttributes, @Nullable String);
+ }
+
public final class MediaSession {
field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000
}
+ public static final class MediaSession.Token implements android.os.Parcelable {
+ method public int getUid();
+ }
+
public final class MediaSessionManager {
method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent);
method public boolean dispatchMediaKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent);
@@ -129,6 +144,14 @@
}
+package android.provider {
+
+ public final class DeviceConfig {
+ field public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
+ }
+
+}
+
package android.util {
public class AtomicFile {
diff --git a/api/system-current.txt b/api/system-current.txt
old mode 100755
new mode 100644
index dbe2e31..4134711
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -205,6 +205,7 @@
field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION";
+ field public static final String SEND_CATEGORY_CAR_NOTIFICATIONS = "android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS";
field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS";
field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
@@ -4199,8 +4200,10 @@
public class AudioManager {
method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException;
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException;
method public void clearAudioServerStateCallback();
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
@@ -4211,6 +4214,7 @@
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -4219,6 +4223,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
@@ -4228,6 +4233,7 @@
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
@@ -4257,6 +4263,10 @@
method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
}
+ public static interface AudioManager.OnPreferredDevicesForCapturePresetChangedListener {
+ method public void onPreferredDevicesForCapturePresetChanged(int, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
+ }
+
public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener {
method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
}
@@ -4328,17 +4338,22 @@
method @NonNull public android.media.HwAudioSource.Builder setAudioDeviceInfo(@NonNull android.media.AudioDeviceInfo);
}
+ public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
+ method @RequiresPermission("android.permission.BIND_IMS_SERVICE") public void setOnImsRxNoticeListener(@Nullable android.media.MediaPlayer.OnImsRxNoticeListener, @Nullable android.os.Handler);
+ }
+
+ public static interface MediaPlayer.OnImsRxNoticeListener {
+ method public void onImsRxNotice(@NonNull android.media.MediaPlayer, @NonNull byte[]);
+ }
+
public final class MediaRecorder.AudioSource {
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int ECHO_REFERENCE = 1997; // 0x7cd
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) public static final int HOTWORD = 1999; // 0x7cf
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int RADIO_TUNER = 1998; // 0x7ce
}
- public final class MediaTranscodeManager implements java.lang.AutoCloseable {
- method public void close();
+ public final class MediaTranscodeManager {
method @NonNull public android.media.MediaTranscodeManager.TranscodingJob enqueueRequest(@NonNull android.media.MediaTranscodeManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodeManager.OnTranscodingFinishedListener) throws java.io.FileNotFoundException;
- method protected void finalize();
- field public static final int PRIORITY_OFFLINE = 2; // 0x2
field public static final int PRIORITY_REALTIME = 1; // 0x1
field public static final int TRANSCODING_TYPE_VIDEO = 1; // 0x1
}
@@ -4367,7 +4382,7 @@
}
@java.lang.FunctionalInterface public static interface MediaTranscodeManager.TranscodingJob.OnProgressUpdateListener {
- method public void onProgressUpdate(@IntRange(from=0, to=100) int);
+ method public void onProgressUpdate(@NonNull android.media.MediaTranscodeManager.TranscodingJob, @IntRange(from=0, to=100) int);
}
public static final class MediaTranscodeManager.TranscodingRequest {
@@ -4388,6 +4403,14 @@
method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.Builder setVideoTrackFormat(@NonNull android.media.MediaFormat);
}
+ public static class MediaTranscodeManager.TranscodingRequest.MediaFormatResolver {
+ ctor public MediaTranscodeManager.TranscodingRequest.MediaFormatResolver();
+ method @Nullable public android.media.MediaFormat resolveVideoFormat();
+ method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver setSourceVideoFormatHint(@NonNull android.media.MediaFormat);
+ method public boolean shouldTranscode();
+ field public static final String CAPS_SUPPORTS_HEVC = "support-hevc";
+ }
+
public class PlayerProxy {
method public void pause();
method public void setPan(float);
@@ -7329,6 +7352,7 @@
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
+ method public boolean is60GHzBandSupported();
method public boolean isApMacRandomizationSupported();
method public boolean isConnectedMacRandomizationSupported();
method @Deprecated public boolean isDeviceToDeviceRttSupported();
@@ -7568,6 +7592,7 @@
field public static final int WIFI_BAND_5_GHZ = 2; // 0x2
field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4
field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6
+ field public static final int WIFI_BAND_60_GHZ = 16; // 0x10
field public static final int WIFI_BAND_6_GHZ = 8; // 0x8
field public static final int WIFI_BAND_BOTH = 3; // 0x3
field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7
@@ -7807,6 +7832,8 @@
field public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 8; // 0x8
field public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 128; // 0x80
field public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 16384; // 0x4000
+ field public static final int BSS_CAPABILITY_DMG_ESS = 3; // 0x3
+ field public static final int BSS_CAPABILITY_DMG_IBSS = 1; // 0x1
field public static final int BSS_CAPABILITY_DSSS_OFDM = 8192; // 0x2000
field public static final int BSS_CAPABILITY_ESS = 1; // 0x1
field public static final int BSS_CAPABILITY_IBSS = 2; // 0x2
@@ -7876,7 +7903,7 @@
method @NonNull public java.util.List<android.net.wifi.nl80211.NativeScanResult> getScanResults(@NonNull String, int);
method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String);
method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]);
- method public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback);
+ method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback);
method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback);
method public void setOnServiceDeadCallback(@NonNull Runnable);
method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback);
@@ -7927,10 +7954,10 @@
field public final int txBitrateMbps;
}
- public static interface WifiNl80211Manager.SoftApCallback {
- method public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean);
- method public void onFailure();
- method public void onSoftApChannelSwitched(int, int);
+ @Deprecated public static interface WifiNl80211Manager.SoftApCallback {
+ method @Deprecated public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean);
+ method @Deprecated public void onFailure();
+ method @Deprecated public void onSoftApChannelSwitched(int, int);
}
public static class WifiNl80211Manager.TxPacketCounters {
@@ -10876,6 +10903,7 @@
method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onPhysicalChannelConfigurationChanged(@NonNull java.util.List<android.telephony.PhysicalChannelConfig>);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
@@ -10883,12 +10911,29 @@
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
+ field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final long LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 4294967296L; // 0x100000000L
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
}
+ public final class PhysicalChannelConfig implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getCellBandwidthDownlink();
+ method public int getChannelNumber();
+ method public int getConnectionStatus();
+ method public int getNetworkType();
+ method @IntRange(from=0, to=1007) public int getPhysicalCellId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff
+ field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
+ field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2
+ field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhysicalChannelConfig> CREATOR;
+ field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
+ }
+
public final class PreciseCallState implements android.os.Parcelable {
ctor public PreciseCallState(int, int, int, int, int);
method public int describeContents();
diff --git a/api/test-current.txt b/api/test-current.txt
index 2dd7409..de2919b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -133,7 +133,6 @@
public class ActivityTaskManager {
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void clearLaunchParamsForPackages(java.util.List<java.lang.String>);
method public static boolean currentUiModeSupportsErrorDialogs(@NonNull android.content.Context);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public String listAllStacks();
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void moveTaskToStack(int, int, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean moveTopActivityToPinnedStack(int, android.graphics.Rect);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
@@ -1819,11 +1818,8 @@
method @NonNull public String getOriginalId();
}
- public final class MediaTranscodeManager implements java.lang.AutoCloseable {
- method public void close();
+ public final class MediaTranscodeManager {
method @NonNull public android.media.MediaTranscodeManager.TranscodingJob enqueueRequest(@NonNull android.media.MediaTranscodeManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodeManager.OnTranscodingFinishedListener) throws java.io.FileNotFoundException;
- method protected void finalize();
- field public static final int PRIORITY_OFFLINE = 2; // 0x2
field public static final int PRIORITY_REALTIME = 1; // 0x1
field public static final int TRANSCODING_TYPE_VIDEO = 1; // 0x1
}
@@ -1852,7 +1848,7 @@
}
@java.lang.FunctionalInterface public static interface MediaTranscodeManager.TranscodingJob.OnProgressUpdateListener {
- method public void onProgressUpdate(@IntRange(from=0, to=100) int);
+ method public void onProgressUpdate(@NonNull android.media.MediaTranscodeManager.TranscodingJob, @IntRange(from=0, to=100) int);
}
public static final class MediaTranscodeManager.TranscodingRequest {
@@ -1873,6 +1869,14 @@
method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.Builder setVideoTrackFormat(@NonNull android.media.MediaFormat);
}
+ public static class MediaTranscodeManager.TranscodingRequest.MediaFormatResolver {
+ ctor public MediaTranscodeManager.TranscodingRequest.MediaFormatResolver();
+ method @Nullable public android.media.MediaFormat resolveVideoFormat();
+ method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver setSourceVideoFormatHint(@NonNull android.media.MediaFormat);
+ method public boolean shouldTranscode();
+ field public static final String CAPS_SUPPORTS_HEVC = "support-hevc";
+ }
+
public final class PlaybackParams implements android.os.Parcelable {
method public int getAudioStretchMode();
method public android.media.PlaybackParams setAudioStretchMode(int);
@@ -3294,6 +3298,7 @@
field public static final String NAMESPACE_AUTOFILL = "autofill";
field public static final String NAMESPACE_BIOMETRICS = "biometrics";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
+ field public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
field public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler";
field public static final String NAMESPACE_PERMISSIONS = "permissions";
field public static final String NAMESPACE_PRIVACY = "privacy";
@@ -5623,18 +5628,18 @@
public class TaskOrganizer extends android.window.WindowOrganizer {
ctor public TaskOrganizer();
- method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static android.app.ActivityManager.RunningTaskInfo createRootTask(int, int);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static boolean deleteRootTask(@NonNull android.window.WindowContainerToken);
- method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
- method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static android.window.WindowContainerToken getImeTarget(int);
- method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]);
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public android.app.ActivityManager.RunningTaskInfo createRootTask(int, int);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean deleteRootTask(@NonNull android.window.WindowContainerToken);
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public android.window.WindowContainerToken getImeTarget(int);
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]);
method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.view.SurfaceControl);
method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void registerOrganizer();
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void setLaunchRoot(int, @NonNull android.window.WindowContainerToken);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setLaunchRoot(int, @NonNull android.window.WindowContainerToken);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void unregisterOrganizer();
}
@@ -5671,7 +5676,7 @@
public class WindowOrganizer {
ctor public WindowOrganizer();
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void applyTransaction(@NonNull android.window.WindowContainerTransaction);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void applyTransaction(@NonNull android.window.WindowContainerTransaction);
}
}
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 1e200c5..437a87e 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -27,9 +27,9 @@
#include <cstring>
#include <memory>
-#include <android/log.h>
#include <android/looper.h>
#include <jni.h>
+#include <log/log.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativehelper/ScopedPrimitiveArray.h>
@@ -37,10 +37,8 @@
#include <android-base/stringprintf.h>
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
-#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
-#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
-#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+// Log debug messages about the output.
+static constexpr bool DEBUG_OUTPUT = false;
namespace android {
namespace uhid {
@@ -61,7 +59,7 @@
static void checkAndClearException(JNIEnv* env, const char* methodName) {
if (env->ExceptionCheck()) {
- LOGE("An exception was thrown by callback '%s'.", methodName);
+ ALOGE("An exception was thrown by callback '%s'.", methodName);
env->ExceptionClear();
}
}
@@ -115,9 +113,9 @@
checkAndClearException(env, "onDeviceGetReport");
}
-void DeviceCallback::onDeviceOutput(const std::vector<uint8_t>& data) {
+void DeviceCallback::onDeviceOutput(uint8_t rType, const std::vector<uint8_t>& data) {
JNIEnv* env = getJNIEnv();
- env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceOutput,
+ env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceOutput, rType,
toJbyteArray(env, data).get());
checkAndClearException(env, "onDeviceOutput");
}
@@ -133,13 +131,13 @@
std::unique_ptr<DeviceCallback> callback) {
size_t size = descriptor.size();
if (size > HID_MAX_DESCRIPTOR_SIZE) {
- LOGE("Received invalid hid report with descriptor size %zu, skipping", size);
+ ALOGE("Received invalid hid report with descriptor size %zu, skipping", size);
return nullptr;
}
android::base::unique_fd fd(::open(UHID_PATH, O_RDWR | O_CLOEXEC));
if (!fd.ok()) {
- LOGE("Failed to open uhid: %s", strerror(errno));
+ ALOGE("Failed to open uhid: %s", strerror(errno));
return nullptr;
}
@@ -159,14 +157,14 @@
errno = 0;
ssize_t ret = TEMP_FAILURE_RETRY(::write(fd, &ev, sizeof(ev)));
if (ret < 0 || ret != sizeof(ev)) {
- LOGE("Failed to create uhid node: %s", strerror(errno));
+ ALOGE("Failed to create uhid node: %s", strerror(errno));
return nullptr;
}
// Wait for the device to actually be created.
ret = TEMP_FAILURE_RETRY(::read(fd, &ev, sizeof(ev)));
if (ret < 0 || ev.type != UHID_START) {
- LOGE("uhid node failed to start: %s", strerror(errno));
+ ALOGE("uhid node failed to start: %s", strerror(errno));
return nullptr;
}
// using 'new' to access non-public constructor
@@ -177,7 +175,7 @@
: mId(id), mFd(std::move(fd)), mDeviceCallback(std::move(callback)) {
ALooper* aLooper = ALooper_forThread();
if (aLooper == NULL) {
- LOGE("Could not get ALooper, ALooper_forThread returned NULL");
+ ALOGE("Could not get ALooper, ALooper_forThread returned NULL");
aLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
}
ALooper_addFd(aLooper, mFd, 0, ALOOPER_EVENT_INPUT, handleLooperEvents,
@@ -189,7 +187,7 @@
if (looper != NULL) {
ALooper_removeFd(looper, mFd);
} else {
- LOGE("Could not remove fd, ALooper_forThread() returned NULL!");
+ ALOGE("Could not remove fd, ALooper_forThread() returned NULL!");
}
struct uhid_event ev = {};
ev.type = UHID_DESTROY;
@@ -200,13 +198,13 @@
static void writeEvent(int fd, struct uhid_event& ev, const char* messageType) {
ssize_t ret = TEMP_FAILURE_RETRY(::write(fd, &ev, sizeof(ev)));
if (ret < 0 || ret != sizeof(ev)) {
- LOGE("Failed to send uhid_event %s: %s", messageType, strerror(errno));
+ ALOGE("Failed to send uhid_event %s: %s", messageType, strerror(errno));
}
}
void Device::sendReport(const std::vector<uint8_t>& report) const {
if (report.size() > UHID_DATA_MAX) {
- LOGE("Received invalid report of size %zu, skipping", report.size());
+ ALOGE("Received invalid report of size %zu, skipping", report.size());
return;
}
@@ -230,14 +228,14 @@
int Device::handleEvents(int events) {
if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
- LOGE("uhid node was closed or an error occurred. events=0x%x", events);
+ ALOGE("uhid node was closed or an error occurred. events=0x%x", events);
mDeviceCallback->onDeviceError();
return 0;
}
struct uhid_event ev;
ssize_t ret = TEMP_FAILURE_RETRY(::read(mFd, &ev, sizeof(ev)));
if (ret < 0) {
- LOGE("Failed to read from uhid node: %s", strerror(errno));
+ ALOGE("Failed to read from uhid node: %s", strerror(errno));
mDeviceCallback->onDeviceError();
return 0;
}
@@ -254,23 +252,28 @@
case UHID_SET_REPORT: {
const struct uhid_set_report_req& set_report = ev.u.set_report;
if (set_report.size > UHID_DATA_MAX) {
- LOGE("SET_REPORT contains too much data: size = %" PRIu16, set_report.size);
+ ALOGE("SET_REPORT contains too much data: size = %" PRIu16, set_report.size);
return 0;
}
std::vector<uint8_t> data(set_report.data, set_report.data + set_report.size);
- LOGI("Received SET_REPORT: id=%" PRIu32 " rnum=%" PRIu8 " data=%s", set_report.id,
- set_report.rnum, toString(data).c_str());
+ if (DEBUG_OUTPUT) {
+ ALOGD("Received SET_REPORT: id=%" PRIu32 " rnum=%" PRIu8 " data=%s", set_report.id,
+ set_report.rnum, toString(data).c_str());
+ }
break;
}
case UHID_OUTPUT: {
struct uhid_output_req& output = ev.u.output;
std::vector<uint8_t> data(output.data, output.data + output.size);
- mDeviceCallback->onDeviceOutput(data);
+ if (DEBUG_OUTPUT) {
+ ALOGD("UHID_OUTPUT rtype=%" PRIu8 " data=%s", output.rtype, toString(data).c_str());
+ }
+ mDeviceCallback->onDeviceOutput(output.rtype, data);
break;
}
default: {
- LOGI("Unhandled event type: %" PRIu32, ev.type);
+ ALOGI("Unhandled event type: %" PRIu32, ev.type);
break;
}
}
@@ -318,7 +321,7 @@
if (d) {
d->sendReport(report);
} else {
- LOGE("Could not send report, Device* is null!");
+ ALOGE("Could not send report, Device* is null!");
}
}
@@ -329,7 +332,7 @@
std::vector<uint8_t> report = getData(env, rawReport);
d->sendGetFeatureReportReply(id, report);
} else {
- LOGE("Could not send get feature report reply, Device* is null!");
+ ALOGE("Could not send get feature report reply, Device* is null!");
}
}
@@ -354,7 +357,7 @@
int register_com_android_commands_hid_Device(JNIEnv* env) {
jclass clazz = env->FindClass("com/android/commands/hid/Device$DeviceCallback");
if (clazz == NULL) {
- LOGE("Unable to find class 'DeviceCallback'");
+ ALOGE("Unable to find class 'DeviceCallback'");
return JNI_ERR;
}
uhid::gDeviceCallbackClassInfo.onDeviceOpen =
@@ -362,12 +365,12 @@
uhid::gDeviceCallbackClassInfo.onDeviceGetReport =
env->GetMethodID(clazz, "onDeviceGetReport", "(II)V");
uhid::gDeviceCallbackClassInfo.onDeviceOutput =
- env->GetMethodID(clazz, "onDeviceOutput", "([B)V");
+ env->GetMethodID(clazz, "onDeviceOutput", "(B[B)V");
uhid::gDeviceCallbackClassInfo.onDeviceError =
env->GetMethodID(clazz, "onDeviceError", "()V");
if (uhid::gDeviceCallbackClassInfo.onDeviceOpen == NULL ||
uhid::gDeviceCallbackClassInfo.onDeviceError == NULL) {
- LOGE("Unable to obtain onDeviceOpen or onDeviceError methods");
+ ALOGE("Unable to obtain onDeviceOpen or onDeviceError methods");
return JNI_ERR;
}
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index 7202b45..5483b40 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -31,7 +31,7 @@
void onDeviceOpen();
void onDeviceGetReport(uint32_t requestId, uint8_t reportId);
- void onDeviceOutput(const std::vector<uint8_t>& data);
+ void onDeviceOutput(uint8_t rType, const std::vector<uint8_t>& data);
void onDeviceError();
private:
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
index dade415..20b4bd8 100644
--- a/cmds/hid/src/com/android/commands/hid/Device.java
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -26,6 +26,12 @@
import com.android.internal.os.SomeArgs;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map;
@@ -38,12 +44,16 @@
private static final int MSG_SEND_GET_FEATURE_REPORT_REPLY = 3;
private static final int MSG_CLOSE_DEVICE = 4;
+ // Sync with linux uhid_event_type::UHID_OUTPUT
+ private static final byte UHID_EVENT_TYPE_UHID_OUTPUT = 6;
+
private final int mId;
private final HandlerThread mThread;
private final DeviceHandler mHandler;
// mFeatureReports is limited to 256 entries, because the report number is 8-bit
private final SparseArray<byte[]> mFeatureReports;
private final Map<ByteBuffer, byte[]> mOutputs;
+ private final OutputStream mOutputStream;
private long mTimeToSend;
private final Object mCond = new Object();
@@ -66,6 +76,7 @@
mHandler = new DeviceHandler(mThread.getLooper());
mFeatureReports = featureReports;
mOutputs = outputs;
+ mOutputStream = System.out;
SomeArgs args = SomeArgs.obtain();
args.argi1 = id;
args.argi2 = vid;
@@ -188,7 +199,27 @@
}
// native callback
- public void onDeviceOutput(byte[] data) {
+ public void onDeviceOutput(byte rtype, byte[] data) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("eventId", UHID_EVENT_TYPE_UHID_OUTPUT);
+ json.put("deviceId", mId);
+ json.put("reportType", rtype);
+ JSONArray dataArray = new JSONArray();
+ for (int i = 0; i < data.length; i++) {
+ dataArray.put(data[i] & 0xFF);
+ }
+ json.put("reportData", dataArray);
+ } catch (JSONException e) {
+ throw new RuntimeException("Could not create JSON object ", e);
+ }
+ try {
+ mOutputStream.write(json.toString().getBytes());
+ mOutputStream.flush();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
if (mOutputs == null) {
Log.e(TAG, "Received OUTPUT request, but 'outputs' section is not found");
return;
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e6e22ba..94c2305 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -488,6 +488,8 @@
UIInteractionFrameInfoReported ui_interaction_frame_info_reported =
305 [(module) = "framework"];
UIActionLatencyReported ui_action_latency_reported = 306 [(module) = "framework"];
+ WifiDisconnectReported wifi_disconnect_reported = 307 [(module) = "wifi"];
+ WifiConnectionStateChanged wifi_connection_state_changed = 308 [(module) = "wifi"];
// StatsdStats tracks platform atoms with ids upto 500.
// Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
@@ -854,10 +856,10 @@
}
/**
- * Logs whether a wifi connection is successful and reasons for failure if it isn't.
+ * Logs whether a Wifi connection attempt was successful and reasons for failure if it wasn't.
*
* Logged from:
- * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java
+ * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java
*/
message WifiConnectionResultReported {
enum FailureCode {
@@ -869,13 +871,159 @@
FAILURE_DHCP = 5;
FAILURE_NETWORK_DISCONNECTION = 6;
FAILURE_ROAM_TIMEOUT = 7;
+ FAILURE_WRONG_PASSWORD = 8;
}
- // true represents a successful connection
+
+ enum Trigger {
+ UNKNOWN = 0;
+ // Connection attempt was initiated manually.
+ MANUAL = 1;
+ // Automatic reconnection to the same network as connected previously.
+ RECONNECT_SAME_NETWORK = 2;
+ // Automatic reconnection to a saved network, but not the previous one.
+ AUTOCONNECT_CONFIGURED_NETWORK = 3;
+ // Automatic first connection attempt after device boot.
+ AUTOCONNECT_BOOT = 4;
+ }
+
+ // True represents a successful connection.
optional bool connection_result = 1;
- // reason for the connection failure
+ // Reason for the connection failure.
optional FailureCode failure_code = 2;
- // scan rssi before the connection attempt
+ // Scan RSSI before the connection attempt.
optional int32 rssi = 3;
+ // Time taken by this connection attempt.
+ optional int32 connection_attempt_duration_millis = 4;
+ // Band bucket the connected network is on.
+ optional android.net.wifi.WifiBandBucket band = 5;
+ // Authentication type.
+ optional android.net.wifi.WifiAuthType auth_type = 6;
+ // What triggered this connection attempt.
+ optional Trigger trigger = 7;
+ // Whether this network was used (successfully connected to) previously.
+ optional bool network_used = 8;
+ // Time taken from the last successful connection (or device boot if that's the first one).
+ optional int32 time_since_last_connection_seconds = 9;
+}
+
+/**
+ * Logs when a Wifi connection drops.
+ *
+ * Logged from:
+ * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java
+ */
+message WifiDisconnectReported {
+ enum FailureCode {
+ UNKNOWN = 0;
+
+ // Wifi supplicant failure reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+ // See ISupplicantStaIfaceCallback.java:ReasonCode
+ UNSPECIFIED = 1;
+ PREV_AUTH_NOT_VALID = 2;
+ DEAUTH_LEAVING = 3;
+ DISASSOC_DUE_TO_INACTIVITY = 4;
+ DISASSOC_AP_BUSY = 5;
+ CLASS2_FRAME_FROM_NONAUTH_STA = 6;
+ CLASS3_FRAME_FROM_NONASSOC_STA = 7;
+ DISASSOC_STA_HAS_LEFT = 8;
+ STA_REQ_ASSOC_WITHOUT_AUTH = 9;
+ PWR_CAPABILITY_NOT_VALID = 10;
+ SUPPORTED_CHANNEL_NOT_VALID = 11;
+ BSS_TRANSITION_DISASSOC = 12;
+ INVALID_IE = 13;
+ MICHAEL_MIC_FAILURE = 14;
+ FOURWAY_HANDSHAKE_TIMEOUT = 15;
+ GROUP_KEY_UPDATE_TIMEOUT = 16;
+ IE_IN_4WAY_DIFFERS = 17;
+ GROUP_CIPHER_NOT_VALID = 18;
+ PAIRWISE_CIPHER_NOT_VALID = 19;
+ AKMP_NOT_VALID = 20;
+ UNSUPPORTED_RSN_IE_VERSION = 21;
+ INVALID_RSN_IE_CAPAB = 22;
+ IEEE_802_1X_AUTH_FAILED = 23;
+ CIPHER_SUITE_REJECTED = 24;
+ TDLS_TEARDOWN_UNREACHABLE = 25;
+ TDLS_TEARDOWN_UNSPECIFIED = 26;
+ SSP_REQUESTED_DISASSOC = 27;
+ NO_SSP_ROAMING_AGREEMENT = 28;
+ BAD_CIPHER_OR_AKM = 29;
+ NOT_AUTHORIZED_THIS_LOCATION = 30;
+ SERVICE_CHANGE_PRECLUDES_TS = 31;
+ UNSPECIFIED_QOS_REASON = 32;
+ NOT_ENOUGH_BANDWIDTH = 33;
+ DISASSOC_LOW_ACK = 34;
+ EXCEEDED_TXOP = 35;
+ STA_LEAVING = 36;
+ END_TS_BA_DLS = 37;
+ UNKNOWN_TS_BA = 38;
+ TIMEOUT = 39;
+ PEERKEY_MISMATCH = 45;
+ AUTHORIZED_ACCESS_LIMIT_REACHED = 46;
+ EXTERNAL_SERVICE_REQUIREMENTS = 47;
+ INVALID_FT_ACTION_FRAME_COUNT = 48;
+ INVALID_PMKID = 49;
+ INVALID_MDE = 50;
+ INVALID_FTE = 51;
+ MESH_PEERING_CANCELLED = 52;
+ MESH_MAX_PEERS = 53;
+ MESH_CONFIG_POLICY_VIOLATION = 54;
+ MESH_CLOSE_RCVD = 55;
+ MESH_MAX_RETRIES = 56;
+ MESH_CONFIRM_TIMEOUT = 57;
+ MESH_INVALID_GTK = 58;
+ MESH_INCONSISTENT_PARAMS = 59;
+ MESH_INVALID_SECURITY_CAP = 60;
+ MESH_PATH_ERROR_NO_PROXY_INFO = 61;
+ MESH_PATH_ERROR_NO_FORWARDING_INFO = 62;
+ MESH_PATH_ERROR_DEST_UNREACHABLE = 63;
+ MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64;
+ MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65;
+ MESH_CHANNEL_SWITCH_UNSPECIFIED = 66;
+
+ // ClientModeImpl error codes
+ // Defined in /frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java
+ IFACE_DESTROYED = 10000;
+ WIFI_DISABLED = 10001;
+ SUPPLICANT_DISCONNECTED = 10002;
+ CONNECTING_WATCHDOG_TIMER = 10003;
+ ROAM_WATCHDOG_TIMER = 10004;
+ }
+
+ // How long the session lasted from successful connection to disconnect.
+ optional int32 connected_duration_seconds = 1;
+
+ // Reason for the disconnect.
+ optional FailureCode failure_code = 2;
+
+ // Band bucket the connected network was on.
+ optional android.net.wifi.WifiBandBucket band = 3;
+
+ // Authentication type.
+ optional android.net.wifi.WifiAuthType auth_type = 4;
+
+ // Last seen RSSI before the disconnect.
+ optional int32 last_rssi = 5;
+
+ // Last seen link speed before the disconnect.
+ optional int32 last_link_speed = 6;
+}
+
+/**
+ * Logs when Wifi connection is established or dropped.
+ *
+ * Logged from:
+ * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java
+ */
+message WifiConnectionStateChanged {
+ optional bool is_connected = 1;
+
+ // Band bucket the connected network was on.
+ // Filled for both connected and disconnected cases.
+ optional android.net.wifi.WifiBandBucket band = 2;
+
+ // Authentication type.
+ // Filled for both connected and disconnected cases.
+ optional android.net.wifi.WifiAuthType auth_type = 3;
}
/**
@@ -11239,4 +11387,4 @@
// List of leasees of this Blob
optional BlobLeaseeListProto leasees = 5 [(log_mode) = MODE_BYTES];
-}
+}
\ No newline at end of file
diff --git a/core/java/android/app/ActivityManager.aidl b/core/java/android/app/ActivityManager.aidl
index 29260e9..45a0e87 100644
--- a/core/java/android/app/ActivityManager.aidl
+++ b/core/java/android/app/ActivityManager.aidl
@@ -24,8 +24,6 @@
parcelable ActivityManager.RunningServiceInfo;
parcelable ActivityManager.RunningTaskInfo;
/** @hide */
-parcelable ActivityManager.StackInfo;
-/** @hide */
parcelable ActivityManager.TaskThumbnail;
/** @hide */
parcelable ActivityManager.TaskSnapshot;
\ No newline at end of file
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index a88c6a8..5aecb61 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -76,7 +76,6 @@
import android.util.Singleton;
import android.util.Size;
import android.view.Surface;
-import android.window.WindowContainerToken;
import com.android.internal.app.LocalePicker;
import com.android.internal.app.procstats.ProcessStats;
@@ -2815,160 +2814,6 @@
}
/**
- * Information you can retrieve about an ActivityStack in the system.
- * @hide
- */
- public static class StackInfo implements Parcelable {
- @UnsupportedAppUsage
- public int stackId;
- @UnsupportedAppUsage
- public Rect bounds = new Rect();
- @UnsupportedAppUsage
- public int[] taskIds;
- @UnsupportedAppUsage
- public String[] taskNames;
- @UnsupportedAppUsage
- public Rect[] taskBounds;
- @UnsupportedAppUsage
- public int[] taskUserIds;
- @UnsupportedAppUsage
- public ComponentName topActivity;
- @UnsupportedAppUsage
- public int displayId;
- @UnsupportedAppUsage
- public int userId;
- @UnsupportedAppUsage
- public boolean visible;
- // Index of the stack in the display's stack list, can be used for comparison of stack order
- // TODO: Can be removed since no one is using it.
- @UnsupportedAppUsage
- @Deprecated
- public int position;
- public WindowContainerToken stackToken;
- /**
- * The full configuration the stack is currently running in.
- * @hide
- */
- final public Configuration configuration = new Configuration();
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(stackId);
- dest.writeInt(bounds.left);
- dest.writeInt(bounds.top);
- dest.writeInt(bounds.right);
- dest.writeInt(bounds.bottom);
- dest.writeIntArray(taskIds);
- dest.writeStringArray(taskNames);
- final int boundsCount = taskBounds == null ? 0 : taskBounds.length;
- dest.writeInt(boundsCount);
- for (int i = 0; i < boundsCount; i++) {
- dest.writeInt(taskBounds[i].left);
- dest.writeInt(taskBounds[i].top);
- dest.writeInt(taskBounds[i].right);
- dest.writeInt(taskBounds[i].bottom);
- }
- dest.writeIntArray(taskUserIds);
- dest.writeInt(displayId);
- dest.writeInt(userId);
- dest.writeInt(visible ? 1 : 0);
- dest.writeInt(position);
- stackToken.writeToParcel(dest, 0);
- if (topActivity != null) {
- dest.writeInt(1);
- topActivity.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
- configuration.writeToParcel(dest, flags);
- }
-
- public void readFromParcel(Parcel source) {
- stackId = source.readInt();
- bounds = new Rect(
- source.readInt(), source.readInt(), source.readInt(), source.readInt());
- taskIds = source.createIntArray();
- taskNames = source.createStringArray();
- final int boundsCount = source.readInt();
- if (boundsCount > 0) {
- taskBounds = new Rect[boundsCount];
- for (int i = 0; i < boundsCount; i++) {
- taskBounds[i] = new Rect();
- taskBounds[i].set(
- source.readInt(), source.readInt(), source.readInt(), source.readInt());
- }
- } else {
- taskBounds = null;
- }
- taskUserIds = source.createIntArray();
- displayId = source.readInt();
- userId = source.readInt();
- visible = source.readInt() > 0;
- position = source.readInt();
- stackToken = WindowContainerToken.CREATOR.createFromParcel(source);
- if (source.readInt() > 0) {
- topActivity = ComponentName.readFromParcel(source);
- }
- configuration.readFromParcel(source);
- }
-
- public static final @android.annotation.NonNull Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
- @Override
- public StackInfo createFromParcel(Parcel source) {
- return new StackInfo(source);
- }
- @Override
- public StackInfo[] newArray(int size) {
- return new StackInfo[size];
- }
- };
-
- public StackInfo() {
- }
-
- private StackInfo(Parcel source) {
- readFromParcel(source);
- }
-
- @UnsupportedAppUsage
- public String toString(String prefix) {
- StringBuilder sb = new StringBuilder(256);
- sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
- sb.append(" bounds="); sb.append(bounds.toShortString());
- sb.append(" displayId="); sb.append(displayId);
- sb.append(" userId="); sb.append(userId);
- sb.append("\n");
- sb.append(" configuration="); sb.append(configuration);
- sb.append("\n");
- prefix = prefix + " ";
- for (int i = 0; i < taskIds.length; ++i) {
- sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
- sb.append(": "); sb.append(taskNames[i]);
- if (taskBounds != null) {
- sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
- }
- sb.append(" userId=").append(taskUserIds[i]);
- sb.append(" visible=").append(visible);
- if (topActivity != null) {
- sb.append(" topActivity=").append(topActivity);
- }
- sb.append("\n");
- }
- return sb.toString();
- }
-
- @Override
- public String toString() {
- return toString("");
- }
- }
-
- /**
* @hide
*/
@RequiresPermission(anyOf={Manifest.permission.CLEAR_APP_USER_DATA,
diff --git a/core/java/android/app/ActivityTaskManager.aidl b/core/java/android/app/ActivityTaskManager.aidl
new file mode 100644
index 0000000..a12bcd5
--- /dev/null
+++ b/core/java/android/app/ActivityTaskManager.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/** @hide */
+parcelable ActivityTaskManager.RootTaskInfo;
\ No newline at end of file
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index 4283d7a..3e4d5ee 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -29,6 +29,8 @@
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
@@ -391,27 +393,6 @@
}
/**
- * List all activity stacks information.
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public String listAllStacks() {
- final List<ActivityManager.StackInfo> stacks;
- try {
- stacks = getService().getAllStackInfos();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- final StringBuilder sb = new StringBuilder();
- if (stacks != null) {
- for (ActivityManager.StackInfo info : stacks) {
- sb.append(info).append("\n");
- }
- }
- return sb.toString();
- }
-
- /**
* Clears launch params for the given package.
* @param packageNames the names of the packages of which the launch params are to be cleared
*/
@@ -468,4 +449,96 @@
final Configuration config = context.getResources().getConfiguration();
return currentUiModeSupportsErrorDialogs(config);
}
+
+ /**
+ * Information you can retrieve about a root task in the system.
+ * @hide
+ */
+ public static class RootTaskInfo extends TaskInfo implements Parcelable {
+ // TODO(b/148895075): Move some of the fields to TaskInfo.
+ public Rect bounds = new Rect();
+ public int[] childTaskIds;
+ public String[] childTaskNames;
+ public Rect[] childTaskBounds;
+ public int[] childTaskUserIds;
+ public boolean visible;
+ // Index of the stack in the display's stack list, can be used for comparison of stack order
+ public int position;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeTypedObject(bounds, flags);
+ dest.writeIntArray(childTaskIds);
+ dest.writeStringArray(childTaskNames);
+ dest.writeTypedArray(childTaskBounds, flags);
+ dest.writeIntArray(childTaskUserIds);
+ dest.writeInt(visible ? 1 : 0);
+ dest.writeInt(position);
+ super.writeToParcel(dest, flags);
+ }
+
+ @Override
+ void readFromParcel(Parcel source) {
+ bounds = source.readTypedObject(Rect.CREATOR);
+ childTaskIds = source.createIntArray();
+ childTaskNames = source.createStringArray();
+ childTaskBounds = source.createTypedArray(Rect.CREATOR);
+ childTaskUserIds = source.createIntArray();
+ visible = source.readInt() > 0;
+ position = source.readInt();
+ super.readFromParcel(source);
+ }
+
+ public static final @NonNull Creator<RootTaskInfo> CREATOR = new Creator<>() {
+ @Override
+ public RootTaskInfo createFromParcel(Parcel source) {
+ return new RootTaskInfo(source);
+ }
+
+ @Override
+ public RootTaskInfo[] newArray(int size) {
+ return new RootTaskInfo[size];
+ }
+ };
+
+ public RootTaskInfo() {
+ }
+
+ private RootTaskInfo(Parcel source) {
+ readFromParcel(source);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(256);
+ sb.append("RootTask id="); sb.append(taskId);
+ sb.append(" bounds="); sb.append(bounds.toShortString());
+ sb.append(" displayId="); sb.append(displayId);
+ sb.append(" userId="); sb.append(userId);
+ sb.append("\n");
+
+ sb.append(" configuration="); sb.append(configuration);
+ sb.append("\n");
+
+ for (int i = 0; i < childTaskIds.length; ++i) {
+ sb.append(" taskId="); sb.append(childTaskIds[i]);
+ sb.append(": "); sb.append(childTaskNames[i]);
+ if (childTaskBounds != null) {
+ sb.append(" bounds="); sb.append(childTaskBounds[i].toShortString());
+ }
+ sb.append(" userId=").append(childTaskUserIds[i]);
+ sb.append(" visible=").append(visible);
+ if (topActivity != null) {
+ sb.append(" topActivity=").append(topActivity);
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+ }
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index caca05a..763ce6c6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5418,13 +5418,12 @@
final int prevState = r.getLifecycleState();
- if (prevState < ON_RESUME || prevState > ON_STOP) {
- Log.w(TAG, "Activity state must be in [ON_RESUME..ON_STOP] in order to be relaunched,"
+ if (prevState < ON_START || prevState > ON_STOP) {
+ Log.w(TAG, "Activity state must be in [ON_START..ON_STOP] in order to be relaunched,"
+ "current state is " + prevState);
return;
}
-
// Initialize a relaunch request.
final MergedConfiguration mergedConfiguration = new MergedConfiguration(
r.createdConfig != null ? r.createdConfig : mConfiguration,
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index cd9e02d..45b25a3 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -17,6 +17,7 @@
package android.app;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.ApplicationErrorReport;
import android.app.ApplicationExitInfo;
import android.app.ContentProviderHolder;
@@ -99,7 +100,6 @@
void unregisterUidObserver(in IUidObserver observer);
boolean isUidActive(int uid, String callingPackage);
int getUidProcessState(int uid, in String callingPackage);
- boolean setSchedPolicyCgroup(int tid, int group);
// =============== End of transactions used on native side as well ============================
// Special low-level communication with activity manager.
@@ -449,12 +449,11 @@
@UnsupportedAppUsage
void hang(in IBinder who, boolean allowRestart);
- @UnsupportedAppUsage
- List<ActivityManager.StackInfo> getAllStackInfos();
+ List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfos();
@UnsupportedAppUsage
void moveTaskToStack(int taskId, int stackId, boolean toTop);
void setFocusedStack(int stackId);
- ActivityManager.StackInfo getFocusedStackInfo();
+ ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo();
@UnsupportedAppUsage
void restart();
void performIdleMaintenance();
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 72a3637d..f3c7fe94 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -17,6 +17,7 @@
package android.app;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.ApplicationErrorReport;
import android.app.ContentProviderHolder;
import android.app.GrantedUriPermission;
@@ -186,7 +187,7 @@
in AssistStructure structure, in AssistContent content, in Uri referrer);
void setFocusedStack(int stackId);
- ActivityManager.StackInfo getFocusedStackInfo();
+ ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo();
Rect getTaskBounds(int taskId);
void cancelRecentsAnimation(boolean restoreHomeStackPosition);
@@ -260,11 +261,10 @@
/** Removes stack of the activity types from the system. */
void removeStacksWithActivityTypes(in int[] activityTypes);
- List<ActivityManager.StackInfo> getAllStackInfos();
- ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType);
- List<ActivityManager.StackInfo> getAllStackInfosOnDisplay(int displayId);
- ActivityManager.StackInfo getStackInfoOnDisplay(int windowingMode, int activityType,
- int displayId);
+ List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfos();
+ ActivityTaskManager.RootTaskInfo getRootTaskInfo(int windowingMode, int activityType);
+ List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId);
+ ActivityTaskManager.RootTaskInfo getRootTaskInfoOnDisplay(int windowingMode, int activityType, int displayId);
/**
* Informs ActivityTaskManagerService that the keyguard is showing.
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 2ef147b..f2a9daa 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -97,7 +97,8 @@
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({0, UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES})
+ @IntDef({0, UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES,
+ UiAutomation.FLAG_DONT_USE_ACCESSIBILITY})
public @interface UiAutomationFlags {};
@@ -2170,7 +2171,8 @@
* </p>
*
* @param flags The flags to be passed to the UiAutomation, for example
- * {@link UiAutomation#FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES}.
+ * {@link UiAutomation#FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES},
+ * {@link UiAutomation#FLAG_DONT_USE_ACCESSIBILITY}.
*
* @return The UI automation instance.
*
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6737972..1ff48f6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -207,7 +207,7 @@
* <p>
* Avoids spamming the system with overly large strings such as full e-mails.
*/
- private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;
+ private static final int MAX_CHARSEQUENCE_LENGTH = 1024;
/**
* Maximum entries of reply text that are accepted by Builder and friends.
@@ -7863,7 +7863,7 @@
*/
public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender,
boolean remoteInputHistory) {
- mText = text;
+ mText = safeCharSequence(text);
mTimestamp = timestamp;
mSender = sender;
mRemoteInputHistory = remoteInputHistory;
@@ -7977,7 +7977,7 @@
bundle.putLong(KEY_TIMESTAMP, mTimestamp);
if (mSender != null) {
// Legacy listeners need this
- bundle.putCharSequence(KEY_SENDER, mSender.getName());
+ bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName()));
bundle.putParcelable(KEY_SENDER_PERSON, mSender);
}
if (mDataMimeType != null) {
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index 67d94de..18c4d70 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.graphics.Rect;
@@ -46,6 +47,8 @@
@Nullable
private Rect mSourceRectHint;
+ private boolean mAutoEnterAllowed;
+
/**
* Sets the aspect ratio. This aspect ratio is defined as the desired width / height, and
* does not change upon device rotation.
@@ -103,6 +106,25 @@
}
/**
+ * Sets whether the system is allowed to automatically put the activity in
+ * picture-in-picture mode without needing/waiting for the activity to call
+ * {@link Activity#enterPictureInPictureMode(PictureInPictureParams)}.
+ *
+ * If true, {@link Activity#onPictureInPictureRequested()} will never be called.
+ *
+ * This property is false by default.
+ * @param autoEnterAllowed {@code true} if the system is allowed to automatically put the
+ * activity in picture-in-picture mode.
+ *
+ * @return this builder instance.
+ */
+ @NonNull
+ public Builder setAutoEnterAllowed(boolean autoEnterAllowed) {
+ mAutoEnterAllowed = autoEnterAllowed;
+ return this;
+ }
+
+ /**
* @return an immutable {@link PictureInPictureParams} to be used when entering or updating
* the activity in picture-in-picture.
*
@@ -111,7 +133,7 @@
*/
public PictureInPictureParams build() {
PictureInPictureParams params = new PictureInPictureParams(mAspectRatio, mUserActions,
- mSourceRectHint);
+ mSourceRectHint, mAutoEnterAllowed);
return params;
}
}
@@ -136,6 +158,11 @@
@Nullable
private Rect mSourceRectHint;
+ /**
+ * Whether the system is allowed to automatically put the activity in picture-in-picture mode.
+ */
+ private boolean mAutoEnterAllowed;
+
/** {@hide} */
PictureInPictureParams() {
}
@@ -152,14 +179,18 @@
if (in.readInt() != 0) {
mSourceRectHint = Rect.CREATOR.createFromParcel(in);
}
+ if (in.readInt() != 0) {
+ mAutoEnterAllowed = in.readBoolean();
+ }
}
/** {@hide} */
PictureInPictureParams(Rational aspectRatio, List<RemoteAction> actions,
- Rect sourceRectHint) {
+ Rect sourceRectHint, boolean autoEnterAllowed) {
mAspectRatio = aspectRatio;
mUserActions = actions;
mSourceRectHint = sourceRectHint;
+ mAutoEnterAllowed = autoEnterAllowed;
}
/**
@@ -176,6 +207,7 @@
if (otherArgs.hasSourceBoundsHint()) {
mSourceRectHint = new Rect(otherArgs.getSourceRectHint());
}
+ mAutoEnterAllowed = otherArgs.mAutoEnterAllowed;
}
/**
@@ -248,11 +280,20 @@
}
/**
+ * @return whether auto pip allowed.
+ * @hide
+ */
+ public boolean isAutoEnterAllowed() {
+ return mAutoEnterAllowed;
+ }
+
+ /**
* @return True if no parameters are set
* @hide
*/
public boolean empty() {
- return !hasSourceBoundsHint() && !hasSetActions() && !hasSetAspectRatio();
+ return !hasSourceBoundsHint() && !hasSetActions() && !hasSetAspectRatio()
+ && !mAutoEnterAllowed;
}
@Override
@@ -281,6 +322,8 @@
} else {
out.writeInt(0);
}
+ out.writeInt(1);
+ out.writeBoolean(mAutoEnterAllowed);
}
public static final @android.annotation.NonNull Creator<PictureInPictureParams> CREATOR =
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index f3f00e5..4718cf1 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -36,7 +36,8 @@
private static final String TAG = "TaskInfo";
/**
- * The id of the user the task was running as.
+ * The id of the user the task was running as if this is a leaf task. The id of the current
+ * running user of the system otherwise.
* @hide
*/
@UnsupportedAppUsage
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 109205f..ab997e9 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -56,6 +56,7 @@
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.pooled.PooledLambda;
import libcore.io.IoUtils;
@@ -142,13 +143,22 @@
}
/**
- * UiAutomation supresses accessibility services by default. This flag specifies that
+ * UiAutomation suppresses accessibility services by default. This flag specifies that
* existing accessibility services should continue to run, and that new ones may start.
* This flag is set when obtaining the UiAutomation from
* {@link Instrumentation#getUiAutomation(int)}.
*/
public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 0x00000001;
+ /**
+ * UiAutomation uses the accessibility subsystem by default. This flag provides an option to
+ * eliminate the overhead of engaging the accessibility subsystem for tests that do not need to
+ * interact with the user interface. Setting this flag disables methods that rely on
+ * accessibility. This flag is set when obtaining the UiAutomation from
+ * {@link Instrumentation#getUiAutomation(int)}.
+ */
+ public static final int FLAG_DONT_USE_ACCESSIBILITY = 0x00000002;
+
private final Object mLock = new Object();
private final ArrayList<AccessibilityEvent> mEventQueue = new ArrayList<AccessibilityEvent>();
@@ -267,11 +277,14 @@
/**
* Connects this UiAutomation to the accessibility introspection APIs.
*
- * @param flags Any flags to apply to the automation as it gets connected
+ * @param flags Any flags to apply to the automation as it gets connected while
+ * {@link UiAutomation#FLAG_DONT_USE_ACCESSIBILITY} would keep the
+ * connection disconnected and not to register UiAutomation service.
* @param timeoutMillis The wait timeout in milliseconds
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is already
+ * established.
* @throws TimeoutException If not connected within the timeout
- *
* @hide
*/
public void connectWithTimeout(int flags, long timeoutMillis) throws TimeoutException {
@@ -292,6 +305,12 @@
// Calling out without a lock held.
mUiAutomationConnection.connect(mClient, flags);
mFlags = flags;
+ // If UiAutomation is not allowed to use the accessibility subsystem, the
+ // connection state should keep disconnected and not to start the client connection.
+ if (!useAccessibility()) {
+ mConnectionState = ConnectionState.DISCONNECTED;
+ return;
+ }
} catch (RemoteException re) {
throw new RuntimeException("Error while connecting " + this, re);
}
@@ -340,7 +359,7 @@
throw new IllegalStateException(
"Cannot call disconnect() while connecting " + this);
}
- if (mConnectionState == ConnectionState.DISCONNECTED) {
+ if (useAccessibility() && mConnectionState == ConnectionState.DISCONNECTED) {
return;
}
mConnectionState = ConnectionState.DISCONNECTED;
@@ -354,8 +373,10 @@
} catch (RemoteException re) {
throw new RuntimeException("Error while disconnecting " + this, re);
} finally {
- mRemoteCallbackThread.quit();
- mRemoteCallbackThread = null;
+ if (mRemoteCallbackThread != null) {
+ mRemoteCallbackThread.quit();
+ mRemoteCallbackThread = null;
+ }
}
}
@@ -389,9 +410,13 @@
* The callbacks are delivered on the main application thread.
*
* @param listener The callback.
+ *
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
*/
public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
synchronized (mLock) {
+ throwIfNotConnectedLocked();
mOnAccessibilityEventListener = listener;
}
}
@@ -423,9 +448,6 @@
* @see #dropShellPermissionIdentity()
*/
public void adoptShellPermissionIdentity() {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
// Calling out without a lock held.
mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid(), null);
@@ -451,9 +473,6 @@
* @see #dropShellPermissionIdentity()
*/
public void adoptShellPermissionIdentity(@Nullable String... permissions) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
// Calling out without a lock held.
mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid(), permissions);
@@ -470,9 +489,6 @@
* @see #adoptShellPermissionIdentity()
*/
public void dropShellPermissionIdentity() {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
// Calling out without a lock held.
mUiAutomationConnection.dropShellPermissionIdentity();
@@ -489,6 +505,8 @@
* @param action The action to perform.
* @return Whether the action was successfully performed.
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
* @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK
* @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_HOME
* @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
@@ -523,13 +541,18 @@
* </p>
*
* @param focus The focus to find. One of {@link AccessibilityNodeInfo#FOCUS_INPUT} or
- * {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
+ * {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
* @return The node info of the focused view or null.
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
* @see AccessibilityNodeInfo#FOCUS_INPUT
* @see AccessibilityNodeInfo#FOCUS_ACCESSIBILITY
*/
public AccessibilityNodeInfo findFocus(int focus) {
+ synchronized (mLock) {
+ throwIfNotConnectedLocked();
+ }
return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
AccessibilityWindowInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
}
@@ -541,6 +564,8 @@
*
* @return The accessibility service info.
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
* @see AccessibilityServiceInfo
*/
public final AccessibilityServiceInfo getServiceInfo() {
@@ -567,6 +592,8 @@
*
* @param info The info.
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
* @see AccessibilityServiceInfo
*/
public final void setServiceInfo(AccessibilityServiceInfo info) {
@@ -602,6 +629,8 @@
* </p>
*
* @return The windows if there are windows such, otherwise an empty list.
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
*/
public List<AccessibilityWindowInfo> getWindows() {
final int connectionId;
@@ -630,6 +659,8 @@
*
* @return The windows of all displays if there are windows and the service is can retrieve
* them, otherwise an empty list. The key of SparseArray is display ID.
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
*/
@NonNull
public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
@@ -647,6 +678,8 @@
* Gets the root {@link AccessibilityNodeInfo} in the active window.
*
* @return The root info.
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
*/
public AccessibilityNodeInfo getRootInActiveWindow() {
final int connectionId;
@@ -664,14 +697,12 @@
* <p>
* <strong>Note:</strong> It is caller's responsibility to recycle the event.
* </p>
+ *
* @param event The event to inject.
* @param sync Whether to inject the event synchronously.
* @return Whether event injection succeeded.
*/
public boolean injectInputEvent(InputEvent event, boolean sync) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
if (DEBUG) {
Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync);
@@ -692,9 +723,6 @@
*/
@TestApi
public void syncInputTransactions() {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
// Calling out without a lock held.
mUiAutomationConnection.syncInputTransactions();
@@ -720,9 +748,6 @@
* @see #ROTATION_UNFREEZE
*/
public boolean setRotation(int rotation) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
switch (rotation) {
case ROTATION_FREEZE_0:
case ROTATION_FREEZE_90:
@@ -752,11 +777,14 @@
* <p>
* <strong>Note:</strong> It is caller's responsibility to recycle the returned event.
* </p>
+ *
* @param command The command to execute.
* @param filter Filter that recognizes the expected event.
* @param timeoutMillis The wait timeout in milliseconds.
*
* @throws TimeoutException If the expected event is not received within the timeout.
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
*/
public AccessibilityEvent executeAndWaitForEvent(Runnable command,
AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
@@ -845,6 +873,8 @@
*
* @throws TimeoutException If no idle state was detected within
* <code>globalTimeoutMillis.</code>
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
*/
public void waitForIdle(long idleTimeoutMillis, long globalTimeoutMillis)
throws TimeoutException {
@@ -874,9 +904,9 @@
return;
}
try {
- mLock.wait(remainingIdleTimeMillis);
+ mLock.wait(remainingIdleTimeMillis);
} catch (InterruptedException ie) {
- /* ignore */
+ /* ignore */
}
}
}
@@ -888,9 +918,6 @@
* @return The screenshot bitmap on success, null otherwise.
*/
public Bitmap takeScreenshot() {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
Display display = DisplayManagerGlobal.getInstance()
.getRealDisplay(Display.DEFAULT_DISPLAY);
Point displaySize = new Point();
@@ -927,9 +954,6 @@
* @see ActivityManager#isUserAMonkey()
*/
public void setRunAsMonkey(boolean enable) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
ActivityManager.getService().setUserIsMonkey(enable);
} catch (RemoteException re) {
@@ -946,6 +970,8 @@
* @return Whether the window is present and its frame statistics
* were cleared.
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
* @see android.view.WindowContentFrameStats
* @see #getWindowContentFrameStats(int)
* @see #getWindows()
@@ -991,6 +1017,8 @@
* @param windowId The window id.
* @return The window frame statistics, or null if the window is not present.
*
+ * @throws IllegalStateException If the connection to the accessibility subsystem is not
+ * established.
* @see android.view.WindowContentFrameStats
* @see #clearWindowContentFrameStats(int)
* @see #getWindows()
@@ -1022,9 +1050,6 @@
* @see android.R.styleable#WindowAnimation
*/
public void clearWindowAnimationFrameStats() {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
if (DEBUG) {
Log.i(LOG_TAG, "Clearing window animation frame stats");
@@ -1064,9 +1089,6 @@
* @see android.R.styleable#WindowAnimation
*/
public WindowAnimationFrameStats getWindowAnimationFrameStats() {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
if (DEBUG) {
Log.i(LOG_TAG, "Getting window animation frame stats");
@@ -1081,6 +1103,7 @@
/**
* Grants a runtime permission to a package.
+ *
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to grant the permission.
@@ -1104,15 +1127,13 @@
/**
* Grants a runtime permission to a package for a user.
+ *
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to grant the permission.
*/
public void grantRuntimePermissionAsUser(String packageName, String permission,
UserHandle userHandle) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
if (DEBUG) {
Log.i(LOG_TAG, "Granting runtime permission");
@@ -1127,6 +1148,7 @@
/**
* Revokes a runtime permission from a package.
+ *
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to revoke the permission.
@@ -1150,15 +1172,13 @@
/**
* Revokes a runtime permission from a package.
+ *
* @param packageName The package to which to grant.
* @param permission The permission to grant.
* @throws SecurityException if unable to revoke the permission.
*/
public void revokeRuntimePermissionAsUser(String packageName, String permission,
UserHandle userHandle) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
try {
if (DEBUG) {
Log.i(LOG_TAG, "Revoking runtime permission");
@@ -1186,9 +1206,6 @@
* @see #adoptShellPermissionIdentity()
*/
public ParcelFileDescriptor executeShellCommand(String command) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
warnIfBetterCommand(command);
ParcelFileDescriptor source = null;
@@ -1229,9 +1246,6 @@
*/
@TestApi
public ParcelFileDescriptor[] executeShellCommandRw(String command) {
- synchronized (mLock) {
- throwIfNotConnectedLocked();
- }
warnIfBetterCommand(command);
ParcelFileDescriptor source_read = null;
@@ -1276,15 +1290,21 @@
return stringBuilder.toString();
}
+ @GuardedBy("mLock")
private void throwIfConnectedLocked() {
if (mConnectionState == ConnectionState.CONNECTED) {
throw new IllegalStateException("UiAutomation connected, " + this);
}
}
+ @GuardedBy("mLock")
private void throwIfNotConnectedLocked() {
if (mConnectionState != ConnectionState.CONNECTED) {
- throw new IllegalStateException("UiAutomation not connected, " + this);
+ final String msg = useAccessibility()
+ ? "UiAutomation not connected, "
+ : "UiAutomation not connected: Accessibility-dependent method called with "
+ + "FLAG_DONT_USE_ACCESSIBILITY set, ";
+ throw new IllegalStateException(msg + this);
}
}
@@ -1298,11 +1318,16 @@
}
}
+ private boolean useAccessibility() {
+ return (mFlags & UiAutomation.FLAG_DONT_USE_ACCESSIBILITY) == 0;
+ }
+
private class IAccessibilityServiceClientImpl extends IAccessibilityServiceClientWrapper {
public IAccessibilityServiceClientImpl(Looper looper, int generationId) {
super(null, looper, new Callbacks() {
private final int mGenerationId = generationId;
+
/**
* True if UiAutomation doesn't interact with this client anymore.
* Used by methods below to stop sending notifications or changing members
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 22d8c87..b5234f8 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -36,8 +36,6 @@
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
-import com.android.internal.util.Preconditions;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -1676,8 +1674,9 @@
}
/**
- * Returns the maximum length of the text associated with this node node, or {@code -1}
- * if not supported by the node or not set.
+ * Returns the maximum length of the text associated with this node, or {@code -1} if not
+ * supported by the node or not set. System may set a default value if the text length is
+ * not set.
*
* <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
* not for assist purposes.
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
index a34be5c..56bf59b 100644
--- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -185,6 +185,9 @@
final ActivityLifecycleItem lifecycleItem;
switch (prevState) {
// TODO(lifecycler): Extend to support all possible states.
+ case ON_START:
+ lifecycleItem = StartActivityItem.obtain();
+ break;
case ON_PAUSE:
lifecycleItem = PauseActivityItem.obtain();
break;
diff --git a/core/java/android/app/timezonedetector/TimeZoneConfiguration.java b/core/java/android/app/timezonedetector/TimeZoneConfiguration.java
index 95db0a2..e879091 100644
--- a/core/java/android/app/timezonedetector/TimeZoneConfiguration.java
+++ b/core/java/android/app/timezonedetector/TimeZoneConfiguration.java
@@ -162,9 +162,9 @@
@Override
public String toString() {
- return "TimeZoneDetectorConfiguration{"
+ return "TimeZoneConfiguration{"
+ "mUserId=" + mUserId
- + "mBundle=" + mBundle
+ + ", mBundle=" + mBundle
+ '}';
}
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 0e6a063..3522b1b 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -199,7 +199,7 @@
public static final int NOTIFICATION_INTERRUPTION = 12;
/**
- * A Slice was pinned by the default assistant.
+ * A Slice was pinned by the default launcher or the default assistant.
* @hide
*/
@SystemApi
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index b434072..eec7c9c 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -343,20 +343,22 @@
* @param permission The permission to check.
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
- * @param attributionTag attribution tag of caller (if not self)
+ * @param callingPackageName package name tag of caller (if not self)
+ * @param callingAttributionTag attribution tag of caller (if not self)
* @param message A message describing the reason the permission was checked
*
* @see #checkCallingOrSelfPermissionForPreflight(Context, String)
*/
@PermissionResult
public static int checkCallingOrSelfPermissionForDataDelivery(@NonNull Context context,
- @NonNull String permission, @Nullable String attributionTag, @Nullable String message) {
- String packageName = (Binder.getCallingPid() == Process.myPid())
- ? context.getPackageName() : null;
- attributionTag = (Binder.getCallingPid() == Process.myPid())
- ? context.getAttributionTag() : attributionTag;
+ @NonNull String permission, @Nullable String callingPackageName,
+ @Nullable String callingAttributionTag, @Nullable String message) {
+ callingPackageName = (Binder.getCallingPid() == Process.myPid())
+ ? context.getPackageName() : callingPackageName;
+ callingAttributionTag = (Binder.getCallingPid() == Process.myPid())
+ ? context.getAttributionTag() : callingAttributionTag;
return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
- Binder.getCallingUid(), packageName, attributionTag, message);
+ Binder.getCallingUid(), callingPackageName, callingAttributionTag, message);
}
/**
@@ -375,15 +377,15 @@
* app's fg/gb state) and this check will not leave a trace that permission protected
* data was delivered. When you are about to deliver the location data to a registered
* listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context,
- * String, String, String)} which will evaluate the permission access based on the current
- * fg/bg state of the app and leave a record that the data was accessed.
+ * String, String, String, String)} which will evaluate the permission access based on the
+ * current fg/bg state of the app and leave a record that the data was accessed.
*
* @param context Context for accessing resources.
* @param permission The permission to check.
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
*
- * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String, String)
+ * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String, String, String)
*/
@PermissionResult
public static int checkCallingOrSelfPermissionForPreflight(@NonNull Context context,
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0f1f276..e108451 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -30,7 +30,6 @@
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
-import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
@@ -159,8 +158,6 @@
SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
public static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
- public static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
- public static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
private static final int DEFAULT_MIN_SDK_VERSION = 1;
private static final int DEFAULT_TARGET_SDK_VERSION = 0;
@@ -4683,20 +4680,8 @@
* ratio set.
*/
private void setMinAspectRatio(Package owner) {
- final float minAspectRatio;
- if (owner.applicationInfo.minAspectRatio != 0) {
- // Use the application max aspect ration as default if set.
- minAspectRatio = owner.applicationInfo.minAspectRatio;
- } else {
- // Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater.
- // NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD,
- // except for watches which always supported 1:1.
- minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q
- ? 0
- : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH))
- ? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
- : DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
- }
+ // Use the application max aspect ration as default if set.
+ final float minAspectRatio = owner.applicationInfo.minAspectRatio;
for (Activity activity : owner.activities) {
if (activity.hasMinAspectRatio()) {
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 4914601..6d92d3e 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -53,7 +53,7 @@
/** @hide */
public class ApkLiteParseUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
// TODO(b/135203078): Consolidate constants
private static final int DEFAULT_MIN_SDK_VERSION = 1;
@@ -67,7 +67,7 @@
* Automatically detects if the package is a monolithic style (single APK
* file) or cluster style (directory of APKs).
* <p>
- * This performs sanity checking on cluster style packages, such as
+ * This performs validity checking on cluster style packages, such as
* requiring identical package name and version codes, a single base APK,
* and unique split names.
*
diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
index e450748..e573539 100644
--- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
@@ -579,8 +579,8 @@
ii.handleProfiling = i.isHandleProfiling();
ii.functionalTest = i.isFunctionalTest();
- ii.sourceDir = pkg.getBaseCodePath();
- ii.publicSourceDir = pkg.getBaseCodePath();
+ ii.sourceDir = pkg.getBaseApkPath();
+ ii.publicSourceDir = pkg.getBaseApkPath();
ii.splitNames = pkg.getSplitNames();
ii.splitSourceDirs = pkg.getSplitCodePaths();
ii.splitPublicSourceDirs = pkg.getSplitCodePaths();
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index 0c0dc31..ed12a17 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -145,7 +145,7 @@
private String realPackage;
@NonNull
- protected String baseCodePath;
+ protected String mBaseApkPath;
private boolean requiredForAllUsers;
@Nullable
@@ -280,7 +280,7 @@
@NonNull
@DataClass.ParcelWith(ForInternedString.class)
- protected String codePath;
+ protected String mPath;
private boolean use32BitAbi;
private boolean visibleToInstantApps;
@@ -429,11 +429,11 @@
private ArraySet<String> mimeGroups;
@VisibleForTesting
- public ParsingPackageImpl(@NonNull String packageName, @NonNull String baseCodePath,
- @NonNull String codePath, @Nullable TypedArray manifestArray) {
+ public ParsingPackageImpl(@NonNull String packageName, @NonNull String baseApkPath,
+ @NonNull String path, @Nullable TypedArray manifestArray) {
this.packageName = TextUtils.safeIntern(packageName);
- this.baseCodePath = baseCodePath;
- this.codePath = codePath;
+ this.mBaseApkPath = baseApkPath;
+ this.mPath = path;
if (manifestArray != null) {
versionCode = manifestArray.getInteger(R.styleable.AndroidManifest_versionCode, 0);
@@ -888,6 +888,9 @@
public ApplicationInfo toAppInfoWithoutStateWithoutFlags() {
ApplicationInfo appInfo = new ApplicationInfo();
+ // Lines that are commented below are state related and should not be assigned here.
+ // They are left in as placeholders, since there is no good backwards compatible way to
+ // separate these.
appInfo.appComponentFactory = appComponentFactory;
appInfo.backupAgentName = backupAgentName;
appInfo.banner = banner;
@@ -897,13 +900,17 @@
appInfo.compatibleWidthLimitDp = compatibleWidthLimitDp;
appInfo.compileSdkVersion = compileSdkVersion;
appInfo.compileSdkVersionCodename = compileSdkVersionCodeName;
-// appInfo.credentialProtectedDataDir = credentialProtectedDataDir;
-// appInfo.dataDir = dataDir;
+// appInfo.credentialProtectedDataDir
+ appInfo.crossProfile = isCrossProfile();
+// appInfo.dataDir
appInfo.descriptionRes = descriptionRes;
-// appInfo.deviceProtectedDataDir = deviceProtectedDataDir;
+// appInfo.deviceProtectedDataDir
appInfo.enabled = enabled;
+// appInfo.enabledSetting
appInfo.fullBackupContent = fullBackupContent;
-// appInfo.hiddenUntilInstalled = hiddenUntilInstalled;
+ // TODO(b/135203078): See ParsingPackageImpl#getHiddenApiEnforcementPolicy
+// appInfo.mHiddenApiPolicy
+// appInfo.hiddenUntilInstalled
appInfo.icon = (PackageParser.sUseRoundIcon && roundIconRes != 0) ? roundIconRes : iconRes;
appInfo.iconRes = iconRes;
appInfo.roundIconRes = roundIconRes;
@@ -920,9 +927,9 @@
if (appInfo.name != null) {
appInfo.name = appInfo.name.trim();
}
-// appInfo.nativeLibraryDir = nativeLibraryDir;
-// appInfo.nativeLibraryRootDir = nativeLibraryRootDir;
-// appInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+// appInfo.nativeLibraryDir
+// appInfo.nativeLibraryRootDir
+// appInfo.nativeLibraryRootRequiresIsa
appInfo.networkSecurityConfigRes = networkSecurityConfigRes;
appInfo.nonLocalizedLabel = nonLocalizedLabel;
if (appInfo.nonLocalizedLabel != null) {
@@ -930,16 +937,17 @@
}
appInfo.packageName = packageName;
appInfo.permission = permission;
-// appInfo.primaryCpuAbi = primaryCpuAbi;
+// appInfo.primaryCpuAbi
appInfo.processName = getProcessName();
appInfo.requiresSmallestWidthDp = requiresSmallestWidthDp;
-// appInfo.secondaryCpuAbi = secondaryCpuAbi;
-// appInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
-// appInfo.seInfo = seInfo;
-// appInfo.seInfoUser = seInfoUser;
-// appInfo.sharedLibraryFiles = usesLibraryFiles.isEmpty()
-// ? null : usesLibraryFiles.toArray(new String[0]);
-// appInfo.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos;
+// appInfo.resourceDirs
+// appInfo.secondaryCpuAbi
+// appInfo.secondaryNativeLibraryDir
+// appInfo.seInfo
+// appInfo.seInfoUser
+// appInfo.sharedLibraryFiles
+// appInfo.sharedLibraryInfos
+// appInfo.showUserIcon
appInfo.splitClassLoaderNames = splitClassLoaderNames;
appInfo.splitDependencies = splitDependencies;
appInfo.splitNames = splitNames;
@@ -948,29 +956,19 @@
appInfo.targetSdkVersion = targetSdkVersion;
appInfo.taskAffinity = taskAffinity;
appInfo.theme = theme;
-// appInfo.uid = uid;
+// appInfo.uid
appInfo.uiOptions = uiOptions;
appInfo.volumeUuid = volumeUuid;
appInfo.zygotePreloadName = zygotePreloadName;
- appInfo.crossProfile = isCrossProfile();
appInfo.setGwpAsanMode(gwpAsanMode);
- appInfo.setBaseCodePath(baseCodePath);
- appInfo.setBaseResourcePath(baseCodePath);
- appInfo.setCodePath(codePath);
- appInfo.setResourcePath(codePath);
+ appInfo.setBaseCodePath(mBaseApkPath);
+ appInfo.setBaseResourcePath(mBaseApkPath);
+ appInfo.setCodePath(mPath);
+ appInfo.setResourcePath(mPath);
appInfo.setSplitCodePaths(splitCodePaths);
appInfo.setSplitResourcePaths(splitCodePaths);
appInfo.setVersionCode(PackageInfo.composeLongVersionCode(versionCodeMajor, versionCode));
- // TODO(b/135203078): Can this be removed? Looks only used in ActivityInfo.
-// appInfo.showUserIcon = pkg.getShowUserIcon();
- // TODO(b/135203078): Unused?
-// appInfo.resourceDirs = pkg.getResourceDirs();
- // TODO(b/135203078): Unused?
-// appInfo.enabledSetting = pkg.getEnabledSetting();
- // TODO(b/135203078): See ParsingPackageImpl#getHiddenApiEnforcementPolicy
-// appInfo.mHiddenApiPolicy = pkg.getHiddenApiPolicy();
-
return appInfo;
}
@@ -995,7 +993,7 @@
dest.writeString(this.compileSdkVersionCodeName);
sForInternedString.parcel(this.packageName, dest, flags);
dest.writeString(this.realPackage);
- dest.writeString(this.baseCodePath);
+ dest.writeString(this.mBaseApkPath);
dest.writeBoolean(this.requiredForAllUsers);
dest.writeString(this.restrictedAccountType);
dest.writeString(this.requiredAccountType);
@@ -1050,7 +1048,7 @@
dest.writeBundle(this.metaData);
sForInternedString.parcel(this.volumeUuid, dest, flags);
dest.writeParcelable(this.signingDetails, flags);
- dest.writeString(this.codePath);
+ dest.writeString(this.mPath);
dest.writeBoolean(this.use32BitAbi);
dest.writeBoolean(this.visibleToInstantApps);
dest.writeBoolean(this.forceQueryable);
@@ -1159,7 +1157,7 @@
this.compileSdkVersionCodeName = in.readString();
this.packageName = sForInternedString.unparcel(in);
this.realPackage = in.readString();
- this.baseCodePath = in.readString();
+ this.mBaseApkPath = in.readString();
this.requiredForAllUsers = in.readBoolean();
this.restrictedAccountType = in.readString();
this.requiredAccountType = in.readString();
@@ -1214,7 +1212,7 @@
this.metaData = in.readBundle(boot);
this.volumeUuid = sForInternedString.unparcel(in);
this.signingDetails = in.readParcelable(boot);
- this.codePath = in.readString();
+ this.mPath = in.readString();
this.use32BitAbi = in.readBoolean();
this.visibleToInstantApps = in.readBoolean();
this.forceQueryable = in.readBoolean();
@@ -1363,8 +1361,8 @@
@NonNull
@Override
- public String getBaseCodePath() {
- return baseCodePath;
+ public String getBaseApkPath() {
+ return mBaseApkPath;
}
@Override
@@ -1649,8 +1647,8 @@
@NonNull
@Override
- public String getCodePath() {
- return codePath;
+ public String getPath() {
+ return mPath;
}
@Override
diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java
index 7e0fe7d..dbd15f5 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageRead.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java
@@ -548,7 +548,7 @@
String getPackageName();
/** Path of base APK */
- String getBaseCodePath();
+ String getBaseApkPath();
/**
* Path where this package was found on disk. For monolithic packages
@@ -556,7 +556,7 @@
* path to the cluster directory.
*/
@NonNull
- String getCodePath();
+ String getPath();
/**
* @see ApplicationInfo#compatibleWidthLimitDp
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index e1f08f3..bce75cd 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -18,7 +18,6 @@
import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED;
@@ -128,7 +127,7 @@
*/
public class ParsingPackageUtils {
- public static final String TAG = ParsingUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
/**
* @see #parseDefault(ParseInput, File, int, boolean)
@@ -163,10 +162,10 @@
@Override
public ParsingPackage startParsingPackage(
@NonNull String packageName,
- @NonNull String baseCodePath,
- @NonNull String codePath,
+ @NonNull String baseApkPath,
+ @NonNull String path,
@NonNull TypedArray manifestArray, boolean isCoreApp) {
- return new ParsingPackageImpl(packageName, baseCodePath, codePath, manifestArray);
+ return new ParsingPackageImpl(packageName, baseApkPath, path, manifestArray);
}
});
try {
@@ -211,7 +210,7 @@
* package is a monolithic style (single APK file) or cluster style
* (directory of APKs).
* <p>
- * This performs sanity checking on cluster style packages, such as
+ * This performs validity checking on cluster style packages, such as
* requiring identical package name and version codes, a single base APK,
* and unique split names.
* <p>
@@ -237,7 +236,7 @@
/**
* Parse all APKs contained in the given directory, treating them as a
- * single package. This also performs sanity checking, such as requiring
+ * single package. This also performs validity checking, such as requiring
* identical package name and version codes, a single base APK, and unique
* split names.
* <p>
@@ -740,7 +739,6 @@
String tagName = parser.getName();
final ParseResult result;
- // TODO(b/135203078): Convert to instance methods to share variables
// <application> has special logic, so it's handled outside the general method
if (PackageParser.TAG_APPLICATION.equals(tagName)) {
if (foundApp) {
@@ -1215,9 +1213,9 @@
features = ArrayUtils.add(features, featureInfo);
} else {
Slog.w(TAG,
- "Unknown element under <feature-group>: " + innerTagName +
- " at " + pkg.getBaseCodePath() + " " +
- parser.getPositionDescription());
+ "Unknown element under <feature-group>: " + innerTagName
+ + " at " + pkg.getBaseApkPath() + " "
+ + parser.getPositionDescription());
}
}
@@ -1720,10 +1718,6 @@
pkg.setPersistent(requiredFeature == null || mCallback.hasFeature(requiredFeature));
}
- // TODO(b/135203078): Should parsing code be responsible for this? Maybe move to a
- // util or just have PackageImpl return true if either flag is set
- pkg.setProfileableByShell(pkg.isProfileableByShell());
-
if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) {
pkg.setResizeableActivity(sa.getBoolean(
R.styleable.AndroidManifestApplication_resizeableActivity, true));
@@ -2375,21 +2369,8 @@
* ratio set.
*/
private void setMinAspectRatio(ParsingPackage pkg) {
- final float minAspectRatio;
- float packageMinAspectRatio = pkg.getMinAspectRatio();
- if (packageMinAspectRatio != 0) {
- // Use the application max aspect ration as default if set.
- minAspectRatio = packageMinAspectRatio;
- } else {
- // Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater.
- // NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD,
- // except for watches which always supported 1:1.
- minAspectRatio = pkg.getTargetSdkVersion() >= Build.VERSION_CODES.Q
- ? 0
- : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH))
- ? PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
- : PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
- }
+ // Use the application max aspect ration as default if set.
+ final float minAspectRatio = pkg.getMinAspectRatio();
List<ParsedActivity> activities = pkg.getActivities();
int activitiesSize = activities.size();
@@ -2438,7 +2419,7 @@
R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyValue);
if (!PackageParser.checkRequiredSystemProperties(propName, propValue)) {
String message = "Skipping target and overlay pair " + target + " and "
- + pkg.getBaseCodePath()
+ + pkg.getBaseApkPath()
+ ": overlay ignored due to required system property: "
+ propName + " with value: " + propValue;
Slog.i(TAG, message);
@@ -2693,7 +2674,7 @@
"<meta-data> only supports string, integer, float, color, "
+ "boolean, and resource reference types: "
+ parser.getName() + " at "
- + pkg.getBaseCodePath() + " "
+ + pkg.getBaseApkPath() + " "
+ parser.getPositionDescription());
} else {
return input.error("<meta-data> only supports string, integer, float, "
@@ -2730,7 +2711,7 @@
try {
ParseResult<SigningDetails> result = getSigningDetails(
input,
- pkg.getBaseCodePath(),
+ pkg.getBaseApkPath(),
skipVerify,
pkg.isStaticSharedLibrary(),
signingDetails,
@@ -2876,7 +2857,7 @@
boolean hasFeature(String feature);
ParsingPackage startParsingPackage(@NonNull String packageName,
- @NonNull String baseCodePath, @NonNull String codePath,
+ @NonNull String baseApkPath, @NonNull String path,
@NonNull TypedArray manifestArray, boolean isCoreApp);
}
}
diff --git a/core/java/android/content/pm/parsing/ParsingUtils.java b/core/java/android/content/pm/parsing/ParsingUtils.java
index ba61de1..5da5fbf 100644
--- a/core/java/android/content/pm/parsing/ParsingUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingUtils.java
@@ -33,7 +33,6 @@
/** @hide **/
public class ParsingUtils {
- // TODO(b/135203078): Consolidate log tags
public static final String TAG = "PackageParsing";
@Nullable
@@ -62,7 +61,7 @@
return input.error("Bad element under " + parentTag + ": " + parser.getName());
}
Slog.w(TAG, "Unknown element under " + parentTag + ": "
- + parser.getName() + " at " + pkg.getBaseCodePath() + " "
+ + parser.getName() + " at " + pkg.getBaseApkPath() + " "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
return input.success(null); // Type doesn't matter
diff --git a/core/java/android/content/pm/parsing/component/ComponentParseUtils.java b/core/java/android/content/pm/parsing/component/ComponentParseUtils.java
index c4caedc..cfefc016 100644
--- a/core/java/android/content/pm/parsing/component/ComponentParseUtils.java
+++ b/core/java/android/content/pm/parsing/component/ComponentParseUtils.java
@@ -24,15 +24,13 @@
import android.content.pm.PackageUserState;
import android.content.pm.parsing.ParsingPackage;
import android.content.pm.parsing.ParsingUtils;
+import android.content.pm.parsing.result.ParseInput;
+import android.content.pm.parsing.result.ParseResult;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.text.TextUtils;
-import android.content.pm.parsing.ParsingPackageUtils;
-import android.content.pm.parsing.result.ParseInput;
-import android.content.pm.parsing.result.ParseResult;
-
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -41,8 +39,6 @@
/** @hide */
public class ComponentParseUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
-
public static boolean isImplicitlyExposedIntent(ParsedIntentInfo intentInfo) {
return intentInfo.hasCategory(Intent.CATEGORY_BROWSABLE)
|| intentInfo.hasAction(Intent.ACTION_SEND)
diff --git a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
index 6927f3b..8c0bfef 100644
--- a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
@@ -24,7 +24,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageParser;
import android.content.pm.parsing.ParsingPackage;
-import android.content.pm.parsing.ParsingPackageUtils;
import android.content.pm.parsing.ParsingUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseInput.DeferredError;
@@ -55,7 +54,7 @@
/** @hide */
public class ParsedActivityUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
@NonNull
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
diff --git a/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java b/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java
index 6811e06..dd2fb5b 100644
--- a/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java
@@ -36,8 +36,6 @@
/** @hide */
class ParsedComponentUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
-
@NonNull
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
static <Component extends ParsedComponent> ParseResult<Component> parseComponent(
diff --git a/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java b/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java
index 0ba92cc..6b797bc 100644
--- a/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java
+++ b/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java
@@ -22,7 +22,6 @@
import android.os.Parcelable;
import android.util.Pair;
-import com.android.internal.util.DataClass;
import com.android.internal.util.Parcelling;
import java.util.ArrayList;
@@ -163,7 +162,7 @@
}
public String toString() {
- return "ProviderIntentInfo{"
+ return "ParsedIntentInfo{"
+ Integer.toHexString(System.identityHashCode(this))
+ '}';
}
diff --git a/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java b/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java
index 390f769..c0536bb 100644
--- a/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java
@@ -21,7 +21,6 @@
import android.content.IntentFilter;
import android.content.pm.PackageParser;
import android.content.pm.parsing.ParsingPackage;
-import android.content.pm.parsing.ParsingPackageUtils;
import android.content.pm.parsing.ParsingUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
@@ -43,7 +42,7 @@
/** @hide */
public class ParsedIntentInfoUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
@NonNull
public static ParseResult<ParsedIntentInfo> parseIntentInfo(String className,
diff --git a/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java b/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java
index f4c9914..f70d62b 100644
--- a/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java
@@ -20,7 +20,7 @@
import android.annotation.Nullable;
import android.content.IntentFilter;
import android.content.pm.parsing.ParsingPackage;
-import android.content.pm.parsing.ParsingPackageUtils;
+import android.content.pm.parsing.ParsingUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
import android.content.res.Configuration;
@@ -39,7 +39,7 @@
/** @hide */
class ParsedMainComponentUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
@NonNull
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -113,7 +113,7 @@
ParsedIntentInfo intent = intentResult.getResult();
int actionCount = intent.countActions();
if (actionCount == 0 && failOnNoActions) {
- Slog.w(TAG, "No actions in " + parser.getName() + " at " + pkg.getBaseCodePath() + " "
+ Slog.w(TAG, "No actions in " + parser.getName() + " at " + pkg.getBaseApkPath() + " "
+ parser.getPositionDescription());
// Backward-compat, do not actually fail
return input.success(null);
diff --git a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java
index 1884a1e..894849a 100644
--- a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java
@@ -19,15 +19,15 @@
import android.annotation.NonNull;
import android.content.pm.PermissionInfo;
import android.content.pm.parsing.ParsingPackage;
+import android.content.pm.parsing.ParsingUtils;
+import android.content.pm.parsing.result.ParseInput;
+import android.content.pm.parsing.result.ParseResult;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.Slog;
import com.android.internal.R;
-import android.content.pm.parsing.ParsingPackageUtils;
-import android.content.pm.parsing.result.ParseInput;
-import android.content.pm.parsing.result.ParseResult;
import org.xmlpull.v1.XmlPullParserException;
@@ -36,7 +36,7 @@
/** @hide */
public class ParsedPermissionUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
@NonNull
public static ParseResult<ParsedPermission> parsePermission(ParsingPackage pkg, Resources res,
@@ -106,11 +106,6 @@
sa.recycle();
}
- // TODO(b/135203078): This is impossible because of default value in above getInt
- if (permission.protectionLevel == -1) {
- return input.error("<permission> does not specify protectionLevel");
- }
-
permission.protectionLevel = PermissionInfo.fixProtectionLevel(permission.protectionLevel);
if (permission.getProtectionFlags() != 0) {
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
index 8372707..9bff719 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
@@ -40,8 +40,6 @@
/** @hide */
public class ParsedProcessUtils {
- private static final String TAG = ParsingUtils.TAG;
-
@NonNull
private static ParseResult<Set<String>> parseDenyPermission(Set<String> perms,
Resources res, XmlResourceParser parser, ParseInput input)
diff --git a/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java b/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java
index aa5ea8d..37cbeca 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java
@@ -23,7 +23,6 @@
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.pm.parsing.ParsingPackage;
-import android.content.pm.parsing.ParsingPackageUtils;
import android.content.pm.parsing.ParsingUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
@@ -45,7 +44,7 @@
/** @hide */
public class ParsedProviderUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
+ private static final String TAG = ParsingUtils.TAG;
@NonNull
public static ParseResult<ParsedProvider> parseProvider(String[] separateProcesses,
@@ -247,7 +246,7 @@
}
Slog.w(TAG, "Unknown element under <path-permission>: " + name + " at "
- + pkg.getBaseCodePath() + " " + parser.getPositionDescription());
+ + pkg.getBaseApkPath() + " " + parser.getPositionDescription());
}
return input.success(provider);
@@ -293,7 +292,8 @@
"No readPermission or writePermission for <path-permission>");
}
Slog.w(TAG, "No readPermission or writePermission for <path-permission>: "
- + name + " at " + pkg.getBaseCodePath() + " " + parser.getPositionDescription());
+ + name + " at " + pkg.getBaseApkPath() + " "
+ + parser.getPositionDescription());
return input.success(provider);
}
@@ -342,7 +342,7 @@
}
Slog.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>: "
- + name + " at " + pkg.getBaseCodePath()
+ + name + " at " + pkg.getBaseApkPath()
+ " "
+ parser.getPositionDescription());
}
diff --git a/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java b/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java
index a8d2d67..afe3c54 100644
--- a/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java
@@ -22,7 +22,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.parsing.ParsingPackage;
-import android.content.pm.parsing.ParsingPackageUtils;
import android.content.pm.parsing.ParsingUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseInput.DeferredError;
@@ -43,8 +42,6 @@
/** @hide */
public class ParsedServiceUtils {
- private static final String TAG = ParsingPackageUtils.TAG;
-
@NonNull
public static ParseResult<ParsedService> parseService(String[] separateProcesses,
ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags,
diff --git a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
index 14992fb..0f90b53 100644
--- a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
+++ b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
@@ -95,7 +95,7 @@
return platformCompat.isChangeEnabled(changeId, appInfo);
} catch (Exception e) {
// This shouldn't happen, but assume enforcement if it does
- Slog.wtf(ParsingUtils.TAG, "IPlatformCompat query failed", e);
+ Slog.wtf(TAG, "IPlatformCompat query failed", e);
return true;
}
});
@@ -125,7 +125,7 @@
@Override
public <ResultType> ParseResult<ResultType> success(ResultType result) {
if (mErrorCode != PackageManager.INSTALL_SUCCEEDED) {
- Slog.wtf(ParsingUtils.TAG, "Cannot set to success after set to error, was "
+ Slog.wtf(TAG, "Cannot set to success after set to error, was "
+ mErrorMessage, mException);
}
mResult = result;
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 515704c..bec96f9 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -1102,7 +1102,6 @@
}
private static native long getNativeBBinderHolder();
- private static native long getFinalizer();
/**
* By default, we use the calling uid since we can always trust it.
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 8e865e7..1db544c 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1027,6 +1027,18 @@
/**
* R.
+ *
+ * <p>Applications targeting this or a later release will get these new changes in behavior.
+ * For more information about this release, see the
+ * <a href="/about/versions/11">Android 11 overview</a>.</p>
+ * <ul>
+ * <li><a href="/about/versions/11/behavior-changes-all">Behavior changes: all apps</a></li>
+ * <li><a href="/about/versions/11/behavior-changes-11">Behavior changes: Apps targeting
+ * Android 11</a></li>
+ * <li><a href="/about/versions/11/non-sdk-11">Updates to non-SDK interface restrictions
+ * in Android 11</a></li>
+ * </ul>
+ *
*/
public static final int R = 30;
diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java
index ab4bb0b..9c0bc45 100644
--- a/core/java/android/os/LocaleList.java
+++ b/core/java/android/os/LocaleList.java
@@ -25,6 +25,7 @@
import com.android.internal.annotations.GuardedBy;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -151,18 +152,18 @@
/**
* Creates a new {@link LocaleList}.
*
+ * If two or more same locales are passed, the repeated locales will be dropped.
* <p>For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()},
* which returns a pre-constructed empty list.</p>
*
* @throws NullPointerException if any of the input locales is <code>null</code>.
- * @throws IllegalArgumentException if any of the input locales repeat.
*/
public LocaleList(@NonNull Locale... list) {
if (list.length == 0) {
mList = sEmptyList;
mStringRepresentation = "";
} else {
- final Locale[] localeList = new Locale[list.length];
+ final ArrayList<Locale> localeList = new ArrayList<>();
final HashSet<Locale> seenLocales = new HashSet<Locale>();
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.length; i++) {
@@ -170,10 +171,10 @@
if (l == null) {
throw new NullPointerException("list[" + i + "] is null");
} else if (seenLocales.contains(l)) {
- throw new IllegalArgumentException("list[" + i + "] is a repetition");
+ // Dropping duplicated locale entries.
} else {
final Locale localeClone = (Locale) l.clone();
- localeList[i] = localeClone;
+ localeList.add(localeClone);
sb.append(localeClone.toLanguageTag());
if (i < list.length - 1) {
sb.append(',');
@@ -181,7 +182,7 @@
seenLocales.add(localeClone);
}
}
- mList = localeList;
+ mList = localeList.toArray(new Locale[localeList.size()]);
mStringRepresentation = sb.toString();
}
}
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index 17851ad..7f01cad 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -155,6 +155,19 @@
}
}
/**
+ * Complete the current partition installation.
+ *
+ * @return true if the partition installation completes without error.
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+ public boolean closePartition() {
+ try {
+ return mService.closePartition();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ /**
* Finish a previously started installation. Installations without a cooresponding
* finishInstallation() will be cleaned up during device boot.
*/
diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
index a1f9272..df0a69b 100644
--- a/core/java/android/os/image/IDynamicSystemService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -39,6 +39,13 @@
boolean createPartition(@utf8InCpp String name, long size, boolean readOnly);
/**
+ * Complete the current partition installation.
+ *
+ * @return true if the partition installation completes without error.
+ */
+ boolean closePartition();
+
+ /**
* Finish a previously started installation. Installations without
* a cooresponding finishInstallation() will be cleaned up during device boot.
*/
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index e05991b..a79a1cf 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -118,7 +118,7 @@
* affects them.
*/
public abstract void onAppOpsChanged(int code, int uid,
- @Nullable String packageName, int mode);
+ @Nullable String packageName, int mode, int previousMode);
/**
* Asks the StorageManager to reset all state for the provided user; this will result
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 859b703..7a03953 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -145,6 +145,15 @@
public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
/**
+ * Namespace for device idle configurations.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
+ public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
+
+ /**
* Namespace for how dex runs. The feature requires a reboot to reach a clean state.
*
* @deprecated No longer used
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index d55fc51..4e1f819 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -239,6 +239,10 @@
}
}
+ private Uri validateIncomingNullableUri(@Nullable Uri uri) {
+ return uri == null ? null : validateIncomingUri(uri);
+ }
+
/**
* Create a new document and return its newly generated
* {@link Document#COLUMN_DOCUMENT_ID}. You must allocate a new
@@ -1086,11 +1090,18 @@
// If the URI is a tree URI performs some validation.
enforceTreeForExtraUris(extras);
+ final Uri extraUri = validateIncomingNullableUri(
+ extras.getParcelable(DocumentsContract.EXTRA_URI));
+ final Uri extraTargetUri = validateIncomingNullableUri(
+ extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
+ final Uri extraParentUri = validateIncomingNullableUri(
+ extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
+
if (METHOD_EJECT_ROOT.equals(method)) {
// Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps
// signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for
// MANAGE_DOCUMENTS or associated URI permission here instead
- final Uri rootUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
+ final Uri rootUri = extraUri;
enforceWritePermissionInner(rootUri, getCallingPackage(), getCallingAttributionTag(),
null);
@@ -1100,7 +1111,7 @@
return out;
}
- final Uri documentUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
+ final Uri documentUri = extraUri;
final String authority = documentUri.getAuthority();
final String documentId = DocumentsContract.getDocumentId(documentUri);
@@ -1113,7 +1124,7 @@
enforceReadPermissionInner(documentUri, getCallingPackage(),
getCallingAttributionTag(), null);
- final Uri childUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
+ final Uri childUri = extraTargetUri;
final String childAuthority = childUri.getAuthority();
final String childId = DocumentsContract.getDocumentId(childUri);
@@ -1180,7 +1191,7 @@
revokeDocumentPermission(documentId);
} else if (METHOD_COPY_DOCUMENT.equals(method)) {
- final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
+ final Uri targetUri = extraTargetUri;
final String targetId = DocumentsContract.getDocumentId(targetUri);
enforceReadPermissionInner(documentUri, getCallingPackage(),
@@ -1204,9 +1215,9 @@
}
} else if (METHOD_MOVE_DOCUMENT.equals(method)) {
- final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
+ final Uri parentSourceUri = extraParentUri;
final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
- final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
+ final Uri targetUri = extraTargetUri;
final String targetId = DocumentsContract.getDocumentId(targetUri);
enforceWritePermissionInner(documentUri, getCallingPackage(),
@@ -1232,7 +1243,7 @@
}
} else if (METHOD_REMOVE_DOCUMENT.equals(method)) {
- final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
+ final Uri parentSourceUri = extraParentUri;
final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
enforceReadPermissionInner(parentSourceUri, getCallingPackage(),
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 03cf0cf..18337b6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6801,6 +6801,13 @@
public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri";
/**
+ * Whether to draw text in bold.
+ *
+ * @hide
+ */
+ public static final String FORCE_BOLD_TEXT = "force_bold_text";
+
+ /**
* Whether to speak passwords while in accessibility mode.
*
* @deprecated The speaking of passwords is controlled by individual accessibility services.
@@ -11534,38 +11541,6 @@
public static final String APP_OPS_CONSTANTS = "app_ops_constants";
/**
- * Device Idle (Doze) specific settings.
- * This is encoded as a key=value list, separated by commas. Ex:
- *
- * "inactive_to=60000,sensing_to=400000"
- *
- * The following keys are supported:
- *
- * <pre>
- * inactive_to (long)
- * sensing_to (long)
- * motion_inactive_to (long)
- * idle_after_inactive_to (long)
- * idle_pending_to (long)
- * max_idle_pending_to (long)
- * idle_pending_factor (float)
- * quick_doze_delay_to (long)
- * idle_to (long)
- * max_idle_to (long)
- * idle_factor (float)
- * min_time_to_alarm (long)
- * max_temp_app_whitelist_duration (long)
- * notification_whitelist_duration (long)
- * </pre>
- *
- * <p>
- * Type: string
- * @hide
- * @see com.android.server.DeviceIdleController.Constants
- */
- public static final String DEVICE_IDLE_CONSTANTS = "device_idle_constants";
-
- /**
* Battery Saver specific settings
* This is encoded as a key=value list, separated by commas. Ex:
*
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index e083417..19860eb 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -71,6 +71,7 @@
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.window.ClientWindowFrames;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.HandlerCaller;
@@ -186,17 +187,11 @@
int mCurWindowFlags = mWindowFlags;
int mCurWindowPrivateFlags = mWindowPrivateFlags;
Rect mPreviewSurfacePosition;
- final Rect mVisibleInsets = new Rect();
- final Rect mWinFrame = new Rect();
- final Rect mContentInsets = new Rect();
- final Rect mStableInsets = new Rect();
+ final ClientWindowFrames mWinFrames = new ClientWindowFrames();
final Rect mDispatchedContentInsets = new Rect();
final Rect mDispatchedStableInsets = new Rect();
final Rect mFinalSystemInsets = new Rect();
final Rect mFinalStableInsets = new Rect();
- final Rect mBackdropFrame = new Rect();
- final DisplayCutout.ParcelableWrapper mDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT;
final InsetsState mInsetsState = new InsetsState();
final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0];
@@ -332,11 +327,9 @@
final BaseIWindow mWindow = new BaseIWindow() {
@Override
- public void resized(Rect frame, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
- MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {
+ public void resized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration mergedConfiguration, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId) {
Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
reportDraw ? 1 : 0);
mCaller.sendMessage(msg);
@@ -749,10 +742,7 @@
out.print(" mCurWindowFlags="); out.println(mCurWindowFlags);
out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags);
out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags);
- out.print(prefix); out.print("mVisibleInsets=");
- out.print(mVisibleInsets.toShortString());
- out.print(" mWinFrame="); out.print(mWinFrame.toShortString());
- out.print(" mContentInsets="); out.println(mContentInsets.toShortString());
+ out.print(prefix); out.println("mWinFrames="); out.println(mWinFrames);
out.print(prefix); out.print("mConfiguration=");
out.println(mMergedConfiguration.getMergedConfiguration());
out.print(prefix); out.print("mLayout="); out.println(mLayout);
@@ -890,8 +880,8 @@
InputChannel inputChannel = new InputChannel();
if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE,
- mDisplay.getDisplayId(), mWinFrame, mContentInsets, mStableInsets,
- mDisplayCutout, inputChannel,
+ mDisplay.getDisplayId(), mWinFrames.frame, mWinFrames.contentInsets,
+ mWinFrames.stableInsets, mWinFrames.displayCutout, inputChannel,
mInsetsState, mTempControls) < 0) {
Log.w(TAG, "Failed to add window while updating wallpaper surface.");
return;
@@ -914,34 +904,32 @@
final int relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
- View.VISIBLE, 0, -1, mWinFrame, mContentInsets,
- mVisibleInsets, mStableInsets, mBackdropFrame,
- mDisplayCutout, mMergedConfiguration, mSurfaceControl,
+ View.VISIBLE, 0, -1, mWinFrames, mMergedConfiguration, mSurfaceControl,
mInsetsState, mTempControls, mSurfaceSize, mTmpSurfaceControl);
if (mSurfaceControl.isValid()) {
mSurfaceHolder.mSurface.copyFrom(mSurfaceControl);
}
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
- + ", frame=" + mWinFrame);
+ + ", frame=" + mWinFrames);
- int w = mWinFrame.width();
- int h = mWinFrame.height();
+ int w = mWinFrames.frame.width();
+ int h = mWinFrames.frame.height();
if (!fixedSize) {
final Rect padding = mIWallpaperEngine.mDisplayPadding;
w += padding.left + padding.right;
h += padding.top + padding.bottom;
- mContentInsets.left += padding.left;
- mContentInsets.top += padding.top;
- mContentInsets.right += padding.right;
- mContentInsets.bottom += padding.bottom;
- mStableInsets.left += padding.left;
- mStableInsets.top += padding.top;
- mStableInsets.right += padding.right;
- mStableInsets.bottom += padding.bottom;
- mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top,
- -padding.right, -padding.bottom));
+ mWinFrames.contentInsets.left += padding.left;
+ mWinFrames.contentInsets.top += padding.top;
+ mWinFrames.contentInsets.right += padding.right;
+ mWinFrames.contentInsets.bottom += padding.bottom;
+ mWinFrames.stableInsets.left += padding.left;
+ mWinFrames.stableInsets.top += padding.top;
+ mWinFrames.stableInsets.right += padding.right;
+ mWinFrames.stableInsets.bottom += padding.bottom;
+ mWinFrames.displayCutout.set(mWinFrames.displayCutout.get().inset(
+ -padding.left, -padding.top, -padding.right, -padding.bottom));
} else {
w = myWidth;
h = myHeight;
@@ -960,9 +948,10 @@
Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight);
}
- insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
- insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
- insetsChanged |= !mDispatchedDisplayCutout.equals(mDisplayCutout.get());
+ final DisplayCutout displayCutout = mWinFrames.displayCutout.get();
+ insetsChanged |= !mDispatchedContentInsets.equals(mWinFrames.contentInsets);
+ insetsChanged |= !mDispatchedStableInsets.equals(mWinFrames.stableInsets);
+ insetsChanged |= !mDispatchedDisplayCutout.equals(displayCutout);
mSurfaceHolder.setSurfaceFrameSize(w, h);
mSurfaceHolder.mSurfaceLock.unlock();
@@ -1021,9 +1010,9 @@
}
if (insetsChanged) {
- mDispatchedContentInsets.set(mContentInsets);
- mDispatchedStableInsets.set(mStableInsets);
- mDispatchedDisplayCutout = mDisplayCutout.get();
+ mDispatchedContentInsets.set(mWinFrames.contentInsets);
+ mDispatchedStableInsets.set(mWinFrames.stableInsets);
+ mDispatchedDisplayCutout = displayCutout;
mFinalStableInsets.set(mDispatchedStableInsets);
WindowInsets insets = new WindowInsets(mFinalSystemInsets,
mFinalStableInsets,
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 4b42209..5fd192a 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -183,10 +183,9 @@
@NonNull String packageName, @Nullable String featureId) {
if (DBG) Log.d(TAG, "checkPermissions");
if (forDataDelivery) {
- if (PermissionChecker.checkCallingPermissionForDataDelivery(this,
+ if (PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(this,
android.Manifest.permission.RECORD_AUDIO, packageName, featureId,
- null /*message*/)
- == PermissionChecker.PERMISSION_GRANTED) {
+ null /*message*/) == PermissionChecker.PERMISSION_GRANTED) {
return true;
}
} else {
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index cbc304b..8f31d77 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -486,6 +486,16 @@
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
public static final int LISTEN_BARRING_INFO = 0x80000000;
+ /**
+ * Listen for changes to the physical channel configuration.
+ *
+ * @see #onPhysicalChannelConfigurationChanged
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+ public static final long LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 0x100000000L;
+
/*
* Subscription used to listen to the phone state changes
* @hide
@@ -1145,6 +1155,18 @@
}
/**
+ * Callback invoked when the current physical channel configuration has changed
+ *
+ * @param configs List of the current {@link PhysicalChannelConfig}s
+ * @hide
+ */
+ @SystemApi
+ public void onPhysicalChannelConfigurationChanged(
+ @NonNull List<PhysicalChannelConfig> configs) {
+ // default implementation empty
+ }
+
+ /**
* The callback methods need to be called on the handler thread where
* this object was created. If the binder did that for us it'd be nice.
*
@@ -1447,6 +1469,15 @@
Binder.withCleanCallingIdentity(
() -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo)));
}
+
+ public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) {
+ PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
+ if (psl == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(
+ () -> psl.onPhysicalChannelConfigurationChanged(configs)));
+ }
}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index a720601..6d48dc3 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -211,7 +211,7 @@
* @param notifyNow Whether to notify instantly
*/
public void listenForSubscriber(int subId, @NonNull String pkg, @NonNull String featureId,
- @NonNull PhoneStateListener listener, int events, boolean notifyNow) {
+ @NonNull PhoneStateListener listener, long events, boolean notifyNow) {
try {
// subId from PhoneStateListener is deprecated Q on forward, use the subId from
// TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q.
@@ -754,4 +754,19 @@
}
}
+ /**
+ * Notify {@link PhysicalChannelConfig} has changed for a specific subscription.
+ *
+ * @param subId the subId
+ * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
+ */
+ public void notifyPhysicalChannelConfigurationForSubscriber(
+ int subId, List<PhysicalChannelConfig> configs) {
+ try {
+ sRegistry.notifyPhysicalChannelConfigurationForSubscriber(subId, configs);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index e338fd97..0973608 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -65,6 +65,7 @@
DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true");
DEFAULT_FLAGS.put("settings_tether_all_in_one", "false");
+ DEFAULT_FLAGS.put("settings_silky_home", "false");
}
/**
diff --git a/core/java/android/view/BatchedInputEventReceiver.java b/core/java/android/view/BatchedInputEventReceiver.java
index 30e3ec1..7023e4b 100644
--- a/core/java/android/view/BatchedInputEventReceiver.java
+++ b/core/java/android/view/BatchedInputEventReceiver.java
@@ -24,7 +24,8 @@
* @hide
*/
public class BatchedInputEventReceiver extends InputEventReceiver {
- Choreographer mChoreographer;
+ private Choreographer mChoreographer;
+ private boolean mBatchingEnabled;
private boolean mBatchedInputScheduled;
@UnsupportedAppUsage
@@ -32,19 +33,37 @@
InputChannel inputChannel, Looper looper, Choreographer choreographer) {
super(inputChannel, looper);
mChoreographer = choreographer;
+ mBatchingEnabled = true;
}
@Override
public void onBatchedInputEventPending(int source) {
- scheduleBatchedInput();
+ if (mBatchingEnabled) {
+ scheduleBatchedInput();
+ } else {
+ consumeBatchedInputEvents(-1);
+ }
}
@Override
public void dispose() {
unscheduleBatchedInput();
+ consumeBatchedInputEvents(-1);
super.dispose();
}
+ /**
+ * Sets whether to enable batching on this input event receiver.
+ * @hide
+ */
+ public void setBatchingEnabled(boolean batchingEnabled) {
+ mBatchingEnabled = batchingEnabled;
+ if (!batchingEnabled) {
+ unscheduleBatchedInput();
+ consumeBatchedInputEvents(-1);
+ }
+ }
+
void doConsumeBatchedInput(long frameTimeNanos) {
if (mBatchedInputScheduled) {
mBatchedInputScheduled = false;
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index e09bf9d..94e641c 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -29,6 +29,7 @@
import android.view.IScrollCaptureController;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.window.ClientWindowFrames;
import com.android.internal.os.IResultReceiver;
@@ -52,11 +53,9 @@
*/
void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor);
- void resized(in Rect frame, in Rect contentInsets,
- in Rect visibleInsets, in Rect stableInsets, boolean reportDraw,
- in MergedConfiguration newMergedConfiguration, in Rect backDropFrame,
- boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
- in DisplayCutout.ParcelableWrapper displayCutout);
+ void resized(in ClientWindowFrames frames, boolean reportDraw,
+ in MergedConfiguration newMergedConfiguration,
+ boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId);
/**
* Called when the window location in parent display has changed. The offset will only be a
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 00fc672..8e875d7 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -393,11 +393,6 @@
oneway void setRecentsVisibility(boolean visible);
/**
- * Called by System UI to notify of changes to the visibility of PIP.
- */
- oneway void setPipVisibility(boolean visible);
-
- /**
* Called by System UI to enable or disable haptic feedback on the navigation bar buttons.
*/
@UnsupportedAppUsage
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 819e89b..70850d8 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -34,6 +34,7 @@
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import android.window.ClientWindowFrames;
import java.util.List;
@@ -107,10 +108,7 @@
*/
int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility,
- int flags, long frameNumber, out Rect outFrame,
- out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
- out Rect outBackdropFrame,
- out DisplayCutout.ParcelableWrapper displayCutout,
+ int flags, long frameNumber, out ClientWindowFrames outFrames,
out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
out InsetsState insetsState, out InsetsSourceControl[] activeControls,
out Point outSurfaceSize, out SurfaceControl outBlastSurfaceControl);
@@ -152,12 +150,6 @@
in Rect visibleInsets, in Region touchableRegion);
/**
- * Return the current display size in which the window is being laid out,
- * accounting for screen decorations around it.
- */
- void getDisplayFrame(IWindow window, out Rect outDisplayFrame);
-
- /**
* Called when the client has finished drawing the surface, if needed.
*
* @param postDrawTransaction transaction filled by the client that can be
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 6922072..6ffd892 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
@@ -24,6 +25,7 @@
import static android.view.InsetsState.ISIDE_RIGHT;
import static android.view.InsetsState.ISIDE_TOP;
import static android.view.InsetsState.ITYPE_IME;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
@@ -308,8 +310,8 @@
false /* isScreenRound */,
false /* alwaysConsumeSystemBars */, null /* displayCutout */,
LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/,
- 0 /* legacyWindowFlags */, 0 /* legacySystemUiFlags */, typeSideMap)
- .getInsets(mTypes);
+ 0 /* legacyWindowFlags */, 0 /* legacySystemUiFlags */, TYPE_APPLICATION,
+ WINDOWING_MODE_UNDEFINED, typeSideMap).getInsets(mTypes);
}
private Insets sanitize(Insets insets) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 403ac3a..92eade3 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -500,9 +500,11 @@
/** Pending control request that is waiting on IME to be ready to be shown */
private PendingControlRequest mPendingImeControlRequest;
+ private int mWindowType;
private int mLastLegacySoftInputMode;
private int mLastLegacyWindowFlags;
private int mLastLegacySystemUiFlags;
+ private int mLastWindowingMode;
private DisplayCutout mLastDisplayCutout;
private boolean mStartingAnimation;
private int mCaptionInsetsHeight = 0;
@@ -571,7 +573,8 @@
WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/,
mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(),
mLastDisplayCutout, mLastLegacySoftInputMode, mLastLegacyWindowFlags,
- mLastLegacySystemUiFlags, null /* typeSideMap */);
+ mLastLegacySystemUiFlags, mWindowType, mLastWindowingMode,
+ null /* typeSideMap */);
mHost.dispatchWindowInsetsAnimationProgress(insets, mUnmodifiableTmpRunningAnims);
if (DEBUG) {
for (WindowInsetsAnimation anim : mUnmodifiableTmpRunningAnims) {
@@ -709,9 +712,11 @@
* @see InsetsState#calculateInsets
*/
@VisibleForTesting
- public WindowInsets calculateInsets(boolean isScreenRound,
- boolean alwaysConsumeSystemBars, DisplayCutout cutout,
+ public WindowInsets calculateInsets(boolean isScreenRound, boolean alwaysConsumeSystemBars,
+ DisplayCutout cutout, int windowType, int windowingMode,
int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags) {
+ mWindowType = windowType;
+ mLastWindowingMode = windowingMode;
mLastLegacySoftInputMode = legacySoftInputMode;
mLastLegacyWindowFlags = legacyWindowFlags;
mLastLegacySystemUiFlags = legacySystemUiFlags;
@@ -719,7 +724,7 @@
mLastInsets = mState.calculateInsets(mFrame, null /* ignoringVisibilityState*/,
isScreenRound, alwaysConsumeSystemBars, cutout,
legacySoftInputMode, legacyWindowFlags, legacySystemUiFlags,
- null /* typeSideMap */);
+ windowType, windowingMode, null /* typeSideMap */);
return mLastInsets;
}
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 700dc66..ba40459 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -113,13 +113,20 @@
InsetsState.typeToString(control.getType()),
mController.getHost().getRootViewTitle()));
}
- // We are loosing control
if (mSourceControl == null) {
+ // We are loosing control
mController.notifyControlRevoked(this);
- // Restore server visibility.
- mState.getSource(getType()).setVisible(
- mController.getLastDispatchedState().getSource(getType()).isVisible());
+ // Check if we need to restore server visibility.
+ final InsetsSource source = mState.getSource(mType);
+ final boolean serverVisibility =
+ mController.getLastDispatchedState().getSourceOrDefaultVisibility(mType);
+ if (source.isVisible() != serverVisibility) {
+ source.setVisible(serverVisibility);
+ mController.notifyVisibilityChanged();
+ }
+
+ // For updateCompatSysUiVisibility
applyLocalVisibilityOverride();
} else {
// We are gaining control, and need to run an animation since previous state
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 593b37a..373a096 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -30,11 +30,15 @@
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Parcel;
@@ -174,6 +178,7 @@
public WindowInsets calculateInsets(Rect frame, @Nullable InsetsState ignoringVisibilityState,
boolean isScreenRound, boolean alwaysConsumeSystemBars, DisplayCutout cutout,
int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags,
+ int windowType, @WindowConfiguration.WindowingMode int windowingMode,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
Insets[] typeInsetsMap = new Insets[Type.SIZE];
Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
@@ -228,6 +233,9 @@
if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) {
compatInsetsTypes &= ~statusBars();
}
+ if (clearCompatInsets(windowType, legacyWindowFlags, windowingMode)) {
+ compatInsetsTypes = 0;
+ }
return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
alwaysConsumeSystemBars, cutout, compatInsetsTypes,
@@ -449,6 +457,12 @@
mSources[source.getType()] = source;
}
+ public static boolean clearCompatInsets(int windowType, int windowFlags, int windowingMode) {
+ return (windowFlags & FLAG_LAYOUT_NO_LIMITS) != 0
+ && windowType != TYPE_WALLPAPER && windowType != TYPE_SYSTEM_ERROR
+ && !WindowConfiguration.inMultiWindowMode(windowingMode);
+ }
+
public static @InternalInsetsType ArraySet<Integer> toInternalType(@InsetsType int types) {
final ArraySet<Integer> result = new ArraySet<>();
if ((types & Type.STATUS_BARS) != 0) {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index e249c77..0ab1751 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1908,8 +1908,6 @@
/**
* Returns whether this key will be sent to the
* {@link android.media.session.MediaSession.Callback} if not handled.
- *
- * @hide
*/
public static final boolean isMediaSessionKey(int keyCode) {
switch (keyCode) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6ef086b..2bd3c06 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -221,6 +221,8 @@
private static native void nativeReleaseFrameRateFlexibilityToken(long token);
private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
int transformHint);
+ private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken,
+ IBinder focusedToken, int displayId);
@Nullable
@GuardedBy("mLock")
@@ -3184,6 +3186,39 @@
}
/**
+ * Sets focus on the window identified by the input {@code token} if the window is focusable
+ * otherwise the request is dropped.
+ *
+ * If the window is not visible, the request will be queued until the window becomes
+ * visible or the request is overrriden by another request. The currently focused window
+ * will lose focus immediately. This is to send the newly focused window any focus
+ * dispatched events that occur while it is completing its first draw.
+ *
+ * @hide
+ */
+ public Transaction setFocusedWindow(@NonNull IBinder token, int displayId) {
+ nativeSetFocusedWindow(mNativeObject, token, null /* focusedToken */, displayId);
+ return this;
+ }
+
+ /**
+ * Set focus on the window identified by the input {@code token} if the window identified by
+ * the input {@code focusedToken} is currently focused. If the {@code focusedToken} does not
+ * have focus, the request is dropped.
+ *
+ * This is used by forward focus transfer requests from clients that host embedded windows,
+ * and want to transfer focus to/from them.
+ *
+ * @hide
+ */
+ public Transaction requestFocusTransfer(@NonNull IBinder token,
+ @NonNull IBinder focusedToken,
+ int displayId) {
+ nativeSetFocusedWindow(mNativeObject, token, focusedToken, displayId);
+ return this;
+ }
+
+ /**
* Merge the other transaction into this transaction, clearing the
* other transaction as if it had been applied.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8917821..92a0f63 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14940,20 +14940,12 @@
* inside. In effect, this tells you the available area where content can
* be placed and remain visible to users.
*
- * <p>This function requires an IPC back to the window manager to retrieve
- * the requested information, so should not be used in performance critical
- * code like drawing.
- *
* @param outRect Filled in with the visible display frame. If the view
* is not attached to a window, this is simply the raw display size.
*/
public void getWindowVisibleDisplayFrame(Rect outRect) {
if (mAttachInfo != null) {
- try {
- mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
- } catch (RemoteException e) {
- return;
- }
+ mAttachInfo.mViewRootImpl.getDisplayFrame(outRect);
// XXX This is really broken, and probably all needs to be done
// in the window manager, and we need to know more about whether
// we want the area behind or in front of the IME.
@@ -14979,11 +14971,7 @@
@UnsupportedAppUsage
public void getWindowDisplayFrame(Rect outRect) {
if (mAttachInfo != null) {
- try {
- mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
- } catch (RemoteException e) {
- return;
- }
+ mAttachInfo.mViewRootImpl.getDisplayFrame(outRect);
return;
}
// The view is not attached to a display so we don't have a context.
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index ccf1fb0..abf76ec 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -100,7 +100,7 @@
* Defines the duration in milliseconds a user needs to hold down the
* appropriate buttons (power + volume down) to trigger the screenshot chord.
*/
- private static final int SCREENSHOT_CHORD_KEY_TIMEOUT = 500;
+ private static final int SCREENSHOT_CHORD_KEY_TIMEOUT = 0;
/**
* Defines the duration in milliseconds a user needs to hold down the
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 8a5be75..4303d70 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -33,7 +33,6 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -755,11 +754,7 @@
try {
Rect outRect = new Rect();
- try {
- root.mAttachInfo.mSession.getDisplayFrame(root.mAttachInfo.mWindow, outRect);
- } catch (RemoteException e) {
- // Ignore
- }
+ root.mAttachInfo.mViewRootImpl.getDisplayFrame(outRect);
clientStream.writeInt(outRect.width());
clientStream.writeInt(outRect.height());
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6e17ac9..af839d4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -53,6 +53,9 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
@@ -134,7 +137,6 @@
import android.view.Window.OnContentApplyWindowInsetsListener;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -157,6 +159,7 @@
import android.view.contentcapture.MainContentCaptureSession;
import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
+import android.window.ClientWindowFrames;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -462,6 +465,7 @@
// used in relayout to get SurfaceControl size
// for BLAST adapter surface setup
private final Point mSurfaceSize = new Point();
+ private final Point mLastSurfaceSize = new Point();
final Rect mTempRect; // used in the transaction to not thrash the heap.
final Rect mVisRect; // used to retrieve visible rect of focused view.
@@ -556,8 +560,11 @@
boolean mAdded;
boolean mAddedTouchMode;
- final Rect mTmpFrame = new Rect();
- final Rect mTmpRect = new Rect();
+ /**
+ * It usually keeps the latest layout result from {@link IWindow#resized} or
+ * {@link IWindowSession#relayout}.
+ */
+ private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
// These are accessed by multiple threads.
final Rect mWinFrame; // frame given by window manager.
@@ -1029,11 +1036,11 @@
collectViewAttributes();
adjustLayoutParamsForCompatibility(mWindowAttributes);
res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes,
- getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame,
+ getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrames.frame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mDisplayCutout, inputChannel,
mTempInsets, mTempControls);
- setFrame(mTmpFrame);
+ setFrame(mTmpFrames.frame);
} catch (RemoteException e) {
mAdded = false;
mView = null;
@@ -1439,14 +1446,13 @@
}
// Don't lose the mode we last auto-computed.
- if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
+ if ((attrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
== WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode
- & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
- | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
+ & ~SOFT_INPUT_MASK_ADJUST) | (oldSoftInputMode & SOFT_INPUT_MASK_ADJUST);
}
- if ((changes & LayoutParams.SOFT_INPUT_MODE_CHANGED) != 0) {
+ if (mWindowAttributes.softInputMode != oldSoftInputMode) {
requestFitSystemWindows();
}
@@ -1472,6 +1478,55 @@
scheduleTraversals();
}
+ /** Handles messages {@link #MSG_RESIZED} and {@link #MSG_RESIZED_REPORT}. */
+ private void handleResized(int msg, SomeArgs args) {
+ if (!mAdded) {
+ return;
+ }
+
+ final ClientWindowFrames frames = (ClientWindowFrames) args.arg1;
+ final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg2;
+ final boolean forceNextWindowRelayout = args.argi1 != 0;
+ final int displayId = args.argi3;
+ final Rect backdropFrame = frames.backdropFrame;
+ final DisplayCutout displayCutout = frames.displayCutout.get();
+
+ final boolean frameChanged = !mWinFrame.equals(frames.frame);
+ final boolean cutoutChanged = !mPendingDisplayCutout.get().equals(displayCutout);
+ final boolean backdropFrameChanged = !mPendingBackDropFrame.equals(backdropFrame);
+ final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration);
+ final boolean displayChanged = mDisplay.getDisplayId() != displayId;
+ if (msg == MSG_RESIZED && !frameChanged && !cutoutChanged && !backdropFrameChanged
+ && !configChanged && !displayChanged && !forceNextWindowRelayout) {
+ return;
+ }
+
+ if (configChanged) {
+ // If configuration changed - notify about that and, maybe, about move to display.
+ performConfigurationChange(mergedConfiguration, false /* force */,
+ displayChanged ? displayId : INVALID_DISPLAY /* same display */);
+ } else if (displayChanged) {
+ // Moved to display without config change - report last applied one.
+ onMovedToDisplay(displayId, mLastConfigurationFromResources);
+ }
+
+ setFrame(frames.frame);
+ mTmpFrames.displayFrame.set(frames.displayFrame);
+ mPendingDisplayCutout.set(displayCutout);
+ mPendingBackDropFrame.set(backdropFrame);
+ mForceNextWindowRelayout = forceNextWindowRelayout;
+ mPendingAlwaysConsumeSystemBars = args.argi2 != 0;
+
+ if (msg == MSG_RESIZED_REPORT) {
+ reportNextDraw();
+ }
+
+ if (mView != null && (frameChanged || cutoutChanged || configChanged)) {
+ forceLayout(mView);
+ }
+ requestLayout();
+ }
+
private final DisplayListener mDisplayListener = new DisplayListener() {
@Override
public void onDisplayChanged(int displayId) {
@@ -2063,6 +2118,7 @@
final int sysUiVis = inOutParams.systemUiVisibility | inOutParams.subtreeSystemUiVisibility;
final int flags = inOutParams.flags;
final int type = inOutParams.type;
+ final int adjust = inOutParams.softInputMode & SOFT_INPUT_MASK_ADJUST;
if ((inOutParams.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
inOutParams.insetsFlags.appearance = 0;
@@ -2088,12 +2144,13 @@
}
}
+ inOutParams.privateFlags &= ~PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
+
if ((inOutParams.privateFlags & PRIVATE_FLAG_FIT_INSETS_CONTROLLED) != 0) {
return;
}
int types = inOutParams.getFitInsetsTypes();
- int sides = inOutParams.getFitInsetsSides();
boolean ignoreVis = inOutParams.isFitInsetsIgnoringVisibility();
if (((sysUiVis & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0
@@ -2108,10 +2165,13 @@
if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) {
ignoreVis = true;
} else if ((types & Type.systemBars()) == Type.systemBars()) {
- types |= Type.ime();
+ if (adjust == SOFT_INPUT_ADJUST_RESIZE) {
+ types |= Type.ime();
+ } else {
+ inOutParams.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
+ }
}
inOutParams.setFitInsetsTypes(types);
- inOutParams.setFitInsetsSides(sides);
inOutParams.setFitInsetsIgnoringVisibility(ignoreVis);
// The fitting of insets are not really controlled by the clients, so we remove the flag.
@@ -2246,9 +2306,11 @@
/* package */ WindowInsets getWindowInsets(boolean forceConstruct) {
if (mLastWindowInsets == null || forceConstruct) {
+ final Configuration config = mContext.getResources().getConfiguration();
mLastWindowInsets = mInsetsController.calculateInsets(
- mContext.getResources().getConfiguration().isScreenRound(),
- mAttachInfo.mAlwaysConsumeSystemBars, mPendingDisplayCutout.get(),
+ config.isScreenRound(), mAttachInfo.mAlwaysConsumeSystemBars,
+ mPendingDisplayCutout.get(), mWindowAttributes.type,
+ config.windowConfiguration.getWindowingMode(),
mWindowAttributes.softInputMode, mWindowAttributes.flags,
(mWindowAttributes.systemUiVisibility
| mWindowAttributes.subtreeSystemUiVisibility));
@@ -2481,8 +2543,7 @@
if (mFirst || mAttachInfo.mViewVisibilityChanged) {
mAttachInfo.mViewVisibilityChanged = false;
- int resizeMode = mSoftInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+ int resizeMode = mSoftInputMode & SOFT_INPUT_MASK_ADJUST;
// If we are in auto resize mode, then we need to determine
// what mode to use now.
if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
@@ -2495,11 +2556,8 @@
if (resizeMode == 0) {
resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
}
- if ((lp.softInputMode &
- WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) != resizeMode) {
- lp.softInputMode = (lp.softInputMode &
- ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) |
- resizeMode;
+ if ((lp.softInputMode & SOFT_INPUT_MASK_ADJUST) != resizeMode) {
+ lp.softInputMode = (lp.softInputMode & ~SOFT_INPUT_MASK_ADJUST) | resizeMode;
params = lp;
}
}
@@ -2636,9 +2694,12 @@
}
cutoutChanged = !mPendingDisplayCutout.equals(mAttachInfo.mDisplayCutout);
- surfaceSizeChanged = (relayoutResult
- & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
- final boolean alwaysConsumeSystemBarsChanged =
+ surfaceSizeChanged = false;
+ if (!mLastSurfaceSize.equals(mSurfaceSize)) {
+ surfaceSizeChanged = true;
+ mLastSurfaceSize.set(mSurfaceSize.x, mSurfaceSize.y);
+ }
+ final boolean alwaysConsumeSystemBarsChanged =
mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars;
updateColorModeIfNeeded(lp.getColorMode());
surfaceCreated = !hadSurface && mSurface.isValid();
@@ -3234,8 +3295,8 @@
// Note: must be done after the focus change callbacks,
// so all of the view state is set up correctly.
- mImeFocusController.onPostWindowFocus(mView.findFocus(), hasWindowFocus,
- mWindowAttributes);
+ mImeFocusController.onPostWindowFocus(mView != null ? mView.findFocus() : null,
+ hasWindowFocus, mWindowAttributes);
if (hasWindowFocus) {
// Clear the forward bit. We can just do this directly, since
@@ -4914,60 +4975,13 @@
case MSG_DISPATCH_GET_NEW_SURFACE:
handleGetNewSurface();
break;
- case MSG_RESIZED: {
- // Recycled in the fall through...
- SomeArgs args = (SomeArgs) msg.obj;
- if (mWinFrame.equals(args.arg1)
- && mPendingDisplayCutout.get().equals(args.arg9)
- && mPendingBackDropFrame.equals(args.arg8)
- && mLastReportedMergedConfiguration.equals(args.arg4)
- && args.argi1 == 0
- && mDisplay.getDisplayId() == args.argi3) {
- break;
- }
- } // fall through...
- case MSG_RESIZED_REPORT:
- if (mAdded) {
- SomeArgs args = (SomeArgs) msg.obj;
-
- final int displayId = args.argi3;
- MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
- final boolean displayChanged = mDisplay.getDisplayId() != displayId;
- boolean configChanged = false;
-
- if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
- // If configuration changed - notify about that and, maybe,
- // about move to display.
- performConfigurationChange(mergedConfiguration, false /* force */,
- displayChanged
- ? displayId : INVALID_DISPLAY /* same display */);
- configChanged = true;
- } else if (displayChanged) {
- // Moved to display without config change - report last applied one.
- onMovedToDisplay(displayId, mLastConfigurationFromResources);
- }
-
- final boolean framesChanged = !mWinFrame.equals(args.arg1)
- || !mPendingDisplayCutout.get().equals(args.arg9);
-
- setFrame((Rect) args.arg1);
- mPendingDisplayCutout.set((DisplayCutout) args.arg9);
- mPendingBackDropFrame.set((Rect) args.arg8);
- mForceNextWindowRelayout = args.argi1 != 0;
- mPendingAlwaysConsumeSystemBars = args.argi2 != 0;
-
- args.recycle();
-
- if (msg.what == MSG_RESIZED_REPORT) {
- reportNextDraw();
- }
-
- if (mView != null && (framesChanged || configChanged)) {
- forceLayout(mView);
- }
- requestLayout();
- }
+ case MSG_RESIZED:
+ case MSG_RESIZED_REPORT: {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ handleResized(msg.what, args);
+ args.recycle();
break;
+ }
case MSG_INSETS_CHANGED:
mInsetsController.onStateChanged((InsetsState) msg.obj);
break;
@@ -5002,11 +5016,11 @@
final int h = mWinFrame.height();
final int l = msg.arg1;
final int t = msg.arg2;
- mTmpFrame.left = l;
- mTmpFrame.right = l + w;
- mTmpFrame.top = t;
- mTmpFrame.bottom = t + h;
- setFrame(mTmpFrame);
+ mTmpFrames.frame.left = l;
+ mTmpFrames.frame.right = l + w;
+ mTmpFrames.frame.top = t;
+ mTmpFrames.frame.bottom = t + h;
+ setFrame(mTmpFrames.frame);
mPendingBackDropFrame.set(mWinFrame);
maybeHandleWindowMove(mWinFrame);
@@ -7413,9 +7427,10 @@
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
- mTmpFrame, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame,
- mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
+ mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize, mBlastSurfaceControl);
+ mPendingDisplayCutout.set(mTmpFrames.displayCutout);
+ mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
if (mSurfaceControl.isValid()) {
if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
@@ -7441,9 +7456,9 @@
}
if (mTranslator != null) {
- mTranslator.translateRectInScreenToAppWinFrame(mTmpFrame);
+ mTranslator.translateRectInScreenToAppWinFrame(mTmpFrames.frame);
}
- setFrame(mTmpFrame);
+ setFrame(mTmpFrames.frame);
mInsetsController.onStateChanged(mTempInsets);
mInsetsController.onControlsChanged(mTempControls);
return relayoutResult;
@@ -7455,6 +7470,14 @@
}
/**
+ * Gets the current display size in which the window is being laid out, accounting for screen
+ * decorations around it.
+ */
+ void getDisplayFrame(Rect outFrame) {
+ outFrame.set(mTmpFrames.displayFrame);
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -7737,11 +7760,14 @@
}
@UnsupportedAppUsage
- private void dispatchResized(Rect frame, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
- MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {
+ private void dispatchResized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration mergedConfiguration, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId) {
+ final Rect frame = frames.frame;
+ final Rect contentInsets = frames.contentInsets;
+ final Rect visibleInsets = frames.visibleInsets;
+ final Rect stableInsets = frames.stableInsets;
+ final Rect backDropFrame = frames.backdropFrame;
if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString()
+ " contentInsets=" + contentInsets.toShortString()
+ " visibleInsets=" + visibleInsets.toShortString()
@@ -7768,14 +7794,9 @@
}
SomeArgs args = SomeArgs.obtain();
final boolean sameProcessCall = (Binder.getCallingPid() == android.os.Process.myPid());
- args.arg1 = sameProcessCall ? new Rect(frame) : frame;
- args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets;
- args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets;
- args.arg4 = sameProcessCall && mergedConfiguration != null
+ args.arg1 = sameProcessCall ? new ClientWindowFrames(frames) : frames;
+ args.arg2 = sameProcessCall && mergedConfiguration != null
? new MergedConfiguration(mergedConfiguration) : mergedConfiguration;
- args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
- args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame;
- args.arg9 = displayCutout.get(); // DisplayCutout is immutable.
args.argi1 = forceLayout ? 1 : 0;
args.argi2 = alwaysConsumeSystemBars ? 1 : 0;
args.argi3 = displayId;
@@ -9069,17 +9090,13 @@
}
@Override
- public void resized(Rect frame, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
- MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {
+ public void resized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration mergedConfiguration, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
- viewAncestor.dispatchResized(frame, contentInsets,
- visibleInsets, stableInsets, reportDraw, mergedConfiguration,
- backDropFrame, forceLayout, alwaysConsumeSystemBars, displayId,
- displayCutout);
+ viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, forceLayout,
+ alwaysConsumeSystemBars, displayId);
}
}
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 1a90035..e879bb4 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -32,8 +32,6 @@
/**
* Interface to control windows that generate insets.
- *
- * TODO(118118435): Needs more information and examples once the API is more baked.
*/
public interface WindowInsetsController {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 32ee290..0d62da6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2105,6 +2105,12 @@
public static final int PRIVATE_FLAG_TRUSTED_OVERLAY = 0x20000000;
/**
+ * Flag to indicate that the parent frame of a window should be inset by IME.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME = 0x40000000;
+
+ /**
* An internal annotation for flags that can be specified to {@link #softInputMode}.
*
* @hide
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 27fbfb6..5d53ad7 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -29,6 +29,7 @@
import android.app.ResourcesManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Region;
@@ -271,13 +272,14 @@
final boolean alwaysConsumeSystemBars = WindowManagerGlobal.getWindowManagerService()
.getWindowInsets(attrs, mContext.getDisplayId(), systemWindowInsets,
stableInsets, displayCutout, insetsState);
- final boolean isScreenRound =
- mContext.getResources().getConfiguration().isScreenRound();
+ final Configuration config = mContext.getResources().getConfiguration();
+ final boolean isScreenRound = config.isScreenRound();
+ final int windowingMode = config.windowConfiguration.getWindowingMode();
if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
return insetsState.calculateInsets(bounds, null /* ignoringVisibilityState*/,
isScreenRound, alwaysConsumeSystemBars, displayCutout.get(),
- SOFT_INPUT_ADJUST_NOTHING, attrs.flags,
- SYSTEM_UI_FLAG_VISIBLE, null /* typeSideMap */);
+ SOFT_INPUT_ADJUST_NOTHING, attrs.flags, SYSTEM_UI_FLAG_VISIBLE, attrs.type,
+ windowingMode, null /* typeSideMap */);
} else {
return new WindowInsets.Builder()
.setAlwaysConsumeSystemBars(alwaysConsumeSystemBars)
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 060311e..368918d 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -26,6 +26,7 @@
import android.os.RemoteException;
import android.util.Log;
import android.util.MergedConfiguration;
+import android.window.ClientWindowFrames;
import java.util.HashMap;
import java.util.Objects;
@@ -224,9 +225,7 @@
@Override
public int relayout(IWindow window, int seq, WindowManager.LayoutParams inAttrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
- Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
- Rect outStableInsets, Rect outBackdropFrame,
- DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
+ ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
SurfaceControl outBLASTSurfaceControl) {
@@ -255,7 +254,8 @@
t.hide(sc).apply();
outSurfaceControl.release();
}
- outFrame.set(0, 0, attrs.width, attrs.height);
+ outFrames.frame.set(0, 0, attrs.width, attrs.height);
+ outFrames.displayFrame.set(outFrames.frame);
mergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
@@ -292,11 +292,6 @@
}
@Override
- public void getDisplayFrame(android.view.IWindow window,
- android.graphics.Rect outDisplayFrame) {
- }
-
- @Override
public void finishDrawing(android.view.IWindow window,
android.view.SurfaceControl.Transaction postDrawTransaction) {
synchronized (this) {
diff --git a/core/java/android/view/accessibility/MagnificationAnimationCallback.java b/core/java/android/view/accessibility/MagnificationAnimationCallback.java
new file mode 100644
index 0000000..491f7fb
--- /dev/null
+++ b/core/java/android/view/accessibility/MagnificationAnimationCallback.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.view.accessibility;
+
+/**
+ * A callback for magnification animation result.
+ * @hide
+ */
+public interface MagnificationAnimationCallback {
+ /**
+ * Called when the animation is finished or interrupted during animating.
+ *
+ * @param success {@code true} if animating successfully with given spec or the spec did not
+ * change. Otherwise {@code false}
+ */
+ void onResult(boolean success);
+}
diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING
index df3024e..b5beac9 100644
--- a/core/java/android/widget/TEST_MAPPING
+++ b/core/java/android/widget/TEST_MAPPING
@@ -36,17 +36,6 @@
"name": "CtsAutoFillServiceTestCases",
"options": [
{
- "include-filter": "android.autofillservice.cts.AutofillValueTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- },
- {
- "name": "CtsAutoFillServiceTestCases",
- "options": [
- {
"include-filter": "android.autofillservice.cts.CheckoutActivityTest"
},
{
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java b/core/java/android/window/ClientWindowFrames.aidl
similarity index 61%
copy from packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
copy to core/java/android/window/ClientWindowFrames.aidl
index e65f19d..22bbea9 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
+++ b/core/java/android/window/ClientWindowFrames.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,17 +14,6 @@
* limitations under the License.
*/
-package com.android.keyguard.dagger;
+package android.window;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface ContainerView {
-}
+parcelable ClientWindowFrames;
diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java
new file mode 100644
index 0000000..0523e64
--- /dev/null
+++ b/core/java/android/window/ClientWindowFrames.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2020 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.window;
+
+import android.annotation.NonNull;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.DisplayCutout;
+
+/**
+ * The window frame container class used by client side for layout.
+ * @hide
+ */
+public class ClientWindowFrames implements Parcelable {
+ /** The actual window bounds. */
+ public final @NonNull Rect frame;
+
+ /**
+ * The container frame that is usually the same as display size. It may exclude the area of
+ * insets if the window layout parameter has specified fit-insets-sides.
+ */
+ public final @NonNull Rect displayFrame;
+
+ /** The background area while the window is resizing. */
+ public final @NonNull Rect backdropFrame;
+
+ /** The area cut from the display. */
+ public final @NonNull DisplayCutout.ParcelableWrapper displayCutout;
+
+ // TODO(b/149813814): Remove legacy insets.
+ public final Rect contentInsets;
+ public final Rect visibleInsets;
+ public final Rect stableInsets;
+
+ public ClientWindowFrames() {
+ frame = new Rect();
+ displayFrame = new Rect();
+ backdropFrame = new Rect();
+ displayCutout = new DisplayCutout.ParcelableWrapper();
+ contentInsets = new Rect();
+ visibleInsets = new Rect();
+ stableInsets = new Rect();
+ }
+
+ public ClientWindowFrames(ClientWindowFrames other) {
+ frame = new Rect(other.frame);
+ displayFrame = new Rect(other.displayFrame);
+ backdropFrame = new Rect(other.backdropFrame);
+ displayCutout = new DisplayCutout.ParcelableWrapper(other.displayCutout.get());
+ contentInsets = new Rect(other.contentInsets);
+ visibleInsets = new Rect(other.visibleInsets);
+ stableInsets = new Rect(other.stableInsets);
+ }
+
+ private ClientWindowFrames(Parcel in) {
+ frame = Rect.CREATOR.createFromParcel(in);
+ displayFrame = Rect.CREATOR.createFromParcel(in);
+ backdropFrame = Rect.CREATOR.createFromParcel(in);
+ displayCutout = DisplayCutout.ParcelableWrapper.CREATOR.createFromParcel(in);
+ contentInsets = Rect.CREATOR.createFromParcel(in);
+ visibleInsets = Rect.CREATOR.createFromParcel(in);
+ stableInsets = Rect.CREATOR.createFromParcel(in);
+ }
+
+ /** Needed for AIDL out parameters. */
+ public void readFromParcel(Parcel in) {
+ frame.set(Rect.CREATOR.createFromParcel(in));
+ displayFrame.set(Rect.CREATOR.createFromParcel(in));
+ backdropFrame.set(Rect.CREATOR.createFromParcel(in));
+ displayCutout.set(DisplayCutout.ParcelableWrapper.CREATOR.createFromParcel(in));
+ contentInsets.set(Rect.CREATOR.createFromParcel(in));
+ visibleInsets.set(Rect.CREATOR.createFromParcel(in));
+ stableInsets.set(Rect.CREATOR.createFromParcel(in));
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ frame.writeToParcel(dest, flags);
+ displayFrame.writeToParcel(dest, flags);
+ backdropFrame.writeToParcel(dest, flags);
+ displayCutout.writeToParcel(dest, flags);
+ contentInsets.writeToParcel(dest, flags);
+ visibleInsets.writeToParcel(dest, flags);
+ stableInsets.writeToParcel(dest, flags);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(32);
+ return "ClientWindowFrames{frame=" + frame.toShortString(sb)
+ + " display=" + displayFrame.toShortString(sb)
+ + " backdrop=" + backdropFrame.toShortString(sb)
+ + " cutout=" + displayCutout + "}";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<ClientWindowFrames> CREATOR = new Creator<ClientWindowFrames>() {
+ public ClientWindowFrames createFromParcel(Parcel in) {
+ return new ClientWindowFrames(in);
+ }
+
+ public ClientWindowFrames[] newArray(int size) {
+ return new ClientWindowFrames[size];
+ }
+ };
+}
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index f035d36..78fa303 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -20,7 +20,6 @@
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.os.RemoteException;
-import android.util.Singleton;
import android.view.SurfaceControl;
/**
@@ -135,22 +134,12 @@
}
};
- private static IDisplayAreaOrganizerController getController() {
- return IDisplayAreaOrganizerControllerSingleton.get();
+ private IDisplayAreaOrganizerController getController() {
+ try {
+ return getWindowOrganizerController().getDisplayAreaOrganizerController();
+ } catch (RemoteException e) {
+ return null;
+ }
}
- private static final Singleton<IDisplayAreaOrganizerController>
- IDisplayAreaOrganizerControllerSingleton =
- new Singleton<IDisplayAreaOrganizerController>() {
- @Override
- protected IDisplayAreaOrganizerController create() {
- try {
- return getWindowOrganizerController()
- .getDisplayAreaOrganizerController();
- } catch (RemoteException e) {
- return null;
- }
- }
- };
-
}
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index 38fb023..d8f2bb2 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -23,9 +23,10 @@
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.os.RemoteException;
-import android.util.Singleton;
import android.view.SurfaceControl;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.List;
/**
@@ -35,13 +36,25 @@
@TestApi
public class TaskOrganizer extends WindowOrganizer {
+ private ITaskOrganizerController mTaskOrganizerController;
+
+ public TaskOrganizer() {
+ mTaskOrganizerController = getController();
+ }
+
+ /** @hide */
+ @VisibleForTesting
+ public TaskOrganizer(ITaskOrganizerController taskOrganizerController) {
+ mTaskOrganizerController = taskOrganizerController;
+ }
+
/**
* Register a TaskOrganizer to manage tasks as they enter a supported windowing mode.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public final void registerOrganizer() {
try {
- getController().registerTaskOrganizer(mInterface);
+ mTaskOrganizerController.registerTaskOrganizer(mInterface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -51,7 +64,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public final void unregisterOrganizer() {
try {
- getController().unregisterTaskOrganizer(mInterface);
+ mTaskOrganizerController.unregisterTaskOrganizer(mInterface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -78,9 +91,9 @@
/** Creates a persistent root task in WM for a particular windowing-mode. */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
- public static ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) {
+ public ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) {
try {
- return getController().createRootTask(displayId, windowingMode);
+ return mTaskOrganizerController.createRootTask(displayId, windowingMode);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -88,9 +101,9 @@
/** Deletes a persistent root task in WM */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public static boolean deleteRootTask(@NonNull WindowContainerToken task) {
+ public boolean deleteRootTask(@NonNull WindowContainerToken task) {
try {
- return getController().deleteRootTask(task);
+ return mTaskOrganizerController.deleteRootTask(task);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -99,10 +112,10 @@
/** Gets direct child tasks (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
- public static List<ActivityManager.RunningTaskInfo> getChildTasks(
+ public List<ActivityManager.RunningTaskInfo> getChildTasks(
@NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
try {
- return getController().getChildTasks(parent, activityTypes);
+ return mTaskOrganizerController.getChildTasks(parent, activityTypes);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -111,10 +124,10 @@
/** Gets all root tasks on a display (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
- public static List<ActivityManager.RunningTaskInfo> getRootTasks(
+ public List<ActivityManager.RunningTaskInfo> getRootTasks(
int displayId, @NonNull int[] activityTypes) {
try {
- return getController().getRootTasks(displayId, activityTypes);
+ return mTaskOrganizerController.getRootTasks(displayId, activityTypes);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -123,9 +136,9 @@
/** Get the root task which contains the current ime target */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
@Nullable
- public static WindowContainerToken getImeTarget(int display) {
+ public WindowContainerToken getImeTarget(int display) {
try {
- return getController().getImeTarget(display);
+ return mTaskOrganizerController.getImeTarget(display);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -136,9 +149,9 @@
* root and thus new tasks just end up directly on the display.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public static void setLaunchRoot(int displayId, @NonNull WindowContainerToken root) {
+ public void setLaunchRoot(int displayId, @NonNull WindowContainerToken root) {
try {
- getController().setLaunchRoot(displayId, root);
+ mTaskOrganizerController.setLaunchRoot(displayId, root);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -152,7 +165,7 @@
public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task,
boolean interceptBackPressed) {
try {
- getController().setInterceptBackPressedOnTaskRoot(task, interceptBackPressed);
+ mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(task, interceptBackPressed);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -181,19 +194,11 @@
}
};
- private static ITaskOrganizerController getController() {
- return ITaskOrganizerControllerSingleton.get();
+ private ITaskOrganizerController getController() {
+ try {
+ return getWindowOrganizerController().getTaskOrganizerController();
+ } catch (RemoteException e) {
+ return null;
+ }
}
-
- private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
- new Singleton<ITaskOrganizerController>() {
- @Override
- protected ITaskOrganizerController create() {
- try {
- return getWindowOrganizerController().getTaskOrganizerController();
- } catch (RemoteException e) {
- return null;
- }
- }
- };
}
diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java
index eb9dfed..1e293df 100644
--- a/core/java/android/window/TaskOrganizerTaskEmbedder.java
+++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java
@@ -109,7 +109,7 @@
}
WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setHidden(mTaskToken, false /* hidden */);
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
// TODO(b/151449487): Only call callback once we enable synchronization
if (mListener != null) {
mListener.onTaskVisibilityChanged(getTaskId(), true);
@@ -133,7 +133,7 @@
}
WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setHidden(mTaskToken, true /* hidden */);
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
// TODO(b/151449487): Only call callback once we enable synchronization
if (mListener != null) {
mListener.onTaskVisibilityChanged(getTaskId(), false);
@@ -165,7 +165,7 @@
WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mTaskToken, screenBounds);
// TODO(b/151449487): Enable synchronization
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
}
/**
diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java
index 9013da3..db27d62 100644
--- a/core/java/android/window/VirtualDisplayTaskEmbedder.java
+++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java
@@ -25,6 +25,7 @@
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.ActivityView;
import android.app.TaskStackListener;
import android.content.ComponentName;
@@ -357,40 +358,40 @@
private class TaskStackListenerImpl extends TaskStackListener {
@Override
- public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
+ public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo runningTaskInfo)
throws RemoteException {
if (!isInitialized()) {
return;
}
- if (taskInfo.displayId != getDisplayId()) {
+ if (runningTaskInfo.displayId != getDisplayId()) {
return;
}
- ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
- if (stackInfo == null) {
+ RootTaskInfo taskInfo = getTopMostRootTaskInfo();
+ if (taskInfo == null) {
return;
}
// Found the topmost stack on target display. Now check if the topmost task's
// description changed.
- if (taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+ if (runningTaskInfo.taskId == taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]) {
mHost.post(()-> mHost.onTaskBackgroundColorChanged(VirtualDisplayTaskEmbedder.this,
- taskInfo.taskDescription.getBackgroundColor()));
+ runningTaskInfo.taskDescription.getBackgroundColor()));
}
}
@Override
- public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
+ public void onTaskMovedToFront(ActivityManager.RunningTaskInfo runningTaskInfo)
throws RemoteException {
if (!isInitialized() || mListener == null
- || taskInfo.displayId != getDisplayId()) {
+ || runningTaskInfo.displayId != getDisplayId()) {
return;
}
- ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
- // if StackInfo was null or unrelated to the "move to front" then there's no use
+ RootTaskInfo taskInfo = getTopMostRootTaskInfo();
+ // if TaskInfo was null or unrelated to the "move to front" then there's no use
// notifying the callback
- if (stackInfo != null
- && taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
- mListener.onTaskMovedToFront(taskInfo.taskId);
+ if (taskInfo != null && runningTaskInfo.taskId == taskInfo.childTaskIds[
+ taskInfo.childTaskIds.length - 1]) {
+ mListener.onTaskMovedToFront(runningTaskInfo.taskId);
}
}
@@ -400,11 +401,11 @@
return;
}
- ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
- // if StackInfo was null or unrelated to the task creation then there's no use
+ RootTaskInfo taskInfo = getTopMostRootTaskInfo();
+ // if TaskInfo was null or unrelated to the task creation then there's no use
// notifying the callback
- if (stackInfo != null
- && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+ if (taskInfo != null
+ && taskId == taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]) {
mListener.onTaskCreated(taskId, componentName);
}
}
@@ -420,16 +421,16 @@
mListener.onTaskRemovalStarted(taskInfo.taskId);
}
- private ActivityManager.StackInfo getTopMostStackInfo() throws RemoteException {
+ private RootTaskInfo getTopMostRootTaskInfo() throws RemoteException {
// Find the topmost task on our virtual display - it will define the background
// color of the surface view during resizing.
final int displayId = getDisplayId();
- final List<ActivityManager.StackInfo> stackInfoList =
- mActivityTaskManager.getAllStackInfosOnDisplay(displayId);
- if (stackInfoList.isEmpty()) {
+ final List<RootTaskInfo> taskInfoList =
+ mActivityTaskManager.getAllRootTaskInfosOnDisplay(displayId);
+ if (taskInfoList.isEmpty()) {
return null;
}
- return stackInfoList.get(0);
+ return taskInfoList.get(0);
}
}
}
diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java
index ff40dda..97a97d9 100644
--- a/core/java/android/window/WindowOrganizer.java
+++ b/core/java/android/window/WindowOrganizer.java
@@ -38,7 +38,7 @@
* @param t The transaction to apply.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public static void applyTransaction(@NonNull WindowContainerTransaction t) {
+ public void applyTransaction(@NonNull WindowContainerTransaction t) {
try {
getWindowOrganizerController().applyTransaction(t);
} catch (RemoteException e) {
@@ -74,7 +74,7 @@
*/
@Nullable
@RequiresPermission(android.Manifest.permission.READ_FRAME_BUFFER)
- public static SurfaceControl takeScreenshot(@NonNull WindowContainerToken token) {
+ public SurfaceControl takeScreenshot(@NonNull WindowContainerToken token) {
try {
SurfaceControl surfaceControl = new SurfaceControl();
if (getWindowOrganizerController().takeScreenshot(token, surfaceControl)) {
@@ -88,7 +88,7 @@
}
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- static IWindowOrganizerController getWindowOrganizerController() {
+ IWindowOrganizerController getWindowOrganizerController() {
return IWindowOrganizerControllerSingleton.get();
}
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index da26930..8b4fddb 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -390,9 +390,9 @@
public static final String CHOOSER_TARGET_RANKING_ENABLED = "chooser_target_ranking_enabled";
/**
- * (boolean) Whether to enable user-drag resizing for PIP.
+ * (boolean) Whether to enable pinch resizing for PIP.
*/
- public static final String PIP_USER_RESIZE = "pip_user_resize";
+ public static final String PIP_PINCH_RESIZE = "pip_pinch_resize";
/**
* (float) Bottom height in DP for Back Gesture.
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index 3b5cf48..b38f623e 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -296,7 +296,7 @@
if (p.getOverlayTarget() != null && isSystem) {
overlays.add(new ParsedOverlayInfo(p.getPackageName(), p.getOverlayTarget(),
p.getTargetSdkVersion(), p.isOverlayIsStatic(), p.getOverlayPriority(),
- new File(p.getBaseCodePath())));
+ new File(p.getBaseApkPath())));
}
});
return overlays;
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index e5c8450..dd1978e 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -45,8 +45,8 @@
private long mBeginTime = UNKNOWN_TIMESTAMP;
private long mEndTime = UNKNOWN_TIMESTAMP;
private boolean mShouldTriggerTrace;
- private long mTotalFramesCount = 0;
- private long mMissedFramesCount = 0;
+ private int mTotalFramesCount = 0;
+ private int mMissedFramesCount = 0;
private long mMaxFrameTimeNanos = 0;
private Session mSession;
@@ -124,6 +124,15 @@
if (mEndTime != UNKNOWN_TIMESTAMP && vsyncTimestamp > mEndTime) {
// The tracing has been ended, remove the observer, see if need to trigger perfetto.
mRendererWrapper.removeObserver(mObserver);
+
+ // Log the frame stats as counters to make them easily accessible in traces.
+ Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#missedFrames",
+ mMissedFramesCount);
+ Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#totalFrames",
+ mTotalFramesCount);
+ Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxFrameTimeMillis",
+ (int) (mMaxFrameTimeNanos / 1_000_000));
+
// Trigger perfetto if necessary.
if (mShouldTriggerTrace) {
if (DEBUG) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8498151..41bf74c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -256,7 +256,7 @@
@GuardedBy("this")
private long mNumBatchedSingleUidCpuTimeReads;
@GuardedBy("this")
- private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis();
+ private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis();
@GuardedBy("this")
private int mNumUidsRemoved;
@GuardedBy("this")
@@ -290,7 +290,7 @@
public final class UidToRemove {
int startUid;
int endUid;
- long timeAddedInQueue;
+ long mTimeAddedInQueueMs;
/** Remove just one UID */
public UidToRemove(int uid, long timestamp) {
@@ -301,7 +301,7 @@
public UidToRemove(int startUid, int endUid, long timestamp) {
this.startUid = startUid;
this.endUid = endUid;
- timeAddedInQueue = timestamp;
+ mTimeAddedInQueueMs = timestamp;
}
void remove() {
@@ -382,9 +382,9 @@
}
boolean changed = setChargingLocked(true);
if (changed) {
- final long uptime = mClocks.uptimeMillis();
- final long elapsedRealtime = mClocks.elapsedRealtime();
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ final long uptimeMs = mClocks.uptimeMillis();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
}
@@ -502,9 +502,9 @@
}
public void clearPendingRemovedUids() {
- long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS;
+ long cutOffTimeMs = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS;
while (!mPendingRemovedUids.isEmpty()
- && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) {
+ && mPendingRemovedUids.peek().mTimeAddedInQueueMs < cutOffTimeMs) {
mPendingRemovedUids.poll().remove();
}
}
@@ -572,7 +572,7 @@
}
@VisibleForTesting
- public long[] addCpuTimes(long[] timesA, long[] timesB) {
+ public static long[] addCpuTimes(long[] timesA, long[] timesB) {
if (timesA != null && timesB != null) {
for (int i = timesA.length - 1; i >= 0; --i) {
timesA[i] += timesB[i];
@@ -700,7 +700,7 @@
final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
- long mHistoryBaseTime;
+ long mHistoryBaseTimeMs;
protected boolean mHaveBatteryLevel = false;
protected boolean mRecordingHistory = false;
int mNumHistoryItems;
@@ -719,9 +719,9 @@
int mHistoryBufferLastPos = -1;
int mActiveHistoryStates = 0xffffffff;
int mActiveHistoryStates2 = 0xffffffff;
- long mLastHistoryElapsedRealtime = 0;
- long mTrackRunningHistoryElapsedRealtime = 0;
- long mTrackRunningHistoryUptime = 0;
+ long mLastHistoryElapsedRealtimeMs = 0;
+ long mTrackRunningHistoryElapsedRealtimeMs = 0;
+ long mTrackRunningHistoryUptimeMs = 0;
final BatteryStatsHistory mBatteryStatsHistory;
@@ -742,28 +742,28 @@
/**
* Total time (in milliseconds) spent executing in user code.
*/
- long mLastStepCpuUserTime;
- long mCurStepCpuUserTime;
+ long mLastStepCpuUserTimeMs;
+ long mCurStepCpuUserTimeMs;
/**
* Total time (in milliseconds) spent executing in kernel code.
*/
- long mLastStepCpuSystemTime;
- long mCurStepCpuSystemTime;
+ long mLastStepCpuSystemTimeMs;
+ long mCurStepCpuSystemTimeMs;
/**
* Times from /proc/stat (but measured in milliseconds).
*/
- long mLastStepStatUserTime;
- long mLastStepStatSystemTime;
- long mLastStepStatIOWaitTime;
- long mLastStepStatIrqTime;
- long mLastStepStatSoftIrqTime;
- long mLastStepStatIdleTime;
- long mCurStepStatUserTime;
- long mCurStepStatSystemTime;
- long mCurStepStatIOWaitTime;
- long mCurStepStatIrqTime;
- long mCurStepStatSoftIrqTime;
- long mCurStepStatIdleTime;
+ long mLastStepStatUserTimeMs;
+ long mLastStepStatSystemTimeMs;
+ long mLastStepStatIOWaitTimeMs;
+ long mLastStepStatIrqTimeMs;
+ long mLastStepStatSoftIrqTimeMs;
+ long mLastStepStatIdleTimeMs;
+ long mCurStepStatUserTimeMs;
+ long mCurStepStatSystemTimeMs;
+ long mCurStepStatIOWaitTimeMs;
+ long mCurStepStatIrqTimeMs;
+ long mCurStepStatSoftIrqTimeMs;
+ long mCurStepStatIdleTimeMs;
private HistoryItem mHistoryIterator;
private boolean mReadOverflow;
@@ -771,14 +771,14 @@
int mStartCount;
- long mStartClockTime;
+ long mStartClockTimeMs;
String mStartPlatformVersion;
String mEndPlatformVersion;
- long mUptime;
- long mUptimeStart;
- long mRealtime;
- long mRealtimeStart;
+ long mUptimeUs;
+ long mUptimeStartUs;
+ long mRealtimeUs;
+ long mRealtimeStartUs;
int mWakeLockNesting;
boolean mWakeLockImportant;
@@ -810,9 +810,9 @@
StopwatchTimer mDeviceLightIdlingTimer;
int mDeviceIdleMode;
- long mLastIdleTimeStart;
- long mLongestLightIdleTime;
- long mLongestFullIdleTime;
+ long mLastIdleTimeStartMs;
+ long mLongestLightIdleTimeMs;
+ long mLongestFullIdleTimeMs;
StopwatchTimer mDeviceIdleModeLightTimer;
StopwatchTimer mDeviceIdleModeFullTimer;
@@ -921,7 +921,7 @@
protected StopwatchTimer mBluetoothScanTimer;
int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
- long mMobileRadioActiveStartTime;
+ long mMobileRadioActiveStartTimeMs;
StopwatchTimer mMobileRadioActiveTimer;
StopwatchTimer mMobileRadioActivePerAppTimer;
LongSamplingCounter mMobileRadioActiveAdjustedTime;
@@ -989,13 +989,13 @@
static final int MAX_DAILY_ITEMS = 10;
- long mDailyStartTime = 0;
- long mNextMinDailyDeadline = 0;
- long mNextMaxDailyDeadline = 0;
+ long mDailyStartTimeMs = 0;
+ long mNextMinDailyDeadlineMs = 0;
+ long mNextMaxDailyDeadlineMs = 0;
final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
- long mLastWriteTime = 0; // Milliseconds
+ long mLastWriteTimeMs = 0; // Milliseconds
private int mPhoneServiceState = -1;
private int mPhoneServiceStateRaw = -1;
@@ -1131,8 +1131,8 @@
* TimeBase observer.
*/
public interface TimeBaseObs {
- void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
- void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
+ void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs);
+ void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs);
/**
* Reset the observer's state, returns true if the timer/counter is inactive
@@ -1140,7 +1140,18 @@
* @param detachIfReset detach if true, no-op if false.
* @return Returns true if the timer/counter is inactive and can be destroyed.
*/
- boolean reset(boolean detachIfReset);
+ default boolean reset(boolean detachIfReset) {
+ return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000);
+ }
+
+ /**
+ * @see #reset(boolean)
+ * @param detachIfReset detach if true, no-op if false.
+ * @param elapsedRealtimeUs the timestamp when this reset is actually reequested
+ * @return Returns true if the timer/counter is inactive and can be destroyed.
+ */
+ boolean reset(boolean detachIfReset, long elapsedRealtimeUs);
+
/**
* Detach the observer from TimeBase.
*/
@@ -1150,17 +1161,19 @@
// methods are protected not private to be VisibleForTesting
public static class TimeBase {
protected final Collection<TimeBaseObs> mObservers;
- protected long mUptime;
- protected long mRealtime;
+
+ // All below time metrics are in microseconds.
+ protected long mUptimeUs;
+ protected long mRealtimeUs;
protected boolean mRunning;
- protected long mPastUptime;
- protected long mUptimeStart;
- protected long mPastRealtime;
- protected long mRealtimeStart;
- protected long mUnpluggedUptime;
- protected long mUnpluggedRealtime;
+ protected long mPastUptimeUs;
+ protected long mUptimeStartUs;
+ protected long mPastRealtimeUs;
+ protected long mRealtimeStartUs;
+ protected long mUnpluggedUptimeUs;
+ protected long mUnpluggedRealtimeUs;
public void dump(PrintWriter pw, String prefix) {
StringBuilder sb = new StringBuilder(128);
@@ -1168,26 +1181,26 @@
sb.setLength(0);
sb.append(prefix);
sb.append("mUptime=");
- formatTimeMs(sb, mUptime / 1000);
+ formatTimeMs(sb, mUptimeUs / 1000);
pw.println(sb.toString());
sb.setLength(0);
sb.append(prefix);
sb.append("mRealtime=");
- formatTimeMs(sb, mRealtime / 1000);
+ formatTimeMs(sb, mRealtimeUs / 1000);
pw.println(sb.toString());
sb.setLength(0);
sb.append(prefix);
sb.append("mPastUptime=");
- formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
- formatTimeMs(sb, mUptimeStart / 1000);
- sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
+ formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart=");
+ formatTimeMs(sb, mUptimeStartUs / 1000);
+ sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000);
pw.println(sb.toString());
sb.setLength(0);
sb.append(prefix);
sb.append("mPastRealtime=");
- formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
- formatTimeMs(sb, mRealtimeStart / 1000);
- sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
+ formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart=");
+ formatTimeMs(sb, mRealtimeStartUs / 1000);
+ sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000);
pw.println(sb.toString());
}
/**
@@ -1219,94 +1232,96 @@
return mObservers.contains(observer);
}
- public void init(long uptime, long realtime) {
- mRealtime = 0;
- mUptime = 0;
- mPastUptime = 0;
- mPastRealtime = 0;
- mUptimeStart = uptime;
- mRealtimeStart = realtime;
- mUnpluggedUptime = getUptime(mUptimeStart);
- mUnpluggedRealtime = getRealtime(mRealtimeStart);
+ public void init(long uptimeUs, long elapsedRealtimeUs) {
+ mRealtimeUs = 0;
+ mUptimeUs = 0;
+ mPastUptimeUs = 0;
+ mPastRealtimeUs = 0;
+ mUptimeStartUs = uptimeUs;
+ mRealtimeStartUs = elapsedRealtimeUs;
+ mUnpluggedUptimeUs = getUptime(mUptimeStartUs);
+ mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs);
}
- public void reset(long uptime, long realtime) {
+ public void reset(long uptimeUs, long elapsedRealtimeUs) {
if (!mRunning) {
- mPastUptime = 0;
- mPastRealtime = 0;
+ mPastUptimeUs = 0;
+ mPastRealtimeUs = 0;
} else {
- mUptimeStart = uptime;
- mRealtimeStart = realtime;
- // TODO: Since mUptimeStart was just reset and we are running, getUptime will
- // just return mPastUptime. Also, are we sure we don't want to reset that?
- mUnpluggedUptime = getUptime(uptime);
+ mUptimeStartUs = uptimeUs;
+ mRealtimeStartUs = elapsedRealtimeUs;
+ // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will
+ // just return mPastUptimeUs. Also, are we sure we don't want to reset that?
+ mUnpluggedUptimeUs = getUptime(uptimeUs);
// TODO: likewise.
- mUnpluggedRealtime = getRealtime(realtime);
+ mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs);
}
}
- public long computeUptime(long curTime, int which) {
- return mUptime + getUptime(curTime);
+ public long computeUptime(long curTimeUs, int which) {
+ return mUptimeUs + getUptime(curTimeUs);
}
- public long computeRealtime(long curTime, int which) {
- return mRealtime + getRealtime(curTime);
+ public long computeRealtime(long curTimeUs, int which) {
+ return mRealtimeUs + getRealtime(curTimeUs);
}
- public long getUptime(long curTime) {
- long time = mPastUptime;
+ public long getUptime(long curTimeUs) {
+ long time = mPastUptimeUs;
if (mRunning) {
- time += curTime - mUptimeStart;
+ time += curTimeUs - mUptimeStartUs;
}
return time;
}
- public long getRealtime(long curTime) {
- long time = mPastRealtime;
+ public long getRealtime(long curTimeUs) {
+ long time = mPastRealtimeUs;
if (mRunning) {
- time += curTime - mRealtimeStart;
+ time += curTimeUs - mRealtimeStartUs;
}
return time;
}
public long getUptimeStart() {
- return mUptimeStart;
+ return mUptimeStartUs;
}
public long getRealtimeStart() {
- return mRealtimeStart;
+ return mRealtimeStartUs;
}
public boolean isRunning() {
return mRunning;
}
- public boolean setRunning(boolean running, long uptime, long realtime) {
+ public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) {
if (mRunning != running) {
mRunning = running;
if (running) {
- mUptimeStart = uptime;
- mRealtimeStart = realtime;
- long batteryUptime = mUnpluggedUptime = getUptime(uptime);
- long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
+ mUptimeStartUs = uptimeUs;
+ mRealtimeStartUs = elapsedRealtimeUs;
+ long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs);
+ long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs);
// Normally we do not use Iterator in framework code to avoid alloc/dealloc
// Iterator object, here is an exception because mObservers' type is Collection
// instead of list.
final Iterator<TimeBaseObs> iter = mObservers.iterator();
while (iter.hasNext()) {
- iter.next().onTimeStarted(realtime, batteryUptime, batteryRealtime);
+ iter.next().onTimeStarted(
+ elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs);
}
} else {
- mPastUptime += uptime - mUptimeStart;
- mPastRealtime += realtime - mRealtimeStart;
- long batteryUptime = getUptime(uptime);
- long batteryRealtime = getRealtime(realtime);
+ mPastUptimeUs += uptimeUs - mUptimeStartUs;
+ mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs;
+ long batteryUptimeUs = getUptime(uptimeUs);
+ long batteryRealtimeUs = getRealtime(elapsedRealtimeUs);
// Normally we do not use Iterator in framework code to avoid alloc/dealloc
// Iterator object, here is an exception because mObservers' type is Collection
// instead of list.
final Iterator<TimeBaseObs> iter = mObservers.iterator();
while (iter.hasNext()) {
- iter.next().onTimeStopped(realtime, batteryUptime, batteryRealtime);
+ iter.next().onTimeStopped(
+ elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs);
}
}
return true;
@@ -1315,38 +1330,38 @@
}
public void readSummaryFromParcel(Parcel in) {
- mUptime = in.readLong();
- mRealtime = in.readLong();
+ mUptimeUs = in.readLong();
+ mRealtimeUs = in.readLong();
}
- public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
- out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
- out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
+ public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
+ out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED));
+ out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED));
}
public void readFromParcel(Parcel in) {
mRunning = false;
- mUptime = in.readLong();
- mPastUptime = in.readLong();
- mUptimeStart = in.readLong();
- mRealtime = in.readLong();
- mPastRealtime = in.readLong();
- mRealtimeStart = in.readLong();
- mUnpluggedUptime = in.readLong();
- mUnpluggedRealtime = in.readLong();
+ mUptimeUs = in.readLong();
+ mPastUptimeUs = in.readLong();
+ mUptimeStartUs = in.readLong();
+ mRealtimeUs = in.readLong();
+ mPastRealtimeUs = in.readLong();
+ mRealtimeStartUs = in.readLong();
+ mUnpluggedUptimeUs = in.readLong();
+ mUnpluggedRealtimeUs = in.readLong();
}
- public void writeToParcel(Parcel out, long uptime, long realtime) {
- final long runningUptime = getUptime(uptime);
- final long runningRealtime = getRealtime(realtime);
- out.writeLong(mUptime);
+ public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
+ final long runningUptime = getUptime(uptimeUs);
+ final long runningRealtime = getRealtime(elapsedRealtimeUs);
+ out.writeLong(mUptimeUs);
out.writeLong(runningUptime);
- out.writeLong(mUptimeStart);
- out.writeLong(mRealtime);
+ out.writeLong(mUptimeStartUs);
+ out.writeLong(mRealtimeUs);
out.writeLong(runningRealtime);
- out.writeLong(mRealtimeStart);
- out.writeLong(mUnpluggedUptime);
- out.writeLong(mUnpluggedRealtime);
+ out.writeLong(mRealtimeStartUs);
+ out.writeLong(mUnpluggedUptimeUs);
+ out.writeLong(mUnpluggedRealtimeUs);
}
}
@@ -1374,11 +1389,11 @@
}
@Override
- public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
}
@Override
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
}
/**
@@ -1436,7 +1451,7 @@
* Clear state of this counter.
*/
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) {
mCount.set(0);
if (detachIfReset) {
detach();
@@ -1481,11 +1496,11 @@
}
@Override
- public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
+ public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) {
}
@Override
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
}
@Override
@@ -1524,7 +1539,7 @@
* Clear state of this counter.
*/
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) {
if (mCounts != null) {
Arrays.fill(mCounts, 0);
}
@@ -1608,11 +1623,11 @@
}
@Override
- public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
}
@Override
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
}
public long getCountLocked(int which) {
@@ -1638,7 +1653,7 @@
* Clear state of this counter.
*/
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) {
mCount = 0;
if (detachIfReset) {
detach();
@@ -1678,13 +1693,13 @@
* boot, to the last time something interesting happened in the
* current run.
*/
- protected long mTotalTime;
+ protected long mTotalTimeUs;
/**
* The total time this timer has been running until the latest mark has been set.
- * Subtract this from mTotalTime to get the time spent running since the mark was set.
+ * Subtract this from mTotalTimeUs to get the time spent running since the mark was set.
*/
- protected long mTimeBeforeMark;
+ protected long mTimeBeforeMarkUs;
/**
* Constructs from a parcel.
@@ -1698,10 +1713,10 @@
mTimeBase = timeBase;
mCount = in.readInt();
- mTotalTime = in.readLong();
- mTimeBeforeMark = in.readLong();
+ mTotalTimeUs = in.readLong();
+ mTimeBeforeMarkUs = in.readLong();
timeBase.add(this);
- if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
+ if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs);
}
public Timer(Clocks clocks, int type, TimeBase timeBase) {
@@ -1714,14 +1729,17 @@
public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
if (DEBUG) {
Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
- + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
+ + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs),
+ elapsedRealtimeUs));
}
out.writeInt(computeCurrentCountLocked());
- out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
- out.writeLong(mTimeBeforeMark);
+ out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs),
+ elapsedRealtimeUs));
+ out.writeLong(mTimeBeforeMarkUs);
}
- protected abstract long computeRunTimeLocked(long curBatteryRealtime);
+ protected abstract long computeRunTimeLocked(long curBatteryRealtime,
+ long elapsedRealtimeUs);
protected abstract int computeCurrentCountLocked();
@@ -1731,7 +1749,12 @@
*/
@Override
public boolean reset(boolean detachIfReset) {
- mTotalTime = mTimeBeforeMark = 0;
+ return reset(detachIfReset, mClocks.elapsedRealtime() * 1000);
+ }
+
+ @Override
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) {
+ mTotalTimeUs = mTimeBeforeMarkUs = 0;
mCount = 0;
if (detachIfReset) {
detach();
@@ -1745,19 +1768,20 @@
}
@Override
- public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
+ public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs,
+ long baseRealtimeUs) {
}
@Override
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
if (DEBUG && mType < 0) {
- Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
- + " old mTotalTime=" + mTotalTime);
+ Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs
+ + " old mTotalTime=" + mTotalTimeUs);
}
- mTotalTime = computeRunTimeLocked(baseRealtime);
+ mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs);
mCount = computeCurrentCountLocked();
if (DEBUG && mType < 0) {
- Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTime);
+ Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs);
}
}
@@ -1780,7 +1804,8 @@
@Override
@UnsupportedAppUsage
public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
- return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
+ return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs),
+ elapsedRealtimeUs);
}
@Override
@@ -1791,29 +1816,31 @@
@Override
public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
- long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
- return val - mTimeBeforeMark;
+ long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs),
+ elapsedRealtimeUs);
+ return val - mTimeBeforeMarkUs;
}
@Override
public void logState(Printer pw, String prefix) {
pw.println(prefix + "mCount=" + mCount);
- pw.println(prefix + "mTotalTime=" + mTotalTime);
+ pw.println(prefix + "mTotalTime=" + mTotalTimeUs);
}
public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
- long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
- out.writeLong(runTime);
+ long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs),
+ elapsedRealtimeUs);
+ out.writeLong(runTimeUs);
out.writeInt(computeCurrentCountLocked());
}
public void readSummaryFromParcelLocked(Parcel in) {
// Multiply by 1000 for backwards compatibility
- mTotalTime = in.readLong();
+ mTotalTimeUs = in.readLong();
mCount = in.readInt();
// When reading the summary, we set the mark to be the latest information.
- mTimeBeforeMark = mTotalTime;
+ mTimeBeforeMarkUs = mTotalTimeUs;
}
}
@@ -1843,14 +1870,14 @@
/**
* The most recent reported total_time from /proc/wakelocks.
*/
- long mCurrentReportedTotalTime;
+ long mCurrentReportedTotalTimeUs;
/**
* The reported total_time from /proc/wakelocks when unplug() was last
* called.
*/
- long mUnpluggedReportedTotalTime;
+ long mUnpluggedReportedTotalTimeUs;
/**
* Whether we are currently in a discharge cycle.
@@ -1872,8 +1899,8 @@
super(clocks, 0, timeBase, in);
mCurrentReportedCount = in.readInt();
mUnpluggedReportedCount = in.readInt();
- mCurrentReportedTotalTime = in.readLong();
- mUnpluggedReportedTotalTime = in.readLong();
+ mCurrentReportedTotalTimeUs = in.readLong();
+ mUnpluggedReportedTotalTimeUs = in.readLong();
mTrackingReportedValues = in.readInt() == 1;
mTimeBaseRunning = timeBase.isRunning();
}
@@ -1890,9 +1917,16 @@
* be less than the values used for a previous invocation.
*/
public void endSample() {
- mTotalTime = computeRunTimeLocked(0 /* unused by us */);
+ endSample(mClocks.elapsedRealtime() * 1000);
+ }
+
+ /**
+ * @see #endSample()
+ */
+ public void endSample(long elapsedRealtimeUs) {
+ mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs);
mCount = computeCurrentCountLocked();
- mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0;
+ mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0;
mUnpluggedReportedCount = mCurrentReportedCount = 0;
mTrackingReportedValues = false;
}
@@ -1911,26 +1945,33 @@
*
* If the values being recorded have been reset, the monotonically increasing requirement
* will be broken. In this case, {@link #endSample()} is automatically called and
- * the total value of totalTime and count are recorded, starting a new monotonically
+ * the total value of totalTimeUs and count are recorded, starting a new monotonically
* increasing sample.
*
- * @param totalTime total time of sample in microseconds.
+ * @param totalTimeUs total time of sample in microseconds.
* @param count total number of times the event being sampled occurred.
*/
- public void update(long totalTime, int count) {
+ public void updated(long totalTimeUs, int count) {
+ update(totalTimeUs, count, mClocks.elapsedRealtime() * 1000);
+ }
+
+ /**
+ * @see #update(long, int)
+ */
+ public void update(long totalTimeUs, int count, long elapsedRealtimeUs) {
if (mTimeBaseRunning && !mTrackingReportedValues) {
// Updating the reported value for the first time.
- mUnpluggedReportedTotalTime = totalTime;
+ mUnpluggedReportedTotalTimeUs = totalTimeUs;
mUnpluggedReportedCount = count;
}
mTrackingReportedValues = true;
- if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) {
- endSample();
+ if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) {
+ endSample(elapsedRealtimeUs);
}
- mCurrentReportedTotalTime = totalTime;
+ mCurrentReportedTotalTimeUs = totalTimeUs;
mCurrentReportedCount = count;
}
@@ -1940,23 +1981,31 @@
* @param deltaTime additional time recorded since the last sampled event, in microseconds.
* @param deltaCount additional number of times the event being sampled occurred.
*/
- public void add(long deltaTime, int deltaCount) {
- update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount);
+ public void add(long deltaTimeUs, int deltaCount) {
+ add(deltaTimeUs, deltaCount, mClocks.elapsedRealtime() * 1000);
+ }
+
+ /**
+ * @see #add(long, int)
+ */
+ public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) {
+ update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount,
+ elapsedRealtimeUs);
}
@Override
- public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
- super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
+ super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
if (mTrackingReportedValues) {
- mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
+ mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs;
mUnpluggedReportedCount = mCurrentReportedCount;
}
mTimeBaseRunning = true;
}
@Override
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
- super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
+ super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
mTimeBaseRunning = false;
}
@@ -1965,14 +2014,14 @@
super.logState(pw, prefix);
pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
+ " mUnpluggedReportedCount=" + mUnpluggedReportedCount
- + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
- + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
+ + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs
+ + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTimeUs);
}
@Override
- protected long computeRunTimeLocked(long curBatteryRealtime) {
- return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
- ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
+ protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) {
+ return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues
+ ? mCurrentReportedTotalTimeUs - mUnpluggedReportedTotalTimeUs : 0);
}
@Override
@@ -1986,16 +2035,16 @@
super.writeToParcel(out, elapsedRealtimeUs);
out.writeInt(mCurrentReportedCount);
out.writeInt(mUnpluggedReportedCount);
- out.writeLong(mCurrentReportedTotalTime);
- out.writeLong(mUnpluggedReportedTotalTime);
+ out.writeLong(mCurrentReportedTotalTimeUs);
+ out.writeLong(mUnpluggedReportedTotalTimeUs);
out.writeInt(mTrackingReportedValues ? 1 : 0);
}
@Override
- public boolean reset(boolean detachIfReset) {
- super.reset(detachIfReset);
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
+ super.reset(detachIfReset, elapsedRealtimeUs);
mTrackingReportedValues = false;
- mUnpluggedReportedTotalTime = 0;
+ mUnpluggedReportedTotalTimeUs = 0;
mUnpluggedReportedCount = 0;
return true;
}
@@ -2011,12 +2060,12 @@
/**
* The last time at which we updated the timer. This is in elapsed realtime microseconds.
*/
- long mLastAddedTime;
+ long mLastAddedTimeUs;
/**
* The last duration that we added to the timer. This is in microseconds.
*/
- long mLastAddedDuration;
+ long mLastAddedDurationUs;
/**
* Whether we are currently in a discharge cycle.
@@ -2026,8 +2075,8 @@
BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) {
super(clocks, type, timeBase, in);
mUid = uid;
- mLastAddedTime = in.readLong();
- mLastAddedDuration = in.readLong();
+ mLastAddedTimeUs = in.readLong();
+ mLastAddedDurationUs = in.readLong();
mInDischarge = timeBase.isRunning();
}
@@ -2040,74 +2089,82 @@
@Override
public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
super.writeToParcel(out, elapsedRealtimeUs);
- out.writeLong(mLastAddedTime);
- out.writeLong(mLastAddedDuration);
+ out.writeLong(mLastAddedTimeUs);
+ out.writeLong(mLastAddedDurationUs);
}
@Override
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
- recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false);
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
+ recomputeLastDuration(elapsedRealtimeUs, false);
mInDischarge = false;
- super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
+ super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
}
@Override
- public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
- recomputeLastDuration(elapsedRealtime, false);
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
+ recomputeLastDuration(elapsedRealtimeUs, false);
mInDischarge = true;
// If we are still within the last added duration, then re-added whatever remains.
- if (mLastAddedTime == elapsedRealtime) {
- mTotalTime += mLastAddedDuration;
+ if (mLastAddedTimeUs == elapsedRealtimeUs) {
+ mTotalTimeUs += mLastAddedDurationUs;
}
- super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
+ super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
}
@Override
public void logState(Printer pw, String prefix) {
super.logState(pw, prefix);
- pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
- + " mLastAddedDuration=" + mLastAddedDuration);
+ pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs
+ + " mLastAddedDuration=" + mLastAddedDurationUs);
}
- private long computeOverage(long curTime) {
- if (mLastAddedTime > 0) {
- return mLastAddedDuration - curTime;
+ private long computeOverage(long curTimeUs) {
+ if (mLastAddedTimeUs > 0) {
+ return mLastAddedDurationUs - curTimeUs;
}
return 0;
}
- private void recomputeLastDuration(long curTime, boolean abort) {
- final long overage = computeOverage(curTime);
+ private void recomputeLastDuration(long curTimeUs, boolean abort) {
+ final long overage = computeOverage(curTimeUs);
if (overage > 0) {
// Aborting before the duration ran out -- roll back the remaining
// duration. Only do this if currently discharging; otherwise we didn't
// actually add the time.
if (mInDischarge) {
- mTotalTime -= overage;
+ mTotalTimeUs -= overage;
}
if (abort) {
- mLastAddedTime = 0;
+ mLastAddedTimeUs = 0;
} else {
- mLastAddedTime = curTime;
- mLastAddedDuration -= overage;
+ mLastAddedTimeUs = curTimeUs;
+ mLastAddedDurationUs -= overage;
}
}
}
- public void addDuration(BatteryStatsImpl stats, long durationMillis) {
- final long now = mClocks.elapsedRealtime() * 1000;
- recomputeLastDuration(now, true);
- mLastAddedTime = now;
- mLastAddedDuration = durationMillis * 1000;
+ public void addDuration(BatteryStatsImpl stats, long durationMs) {
+ addDuration(stats, durationMs, mClocks.elapsedRealtime());
+ }
+
+ public void addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs) {
+ final long nowUs = elapsedRealtimeMs * 1000;
+ recomputeLastDuration(nowUs, true);
+ mLastAddedTimeUs = nowUs;
+ mLastAddedDurationUs = durationMs * 1000;
if (mInDischarge) {
- mTotalTime += mLastAddedDuration;
+ mTotalTimeUs += mLastAddedDurationUs;
mCount++;
}
}
public void abortLastDuration(BatteryStatsImpl stats) {
- final long now = mClocks.elapsedRealtime() * 1000;
- recomputeLastDuration(now, true);
+ abortLastDuration(stats, mClocks.elapsedRealtime());
+ }
+
+ public void abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs) {
+ final long nowUs = elapsedRealtimeMs * 1000;
+ recomputeLastDuration(nowUs, true);
}
@Override
@@ -2116,20 +2173,19 @@
}
@Override
- protected long computeRunTimeLocked(long curBatteryRealtime) {
- final long overage = computeOverage(mClocks.elapsedRealtime() * 1000);
+ protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) {
+ final long overage = computeOverage(elapsedRealtimeUs);
if (overage > 0) {
- return mTotalTime = overage;
+ return mTotalTimeUs = overage;
}
- return mTotalTime;
+ return mTotalTimeUs;
}
@Override
- public boolean reset(boolean detachIfReset) {
- final long now = mClocks.elapsedRealtime() * 1000;
- recomputeLastDuration(now, true);
- boolean stillActive = mLastAddedTime == now;
- super.reset(!stillActive && detachIfReset);
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
+ recomputeLastDuration(elapsedRealtimeUs, true);
+ boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs;
+ super.reset(!stillActive && detachIfReset, elapsedRealtimeUs);
return !stillActive;
}
}
@@ -2225,10 +2281,10 @@
*
* If the timer is also running, store the start time.
*/
- public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) {
- super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime);
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
+ super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
if (mNesting > 0) {
- mStartTimeMs = baseRealtime / 1000;
+ mStartTimeMs = baseRealtimeUs / 1000;
}
}
@@ -2238,8 +2294,8 @@
* If the timer is running, add the duration into mCurrentDurationMs.
*/
@Override
- public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) {
- super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs);
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
+ super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
if (mNesting > 0) {
// baseRealtimeUs has already been converted to the timebase's realtime.
mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs;
@@ -2284,13 +2340,13 @@
}
@Override
- public boolean reset(boolean detachIfReset) {
- boolean result = super.reset(detachIfReset);
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
+ boolean result = super.reset(detachIfReset, elapsedRealtimeUs);
mMaxDurationMs = 0;
mTotalDurationMs = 0;
mCurrentDurationMs = 0;
if (mNesting > 0) {
- mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000) / 1000;
+ mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000;
} else {
mStartTimeMs = -1;
}
@@ -2364,16 +2420,16 @@
* subtract this from the current battery time to find the amount of
* time we have been running since we last computed an update.
*/
- long mUpdateTime;
+ long mUpdateTimeUs;
/**
* The total time at which the timer was acquired, to determine if it
* was actually held for an interesting duration. If time base was not running when timer
* was acquired, will be -1.
*/
- long mAcquireTime = -1;
+ long mAcquireTimeUs = -1;
- long mTimeout;
+ long mTimeoutUs;
/**
* For partial wake locks, keep track of whether we are in the list
@@ -2387,7 +2443,7 @@
super(clocks, type, timeBase, in);
mUid = uid;
mTimerPool = timerPool;
- mUpdateTime = in.readLong();
+ mUpdateTimeUs = in.readLong();
}
public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
@@ -2397,56 +2453,56 @@
mTimerPool = timerPool;
}
- public void setTimeout(long timeout) {
- mTimeout = timeout;
+ public void setTimeout(long timeoutUs) {
+ mTimeoutUs = timeoutUs;
}
public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
super.writeToParcel(out, elapsedRealtimeUs);
- out.writeLong(mUpdateTime);
+ out.writeLong(mUpdateTimeUs);
}
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
if (mNesting > 0) {
if (DEBUG && mType < 0) {
- Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
+ Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs);
}
- super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
- mUpdateTime = baseRealtime;
+ super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs);
+ mUpdateTimeUs = baseRealtimeUs;
if (DEBUG && mType < 0) {
- Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
+ Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs);
}
}
}
public void logState(Printer pw, String prefix) {
super.logState(pw, prefix);
- pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
- + " mAcquireTime=" + mAcquireTime);
+ pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs
+ + " mAcquireTime=" + mAcquireTimeUs);
}
public void startRunningLocked(long elapsedRealtimeMs) {
if (mNesting++ == 0) {
- final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
- mUpdateTime = batteryRealtime;
+ final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
+ mUpdateTimeUs = batteryRealtimeUs;
if (mTimerPool != null) {
// Accumulate time to all currently active timers before adding
// this new one to the pool.
- refreshTimersLocked(batteryRealtime, mTimerPool, null);
+ refreshTimersLocked(batteryRealtimeUs, mTimerPool, null);
// Add this timer to the active pool
mTimerPool.add(this);
}
if (mTimeBase.isRunning()) {
// Increment the count
mCount++;
- mAcquireTime = mTotalTime;
+ mAcquireTimeUs = mTotalTimeUs;
} else {
- mAcquireTime = -1;
+ mAcquireTimeUs = -1;
}
if (DEBUG && mType < 0) {
- Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
- + " mTotalTime=" + mTotalTime + " mCount=" + mCount
- + " mAcquireTime=" + mAcquireTime);
+ Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs
+ + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount
+ + " mAcquireTime=" + mAcquireTimeUs);
}
}
}
@@ -2461,26 +2517,27 @@
return;
}
if (--mNesting == 0) {
- final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
+ final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
if (mTimerPool != null) {
// Accumulate time to all active counters, scaled by the total
// active in the pool, before taking this one out of the pool.
- refreshTimersLocked(batteryRealtime, mTimerPool, null);
+ refreshTimersLocked(batteryRealtimeUs, mTimerPool, null);
// Remove this timer from the active pool
mTimerPool.remove(this);
} else {
mNesting = 1;
- mTotalTime = computeRunTimeLocked(batteryRealtime);
+ mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs,
+ elapsedRealtimeMs * 1000);
mNesting = 0;
}
if (DEBUG && mType < 0) {
- Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
- + " mTotalTime=" + mTotalTime + " mCount=" + mCount
- + " mAcquireTime=" + mAcquireTime);
+ Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs
+ + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount
+ + " mAcquireTime=" + mAcquireTimeUs);
}
- if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) {
+ if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) {
// If there was no change in the time, then discard this
// count. A somewhat cheezy strategy, but hey.
mCount--;
@@ -2497,32 +2554,32 @@
// Update the total time for all other running Timers with the same type as this Timer
// due to a change in timer count
- private static long refreshTimersLocked(long batteryRealtime,
+ private static long refreshTimersLocked(long batteryRealtimeUs,
final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
- long selfTime = 0;
+ long selfTimeUs = 0;
final int N = pool.size();
for (int i=N-1; i>= 0; i--) {
final StopwatchTimer t = pool.get(i);
- long heldTime = batteryRealtime - t.mUpdateTime;
- if (heldTime > 0) {
- final long myTime = heldTime / N;
+ long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs;
+ if (heldTimeUs > 0) {
+ final long myTimeUs = heldTimeUs / N;
if (t == self) {
- selfTime = myTime;
+ selfTimeUs = myTimeUs;
}
- t.mTotalTime += myTime;
+ t.mTotalTimeUs += myTimeUs;
}
- t.mUpdateTime = batteryRealtime;
+ t.mUpdateTimeUs = batteryRealtimeUs;
}
- return selfTime;
+ return selfTimeUs;
}
@Override
- protected long computeRunTimeLocked(long curBatteryRealtime) {
- if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
- curBatteryRealtime = mUpdateTime + mTimeout;
+ protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) {
+ if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) {
+ curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs;
}
- return mTotalTime + (mNesting > 0
- ? (curBatteryRealtime - mUpdateTime)
+ return mTotalTimeUs + (mNesting > 0
+ ? (curBatteryRealtimeUs - mUpdateTimeUs)
/ (mTimerPool != null ? mTimerPool.size() : 1)
: 0);
}
@@ -2533,13 +2590,14 @@
}
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
boolean canDetach = mNesting <= 0;
- super.reset(canDetach && detachIfReset);
+ super.reset(canDetach && detachIfReset, elapsedRealtimeUs);
if (mNesting > 0) {
- mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000);
+ mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs);
}
- mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later.
+ // To ensure mCount isn't decreased to -1 if timer is stopped later.
+ mAcquireTimeUs = -1;
return canDetach;
}
@@ -2565,17 +2623,17 @@
* @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
*/
public void setMark(long elapsedRealtimeMs) {
- final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
+ final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
if (mNesting > 0) {
// We are running.
if (mTimerPool != null) {
- refreshTimersLocked(batteryRealtime, mTimerPool, this);
+ refreshTimersLocked(batteryRealtimeUs, mTimerPool, this);
} else {
- mTotalTime += batteryRealtime - mUpdateTime;
- mUpdateTime = batteryRealtime;
+ mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs;
+ mUpdateTimeUs = batteryRealtimeUs;
}
}
- mTimeBeforeMark = mTotalTime;
+ mTimeBeforeMarkUs = mTotalTimeUs;
}
}
@@ -2641,11 +2699,11 @@
}
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
boolean active = false;
// Do not detach the subTimer explicitly since that'll be done by DualTimer.detach().
- active |= !mSubTimer.reset(false);
- active |= !super.reset(detachIfReset);
+ active |= !mSubTimer.reset(false, elapsedRealtimeUs);
+ active |= !super.reset(detachIfReset, elapsedRealtimeUs);
return !active;
}
@@ -2682,10 +2740,10 @@
final ArrayMap<String, T> mMap = new ArrayMap<>();
T mCurOverflow;
ArrayMap<String, MutableInt> mActiveOverflow;
- long mLastOverflowTime;
- long mLastOverflowFinishTime;
- long mLastClearTime;
- long mLastCleanupTime;
+ long mLastOverflowTimeMs;
+ long mLastOverflowFinishTimeMs;
+ long mLastClearTimeMs;
+ long mLastCleanupTimeMs;
public OverflowArrayMap(int uid) {
mUid = uid;
@@ -2696,7 +2754,7 @@
}
public void clear() {
- mLastClearTime = SystemClock.elapsedRealtime();
+ mLastClearTimeMs = SystemClock.elapsedRealtime();
mMap.clear();
mCurOverflow = null;
mActiveOverflow = null;
@@ -2712,8 +2770,8 @@
}
}
- public void cleanup() {
- mLastCleanupTime = SystemClock.elapsedRealtime();
+ public void cleanup(long elapsedRealtimeMs) {
+ mLastCleanupTimeMs = elapsedRealtimeMs;
if (mActiveOverflow != null) {
if (mActiveOverflow.size() == 0) {
mActiveOverflow = null;
@@ -2737,7 +2795,7 @@
}
}
- public T startObject(String name) {
+ public T startObject(String name, long elapsedRealtimeMs) {
if (name == null) {
name = "";
}
@@ -2780,7 +2838,7 @@
mActiveOverflow = new ArrayMap<>();
}
mActiveOverflow.put(name, new MutableInt(1));
- mLastOverflowTime = SystemClock.elapsedRealtime();
+ mLastOverflowTimeMs = elapsedRealtimeMs;
return obj;
}
@@ -2790,7 +2848,7 @@
return obj;
}
- public T stopObject(String name) {
+ public T stopObject(String name, long elapsedRealtimeMs) {
if (name == null) {
name = "";
}
@@ -2810,7 +2868,7 @@
over.value--;
if (over.value <= 0) {
mActiveOverflow.remove(name);
- mLastOverflowFinishTime = SystemClock.elapsedRealtime();
+ mLastOverflowFinishTimeMs = elapsedRealtimeMs;
}
return obj;
}
@@ -2830,22 +2888,22 @@
sb.append(mActiveOverflow);
sb.append(" curoverflow=");
sb.append(mCurOverflow);
- long now = SystemClock.elapsedRealtime();
- if (mLastOverflowTime != 0) {
+ long now = elapsedRealtimeMs;
+ if (mLastOverflowTimeMs != 0) {
sb.append(" lastOverflowTime=");
- TimeUtils.formatDuration(mLastOverflowTime-now, sb);
+ TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb);
}
- if (mLastOverflowFinishTime != 0) {
+ if (mLastOverflowFinishTimeMs != 0) {
sb.append(" lastOverflowFinishTime=");
- TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb);
+ TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb);
}
- if (mLastClearTime != 0) {
+ if (mLastClearTimeMs != 0) {
sb.append(" lastClearTime=");
- TimeUtils.formatDuration(mLastClearTime-now, sb);
+ TimeUtils.formatDuration(mLastClearTimeMs - now, sb);
}
- if (mLastCleanupTime != 0) {
+ if (mLastCleanupTimeMs != 0) {
sb.append(" lastCleanupTime=");
- TimeUtils.formatDuration(mLastCleanupTime-now, sb);
+ TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb);
}
Slog.wtf(TAG, sb.toString());
return null;
@@ -2943,16 +3001,16 @@
mMonitoredRailChargeConsumedMaMs.writeToParcel(dest);
}
- public void reset(boolean detachIfReset) {
- mIdleTimeMillis.reset(detachIfReset);
- mScanTimeMillis.reset(detachIfReset);
- mSleepTimeMillis.reset(detachIfReset);
- mRxTimeMillis.reset(detachIfReset);
+ public void reset(boolean detachIfReset, long elapsedRealtimeUs) {
+ mIdleTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
+ mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
+ mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
+ mRxTimeMillis.reset(detachIfReset, elapsedRealtimeUs);
for (LongSamplingCounter counter : mTxTimeMillis) {
- counter.reset(detachIfReset);
+ counter.reset(detachIfReset, elapsedRealtimeUs);
}
- mPowerDrainMaMs.reset(detachIfReset);
- mMonitoredRailChargeConsumedMaMs.reset(detachIfReset);
+ mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs);
+ mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs);
}
public void detach() {
@@ -3416,82 +3474,82 @@
final int NU = mUidStats.size();
for (int i=0; i<NU; i++) {
final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- uid.mLastStepUserTime = uid.mCurStepUserTime;
- uid.mLastStepSystemTime = uid.mCurStepSystemTime;
+ uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs;
+ uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs;
}
- mLastStepCpuUserTime = mCurStepCpuUserTime;
- mLastStepCpuSystemTime = mCurStepCpuSystemTime;
- mLastStepStatUserTime = mCurStepStatUserTime;
- mLastStepStatSystemTime = mCurStepStatSystemTime;
- mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
- mLastStepStatIrqTime = mCurStepStatIrqTime;
- mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
- mLastStepStatIdleTime = mCurStepStatIdleTime;
+ mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
+ mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
+ mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
+ mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
+ mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
+ mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
+ mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
+ mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
tmp.clear();
return;
}
if (DEBUG) {
- Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
- + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
- + " irq=" + mLastStepStatIrqTime + " sirq="
- + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
- Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
- + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
- + " irq=" + mCurStepStatIrqTime + " sirq="
- + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
+ Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys="
+ + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs
+ + " irq=" + mLastStepStatIrqTimeMs + " sirq="
+ + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs);
+ Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys="
+ + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs
+ + " irq=" + mCurStepStatIrqTimeMs + " sirq="
+ + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs);
}
- out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
- out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
- out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
- out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
- out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
- out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
- out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
- out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
+ out.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs);
+ out.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs);
+ out.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs);
+ out.statSystemTime = (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs);
+ out.statIOWaitTime = (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs);
+ out.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs);
+ out.statSoftIrqTime = (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs);
+ out.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs);
out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
final int NU = mUidStats.size();
for (int i=0; i<NU; i++) {
final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
- final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
- final int totalTime = totalUTime + totalSTime;
- uid.mLastStepUserTime = uid.mCurStepUserTime;
- uid.mLastStepSystemTime = uid.mCurStepSystemTime;
- if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
+ final int totalUTimeMs = (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs);
+ final int totalSTimeMs = (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs);
+ final int totalTimeMs = totalUTimeMs + totalSTimeMs;
+ uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs;
+ uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs;
+ if (totalTimeMs <= (out.appCpuUTime3 + out.appCpuSTime3)) {
continue;
}
- if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
+ if (totalTimeMs <= (out.appCpuUTime2 + out.appCpuSTime2)) {
out.appCpuUid3 = uid.mUid;
- out.appCpuUTime3 = totalUTime;
- out.appCpuSTime3 = totalSTime;
+ out.appCpuUTime3 = totalUTimeMs;
+ out.appCpuSTime3 = totalSTimeMs;
} else {
out.appCpuUid3 = out.appCpuUid2;
out.appCpuUTime3 = out.appCpuUTime2;
out.appCpuSTime3 = out.appCpuSTime2;
- if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
+ if (totalTimeMs <= (out.appCpuUTime1 + out.appCpuSTime1)) {
out.appCpuUid2 = uid.mUid;
- out.appCpuUTime2 = totalUTime;
- out.appCpuSTime2 = totalSTime;
+ out.appCpuUTime2 = totalUTimeMs;
+ out.appCpuSTime2 = totalSTimeMs;
} else {
out.appCpuUid2 = out.appCpuUid1;
out.appCpuUTime2 = out.appCpuUTime1;
out.appCpuSTime2 = out.appCpuSTime1;
out.appCpuUid1 = uid.mUid;
- out.appCpuUTime1 = totalUTime;
- out.appCpuSTime1 = totalSTime;
+ out.appCpuUTime1 = totalUTimeMs;
+ out.appCpuSTime1 = totalSTimeMs;
}
}
}
- mLastStepCpuUserTime = mCurStepCpuUserTime;
- mLastStepCpuSystemTime = mCurStepCpuSystemTime;
- mLastStepStatUserTime = mCurStepStatUserTime;
- mLastStepStatSystemTime = mCurStepStatSystemTime;
- mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
- mLastStepStatIrqTime = mCurStepStatIrqTime;
- mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
- mLastStepStatIdleTime = mCurStepStatIdleTime;
+ mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
+ mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
+ mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
+ mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
+ mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
+ mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
+ mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
+ mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
}
public void readHistoryDelta(Parcel src, HistoryItem cur) {
@@ -3631,29 +3689,35 @@
}
public void createFakeHistoryEvents(long numEvents) {
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ final long uptimeMs = mClocks.uptimeMillis();
for(long i = 0; i < numEvents; i++) {
- noteLongPartialWakelockStart("name1", "historyName1", 1000);
- noteLongPartialWakelockFinish("name1", "historyName1", 1000);
+ noteLongPartialWakelockStart("name1", "historyName1", 1000,
+ elapsedRealtimeMs, uptimeMs);
+ noteLongPartialWakelockFinish("name1", "historyName1", 1000,
+ elapsedRealtimeMs, uptimeMs);
}
}
- void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) {
+ void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
if (!mHaveBatteryLevel || !mRecordingHistory) {
return;
}
- final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
+ final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time;
final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
- if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
- + Integer.toHexString(diffStates) + " lastDiff="
- + Integer.toHexString(lastDiffStates) + " diff2="
- + Integer.toHexString(diffStates2) + " lastDiff2="
- + Integer.toHexString(lastDiffStates2));
+ if (DEBUG) {
+ Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff="
+ + Integer.toHexString(diffStates) + " lastDiff="
+ + Integer.toHexString(lastDiffStates) + " diff2="
+ + Integer.toHexString(diffStates2) + " lastDiff2="
+ + Integer.toHexString(lastDiffStates2));
+ }
if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
- && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
+ && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0
&& (diffStates2&lastDiffStates2) == 0
&& (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
&& (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
@@ -3674,7 +3738,7 @@
mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
mHistoryBufferLastPos = -1;
- elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
+ elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs;
// If the last written history had a wakelock tag, we need to retain it.
// Note that the condition above made sure that we aren't in a case where
// both it and the current history item have a wakelock tag.
@@ -3714,11 +3778,9 @@
mHistoryBuffer.setDataPosition(0);
mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2);
mHistoryBufferLastPos = -1;
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
HistoryItem newItem = new HistoryItem();
newItem.setTo(cur);
- startRecordingHistory(elapsedRealtime, uptime, false);
+ startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem);
return;
}
@@ -3737,11 +3799,11 @@
}
mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
mHistoryLastLastWritten.setTo(mHistoryLastWritten);
- mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
+ mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur);
mHistoryLastWritten.states &= mActiveHistoryStates;
mHistoryLastWritten.states2 &= mActiveHistoryStates2;
writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
- mLastHistoryElapsedRealtime = elapsedRealtimeMs;
+ mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs;
cur.wakelockTag = null;
cur.wakeReasonTag = null;
cur.eventCode = HistoryItem.EVENT_NONE;
@@ -3755,27 +3817,27 @@
int mChangedStates2 = 0;
void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
- if (mTrackRunningHistoryElapsedRealtime != 0) {
- final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
- final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
- if (diffUptime < (diffElapsed-20)) {
- final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
+ if (mTrackRunningHistoryElapsedRealtimeMs != 0) {
+ final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs;
+ final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs;
+ if (diffUptimeMs < (diffElapsedMs - 20)) {
+ final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs);
mHistoryAddTmp.setTo(mHistoryLastWritten);
mHistoryAddTmp.wakelockTag = null;
mHistoryAddTmp.wakeReasonTag = null;
mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
- addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp);
+ addHistoryRecordInnerLocked(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp);
}
}
mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
- mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
- mTrackRunningHistoryUptime = uptimeMs;
- addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur);
+ mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs;
+ mTrackRunningHistoryUptimeMs = uptimeMs;
+ addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
}
- void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) {
- addHistoryBufferLocked(elapsedRealtimeMs, cur);
+ void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
+ addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
if (!USE_OLD_HISTORY) {
return;
@@ -3790,13 +3852,13 @@
// are now resetting back to their original value, then just collapse
// into one record.
if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
- && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
+ && (mHistoryBaseTimeMs + elapsedRealtimeMs) < (mHistoryEnd.time + 1000)
&& ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0
&& ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) {
// If the current is the same as the one before, then we no
// longer need the entry.
if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
- && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
+ && (mHistoryBaseTimeMs + elapsedRealtimeMs) < (mHistoryEnd.time + 500)
&& mHistoryLastEnd.sameNonEvent(cur)) {
mHistoryLastEnd.next = null;
mHistoryEnd.next = mHistoryCache;
@@ -3832,7 +3894,7 @@
} else {
rec = new HistoryItem();
}
- rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
+ rec.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur);
addHistoryRecordLocked(rec);
}
@@ -3860,10 +3922,10 @@
mNumHistoryItems = 0;
}
- mHistoryBaseTime = 0;
- mLastHistoryElapsedRealtime = 0;
- mTrackRunningHistoryElapsedRealtime = 0;
- mTrackRunningHistoryUptime = 0;
+ mHistoryBaseTimeMs = 0;
+ mLastHistoryElapsedRealtimeMs = 0;
+ mTrackRunningHistoryElapsedRealtimeMs = 0;
+ mTrackRunningHistoryUptimeMs = 0;
mHistoryBuffer.setDataSize(0);
mHistoryBuffer.setDataPosition(0);
@@ -3879,8 +3941,8 @@
}
@GuardedBy("this")
- public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime,
- long realtime) {
+ public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs,
+ long realtimeUs) {
final boolean screenOff = !isScreenOn(screenState);
final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning();
final boolean updateOnBatteryScreenOffTimeBase =
@@ -3888,14 +3950,15 @@
if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) {
if (updateOnBatteryScreenOffTimeBase) {
- updateKernelWakelocksLocked();
+ updateKernelWakelocksLocked(realtimeUs);
updateBatteryPropertiesLocked();
}
// This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because
// updateRpmStatsLocked is too slow to run each screen change. When the speed is
// improved, remove the surrounding if{}.
if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) {
- updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes.
+ // if either OnBattery or OnBatteryScreenOfftimebase changes.
+ updateRpmStatsLocked(realtimeUs);
}
if (DEBUG_ENERGY_CPU) {
Slog.d(TAG, "Updating cpu time because screen is now "
@@ -3903,16 +3966,17 @@
+ " and battery is " + (unplugged ? "on" : "off"));
}
- mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
+ mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs);
if (updateOnBatteryTimeBase) {
for (int i = mUidStats.size() - 1; i >= 0; --i) {
- mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
+ mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs);
}
}
if (updateOnBatteryScreenOffTimeBase) {
- mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime);
+ mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff,
+ uptimeUs, realtimeUs);
for (int i = mUidStats.size() - 1; i >= 0; --i) {
- mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
+ mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs);
}
}
}
@@ -3931,8 +3995,14 @@
}
public void addIsolatedUidLocked(int isolatedUid, int appUid) {
+ addIsolatedUidLocked(isolatedUid, appUid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void addIsolatedUidLocked(int isolatedUid, int appUid,
+ long elapsedRealtimeMs, long uptimeMs) {
mIsolatedUids.put(isolatedUid, appUid);
- final Uid u = getUidStatsLocked(appUid);
+ final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs);
u.addIsolatedUid(isolatedUid);
}
@@ -3955,14 +4025,22 @@
*/
@GuardedBy("this")
public void removeIsolatedUidLocked(int isolatedUid) {
+ removeIsolatedUidLocked(isolatedUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ /**
+ * @see #removeIsolatedUidLocked(int)
+ */
+ @GuardedBy("this")
+ public void removeIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) {
final int idx = mIsolatedUids.indexOfKey(isolatedUid);
if (idx >= 0) {
final int ownerUid = mIsolatedUids.valueAt(idx);
- final Uid u = getUidStatsLocked(ownerUid);
+ final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs);
u.removeIsolatedUid(isolatedUid);
mIsolatedUids.removeAt(idx);
}
- mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime()));
+ mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs));
}
public int mapUid(int uid) {
@@ -3971,26 +4049,39 @@
}
public void noteEventLocked(int code, String name, int uid) {
+ noteEventLocked(code, name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteEventLocked(int code, String name, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (!mActiveEvents.updateState(code, name, uid, 0)) {
return;
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid);
}
public void noteCurrentTimeChangedLocked() {
final long currentTime = System.currentTimeMillis();
final long elapsedRealtime = mClocks.elapsedRealtime();
final long uptime = mClocks.uptimeMillis();
- recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
+ noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime);
+ }
+
+ public void noteCurrentTimeChangedLocked(long currentTimeMs,
+ long elapsedRealtimeMs, long uptimeMs) {
+ recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs);
}
public void noteProcessStartLocked(String name, int uid) {
+ noteProcessStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteProcessStartLocked(String name, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (isOnBattery()) {
- Uid u = getUidStatsLocked(uid);
+ Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
u.getProcessStatsLocked(name).incStartsLocked();
}
if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
@@ -3999,28 +4090,40 @@
if (!mRecordAllHistory) {
return;
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid);
}
public void noteProcessCrashLocked(String name, int uid) {
+ noteProcessCrashLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteProcessCrashLocked(String name, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (isOnBattery()) {
- Uid u = getUidStatsLocked(uid);
+ Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
u.getProcessStatsLocked(name).incNumCrashesLocked();
}
}
public void noteProcessAnrLocked(String name, int uid) {
+ noteProcessAnrLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (isOnBattery()) {
- Uid u = getUidStatsLocked(uid);
+ Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
u.getProcessStatsLocked(name).incNumAnrsLocked();
}
}
public void noteUidProcessStateLocked(int uid, int state) {
+ noteUidProcessStateLocked(uid, state, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteUidProcessStateLocked(int uid, int state,
+ long elapsedRealtimeMs, long uptimeMs) {
int parentUid = mapUid(uid);
if (uid != parentUid) {
// Isolated UIDs process state is already rolled up into parent, so no need to track
@@ -4032,10 +4135,16 @@
// and isolated uids rather than only the parent uid.
FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid,
ActivityManager.processStateAmToProto(state));
- getUidStatsLocked(uid).updateUidProcessStateLocked(state);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs);
}
public void noteProcessFinishLocked(String name, int uid) {
+ noteProcessFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteProcessFinishLocked(String name, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
return;
@@ -4043,82 +4152,120 @@
if (!mRecordAllHistory) {
return;
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH,
+ name, uid);
}
public void noteSyncStartLocked(String name, int uid) {
+ noteSyncStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStartSyncLocked(name, elapsedRealtimeMs);
if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
return;
}
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid);
}
public void noteSyncFinishLocked(String name, int uid) {
+ noteSyncFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStopSyncLocked(name, elapsedRealtimeMs);
if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
return;
}
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH,
+ name, uid);
}
public void noteJobStartLocked(String name, int uid) {
+ noteJobStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStartJobLocked(name, elapsedRealtimeMs);
if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
return;
}
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid);
}
public void noteJobFinishLocked(String name, int uid, int stopReason) {
+ noteJobFinishLocked(name, uid, stopReason,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteJobFinishLocked(String name, int uid, int stopReason,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStopJobLocked(name, elapsedRealtimeMs, stopReason);
if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
return;
}
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid);
}
public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) {
+ noteJobsDeferredLocked(uid, numDeferred, sinceLast,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteJobsDeferredLocked(numDeferred, sinceLast);
}
public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) {
- noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid);
+ noteAlarmStartLocked(name, workSource, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteAlarmStartLocked(String name, WorkSource workSource, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
+ noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid,
+ elapsedRealtimeMs, uptimeMs);
}
public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) {
- noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid);
+ noteAlarmFinishLocked(name, workSource, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
+ noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid,
+ elapsedRealtimeMs, uptimeMs);
}
private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource,
int uid) {
+ noteAlarmStartOrFinishLocked(historyItem, name, workSource, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource,
+ int uid, long elapsedRealtimeMs, long uptimeMs) {
if (!mRecordAllHistory) {
return;
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
-
if (workSource != null) {
for (int i = 0; i < workSource.size(); ++i) {
uid = mapUid(workSource.getUid(i));
if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
- addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
}
}
@@ -4127,7 +4274,7 @@
for (int i = 0; i < workChains.size(); ++i) {
uid = mapUid(workChains.get(i).getAttributionUid());
if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
- addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
}
}
}
@@ -4135,13 +4282,19 @@
uid = mapUid(uid);
if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
- addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
}
}
}
public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource,
String tag) {
+ noteWakupAlarmLocked(packageName, uid, workSource, tag,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource,
+ String tag, long elapsedRealtimeMs, long uptimeMs) {
if (workSource != null) {
for (int i = 0; i < workSource.size(); ++i) {
uid = workSource.getUid(i);
@@ -4149,7 +4302,8 @@
if (isOnBattery()) {
BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid,
- workSourceName != null ? workSourceName : packageName);
+ workSourceName != null ? workSourceName : packageName,
+ elapsedRealtimeMs, uptimeMs);
pkg.noteWakeupAlarmLocked(tag);
}
}
@@ -4161,14 +4315,16 @@
uid = wc.getAttributionUid();
if (isOnBattery()) {
- BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName);
+ BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName,
+ elapsedRealtimeMs, uptimeMs);
pkg.noteWakeupAlarmLocked(tag);
}
}
}
} else {
if (isOnBattery()) {
- BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName);
+ BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName,
+ elapsedRealtimeMs, uptimeMs);
pkg.noteWakeupAlarmLocked(tag);
}
}
@@ -4228,7 +4384,8 @@
public void setPretendScreenOff(boolean pretendScreenOff) {
if (mPretendScreenOff != pretendScreenOff) {
mPretendScreenOff = pretendScreenOff;
- noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON);
+ noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis(), System.currentTimeMillis());
}
}
@@ -4236,19 +4393,25 @@
private int mInitialAcquireWakeUid = -1;
public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
- int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) {
+ int type, boolean unimportantForLogging) {
+ noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
+ int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (type == WAKE_TYPE_PARTIAL) {
// Only care about partial wake locks, since full wake locks
// will be canceled when the user puts the screen to sleep.
- aggregateLastWakeupUptimeLocked(uptime);
+ aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
if (historyName == null) {
historyName = name;
}
if (mRecordAllHistory) {
if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
uid, 0)) {
- addHistoryEventLocked(elapsedRealtime, uptime,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
}
}
@@ -4260,7 +4423,7 @@
mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
mWakeLockImportant = !unimportantForLogging;
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
} else if (!mWakeLockImportant && !unimportantForLogging
&& mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
if (mHistoryLastWritten.wakelockTag != null) {
@@ -4269,7 +4432,7 @@
mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mWakeLockImportant = true;
}
@@ -4285,7 +4448,8 @@
requestWakelockCpuUpdate();
}
- getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStartWakeLocked(pid, name, type, elapsedRealtimeMs);
if (wc != null) {
FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(),
@@ -4300,7 +4464,13 @@
}
public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
- int type, long elapsedRealtime, long uptime) {
+ int type) {
+ noteStopWakeLocked(uid, pid, wc, name, historyName, type,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName,
+ int type, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (type == WAKE_TYPE_PARTIAL) {
mWakeLockNesting--;
@@ -4310,7 +4480,7 @@
}
if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
uid, 0)) {
- addHistoryEventLocked(elapsedRealtime, uptime,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
}
}
@@ -4320,7 +4490,7 @@
+ Integer.toHexString(mHistoryCur.states));
mInitialAcquireWakeName = null;
mInitialAcquireWakeUid = -1;
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
if (uid >= 0) {
@@ -4331,7 +4501,8 @@
requestWakelockCpuUpdate();
}
- getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStopWakeLocked(pid, name, type, elapsedRealtimeMs);
if (wc != null) {
FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(),
wc.getTags(), getPowerManagerWakeLockLevel(type), name,
@@ -4377,12 +4548,17 @@
public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
String historyName, int type, boolean unimportantForLogging) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteStartWakeFromSourceLocked(ws, pid, name, historyName, type, unimportantForLogging,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
+ String historyName, int type, boolean unimportantForLogging,
+ long elapsedRealtimeMs, long uptimeMs) {
final int N = ws.size();
for (int i=0; i<N; i++) {
noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type,
- unimportantForLogging, elapsedRealtime, uptime);
+ unimportantForLogging, elapsedRealtimeMs, uptimeMs);
}
List<WorkChain> wcs = ws.getWorkChains();
@@ -4390,7 +4566,7 @@
for (int i = 0; i < wcs.size(); ++i) {
final WorkChain wc = wcs.get(i);
noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type,
- unimportantForLogging, elapsedRealtime, uptime);
+ unimportantForLogging, elapsedRealtimeMs, uptimeMs);
}
}
}
@@ -4398,9 +4574,15 @@
public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
String historyName, int type, WorkSource newWs, int newPid, String newName,
String newHistoryName, int newType, boolean newUnimportantForLogging) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, newWs, newPid,
+ newName, newHistoryName, newType, newUnimportantForLogging,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+ public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
+ String historyName, int type, WorkSource newWs, int newPid, String newName,
+ String newHistoryName, int newType, boolean newUnimportantForLogging,
+ long elapsedRealtimeMs, long uptimeMs) {
List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs);
// For correct semantics, we start the need worksources first, so that we won't
@@ -4411,7 +4593,7 @@
final int NN = newWs.size();
for (int i=0; i<NN; i++) {
noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType,
- newUnimportantForLogging, elapsedRealtime, uptime);
+ newUnimportantForLogging, elapsedRealtimeMs, uptimeMs);
}
if (wcs != null) {
List<WorkChain> newChains = wcs[0];
@@ -4419,8 +4601,8 @@
for (int i = 0; i < newChains.size(); ++i) {
final WorkChain newChain = newChains.get(i);
noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName,
- newHistoryName, newType, newUnimportantForLogging, elapsedRealtime,
- uptime);
+ newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs,
+ uptimeMs);
}
}
}
@@ -4428,8 +4610,8 @@
// Then the stops :
final int NO = ws.size();
for (int i=0; i<NO; i++) {
- noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime,
- uptime);
+ noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs,
+ uptimeMs);
}
if (wcs != null) {
List<WorkChain> goneChains = wcs[1];
@@ -4437,7 +4619,7 @@
for (int i = 0; i < goneChains.size(); ++i) {
final WorkChain goneChain = goneChains.get(i);
noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name,
- historyName, type, elapsedRealtime, uptime);
+ historyName, type, elapsedRealtimeMs, uptimeMs);
}
}
}
@@ -4445,12 +4627,16 @@
public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
String historyName, int type) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteStopWakeFromSourceLocked(ws, pid, name, historyName, type,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
+ String historyName, int type, long elapsedRealtimeMs, long uptimeMs) {
final int N = ws.size();
for (int i=0; i<N; i++) {
- noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime,
- uptime);
+ noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs,
+ uptimeMs);
}
List<WorkChain> wcs = ws.getWorkChains();
@@ -4458,22 +4644,35 @@
for (int i = 0; i < wcs.size(); ++i) {
final WorkChain wc = wcs.get(i);
noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type,
- elapsedRealtime, uptime);
+ elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
+ noteLongPartialWakelockStart(name, historyName, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteLongPartialWakelockStart(String name, String historyName, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- noteLongPartialWakeLockStartInternal(name, historyName, uid);
+ noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
public void noteLongPartialWakelockStartFromSource(String name, String historyName,
WorkSource workSource) {
+ noteLongPartialWakelockStartFromSource(name, historyName, workSource,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteLongPartialWakelockStartFromSource(String name, String historyName,
+ WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) {
final int N = workSource.size();
for (int i = 0; i < N; ++i) {
final int uid = mapUid(workSource.getUid(i));
- noteLongPartialWakeLockStartInternal(name, historyName, uid);
+ noteLongPartialWakeLockStartInternal(name, historyName, uid,
+ elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = workSource.getWorkChains();
@@ -4481,14 +4680,14 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain workChain = workChains.get(i);
final int uid = workChain.getAttributionUid();
- noteLongPartialWakeLockStartInternal(name, historyName, uid);
+ noteLongPartialWakeLockStartInternal(name, historyName, uid,
+ elapsedRealtimeMs, uptimeMs);
}
}
}
- private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
if (historyName == null) {
historyName = name;
}
@@ -4496,21 +4695,34 @@
0)) {
return;
}
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
historyName, uid);
}
public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
+ noteLongPartialWakelockFinish(name, historyName, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteLongPartialWakelockFinish(String name, String historyName, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- noteLongPartialWakeLockFinishInternal(name, historyName, uid);
+ noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
WorkSource workSource) {
+ noteLongPartialWakelockFinishFromSource(name, historyName, workSource,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
+ WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) {
final int N = workSource.size();
for (int i = 0; i < N; ++i) {
final int uid = mapUid(workSource.getUid(i));
- noteLongPartialWakeLockFinishInternal(name, historyName, uid);
+ noteLongPartialWakeLockFinishInternal(name, historyName, uid,
+ elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = workSource.getWorkChains();
@@ -4518,14 +4730,14 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain workChain = workChains.get(i);
final int uid = workChain.getAttributionUid();
- noteLongPartialWakeLockFinishInternal(name, historyName, uid);
+ noteLongPartialWakeLockFinishInternal(name, historyName, uid,
+ elapsedRealtimeMs, uptimeMs);
}
}
}
- private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
if (historyName == null) {
historyName = name;
}
@@ -4533,33 +4745,35 @@
0)) {
return;
}
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
historyName, uid);
}
- void aggregateLastWakeupUptimeLocked(long uptimeMs) {
+ void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mLastWakeupReason != null) {
- long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
+ long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs;
SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
- timer.add(deltaUptime * 1000, 1); // time in in microseconds
+ timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds
FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason,
- /* duration_usec */ deltaUptime * 1000);
+ /* duration_usec */ deltaUptimeMs * 1000);
mLastWakeupReason = null;
}
}
public void noteWakeupReasonLocked(String reason) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteWakeupReasonLocked(reason, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
+ Integer.toHexString(mHistoryCur.states));
- aggregateLastWakeupUptimeLocked(uptime);
+ aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
mHistoryCur.wakeReasonTag.string = reason;
mHistoryCur.wakeReasonTag.uid = 0;
mLastWakeupReason = reason;
- mLastWakeupUptimeMs = uptime;
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ mLastWakeupUptimeMs = uptimeMs;
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
public boolean startAddingCpuLocked() {
@@ -4567,21 +4781,23 @@
return mOnBatteryInternal;
}
- public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
- int statSystemTime, int statIOWaitTime, int statIrqTime,
- int statSoftIrqTime, int statIdleTime) {
- if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
- + " user=" + statUserTime + " sys=" + statSystemTime
- + " io=" + statIOWaitTime + " irq=" + statIrqTime
- + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
- mCurStepCpuUserTime += totalUTime;
- mCurStepCpuSystemTime += totalSTime;
- mCurStepStatUserTime += statUserTime;
- mCurStepStatSystemTime += statSystemTime;
- mCurStepStatIOWaitTime += statIOWaitTime;
- mCurStepStatIrqTime += statIrqTime;
- mCurStepStatSoftIrqTime += statSoftIrqTime;
- mCurStepStatIdleTime += statIdleTime;
+ public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs,
+ int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs,
+ int statSoftIrqTimeMs, int statIdleTimeMs) {
+ if (DEBUG) {
+ Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs
+ + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs
+ + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs
+ + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs);
+ }
+ mCurStepCpuUserTimeMs += totalUTimeMs;
+ mCurStepCpuSystemTimeMs += totalSTimeMs;
+ mCurStepStatUserTimeMs += statUserTimeMs;
+ mCurStepStatSystemTimeMs += statSystemTimeMs;
+ mCurStepStatIOWaitTimeMs += statIOWaitTimeMs;
+ mCurStepStatIrqTimeMs += statIrqTimeMs;
+ mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs;
+ mCurStepStatIdleTimeMs += statIdleTimeMs;
}
public void noteProcessDiedLocked(int uid, int pid) {
@@ -4592,65 +4808,76 @@
}
}
- public long getProcessWakeTime(int uid, int pid, long realtime) {
+ public long getProcessWakeTime(int uid, int pid, long realtimeMs) {
uid = mapUid(uid);
Uid u = mUidStats.get(uid);
if (u != null) {
Uid.Pid p = u.mPids.get(pid);
if (p != null) {
- return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
+ return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtimeMs - p.mWakeStartMs) : 0);
}
}
return 0;
}
- public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
+ public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) {
uid = mapUid(uid);
Uid u = mUidStats.get(uid);
if (u != null) {
- u.reportExcessiveCpuLocked(proc, overTime, usedTime);
+ u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs);
}
}
int mSensorNesting;
public void noteStartSensorLocked(int uid, int sensor) {
+ noteStartSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mSensorNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mSensorNesting++;
- getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStartSensor(sensor, elapsedRealtimeMs);
}
public void noteStopSensorLocked(int uid, int sensor) {
+ noteStopSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mSensorNesting--;
if (mSensorNesting == 0) {
mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
- getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteStopSensor(sensor, elapsedRealtimeMs);
}
int mGpsNesting;
public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) {
+ noteGpsChangedLocked(oldWs, newWs, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs,
+ long elapsedRealtimeMs, long uptimeMs) {
for (int i = 0; i < newWs.size(); ++i) {
- noteStartGpsLocked(newWs.getUid(i), null);
+ noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs);
}
for (int i = 0; i < oldWs.size(); ++i) {
- noteStopGpsLocked((oldWs.getUid(i)), null);
+ noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs);
}
List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs);
@@ -4658,28 +4885,27 @@
if (wcs[0] != null) {
final List<WorkChain> newChains = wcs[0];
for (int i = 0; i < newChains.size(); ++i) {
- noteStartGpsLocked(-1, newChains.get(i));
+ noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs);
}
}
if (wcs[1] != null) {
final List<WorkChain> goneChains = wcs[1];
for (int i = 0; i < goneChains.size(); ++i) {
- noteStopGpsLocked(-1, goneChains.get(i));
+ noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs);
}
}
}
}
- private void noteStartGpsLocked(int uid, WorkChain workChain) {
+ private void noteStartGpsLocked(int uid, WorkChain workChain,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = getAttributionUid(uid, workChain);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mGpsNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mGpsNesting++;
@@ -4692,20 +4918,19 @@
FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON);
}
- getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs);
}
- private void noteStopGpsLocked(int uid, WorkChain workChain) {
+ private void noteStopGpsLocked(int uid, WorkChain workChain,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = getAttributionUid(uid, workChain);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mGpsNesting--;
if (mGpsNesting == 0) {
mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- stopAllGpsSignalQualityTimersLocked(-1);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs);
mGpsSignalQualityBin = -1;
}
@@ -4717,29 +4942,31 @@
workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF);
}
- getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs);
}
public void noteGpsSignalQualityLocked(int signalLevel) {
+ noteGpsSignalQualityLocked(signalLevel, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) {
if (mGpsNesting == 0) {
return;
}
if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) {
- stopAllGpsSignalQualityTimersLocked(-1);
+ stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs);
return;
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mGpsSignalQualityBin != signalLevel) {
if (mGpsSignalQualityBin >= 0) {
- mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime);
+ mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs);
}
if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) {
- mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime);
+ mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs);
}
mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK)
| (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT);
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mGpsSignalQualityBin = signalLevel;
}
return;
@@ -4747,6 +4974,13 @@
@GuardedBy("this")
public void noteScreenStateLocked(int state) {
+ noteScreenStateLocked(state, mClocks.elapsedRealtime(), mClocks.uptimeMillis(),
+ System.currentTimeMillis());
+ }
+
+ @GuardedBy("this")
+ public void noteScreenStateLocked(int state,
+ long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) {
state = mPretendScreenOff ? Display.STATE_OFF : state;
// Battery stats relies on there being 4 states. To accommodate this, new states beyond the
@@ -4763,7 +4997,7 @@
}
if (mScreenState != state) {
- recordDailyStatsIfNeededLocked(true);
+ recordDailyStatsIfNeededLocked(true, currentTimeMs);
final int oldState = mScreenState;
mScreenState = state;
if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
@@ -4779,56 +5013,55 @@
}
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
-
boolean updateHistory = false;
if (isScreenDoze(state) && !isScreenDoze(oldState)) {
mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
- mScreenDozeTimer.startRunningLocked(elapsedRealtime);
+ mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs);
updateHistory = true;
} else if (isScreenDoze(oldState) && !isScreenDoze(state)) {
mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG;
- mScreenDozeTimer.stopRunningLocked(elapsedRealtime);
+ mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs);
updateHistory = true;
}
if (isScreenOn(state)) {
mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
+ Integer.toHexString(mHistoryCur.states));
- mScreenOnTimer.startRunningLocked(elapsedRealtime);
+ mScreenOnTimer.startRunningLocked(elapsedRealtimeMs);
if (mScreenBrightnessBin >= 0) {
- mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
+ mScreenBrightnessTimer[mScreenBrightnessBin]
+ .startRunningLocked(elapsedRealtimeMs);
}
updateHistory = true;
} else if (isScreenOn(oldState)) {
mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
+ Integer.toHexString(mHistoryCur.states));
- mScreenOnTimer.stopRunningLocked(elapsedRealtime);
+ mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs);
if (mScreenBrightnessBin >= 0) {
- mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
+ mScreenBrightnessTimer[mScreenBrightnessBin]
+ .stopRunningLocked(elapsedRealtimeMs);
}
updateHistory = true;
}
if (updateHistory) {
if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: "
+ Display.stateToString(state));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mExternalSync.scheduleCpuSyncDueToScreenStateChange(
mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning());
if (isScreenOn(state)) {
updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
- mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
+ uptimeMs * 1000, elapsedRealtimeMs * 1000);
// Fake a wake lock, so we consider the device waked as long as the screen is on.
noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false,
- elapsedRealtime, uptime);
+ elapsedRealtimeMs, uptimeMs);
} else if (isScreenOn(oldState)) {
noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL,
- elapsedRealtime, uptime);
+ elapsedRealtimeMs, uptimeMs);
updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
- mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
+ uptimeMs * 1000, elapsedRealtimeMs * 1000);
}
// Update discharge amounts.
if (mOnBatteryInternal) {
@@ -4839,23 +5072,27 @@
@UnsupportedAppUsage
public void noteScreenBrightnessLocked(int brightness) {
+ noteScreenBrightnessLocked(brightness, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteScreenBrightnessLocked(int brightness, long elapsedRealtimeMs, long uptimeMs) {
// Bin the brightness.
int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
if (bin < 0) bin = 0;
else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
if (mScreenBrightnessBin != bin) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
| (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
if (mScreenState == Display.STATE_ON) {
if (mScreenBrightnessBin >= 0) {
- mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
+ mScreenBrightnessTimer[mScreenBrightnessBin]
+ .stopRunningLocked(elapsedRealtimeMs);
}
- mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
+ mScreenBrightnessTimer[bin]
+ .startRunningLocked(elapsedRealtimeMs);
}
mScreenBrightnessBin = bin;
}
@@ -4863,36 +5100,50 @@
@UnsupportedAppUsage
public void noteUserActivityLocked(int uid, int event) {
+ noteUserActivityLocked(uid, event, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs) {
if (mOnBatteryInternal) {
uid = mapUid(uid);
- getUidStatsLocked(uid).noteUserActivityLocked(event);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event);
}
}
public void noteWakeUpLocked(String reason, int reasonUid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP,
+ noteWakeUpLocked(reason, reasonUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWakeUpLocked(String reason, int reasonUid,
+ long elapsedRealtimeMs, long uptimeMs) {
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP,
reason, reasonUid);
}
public void noteInteractiveLocked(boolean interactive) {
+ noteInteractiveLocked(interactive, mClocks.elapsedRealtime());
+ }
+
+ public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) {
if (mInteractive != interactive) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
mInteractive = interactive;
if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
if (interactive) {
- mInteractiveTimer.startRunningLocked(elapsedRealtime);
+ mInteractiveTimer.startRunningLocked(elapsedRealtimeMs);
} else {
- mInteractiveTimer.stopRunningLocked(elapsedRealtime);
+ mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs);
}
}
}
public void noteConnectivityChangedLocked(int type, String extra) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
+ noteConnectivityChangedLocked(type, extra,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteConnectivityChangedLocked(int type, String extra,
+ long elapsedRealtimeMs, long uptimeMs) {
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
extra, type);
mNumConnectivityChange++;
}
@@ -4902,15 +5153,19 @@
uid = mapUid(uid);
addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
uid);
- getUidStatsLocked(uid).noteMobileRadioApWakeupLocked();
+ getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked();
}
/**
* Updates the radio power state and returns true if an external stats collection should occur.
*/
public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
if (mMobileRadioPowerState != powerState) {
long realElapsedRealtimeMs;
final boolean active =
@@ -4918,31 +5173,31 @@
|| powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
if (active) {
if (uid > 0) {
- noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid);
+ noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid);
}
- mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
+ mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
} else {
realElapsedRealtimeMs = timestampNs / (1000*1000);
- long lastUpdateTimeMs = mMobileRadioActiveStartTime;
+ long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs;
if (realElapsedRealtimeMs < lastUpdateTimeMs) {
Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
+ " is before start time " + lastUpdateTimeMs);
- realElapsedRealtimeMs = elapsedRealtime;
- } else if (realElapsedRealtimeMs < elapsedRealtime) {
- mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
+ realElapsedRealtimeMs = elapsedRealtimeMs;
+ } else if (realElapsedRealtimeMs < elapsedRealtimeMs) {
+ mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs
- realElapsedRealtimeMs);
}
mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
}
if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mMobileRadioPowerState = powerState;
if (active) {
- mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
- mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
+ mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs);
+ mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs);
} else {
mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
@@ -4954,25 +5209,27 @@
}
public void notePowerSaveModeLocked(boolean enabled) {
+ notePowerSaveModeLocked(enabled, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) {
if (mPowerSaveModeEnabled != enabled) {
int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mPowerSaveModeEnabled = enabled;
if (enabled) {
mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
+ Integer.toHexString(mHistoryCur.states2));
- mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
+ mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs);
} else {
mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
+ Integer.toHexString(mHistoryCur.states2));
- mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
+ mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs);
}
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED,
enabled
? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON
@@ -4981,8 +5238,12 @@
}
public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteDeviceIdleModeLocked(mode, activeReason, activeUid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid,
+ long elapsedRealtimeMs, long uptimeMs) {
boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP;
if (mDeviceIdling && !nowIdling && activeReason == null) {
// We don't go out of general idling mode until explicitly taken out of
@@ -4996,7 +5257,7 @@
nowLightIdling = true;
}
if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE,
activeReason, activeUid);
}
if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) {
@@ -5012,17 +5273,17 @@
mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
if (nowIdling) {
- mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
+ mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs);
} else {
- mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
+ mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs);
}
}
if (mDeviceLightIdling != nowLightIdling) {
mDeviceLightIdling = nowLightIdling;
if (nowLightIdling) {
- mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime);
+ mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs);
} else {
- mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime);
+ mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs);
}
}
if (mDeviceIdleMode != mode) {
@@ -5030,24 +5291,24 @@
| (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- long lastDuration = elapsedRealtime - mLastIdleTimeStart;
- mLastIdleTimeStart = elapsedRealtime;
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs;
+ mLastIdleTimeStartMs = elapsedRealtimeMs;
if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
- if (lastDuration > mLongestLightIdleTime) {
- mLongestLightIdleTime = lastDuration;
+ if (lastDuration > mLongestLightIdleTimeMs) {
+ mLongestLightIdleTimeMs = lastDuration;
}
- mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime);
+ mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs);
} else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) {
- if (lastDuration > mLongestFullIdleTime) {
- mLongestFullIdleTime = lastDuration;
+ if (lastDuration > mLongestFullIdleTimeMs) {
+ mLongestFullIdleTimeMs = lastDuration;
}
- mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime);
+ mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs);
}
if (mode == DEVICE_IDLE_MODE_LIGHT) {
- mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime);
+ mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs);
} else if (mode == DEVICE_IDLE_MODE_DEEP) {
- mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime);
+ mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs);
}
mDeviceIdleMode = mode;
FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode);
@@ -5055,10 +5316,14 @@
}
public void notePackageInstalledLocked(String pkgName, long versionCode) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ notePackageInstalledLocked(pkgName, versionCode,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePackageInstalledLocked(String pkgName, long versionCode,
+ long elapsedRealtimeMs, long uptimeMs) {
// XXX need to figure out what to do with long version codes.
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED,
pkgName, (int)versionCode);
PackageChange pc = new PackageChange();
pc.mPackageName = pkgName;
@@ -5068,10 +5333,13 @@
}
public void notePackageUninstalledLocked(String pkgName) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
- pkgName, 0);
+ notePackageUninstalledLocked(pkgName, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePackageUninstalledLocked(String pkgName,
+ long elapsedRealtimeMs, long uptimeMs) {
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
+ HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0);
PackageChange pc = new PackageChange();
pc.mPackageName = pkgName;
pc.mUpdate = true;
@@ -5086,42 +5354,49 @@
}
void stopAllGpsSignalQualityTimersLocked(int except) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
+ stopAllGpsSignalQualityTimersLocked(except, mClocks.elapsedRealtime());
+ }
+
+ void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) {
for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
if (i == except) {
continue;
}
while (mGpsSignalQualityTimer[i].isRunningLocked()) {
- mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime);
+ mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs);
}
}
}
@UnsupportedAppUsage
public void notePhoneOnLocked() {
+ notePhoneOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) {
if (!mPhoneOn) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mPhoneOn = true;
- mPhoneOnTimer.startRunningLocked(elapsedRealtime);
+ mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs);
}
}
@UnsupportedAppUsage
public void notePhoneOffLocked() {
+ notePhoneOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mPhoneOn) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mPhoneOn = false;
- mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
+ mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
}
@@ -5133,7 +5408,8 @@
public void onReceive(Context context, Intent intent) {
final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
synchronized (BatteryStatsImpl.this) {
- noteUsbConnectionStateLocked(state);
+ noteUsbConnectionStateLocked(state, mClocks.elapsedRealtime(),
+ mClocks.uptimeMillis());
}
}
}, usbStateFilter);
@@ -5142,12 +5418,14 @@
final Intent usbState = context.registerReceiver(null, usbStateFilter);
final boolean initState = usbState != null && usbState.getBooleanExtra(
UsbManager.USB_CONNECTED, false);
- noteUsbConnectionStateLocked(initState);
+ noteUsbConnectionStateLocked(initState, mClocks.elapsedRealtime(),
+ mClocks.uptimeMillis());
}
}
}
- private void noteUsbConnectionStateLocked(boolean connected) {
+ private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs,
+ long uptimeMs) {
int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED;
if (mUsbDataState != newState) {
mUsbDataState = newState;
@@ -5156,18 +5434,17 @@
} else {
mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG;
}
- addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
- void stopAllPhoneSignalStrengthTimersLocked(int except) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
+ void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) {
for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) {
if (i == except) {
continue;
}
while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
- mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
+ mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs);
}
}
}
@@ -5185,7 +5462,8 @@
return state;
}
- private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
+ private void updateAllPhoneStateLocked(int state, int simState, int strengthBin,
+ long elapsedRealtimeMs, long uptimeMs) {
boolean scanning = false;
boolean newHistory = false;
@@ -5193,9 +5471,6 @@
mPhoneSimStateRaw = simState;
mPhoneSignalStrengthBinRaw = strengthBin;
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
-
if (simState == TelephonyManager.SIM_STATE_ABSENT) {
// In this case we will always be STATE_OUT_OF_SERVICE, so need
// to infer that we are scanning from other data.
@@ -5223,7 +5498,7 @@
newHistory = true;
if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
+ Integer.toHexString(mHistoryCur.states));
- mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
+ mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs);
FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state,
simState, strengthBin);
}
@@ -5236,7 +5511,7 @@
if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
+ Integer.toHexString(mHistoryCur.states));
newHistory = true;
- mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
+ mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs);
FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state,
simState, strengthBin);
}
@@ -5254,13 +5529,14 @@
if (mPhoneSignalStrengthBin != strengthBin) {
if (mPhoneSignalStrengthBin >= 0) {
mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
- elapsedRealtime);
+ elapsedRealtimeMs);
}
if (strengthBin >= 0) {
if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
- mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
+ mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs);
}
- mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
+ mHistoryCur.states =
+ (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
| (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
+ Integer.toHexString(mHistoryCur.states));
@@ -5268,13 +5544,13 @@
FrameworkStatsLog.write(
FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin);
} else {
- stopAllPhoneSignalStrengthTimersLocked(-1);
+ stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs);
}
mPhoneSignalStrengthBin = strengthBin;
}
if (newHistory) {
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
@@ -5283,18 +5559,37 @@
* @param state phone state from ServiceState.getState()
*/
public void notePhoneStateLocked(int state, int simState) {
- updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
+ notePhoneStateLocked(state, simState, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePhoneStateLocked(int state, int simState,
+ long elapsedRealtimeMs, long uptimeMs) {
+ updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw,
+ elapsedRealtimeMs, uptimeMs);
}
@UnsupportedAppUsage
public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
+ notePhoneSignalStrengthLocked(signalStrength,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePhoneSignalStrengthLocked(SignalStrength signalStrength,
+ long elapsedRealtimeMs, long uptimeMs) {
// Bin the strength.
int bin = signalStrength.getLevel();
- updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
+ updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin,
+ elapsedRealtimeMs, uptimeMs);
}
@UnsupportedAppUsage
public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) {
+ notePhoneDataConnectionStateLocked(dataType, hasData, serviceType,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType,
+ long elapsedRealtimeMs, long uptimeMs) {
// BatteryStats uses 0 to represent no network type.
// Telephony does not have a concept of no network type, and uses 0 to represent unknown.
// Unknown is included in DATA_CONNECTION_OTHER.
@@ -5318,312 +5613,374 @@
}
if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
if (mPhoneDataConnectionType != bin) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
| (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
if (mPhoneDataConnectionType >= 0) {
mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
- elapsedRealtime);
+ elapsedRealtimeMs);
}
mPhoneDataConnectionType = bin;
- mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
+ mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs);
}
}
public void noteWifiOnLocked() {
+ noteWifiOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) {
if (!mWifiOn) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mWifiOn = true;
- mWifiOnTimer.startRunningLocked(elapsedRealtime);
+ mWifiOnTimer.startRunningLocked(elapsedRealtimeMs);
scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI);
}
}
public void noteWifiOffLocked() {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteWifiOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mWifiOn) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mWifiOn = false;
- mWifiOnTimer.stopRunningLocked(elapsedRealtime);
+ mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs);
scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI);
}
}
@UnsupportedAppUsage
public void noteAudioOnLocked(int uid) {
+ noteAudioOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mAudioOnNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mAudioOnTimer.startRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mAudioOnTimer.startRunningLocked(elapsedRealtimeMs);
}
mAudioOnNesting++;
- getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteAudioTurnedOnLocked(elapsedRealtimeMs);
}
@UnsupportedAppUsage
public void noteAudioOffLocked(int uid) {
+ noteAudioOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mAudioOnNesting == 0) {
return;
}
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (--mAudioOnNesting == 0) {
mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mAudioOnTimer.stopRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteAudioTurnedOffLocked(elapsedRealtimeMs);
}
@UnsupportedAppUsage
public void noteVideoOnLocked(int uid) {
+ noteVideoOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mVideoOnNesting == 0) {
mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mVideoOnTimer.startRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mVideoOnTimer.startRunningLocked(elapsedRealtimeMs);
}
mVideoOnNesting++;
- getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteVideoTurnedOnLocked(elapsedRealtimeMs);
}
@UnsupportedAppUsage
public void noteVideoOffLocked(int uid) {
+ noteVideoOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mVideoOnNesting == 0) {
return;
}
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (--mVideoOnNesting == 0) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mVideoOnTimer.stopRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteVideoTurnedOffLocked(elapsedRealtimeMs);
}
public void noteResetAudioLocked() {
+ noteResetAudioLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mAudioOnNesting > 0) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mAudioOnNesting = 0;
mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- uid.noteResetAudioLocked(elapsedRealtime);
+ uid.noteResetAudioLocked(elapsedRealtimeMs);
}
}
}
public void noteResetVideoLocked() {
+ noteResetVideoLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mVideoOnNesting > 0) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mVideoOnNesting = 0;
mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- uid.noteResetVideoLocked(elapsedRealtime);
+ uid.noteResetVideoLocked(elapsedRealtimeMs);
}
}
}
public void noteActivityResumedLocked(int uid) {
+ noteActivityResumedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime());
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteActivityResumedLocked(elapsedRealtimeMs);
}
public void noteActivityPausedLocked(int uid) {
+ noteActivityPausedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime());
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteActivityPausedLocked(elapsedRealtimeMs);
}
public void noteVibratorOnLocked(int uid, long durationMillis) {
+ noteVibratorOnLocked(uid, durationMillis,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteVibratorOnLocked(int uid, long durationMillis,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs);
}
public void noteVibratorOffLocked(int uid) {
+ noteVibratorOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- getUidStatsLocked(uid).noteVibratorOffLocked();
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteVibratorOffLocked(elapsedRealtimeMs);
}
public void noteFlashlightOnLocked(int uid) {
+ noteFlashlightOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mFlashlightOnNesting++ == 0) {
mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteFlashlightTurnedOnLocked(elapsedRealtimeMs);
}
public void noteFlashlightOffLocked(int uid) {
+ noteFlashlightOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mFlashlightOnNesting == 0) {
return;
}
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (--mFlashlightOnNesting == 0) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteFlashlightTurnedOffLocked(elapsedRealtimeMs);
}
public void noteCameraOnLocked(int uid) {
+ noteCameraOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mCameraOnNesting++ == 0) {
mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mCameraOnTimer.startRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mCameraOnTimer.startRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteCameraTurnedOnLocked(elapsedRealtimeMs);
}
public void noteCameraOffLocked(int uid) {
+ noteCameraOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mCameraOnNesting == 0) {
return;
}
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (--mCameraOnNesting == 0) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mCameraOnTimer.stopRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteCameraTurnedOffLocked(elapsedRealtimeMs);
}
public void noteResetCameraLocked() {
+ noteResetCameraLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mCameraOnNesting > 0) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mCameraOnNesting = 0;
mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- uid.noteResetCameraLocked(elapsedRealtime);
+ uid.noteResetCameraLocked(elapsedRealtimeMs);
}
}
}
public void noteResetFlashlightLocked() {
+ noteResetFlashlightLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mFlashlightOnNesting > 0) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mFlashlightOnNesting = 0;
mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- uid.noteResetFlashlightLocked(elapsedRealtime);
+ uid.noteResetFlashlightLocked(elapsedRealtimeMs);
}
}
}
private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid,
- boolean isUnoptimized) {
+ boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) {
uid = getAttributionUid(uid, workChain);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mBluetoothScanNesting == 0) {
mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs);
}
mBluetoothScanNesting++;
- getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized);
}
public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
+ noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized,
+ long elapsedRealtimeMs, long uptimeMs) {
final int N = ws.size();
for (int i = 0; i < N; i++) {
- noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized);
+ noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized,
+ elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
- noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized);
+ noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized,
+ elapsedRealtimeMs, uptimeMs);
}
}
}
private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid,
- boolean isUnoptimized) {
+ boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) {
uid = getAttributionUid(uid, workChain);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mBluetoothScanNesting--;
if (mBluetoothScanNesting == 0) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized);
}
private int getAttributionUid(int uid, WorkChain workChain) {
@@ -5635,41 +5992,58 @@
}
public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
+ noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized,
+ long elapsedRealtimeMs, long uptimeMs) {
final int N = ws.size();
for (int i = 0; i < N; i++) {
- noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized);
+ noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized,
+ elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
- noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized);
+ noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized,
+ elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteResetBluetoothScanLocked() {
+ noteResetBluetoothScanLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mBluetoothScanNesting > 0) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mBluetoothScanNesting = 0;
mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
- mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+ mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
- uid.noteResetBluetoothScanLocked(elapsedRealtime);
+ uid.noteResetBluetoothScanLocked(elapsedRealtimeMs);
}
}
}
public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) {
+ noteBluetoothScanResultsFromSourceLocked(ws, numNewResults,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults,
+ long elapsedRealtimeMs, long uptimeMs) {
final int N = ws.size();
for (int i = 0; i < N; i++) {
int uid = mapUid(ws.getUid(i));
- getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteBluetoothScanResultsLocked(numNewResults);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -5677,7 +6051,8 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain wc = workChains.get(i);
int uid = mapUid(wc.getAttributionUid());
- getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteBluetoothScanResultsLocked(numNewResults);
}
}
}
@@ -5687,55 +6062,62 @@
uid = mapUid(uid);
addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
uid);
- getUidStatsLocked(uid).noteWifiRadioApWakeupLocked();
+ getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked();
}
public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteWifiRadioPowerState(powerState, timestampNs, uid,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid,
+ long elapsedRealtimeMs, long uptimeMs) {
if (mWifiRadioPowerState != powerState) {
final boolean active =
powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
|| powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
if (active) {
if (uid > 0) {
- noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid);
+ noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid);
}
mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
- mWifiActiveTimer.startRunningLocked(elapsedRealtime);
+ mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs);
} else {
mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
- mWifiActiveTimer.stopRunningLocked(
- timestampNs / (1000 * 1000));
+ mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000));
}
if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mWifiRadioPowerState = powerState;
}
}
public void noteWifiRunningLocked(WorkSource ws) {
+ noteWifiRunningLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
if (!mGlobalWifiRunning) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mGlobalWifiRunning = true;
- mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
+ mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
int N = ws.size();
for (int i=0; i<N; i++) {
int uid = mapUid(ws.getUid(i));
- getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiRunningLocked(elapsedRealtimeMs);
}
List<WorkChain> workChains = ws.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
int uid = mapUid(workChains.get(i).getAttributionUid());
- getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiRunningLocked(elapsedRealtimeMs);
}
}
@@ -5746,33 +6128,42 @@
}
public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
+ noteWifiRunningChangedLocked(oldWs, newWs,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs,
+ long elapsedRealtimeMs, long uptimeMs) {
if (mGlobalWifiRunning) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
int N = oldWs.size();
for (int i=0; i<N; i++) {
int uid = mapUid(oldWs.getUid(i));
- getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiStoppedLocked(elapsedRealtimeMs);
}
List<WorkChain> workChains = oldWs.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
int uid = mapUid(workChains.get(i).getAttributionUid());
- getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiStoppedLocked(elapsedRealtimeMs);
}
}
N = newWs.size();
for (int i=0; i<N; i++) {
int uid = mapUid(newWs.getUid(i));
- getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiRunningLocked(elapsedRealtimeMs);
}
workChains = newWs.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
int uid = mapUid(workChains.get(i).getAttributionUid());
- getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiRunningLocked(elapsedRealtimeMs);
}
}
} else {
@@ -5781,26 +6172,30 @@
}
public void noteWifiStoppedLocked(WorkSource ws) {
+ noteWifiStoppedLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
if (mGlobalWifiRunning) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mGlobalWifiRunning = false;
- mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
+ mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
int N = ws.size();
for (int i=0; i<N; i++) {
int uid = mapUid(ws.getUid(i));
- getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiStoppedLocked(elapsedRealtimeMs);
}
List<WorkChain> workChains = ws.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
int uid = mapUid(workChains.get(i).getAttributionUid());
- getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiStoppedLocked(elapsedRealtimeMs);
}
}
@@ -5811,71 +6206,79 @@
}
public void noteWifiStateLocked(int wifiState, String accessPoint) {
+ noteWifiStateLocked(wifiState, accessPoint, mClocks.elapsedRealtime());
+ }
+
+ public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) {
if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
if (mWifiState != wifiState) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
if (mWifiState >= 0) {
- mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
+ mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs);
}
mWifiState = wifiState;
- mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
+ mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs);
scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI);
}
}
public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
+ noteWifiSupplicantStateChangedLocked(supplState, failedAuth,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth,
+ long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
if (mWifiSupplState != supplState) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mWifiSupplState >= 0) {
- mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
+ mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs);
}
mWifiSupplState = supplState;
- mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
+ mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs);
mHistoryCur.states2 =
(mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
| (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
- void stopAllWifiSignalStrengthTimersLocked(int except) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
+ void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) {
for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
if (i == except) {
continue;
}
while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
- mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
+ mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs);
}
}
}
public void noteWifiRssiChangedLocked(int newRssi) {
+ noteWifiRssiChangedLocked(newRssi, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) {
int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
if (mWifiSignalStrengthBin != strengthBin) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mWifiSignalStrengthBin >= 0) {
mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
- elapsedRealtime);
+ elapsedRealtimeMs);
}
if (strengthBin >= 0) {
if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
- mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
+ mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs);
}
mHistoryCur.states2 =
(mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
| (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
+ Integer.toHexString(mHistoryCur.states2));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
} else {
- stopAllWifiSignalStrengthTimersLocked(-1);
+ stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs);
}
mWifiSignalStrengthBin = strengthBin;
}
@@ -5885,121 +6288,155 @@
@UnsupportedAppUsage
public void noteFullWifiLockAcquiredLocked(int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteFullWifiLockAcquiredLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mWifiFullLockNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mWifiFullLockNesting++;
- getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs);
}
@UnsupportedAppUsage
public void noteFullWifiLockReleasedLocked(int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteFullWifiLockReleasedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
mWifiFullLockNesting--;
if (mWifiFullLockNesting == 0) {
mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
- getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteFullWifiLockReleasedLocked(elapsedRealtimeMs);
}
int mWifiScanNesting = 0;
public void noteWifiScanStartedLocked(int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteWifiScanStartedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mWifiScanNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mWifiScanNesting++;
- getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiScanStartedLocked(elapsedRealtimeMs);
}
public void noteWifiScanStoppedLocked(int uid) {
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ noteWifiScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
mWifiScanNesting--;
if (mWifiScanNesting == 0) {
mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
- getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiScanStoppedLocked(elapsedRealtimeMs);
}
public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
+ noteWifiBatchedScanStartedLocked(uid, csph,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiBatchedScanStartedLocked(int uid, int csph,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs);
}
public void noteWifiBatchedScanStoppedLocked(int uid) {
+ noteWifiBatchedScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs);
}
int mWifiMulticastNesting = 0;
@UnsupportedAppUsage
public void noteWifiMulticastEnabledLocked(int uid) {
+ noteWifiMulticastEnabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
if (mWifiMulticastNesting == 0) {
mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
// Start Wifi Multicast overall timer
if (!mWifiMulticastWakelockTimer.isRunningLocked()) {
if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started");
- mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime);
+ mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs);
}
}
mWifiMulticastNesting++;
- getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiMulticastEnabledLocked(elapsedRealtimeMs);
}
@UnsupportedAppUsage
public void noteWifiMulticastDisabledLocked(int uid) {
+ noteWifiMulticastDisabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
mWifiMulticastNesting--;
if (mWifiMulticastNesting == 0) {
mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
+ Integer.toHexString(mHistoryCur.states));
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
// Stop Wifi Multicast overall timer
if (mWifiMulticastWakelockTimer.isRunningLocked()) {
if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped");
- mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime);
+ mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
}
}
- getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteWifiMulticastDisabledLocked(elapsedRealtimeMs);
}
public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
+ noteFullWifiLockAcquiredFromSourceLocked(ws,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws,
+ long elapsedRealtimeMs, long uptimeMs) {
int N = ws.size();
for (int i=0; i<N; i++) {
final int uid = mapUid(ws.getUid(i));
- noteFullWifiLockAcquiredLocked(uid);
+ noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6007,16 +6444,22 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain workChain = workChains.get(i);
final int uid = mapUid(workChain.getAttributionUid());
- noteFullWifiLockAcquiredLocked(uid);
+ noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
+ noteFullWifiLockReleasedFromSourceLocked(ws,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws,
+ long elapsedRealtimeMs, long uptimeMs) {
int N = ws.size();
for (int i=0; i<N; i++) {
final int uid = mapUid(ws.getUid(i));
- noteFullWifiLockReleasedLocked(uid);
+ noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6024,16 +6467,21 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain workChain = workChains.get(i);
final int uid = mapUid(workChain.getAttributionUid());
- noteFullWifiLockReleasedLocked(uid);
+ noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
+ noteWifiScanStartedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiScanStartedFromSourceLocked(WorkSource ws,
+ long elapsedRealtimeMs, long uptimeMs) {
int N = ws.size();
for (int i=0; i<N; i++) {
final int uid = mapUid(ws.getUid(i));
- noteWifiScanStartedLocked(uid);
+ noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6041,16 +6489,21 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain workChain = workChains.get(i);
final int uid = mapUid(workChain.getAttributionUid());
- noteWifiScanStartedLocked(uid);
+ noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
+ noteWifiScanStoppedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiScanStoppedFromSourceLocked(WorkSource ws,
+ long elapsedRealtimeMs, long uptimeMs) {
int N = ws.size();
for (int i=0; i<N; i++) {
final int uid = mapUid(ws.getUid(i));
- noteWifiScanStoppedLocked(uid);
+ noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6058,35 +6511,48 @@
for (int i = 0; i < workChains.size(); ++i) {
final WorkChain workChain = workChains.get(i);
final int uid = mapUid(workChain.getAttributionUid());
- noteWifiScanStoppedLocked(uid);
+ noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
+ noteWifiBatchedScanStartedFromSourceLocked(ws, csph,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph,
+ long elapsedRealtimeMs, long uptimeMs) {
int N = ws.size();
for (int i=0; i<N; i++) {
- noteWifiBatchedScanStartedLocked(ws.getUid(i), csph);
+ noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
- noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph);
+ noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph,
+ elapsedRealtimeMs, uptimeMs);
}
}
}
public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
+ noteWifiBatchedScanStoppedFromSourceLocked(ws,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+ public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws,
+ long elapsedRealtimeMs, long uptimeMs) {
int N = ws.size();
for (int i=0; i<N; i++) {
- noteWifiBatchedScanStoppedLocked(ws.getUid(i));
+ noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs);
}
final List<WorkChain> workChains = ws.getWorkChains();
if (workChains != null) {
for (int i = 0; i < workChains.size(); ++i) {
- noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid());
+ noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(),
+ elapsedRealtimeMs, uptimeMs);
}
}
}
@@ -6147,9 +6613,16 @@
*/
public void noteBinderCallStats(int workSourceUid, long incrementalCallCount,
Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids) {
+ noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, binderThreadNativeTids,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public void noteBinderCallStats(int workSourceUid, long incrementalCallCount,
+ Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids,
+ long elapsedRealtimeMs, long uptimeMs) {
synchronized (this) {
- getUidStatsLocked(workSourceUid).noteBinderCallStatsLocked(incrementalCallCount,
- callStats);
+ getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs)
+ .noteBinderCallStatsLocked(incrementalCallCount, callStats);
mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids);
}
}
@@ -6182,17 +6655,17 @@
for (int i = 0; i < mUidStats.size(); i++) {
Uid uid = mUidStats.valueAt(i);
- long totalTimeForUid = 0;
+ long totalTimeForUidUs = 0;
int totalCallCountForUid = 0;
ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats;
for (int j = binderCallStats.size() - 1; j >= 0; j--) {
BinderCallStats stats = binderCallStats.valueAt(j);
totalCallCountForUid += stats.callCount;
if (stats.recordedCallCount > 0) {
- totalTimeForUid +=
+ totalTimeForUidUs +=
stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount;
} else if (totalRecordedCallCount > 0) {
- totalTimeForUid +=
+ totalTimeForUidUs +=
stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount;
}
}
@@ -6200,13 +6673,13 @@
if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) {
// Estimate remaining calls, which were not tracked because of binder call
// stats sampling
- totalTimeForUid +=
+ totalTimeForUidUs +=
(uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros
/ totalRecordedCallCount;
}
- uid.mSystemServiceTimeUs = totalTimeForUid;
- totalSystemServiceTimeMicros += totalTimeForUid;
+ uid.mSystemServiceTimeUs = totalTimeForUidUs;
+ totalSystemServiceTimeMicros += totalTimeForUidUs;
}
for (int i = 0; i < mUidStats.size(); i++) {
@@ -6296,9 +6769,9 @@
@Override public long getLongestDeviceIdleModeTime(int mode) {
switch (mode) {
case DEVICE_IDLE_MODE_LIGHT:
- return mLongestLightIdleTime;
+ return mLongestLightIdleTimeMs;
case DEVICE_IDLE_MODE_DEEP:
- return mLongestFullIdleTime;
+ return mLongestFullIdleTimeMs;
}
return 0;
}
@@ -6328,12 +6801,12 @@
}
@Override public long getGpsSignalQualityTime(int strengthBin,
- long elapsedRealtimeUs, int which) {
+ long elapsedRealtimeUs, int which) {
if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) {
return 0;
}
return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked(
- elapsedRealtimeUs, which);
+ elapsedRealtimeUs, which);
}
@Override public long getGpsBatteryDrainMaMs() {
@@ -6344,11 +6817,11 @@
}
double energyUsedMaMs = 0.0;
final int which = STATS_SINCE_CHARGED;
- final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+ final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000;
for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
energyUsedMaMs
- += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i)
- * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000);
+ += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i)
+ * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000);
}
return (long) energyUsedMaMs;
}
@@ -6562,18 +7035,18 @@
}
@Override public long getStartClockTime() {
- final long currentTime = System.currentTimeMillis();
- if ((currentTime > MILLISECONDS_IN_YEAR
- && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR))
- || (mStartClockTime > currentTime)) {
+ final long currentTimeMs = System.currentTimeMillis();
+ if ((currentTimeMs > MILLISECONDS_IN_YEAR
+ && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR))
+ || (mStartClockTimeMs > currentTimeMs)) {
// If the start clock time has changed by more than a year, then presumably
// the previous time was completely bogus. So we are going to figure out a
// new time based on how much time has elapsed since we started counting.
- recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
+ recordCurrentTimeChangeLocked(currentTimeMs, mClocks.elapsedRealtime(),
mClocks.uptimeMillis());
- return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000));
+ return currentTimeMs - (mClocks.elapsedRealtime() - (mRealtimeStartUs / 1000));
}
- return mStartClockTime;
+ return mStartClockTimeMs;
}
@Override public String getStartPlatformVersion() {
@@ -6597,29 +7070,32 @@
return mUidStats;
}
- private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset) {
+ private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset,
+ long elapsedRealtimeUs) {
if (t != null) {
- return t.reset(detachIfReset);
+ return t.reset(detachIfReset, elapsedRealtimeUs);
}
return true;
}
- private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset) {
+ private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset,
+ long elapsedRealtimeUs) {
if (t != null) {
boolean ret = true;
for (int i = 0; i < t.length; i++) {
- ret &= resetIfNotNull(t[i], detachIfReset);
+ ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs);
}
return ret;
}
return true;
}
- private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset) {
+ private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset,
+ long elapsedRealtimeUs) {
if (t != null) {
boolean ret = true;
for (int i = 0; i < t.length; i++) {
- ret &= resetIfNotNull(t[i], detachIfReset);
+ ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs);
}
return ret;
}
@@ -6627,9 +7103,9 @@
}
private static boolean resetIfNotNull(ControllerActivityCounterImpl counter,
- boolean detachIfReset) {
+ boolean detachIfReset, long elapsedRealtimeUs) {
if (counter != null) {
- counter.reset(detachIfReset);
+ counter.reset(detachIfReset, elapsedRealtimeUs);
}
return true;
}
@@ -6812,10 +7288,10 @@
/**
* The CPU times we had at the last history details update.
*/
- long mLastStepUserTime;
- long mLastStepSystemTime;
- long mCurStepUserTime;
- long mCurStepSystemTime;
+ long mLastStepUserTimeMs;
+ long mLastStepSystemTimeMs;
+ long mCurStepUserTimeMs;
+ long mCurStepSystemTimeMs;
LongSamplingCounter mUserCpuTime;
LongSamplingCounter mSystemCpuTime;
@@ -6915,17 +7391,19 @@
private double mProportionalSystemServiceUsage;
public Uid(BatteryStatsImpl bsi, int uid) {
+ this(bsi, uid, bsi.mClocks.elapsedRealtime(), bsi.mClocks.uptimeMillis());
+ }
+
+ public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) {
mBsi = bsi;
mUid = uid;
/* Observer list of TimeBase object in Uid is short */
mOnBatteryBackgroundTimeBase = new TimeBase(false);
- mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
- mBsi.mClocks.elapsedRealtime() * 1000);
+ mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000);
/* Observer list of TimeBase object in Uid is short */
mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false);
- mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
- mBsi.mClocks.elapsedRealtime() * 1000);
+ mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000);
mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
@@ -7520,13 +7998,13 @@
return mVibratorOnTimer;
}
- public void noteVibratorOnLocked(long durationMillis) {
- createVibratorOnTimerLocked().addDuration(mBsi, durationMillis);
+ public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) {
+ createVibratorOnTimerLocked().addDuration(mBsi, durationMillis, elapsedRealtimeMs);
}
- public void noteVibratorOffLocked() {
+ public void noteVibratorOffLocked(long elapsedRealtimeMs) {
if (mVibratorOnTimer != null) {
- mVibratorOnTimer.abortLastDuration(mBsi);
+ mVibratorOnTimer.abortLastDuration(mBsi, elapsedRealtimeMs);
}
}
@@ -7962,58 +8440,58 @@
* inactive so can be dropped.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean reset(long uptime, long realtime) {
+ public boolean reset(long uptimeUs, long realtimeUs) {
boolean active = false;
- mOnBatteryBackgroundTimeBase.init(uptime, realtime);
- mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime);
+ mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs);
+ mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs);
if (mWifiRunningTimer != null) {
- active |= !mWifiRunningTimer.reset(false);
+ active |= !mWifiRunningTimer.reset(false, realtimeUs);
active |= mWifiRunning;
}
if (mFullWifiLockTimer != null) {
- active |= !mFullWifiLockTimer.reset(false);
+ active |= !mFullWifiLockTimer.reset(false, realtimeUs);
active |= mFullWifiLockOut;
}
if (mWifiScanTimer != null) {
- active |= !mWifiScanTimer.reset(false);
+ active |= !mWifiScanTimer.reset(false, realtimeUs);
active |= mWifiScanStarted;
}
if (mWifiBatchedScanTimer != null) {
for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (mWifiBatchedScanTimer[i] != null) {
- active |= !mWifiBatchedScanTimer[i].reset(false);
+ active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs);
}
}
active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
}
if (mWifiMulticastTimer != null) {
- active |= !mWifiMulticastTimer.reset(false);
+ active |= !mWifiMulticastTimer.reset(false, realtimeUs);
active |= (mWifiMulticastWakelockCount > 0);
}
- active |= !resetIfNotNull(mAudioTurnedOnTimer, false);
- active |= !resetIfNotNull(mVideoTurnedOnTimer, false);
- active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false);
- active |= !resetIfNotNull(mCameraTurnedOnTimer, false);
- active |= !resetIfNotNull(mForegroundActivityTimer, false);
- active |= !resetIfNotNull(mForegroundServiceTimer, false);
- active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false);
- active |= !resetIfNotNull(mBluetoothScanTimer, false);
- active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false);
+ active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs);
+ active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs);
- resetIfNotNull(mBluetoothScanResultCounter, false);
- resetIfNotNull(mBluetoothScanResultBgCounter, false);
+ resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs);
+ resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs);
if (mProcessStateTimer != null) {
for (int i = 0; i < NUM_PROCESS_STATE; i++) {
- active |= !resetIfNotNull(mProcessStateTimer[i], false);
+ active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs);
}
active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT);
}
if (mVibratorOnTimer != null) {
- if (mVibratorOnTimer.reset(false)) {
+ if (mVibratorOnTimer.reset(false, realtimeUs)) {
mVibratorOnTimer.detach();
mVibratorOnTimer = null;
} else {
@@ -8021,80 +8499,81 @@
}
}
- resetIfNotNull(mUserActivityCounters, false);
+ resetIfNotNull(mUserActivityCounters, false, realtimeUs);
- resetIfNotNull(mNetworkByteActivityCounters, false);
- resetIfNotNull(mNetworkPacketActivityCounters, false);
- resetIfNotNull(mMobileRadioActiveTime, false);
- resetIfNotNull(mMobileRadioActiveCount, false);
+ resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs);
+ resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs);
+ resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs);
+ resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs);
- resetIfNotNull(mWifiControllerActivity, false);
- resetIfNotNull(mBluetoothControllerActivity, false);
- resetIfNotNull(mModemControllerActivity, false);
+ resetIfNotNull(mWifiControllerActivity, false, realtimeUs);
+ resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs);
+ resetIfNotNull(mModemControllerActivity, false, realtimeUs);
- resetIfNotNull(mUserCpuTime, false);
- resetIfNotNull(mSystemCpuTime, false);
+ resetIfNotNull(mUserCpuTime, false, realtimeUs);
+ resetIfNotNull(mSystemCpuTime, false, realtimeUs);
- resetIfNotNull(mCpuClusterSpeedTimesUs, false);
+ resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs);
- resetIfNotNull(mCpuFreqTimeMs, false);
- resetIfNotNull(mScreenOffCpuFreqTimeMs, false);
+ resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */);
+ resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */);
- resetIfNotNull(mCpuActiveTimeMs, false);
- resetIfNotNull(mCpuClusterTimesMs, false);
+ resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */);
+ resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */);
- resetIfNotNull(mProcStateTimeMs, false);
+ resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */);
- resetIfNotNull(mProcStateScreenOffTimeMs, false);
+ resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */);
- resetIfNotNull(mMobileRadioApWakeupCount, false);
+ resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs);
- resetIfNotNull(mWifiRadioApWakeupCount, false);
+ resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs);
final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
for (int iw=wakeStats.size()-1; iw>=0; iw--) {
Wakelock wl = wakeStats.valueAt(iw);
- if (wl.reset()) {
+ if (wl.reset(realtimeUs)) {
wakeStats.removeAt(iw);
} else {
active = true;
}
}
- mWakelockStats.cleanup();
+ final long realtimeMs = realtimeUs / 1000;
+ mWakelockStats.cleanup(realtimeMs);
final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
for (int is=syncStats.size()-1; is>=0; is--) {
DualTimer timer = syncStats.valueAt(is);
- if (timer.reset(false)) {
+ if (timer.reset(false, realtimeUs)) {
syncStats.removeAt(is);
timer.detach();
} else {
active = true;
}
}
- mSyncStats.cleanup();
+ mSyncStats.cleanup(realtimeMs);
final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
for (int ij=jobStats.size()-1; ij>=0; ij--) {
DualTimer timer = jobStats.valueAt(ij);
- if (timer.reset(false)) {
+ if (timer.reset(false, realtimeUs)) {
jobStats.removeAt(ij);
timer.detach();
} else {
active = true;
}
}
- mJobStats.cleanup();
+ mJobStats.cleanup(realtimeMs);
mJobCompletions.clear();
- resetIfNotNull(mJobsDeferredEventCount, false);
- resetIfNotNull(mJobsDeferredCount, false);
- resetIfNotNull(mJobsFreshnessTimeMs, false);
- resetIfNotNull(mJobsFreshnessBuckets, false);
+ resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs);
+ resetIfNotNull(mJobsDeferredCount, false, realtimeUs);
+ resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */);
+ resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs);
for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) {
Sensor s = mSensorStats.valueAt(ise);
- if (s.reset()) {
+ if (s.reset(realtimeUs)) {
mSensorStats.removeAt(ise);
} else {
active = true;
@@ -8128,8 +8607,8 @@
mProportionalSystemServiceUsage = 0;
- mLastStepUserTime = mLastStepSystemTime = 0;
- mCurStepUserTime = mCurStepSystemTime = 0;
+ mLastStepUserTimeMs = mLastStepSystemTimeMs = 0;
+ mCurStepUserTimeMs = mCurStepSystemTimeMs = 0;
return !active;
@@ -8943,13 +9422,13 @@
return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in);
}
- boolean reset() {
+ boolean reset(long elapsedRealtimeUs) {
boolean wlactive = false;
- wlactive |= !resetIfNotNull(mTimerFull,false);
- wlactive |= !resetIfNotNull(mTimerPartial,false);
- wlactive |= !resetIfNotNull(mTimerWindow,false);
- wlactive |= !resetIfNotNull(mTimerDraw,false);
+ wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs);
+ wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs);
+ wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs);
+ wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs);
if (!wlactive) {
detachIfNotNull(mTimerFull);
@@ -9040,8 +9519,8 @@
return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in);
}
- boolean reset() {
- if (mTimer.reset(true)) {
+ boolean reset(long elapsedRealtimeUs) {
+ if (mTimer.reset(true, elapsedRealtimeUs)) {
mTimer = null;
return true;
}
@@ -9103,17 +9582,17 @@
/**
* Total time (in ms) spent executing in user code.
*/
- long mUserTime;
+ long mUserTimeMs;
/**
* Total time (in ms) spent executing in kernel code.
*/
- long mSystemTime;
+ long mSystemTimeMs;
/**
* Amount of time (in ms) the process was running in the foreground.
*/
- long mForegroundTime;
+ long mForegroundTimeMs;
/**
* Number of times the process has been started.
@@ -9138,14 +9617,16 @@
mBsi.mOnBatteryTimeBase.add(this);
}
- public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs,
+ long baseRealtimeUs) {
}
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs,
+ long baseRealtimeUs) {
}
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
if (detachIfReset) {
this.detach();
}
@@ -9169,14 +9650,14 @@
return null;
}
- public void addExcessiveCpu(long overTime, long usedTime) {
+ public void addExcessiveCpu(long overTimeMs, long usedTimeMs) {
if (mExcessivePower == null) {
mExcessivePower = new ArrayList<ExcessivePower>();
}
ExcessivePower ew = new ExcessivePower();
ew.type = ExcessivePower.TYPE_CPU;
- ew.overTime = overTime;
- ew.usedTime = usedTime;
+ ew.overTime = overTimeMs;
+ ew.usedTime = usedTimeMs;
mExcessivePower.add(ew);
}
@@ -9219,9 +9700,9 @@
}
void writeToParcelLocked(Parcel out) {
- out.writeLong(mUserTime);
- out.writeLong(mSystemTime);
- out.writeLong(mForegroundTime);
+ out.writeLong(mUserTimeMs);
+ out.writeLong(mSystemTimeMs);
+ out.writeLong(mForegroundTimeMs);
out.writeInt(mStarts);
out.writeInt(mNumCrashes);
out.writeInt(mNumAnrs);
@@ -9229,9 +9710,9 @@
}
void readFromParcelLocked(Parcel in) {
- mUserTime = in.readLong();
- mSystemTime = in.readLong();
- mForegroundTime = in.readLong();
+ mUserTimeMs = in.readLong();
+ mSystemTimeMs = in.readLong();
+ mForegroundTimeMs = in.readLong();
mStarts = in.readInt();
mNumCrashes = in.readInt();
mNumAnrs = in.readInt();
@@ -9239,20 +9720,20 @@
}
@UnsupportedAppUsage
- public void addCpuTimeLocked(int utime, int stime) {
- addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning());
+ public void addCpuTimeLocked(int utimeMs, int stimeMs) {
+ addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning());
}
- public void addCpuTimeLocked(int utime, int stime, boolean isRunning) {
+ public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) {
if (isRunning) {
- mUserTime += utime;
- mSystemTime += stime;
+ mUserTimeMs += utimeMs;
+ mSystemTimeMs += stimeMs;
}
}
@UnsupportedAppUsage
- public void addForegroundTimeLocked(long ttime) {
- mForegroundTime += ttime;
+ public void addForegroundTimeLocked(long ttimeMs) {
+ mForegroundTimeMs += ttimeMs;
}
@UnsupportedAppUsage
@@ -9276,19 +9757,19 @@
@Override
@UnsupportedAppUsage
public long getUserTime(int which) {
- return mUserTime;
+ return mUserTimeMs;
}
@Override
@UnsupportedAppUsage
public long getSystemTime(int which) {
- return mSystemTime;
+ return mSystemTimeMs;
}
@Override
@UnsupportedAppUsage
public long getForegroundTime(int which) {
- return mForegroundTime;
+ return mForegroundTimeMs;
}
@Override
@@ -9333,14 +9814,16 @@
mBsi.mOnBatteryScreenOffTimeBase.add(this);
}
- public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs,
+ long baseRealtimeUs) {
}
- public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs,
+ long baseRealtimeUs) {
}
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
if (detachIfReset) {
this.detach();
}
@@ -9430,13 +9913,13 @@
/**
* Total time (ms in battery uptime) the service has been left started.
*/
- protected long mStartTime;
+ protected long mStartTimeMs;
/**
* If service has been started and not yet stopped, this is
* when it was started.
*/
- protected long mRunningSince;
+ protected long mRunningSinceMs;
/**
* True if we are currently running.
@@ -9451,13 +9934,13 @@
/**
* Total time (ms in battery uptime) the service has been left launched.
*/
- protected long mLaunchedTime;
+ protected long mLaunchedTimeMs;
/**
* If service has been launched and not yet exited, this is
* when it was launched (ms in battery uptime).
*/
- protected long mLaunchedSince;
+ protected long mLaunchedSinceMs;
/**
* True if we are currently launched.
@@ -9477,16 +9960,16 @@
mBsi.mOnBatteryTimeBase.add(this);
}
- public void onTimeStarted(long elapsedRealtime, long baseUptime,
- long baseRealtime) {
+ public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs,
+ long baseRealtimeUs) {
}
- public void onTimeStopped(long elapsedRealtime, long baseUptime,
- long baseRealtime) {
+ public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs,
+ long baseRealtimeUs) {
}
@Override
- public boolean reset(boolean detachIfReset) {
+ public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) {
if (detachIfReset) {
this.detach();
}
@@ -9495,59 +9978,68 @@
/**
* Remove this Serv as a listener from the time base.
- */
+ Ms*/
@Override
public void detach() {
mBsi.mOnBatteryTimeBase.remove(this);
}
public void readFromParcelLocked(Parcel in) {
- mStartTime = in.readLong();
- mRunningSince = in.readLong();
+ mStartTimeMs = in.readLong();
+ mRunningSinceMs = in.readLong();
mRunning = in.readInt() != 0;
mStarts = in.readInt();
- mLaunchedTime = in.readLong();
- mLaunchedSince = in.readLong();
+ mLaunchedTimeMs = in.readLong();
+ mLaunchedSinceMs = in.readLong();
mLaunched = in.readInt() != 0;
mLaunches = in.readInt();
}
public void writeToParcelLocked(Parcel out) {
- out.writeLong(mStartTime);
- out.writeLong(mRunningSince);
+ out.writeLong(mStartTimeMs);
+ out.writeLong(mRunningSinceMs);
out.writeInt(mRunning ? 1 : 0);
out.writeInt(mStarts);
- out.writeLong(mLaunchedTime);
- out.writeLong(mLaunchedSince);
+ out.writeLong(mLaunchedTimeMs);
+ out.writeLong(mLaunchedSinceMs);
out.writeInt(mLaunched ? 1 : 0);
out.writeInt(mLaunches);
}
- public long getLaunchTimeToNowLocked(long batteryUptime) {
- if (!mLaunched) return mLaunchedTime;
- return mLaunchedTime + batteryUptime - mLaunchedSince;
+ public long getLaunchTimeToNowLocked(long batteryUptimeMs) {
+ if (!mLaunched) return mLaunchedTimeMs;
+ return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs;
}
- public long getStartTimeToNowLocked(long batteryUptime) {
- if (!mRunning) return mStartTime;
- return mStartTime + batteryUptime - mRunningSince;
+ public long getStartTimeToNowLocked(long batteryUptimeMs) {
+ if (!mRunning) return mStartTimeMs;
+ return mStartTimeMs + batteryUptimeMs - mRunningSinceMs;
}
@UnsupportedAppUsage
public void startLaunchedLocked() {
+ startLaunchedLocked(mBsi.mClocks.uptimeMillis());
+ }
+
+ public void startLaunchedLocked(long uptimeMs) {
if (!mLaunched) {
mLaunches++;
- mLaunchedSince = mBsi.getBatteryUptimeLocked();
+ mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000;
mLaunched = true;
}
}
@UnsupportedAppUsage
public void stopLaunchedLocked() {
+ stopLaunchedLocked(mBsi.mClocks.uptimeMillis());
+ }
+
+ public void stopLaunchedLocked(long uptimeMs) {
if (mLaunched) {
- long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince;
- if (time > 0) {
- mLaunchedTime += time;
+ long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000
+ - mLaunchedSinceMs;
+ if (timeMs > 0) {
+ mLaunchedTimeMs += timeMs;
} else {
mLaunches--;
}
@@ -9557,19 +10049,28 @@
@UnsupportedAppUsage
public void startRunningLocked() {
+ startRunningLocked(mBsi.mClocks.uptimeMillis());
+ }
+
+ public void startRunningLocked(long uptimeMs) {
if (!mRunning) {
mStarts++;
- mRunningSince = mBsi.getBatteryUptimeLocked();
+ mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000;
mRunning = true;
}
}
@UnsupportedAppUsage
public void stopRunningLocked() {
+ stopRunningLocked(mBsi.mClocks.uptimeMillis());
+ }
+
+ public void stopRunningLocked(long uptimeMs) {
if (mRunning) {
- long time = mBsi.getBatteryUptimeLocked() - mRunningSince;
- if (time > 0) {
- mStartTime += time;
+ long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000
+ - mRunningSinceMs;
+ if (timeMs > 0) {
+ mStartTimeMs += timeMs;
} else {
mStarts--;
}
@@ -9619,6 +10120,12 @@
@GuardedBy("mBsi")
public void updateUidProcessStateLocked(int procState) {
+ updateUidProcessStateLocked(procState,
+ mBsi.mClocks.elapsedRealtime(), mBsi.mClocks.uptimeMillis());
+ }
+
+ public void updateUidProcessStateLocked(int procState,
+ long elapsedRealtimeMs, long uptimeMs) {
int uidRunningState;
// Make special note of Foreground Services
final boolean userAwareService =
@@ -9629,10 +10136,7 @@
return;
}
- final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime();
if (mProcessState != uidRunningState) {
- final long uptimeMs = mBsi.mClocks.uptimeMillis();
-
if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
@@ -9789,28 +10293,28 @@
}
public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
- DualTimer t = mSyncStats.startObject(name);
+ DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs);
if (t != null) {
t.startRunningLocked(elapsedRealtimeMs);
}
}
public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
- DualTimer t = mSyncStats.stopObject(name);
+ DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs);
if (t != null) {
t.stopRunningLocked(elapsedRealtimeMs);
}
}
public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
- DualTimer t = mJobStats.startObject(name);
+ DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs);
if (t != null) {
t.startRunningLocked(elapsedRealtimeMs);
}
}
public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) {
- DualTimer t = mJobStats.stopObject(name);
+ DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs);
if (t != null) {
t.stopRunningLocked(elapsedRealtimeMs);
}
@@ -9873,7 +10377,7 @@
}
public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
- Wakelock wl = mWakelockStats.startObject(name);
+ Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs);
if (wl != null) {
getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs);
}
@@ -9889,7 +10393,7 @@
}
public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
- Wakelock wl = mWakelockStats.stopObject(name);
+ Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs);
if (wl != null) {
StopwatchTimer wlt = getWakelockTimerLocked(wl, type);
wlt.stopRunningLocked(elapsedRealtimeMs);
@@ -9910,10 +10414,10 @@
}
}
- public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
+ public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) {
Proc p = getProcessStatsLocked(proc);
if (p != null) {
- p.addExcessiveCpu(overTime, usedTime);
+ p.addExcessiveCpu(overTimeMs, usedTimeMs);
}
}
@@ -10041,16 +10545,16 @@
mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
mOnBattery = mOnBatteryInternal = false;
- long uptime = mClocks.uptimeMillis() * 1000;
- long realtime = mClocks.elapsedRealtime() * 1000;
- initTimes(uptime, realtime);
+ long uptimeUs = mClocks.uptimeMillis() * 1000;
+ long realtimeUs = mClocks.elapsedRealtime() * 1000;
+ initTimes(uptimeUs, realtimeUs);
mStartPlatformVersion = mEndPlatformVersion = Build.ID;
mDischargeStartLevel = 0;
mDischargeUnplugLevel = 0;
mDischargePlugLevel = -1;
mDischargeCurrentLevel = 0;
mCurrentBatteryLevel = 0;
- initDischarge();
+ initDischarge(realtimeUs);
clearHistoryLocked();
updateDailyDeadlineLocked();
mPlatformIdleStateCallback = cb;
@@ -10110,9 +10614,9 @@
mCallback = cb;
}
- public void setRadioScanningTimeoutLocked(long timeout) {
+ public void setRadioScanningTimeoutLocked(long timeoutUs) {
if (mPhoneSignalScanningTimer != null) {
- mPhoneSignalScanningTimer.setTimeout(timeout);
+ mPhoneSignalScanningTimer.setTimeout(timeoutUs);
}
}
@@ -10122,9 +10626,9 @@
public void updateDailyDeadlineLocked() {
// Get the current time.
- long currentTime = mDailyStartTime = System.currentTimeMillis();
+ long currentTimeMs = mDailyStartTimeMs = System.currentTimeMillis();
Calendar calDeadline = Calendar.getInstance();
- calDeadline.setTimeInMillis(currentTime);
+ calDeadline.setTimeInMillis(currentTimeMs);
// Move time up to the next day, ranging from 1am to 3pm.
calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
@@ -10132,25 +10636,24 @@
calDeadline.set(Calendar.SECOND, 0);
calDeadline.set(Calendar.MINUTE, 0);
calDeadline.set(Calendar.HOUR_OF_DAY, 1);
- mNextMinDailyDeadline = calDeadline.getTimeInMillis();
+ mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis();
calDeadline.set(Calendar.HOUR_OF_DAY, 3);
- mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
+ mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis();
}
- public void recordDailyStatsIfNeededLocked(boolean settled) {
- long currentTime = System.currentTimeMillis();
- if (currentTime >= mNextMaxDailyDeadline) {
+ public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) {
+ if (currentTimeMs >= mNextMaxDailyDeadlineMs) {
recordDailyStatsLocked();
- } else if (settled && currentTime >= mNextMinDailyDeadline) {
+ } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) {
recordDailyStatsLocked();
- } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
+ } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) {
recordDailyStatsLocked();
}
}
public void recordDailyStatsLocked() {
DailyItem item = new DailyItem();
- item.mStartTime = mDailyStartTime;
+ item.mStartTime = mDailyStartTimeMs;
item.mEndTime = System.currentTimeMillis();
boolean hasData = false;
if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
@@ -10175,7 +10678,7 @@
updateDailyDeadlineLocked();
if (hasData) {
- final long startTime = SystemClock.uptimeMillis();
+ final long startTimeMs = SystemClock.uptimeMillis();
mDailyItems.add(item);
while (mDailyItems.size() > MAX_DAILY_ITEMS) {
mDailyItems.remove(0);
@@ -10185,12 +10688,12 @@
XmlSerializer out = new FastXmlSerializer();
out.setOutput(memStream, StandardCharsets.UTF_8.name());
writeDailyItemsLocked(out);
- final long initialTime = SystemClock.uptimeMillis() - startTime;
+ final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs;
BackgroundThread.getHandler().post(new Runnable() {
@Override
public void run() {
synchronized (mCheckinFile) {
- final long startTime2 = SystemClock.uptimeMillis();
+ final long startTimeMs2 = SystemClock.uptimeMillis();
FileOutputStream stream = null;
try {
stream = mDailyFile.startWrite();
@@ -10199,7 +10702,7 @@
mDailyFile.finishWrite(stream);
com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
"batterystats-daily",
- initialTime + SystemClock.uptimeMillis() - startTime2);
+ initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2);
} catch (IOException e) {
Slog.w("BatteryStats",
"Error writing battery daily items", e);
@@ -10431,17 +10934,17 @@
@Override
public long getCurrentDailyStartTime() {
- return mDailyStartTime;
+ return mDailyStartTimeMs;
}
@Override
public long getNextMinDailyDeadline() {
- return mNextMinDailyDeadline;
+ return mNextMinDailyDeadlineMs;
}
@Override
public long getNextMaxDailyDeadline() {
- return mNextMaxDailyDeadline;
+ return mNextMaxDailyDeadlineMs;
}
@Override
@@ -10554,12 +11057,12 @@
if (p == null) {
return false;
}
- final long lastRealtime = out.time;
- final long lastWalltime = out.currentTime;
+ final long lastRealtimeMs = out.time;
+ final long lastWalltimeMs = out.currentTime;
readHistoryDelta(p, out);
if (out.cmd != HistoryItem.CMD_CURRENT_TIME
- && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
- out.currentTime = lastWalltime + (out.time - lastRealtime);
+ && out.cmd != HistoryItem.CMD_RESET && lastWalltimeMs != 0) {
+ out.currentTime = lastWalltimeMs + (out.time - lastRealtimeMs);
}
return true;
}
@@ -10574,7 +11077,7 @@
@Override
public long getHistoryBaseTime() {
- return mHistoryBaseTime;
+ return mHistoryBaseTimeMs;
}
@Override
@@ -10604,17 +11107,17 @@
return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND;
}
- void initTimes(long uptime, long realtime) {
- mStartClockTime = System.currentTimeMillis();
- mOnBatteryTimeBase.init(uptime, realtime);
- mOnBatteryScreenOffTimeBase.init(uptime, realtime);
- mRealtime = 0;
- mUptime = 0;
- mRealtimeStart = realtime;
- mUptimeStart = uptime;
+ void initTimes(long uptimeUs, long realtimeUs) {
+ mStartClockTimeMs = System.currentTimeMillis();
+ mOnBatteryTimeBase.init(uptimeUs, realtimeUs);
+ mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs);
+ mRealtimeUs = 0;
+ mUptimeUs = 0;
+ mRealtimeStartUs = realtimeUs;
+ mUptimeStartUs = uptimeUs;
}
- void initDischarge() {
+ void initDischarge(long elapsedRealtimeUs) {
mLowDischargeAmountSinceCharge = 0;
mHighDischargeAmountSinceCharge = 0;
mDischargeAmountScreenOn = 0;
@@ -10625,26 +11128,26 @@
mDischargeAmountScreenDozeSinceCharge = 0;
mDischargeStepTracker.init();
mChargeStepTracker.init();
- mDischargeScreenOffCounter.reset(false);
- mDischargeScreenDozeCounter.reset(false);
- mDischargeLightDozeCounter.reset(false);
- mDischargeDeepDozeCounter.reset(false);
- mDischargeCounter.reset(false);
+ mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs);
+ mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs);
+ mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs);
+ mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs);
+ mDischargeCounter.reset(false, elapsedRealtimeUs);
}
public void resetAllStatsCmdLocked() {
- resetAllStatsLocked();
final long mSecUptime = mClocks.uptimeMillis();
- long uptime = mSecUptime * 1000;
+ long uptimeUs = mSecUptime * 1000;
long mSecRealtime = mClocks.elapsedRealtime();
- long realtime = mSecRealtime * 1000;
+ long realtimeUs = mSecRealtime * 1000;
+ resetAllStatsLocked(mSecUptime, mSecRealtime);
mDischargeStartLevel = mHistoryCur.batteryLevel;
pullPendingStateUpdatesLocked();
addHistoryRecordLocked(mSecRealtime, mSecUptime);
mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
= mCurrentBatteryLevel = mHistoryCur.batteryLevel;
- mOnBatteryTimeBase.reset(uptime, realtime);
- mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
+ mOnBatteryTimeBase.reset(uptimeUs, realtimeUs);
+ mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs);
if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
if (isScreenOn(mScreenState)) {
mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
@@ -10666,15 +11169,15 @@
initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
}
- private void resetAllStatsLocked() {
- final long uptimeMillis = mClocks.uptimeMillis();
- final long elapsedRealtimeMillis = mClocks.elapsedRealtime();
+ private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis) {
+ final long uptimeUs = uptimeMillis * 1000;
+ final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000;
mStartCount = 0;
- initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000);
- mScreenOnTimer.reset(false);
- mScreenDozeTimer.reset(false);
+ initTimes(uptimeUs, elapsedRealtimeUs);
+ mScreenOnTimer.reset(false, uptimeUs);
+ mScreenDozeTimer.reset(false, elapsedRealtimeUs);
for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
- mScreenBrightnessTimer[i].reset(false);
+ mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs);
}
if (mPowerProfile != null) {
@@ -10684,60 +11187,60 @@
}
mMinLearnedBatteryCapacity = -1;
mMaxLearnedBatteryCapacity = -1;
- mInteractiveTimer.reset(false);
- mPowerSaveModeEnabledTimer.reset(false);
- mLastIdleTimeStart = elapsedRealtimeMillis;
- mLongestLightIdleTime = 0;
- mLongestFullIdleTime = 0;
- mDeviceIdleModeLightTimer.reset(false);
- mDeviceIdleModeFullTimer.reset(false);
- mDeviceLightIdlingTimer.reset(false);
- mDeviceIdlingTimer.reset(false);
- mPhoneOnTimer.reset(false);
- mAudioOnTimer.reset(false);
- mVideoOnTimer.reset(false);
- mFlashlightOnTimer.reset(false);
- mCameraOnTimer.reset(false);
- mBluetoothScanTimer.reset(false);
+ mInteractiveTimer.reset(false, elapsedRealtimeUs);
+ mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs);
+ mLastIdleTimeStartMs = elapsedRealtimeMillis;
+ mLongestLightIdleTimeMs = 0;
+ mLongestFullIdleTimeMs = 0;
+ mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs);
+ mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs);
+ mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs);
+ mDeviceIdlingTimer.reset(false, elapsedRealtimeUs);
+ mPhoneOnTimer.reset(false, elapsedRealtimeUs);
+ mAudioOnTimer.reset(false, elapsedRealtimeUs);
+ mVideoOnTimer.reset(false, elapsedRealtimeUs);
+ mFlashlightOnTimer.reset(false, elapsedRealtimeUs);
+ mCameraOnTimer.reset(false, elapsedRealtimeUs);
+ mBluetoothScanTimer.reset(false, elapsedRealtimeUs);
for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) {
- mPhoneSignalStrengthsTimer[i].reset(false);
+ mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs);
}
- mPhoneSignalScanningTimer.reset(false);
+ mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
- mPhoneDataConnectionsTimer[i].reset(false);
+ mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs);
}
for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
- mNetworkByteActivityCounters[i].reset(false);
- mNetworkPacketActivityCounters[i].reset(false);
+ mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs);
+ mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs);
}
- mMobileRadioActiveTimer.reset(false);
- mMobileRadioActivePerAppTimer.reset(false);
- mMobileRadioActiveAdjustedTime.reset(false);
- mMobileRadioActiveUnknownTime.reset(false);
- mMobileRadioActiveUnknownCount.reset(false);
- mWifiOnTimer.reset(false);
- mGlobalWifiRunningTimer.reset(false);
+ mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs);
+ mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs);
+ mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs);
+ mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs);
+ mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs);
+ mWifiOnTimer.reset(false, elapsedRealtimeUs);
+ mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs);
for (int i=0; i<NUM_WIFI_STATES; i++) {
- mWifiStateTimer[i].reset(false);
+ mWifiStateTimer[i].reset(false, elapsedRealtimeUs);
}
for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
- mWifiSupplStateTimer[i].reset(false);
+ mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs);
}
for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
- mWifiSignalStrengthsTimer[i].reset(false);
+ mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs);
}
- mWifiMulticastWakelockTimer.reset(false);
- mWifiActiveTimer.reset(false);
- mWifiActivity.reset(false);
+ mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs);
+ mWifiActiveTimer.reset(false, elapsedRealtimeUs);
+ mWifiActivity.reset(false, elapsedRealtimeUs);
for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
- mGpsSignalQualityTimer[i].reset(false);
+ mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs);
}
- mBluetoothActivity.reset(false);
- mModemActivity.reset(false);
+ mBluetoothActivity.reset(false, elapsedRealtimeUs);
+ mModemActivity.reset(false, elapsedRealtimeUs);
mNumConnectivityChange = 0;
for (int i=0; i<mUidStats.size(); i++) {
- if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) {
+ if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs)) {
mUidStats.valueAt(i).detachFromTimeBase();
mUidStats.remove(mUidStats.keyAt(i));
i--;
@@ -10780,25 +11283,25 @@
mTmpRailStats.reset();
- resetIfNotNull(mSystemServerThreadCpuTimesUs, false);
- resetIfNotNull(mBinderThreadCpuTimesUs, false);
+ resetIfNotNull(mSystemServerThreadCpuTimesUs, false, elapsedRealtimeUs);
+ resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs);
mLastHistoryStepDetails = null;
- mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
- mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
- mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
- mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
- mLastStepStatUserTime = mCurStepStatUserTime = 0;
- mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
- mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
- mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
- mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
- mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
+ mLastStepCpuUserTimeMs = mLastStepCpuSystemTimeMs = 0;
+ mCurStepCpuUserTimeMs = mCurStepCpuSystemTimeMs = 0;
+ mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0;
+ mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0;
+ mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0;
+ mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0;
+ mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0;
+ mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0;
+ mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0;
+ mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0;
mNumAllUidCpuTimeReads = 0;
mNumUidsRemoved = 0;
- initDischarge();
+ initDischarge(elapsedRealtimeUs);
clearHistoryLocked();
mBatteryStatsHistory.resetAllFiles();
@@ -10915,6 +11418,14 @@
* @param info The energy information from the WiFi controller.
*/
public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) {
+ updateWifiState(info, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ /**
+ * @see #updateWifiState(WifiActivityEnergyInfo)
+ */
+ public void updateWifiState(@Nullable final WifiActivityEnergyInfo info,
+ long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_ENERGY) {
Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
}
@@ -10939,7 +11450,6 @@
return;
}
- final long elapsedRealtimeMs = mClocks.elapsedRealtime();
SparseLongArray rxPackets = new SparseLongArray();
SparseLongArray txPackets = new SparseLongArray();
long totalTxPackets = 0;
@@ -10961,7 +11471,7 @@
continue;
}
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs);
if (entry.rxBytes != 0) {
u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
entry.rxPackets);
@@ -11127,7 +11637,8 @@
// Distribute the remaining Tx power appropriately between all apps that transmitted
// packets.
for (int i = 0; i < txPackets.size(); i++) {
- final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
+ final Uid uid = getUidStatsLocked(txPackets.keyAt(i),
+ elapsedRealtimeMs, uptimeMs);
final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs)
/ totalTxPackets;
if (DEBUG_ENERGY) {
@@ -11140,7 +11651,8 @@
// Distribute the remaining Rx power appropriately between all apps that received
// packets.
for (int i = 0; i < rxPackets.size(); i++) {
- final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
+ final Uid uid = getUidStatsLocked(rxPackets.keyAt(i),
+ elapsedRealtimeMs, uptimeMs);
final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs)
/ totalRxPackets;
if (DEBUG_ENERGY) {
@@ -11179,7 +11691,7 @@
monitoredRailChargeConsumedMaMs);
mHistoryCur.wifiRailChargeMah +=
(monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
- addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mTmpRailStats.resetWifiTotalEnergyUsed();
}
}
@@ -11210,13 +11722,21 @@
* Distribute Cell radio energy info and network traffic to apps.
*/
public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) {
+ updateMobileRadioState(activityInfo, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ /**
+ * @see #updateMobileRadioState(ModemActivityInfo)
+ */
+ public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo,
+ long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_ENERGY) {
Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
}
ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo);
// Add modem tx power to history.
- addModemTxPowerToHistory(deltaInfo);
+ addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs);
// Grab a separate lock to acquire the network stats, which may do I/O.
NetworkStats delta = null;
@@ -11279,12 +11799,11 @@
monitoredRailChargeConsumedMaMs);
mHistoryCur.modemRailChargeMah +=
(monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
- addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mTmpRailStats.resetCellularTotalEnergyUsed();
}
}
- final long elapsedRealtimeMs = mClocks.elapsedRealtime();
- long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
+ long radioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
elapsedRealtimeMs * 1000);
mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
@@ -11308,7 +11827,7 @@
totalRxPackets += entry.rxPackets;
totalTxPackets += entry.txPackets;
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs);
u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
entry.rxPackets);
u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
@@ -11339,16 +11858,17 @@
continue;
}
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ final Uid u = getUidStatsLocked(mapUid(entry.uid),
+ elapsedRealtimeMs, uptimeMs);
// Distribute total radio active time in to this app.
final long appPackets = entry.rxPackets + entry.txPackets;
- final long appRadioTime = (radioTime * appPackets) / totalPackets;
- u.noteMobileRadioActiveTimeLocked(appRadioTime);
+ final long appRadioTimeUs = (radioTimeUs * appPackets) / totalPackets;
+ u.noteMobileRadioActiveTimeLocked(appRadioTimeUs);
// Remove this app from the totals, so that we don't lose any time
// due to rounding.
- radioTime -= appRadioTime;
+ radioTimeUs -= appRadioTimeUs;
totalPackets -= appPackets;
if (deltaInfo != null) {
@@ -11373,9 +11893,9 @@
}
}
- if (radioTime > 0) {
+ if (radioTimeUs > 0) {
// Whoops, there is some radio time we can't blame on an app!
- mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
+ mMobileRadioActiveUnknownTime.addCountLocked(radioTimeUs);
mMobileRadioActiveUnknownCount.addCountLocked(1);
}
@@ -11391,7 +11911,8 @@
* time at the highest power level.
* @param activityInfo
*/
- private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) {
+ private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo,
+ long elapsedRealtimeMs, long uptimeMs) {
if (activityInfo == null) {
return;
}
@@ -11399,8 +11920,6 @@
if (txPowerInfo == null || txPowerInfo.size() != ModemActivityInfo.TX_POWER_LEVELS) {
return;
}
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
int levelMaxTimeSpent = 0;
for (int i = 1; i < txPowerInfo.size(); i++) {
if (txPowerInfo.get(i).getTimeInMillis() > txPowerInfo.get(levelMaxTimeSpent)
@@ -11410,7 +11929,7 @@
}
if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) {
mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
@@ -11446,6 +11965,14 @@
* @param info The energy information from the bluetooth controller.
*/
public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
+ updateBluetoothStateLocked(info, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ /**
+ * @see #updateBluetoothStateLocked(BluetoothActivityEnergyInfo)
+ */
+ public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info,
+ long elapsedRealtimeMs, long uptimeMs) {
if (DEBUG_ENERGY) {
Slog.d(TAG, "Updating bluetooth stats: " + info);
}
@@ -11456,7 +11983,6 @@
mHasBluetoothReporting = true;
- final long elapsedRealtimeMs = mClocks.elapsedRealtime();
final long rxTimeMs =
info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs;
final long txTimeMs =
@@ -11560,7 +12086,7 @@
mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes);
// Add to the UID counters.
- final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
+ final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs);
u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0);
u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0);
@@ -11579,7 +12105,7 @@
final long txBytes =
traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid);
- final Uid u = getUidStatsLocked(mapUid(uid));
+ final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs);
final ControllerActivityCounterImpl counter =
u.getOrCreateBluetoothControllerActivityLocked();
@@ -11623,6 +12149,13 @@
* instead of fetching it anew.
*/
public void updateRpmStatsLocked() {
+ updateRpmStatsLocked(mClocks.elapsedRealtime() * 1000);
+ }
+
+ /**
+ * @see #updateRpmStatsLocked()
+ */
+ public void updateRpmStatsLocked(long elapsedRealtimeUs) {
if (mPlatformIdleStateCallback == null) return;
long now = SystemClock.elapsedRealtime();
if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) {
@@ -11637,9 +12170,9 @@
final String pName = pstate.getKey();
final long pTimeUs = pstate.getValue().mTimeMs * 1000;
final int pCount = pstate.getValue().mCount;
- getRpmTimerLocked(pName).update(pTimeUs, pCount);
+ getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs);
if (SCREEN_OFF_RPM_STATS_ENABLED) {
- getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount);
+ getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs);
}
// Update values for each voter of this platform state.
@@ -11648,9 +12181,9 @@
final String vName = pName + "." + voter.getKey();
final long vTimeUs = voter.getValue().mTimeMs * 1000;
final int vCount = voter.getValue().mCount;
- getRpmTimerLocked(vName).update(vTimeUs, vCount);
+ getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs);
if (SCREEN_OFF_RPM_STATS_ENABLED) {
- getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount);
+ getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs);
}
}
}
@@ -11664,9 +12197,9 @@
final String name = subsysName + "." + sstate.getKey();
final long timeUs = sstate.getValue().mTimeMs * 1000;
final int count = sstate.getValue().mCount;
- getRpmTimerLocked(name).update(timeUs, count);
+ getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs);
if (SCREEN_OFF_RPM_STATS_ENABLED) {
- getScreenOffRpmTimerLocked(name).update(timeUs, count);
+ getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs);
}
}
}
@@ -11686,6 +12219,13 @@
* Read and distribute kernel wake lock use across apps.
*/
public void updateKernelWakelocksLocked() {
+ updateKernelWakelocksLocked(mClocks.elapsedRealtime() * 1000);
+ }
+
+ /**
+ * @see #updateKernelWakelocksLocked()
+ */
+ public void updateKernelWakelocksLocked(long elapsedRealtimeUs) {
final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
mTmpWakelockStats);
if (wakelockStats == null) {
@@ -11704,7 +12244,7 @@
mKernelWakelockStats.put(name, kwlt);
}
- kwlt.update(kws.mTotalTime, kws.mCount);
+ kwlt.update(kws.mTotalTime, kws.mCount, elapsedRealtimeUs);
kwlt.setUpdateVersion(kws.mVersion);
}
@@ -11714,7 +12254,7 @@
for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
SamplingTimer st = ent.getValue();
if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
- st.endSample();
+ st.endSample(elapsedRealtimeUs);
numWakelocksSetStale++;
}
}
@@ -11742,6 +12282,10 @@
* Reads the newest memory stats from the kernel.
*/
public void updateKernelMemoryBandwidthLocked() {
+ updateKernelMemoryBandwidthLocked(mClocks.elapsedRealtime() * 1000);
+ }
+
+ public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) {
mKernelMemoryBandwidthStats.updateStats();
LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries();
final int bandwidthEntryCount = bandwidthEntries.size();
@@ -11754,12 +12298,12 @@
timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer);
}
- timer.update(bandwidthEntries.valueAt(i), 1);
+ timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs);
if (DEBUG_MEMORY) {
Slog.d(TAG, String.format("Added entry %d and updated timer to: "
- + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i),
+ + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i),
mKernelMemoryStats.get(
- bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime,
+ bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTimeUs,
mKernelMemoryStats.size()));
}
}
@@ -11898,8 +12442,8 @@
}
if (DEBUG_BINDER_STATS) {
Slog.d(TAG, "System server threads per CPU cluster (binder threads/total threads/%)");
- long binderThreadTime = 0;
- long totalThreadTime = 0;
+ long binderThreadTimeMs = 0;
+ long totalThreadTimeMs = 0;
int cpuIndex = 0;
for (int cluster = 0; cluster < numCpuClusters; cluster++) {
StringBuilder sb = new StringBuilder();
@@ -11909,26 +12453,27 @@
if (speed != 0) {
sb.append(", ");
}
- long totalCount = mSystemServerThreadCpuTimesUs[cluster][speed].getCountLocked(
- 0) / 1000;
- long binderCount = mBinderThreadCpuTimesUs[cluster][speed].getCountLocked(0)
+ long totalCountMs =
+ mSystemServerThreadCpuTimesUs[cluster][speed].getCountLocked(0) / 1000;
+ long binderCountMs = mBinderThreadCpuTimesUs[cluster][speed].getCountLocked(0)
/ 1000;
sb.append(String.format("%d/%d(%.1f%%)",
- binderCount,
- totalCount,
- totalCount != 0 ? (double) binderCount * 100 / totalCount : 0));
+ binderCountMs,
+ totalCountMs,
+ totalCountMs != 0 ? (double) binderCountMs * 100 / totalCountMs : 0));
- totalThreadTime += totalCount;
- binderThreadTime += binderCount;
+ totalThreadTimeMs += totalCountMs;
+ binderThreadTimeMs += binderCountMs;
index++;
}
cpuIndex += mPowerProfile.getNumCoresInCpuCluster(cluster);
Slog.d(TAG, sb.toString());
}
- Slog.d(TAG, "Total system server thread time (ms): " + totalThreadTime);
+ Slog.d(TAG, "Total system server thread time (ms): " + totalThreadTimeMs);
Slog.d(TAG, String.format("Total Binder thread time (ms): %d (%.1f%%)",
- binderThreadTime,
- binderThreadTime != 0 ? (double) binderThreadTime * 100 / totalThreadTime : 0));
+ binderThreadTimeMs,
+ binderThreadTimeMs != 0
+ ? (double) binderThreadTimeMs * 100 / totalThreadTimeMs : 0));
}
}
@@ -11985,8 +12530,10 @@
// So, we distribute total time spent by an uid to different cpu freqs based on the
// amount of time cpu was running at that freq.
final int updatedUidsCount = updatedUids.size();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ final long uptimeMs = mClocks.uptimeMillis();
for (int i = 0; i < updatedUidsCount; ++i) {
- final Uid u = getUidStatsLocked(updatedUids.keyAt(i));
+ final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs);
final long appCpuTimeUs = updatedUids.valueAt(i);
// Add the cpu speeds to this UID.
final int numClusters = mPowerProfile.getNumCpuClusters();
@@ -12031,6 +12578,7 @@
mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0;
final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
final long startTimeMs = mClocks.uptimeMillis();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> {
long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
@@ -12048,7 +12596,7 @@
mCpuUidUserSysTimeReader.removeUid(uid);
return;
}
- final Uid u = getUidStatsLocked(uid);
+ final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs);
// Accumulate the total system and user time.
mTempTotalCpuUserTimeUs += userTimeUs;
@@ -12144,6 +12692,7 @@
final int numClusters = mPowerProfile.getNumCpuClusters();
mWakeLockAllocationsUs = null;
final long startTimeMs = mClocks.uptimeMillis();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
@@ -12156,7 +12705,7 @@
mCpuUidFreqTimeReader.removeUid(uid);
return;
}
- final Uid u = getUidStatsLocked(uid);
+ final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs);
if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
detachIfNotNull(u.mCpuFreqTimeMs);
u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
@@ -12257,6 +12806,7 @@
@VisibleForTesting
public void readKernelUidCpuActiveTimesLocked(boolean onBattery) {
final long startTimeMs = mClocks.uptimeMillis();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
@@ -12269,7 +12819,7 @@
mCpuUidActiveTimeReader.removeUid(uid);
return;
}
- final Uid u = getUidStatsLocked(uid);
+ final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs);
u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery);
});
@@ -12286,6 +12836,7 @@
@VisibleForTesting
public void readKernelUidCpuClusterTimesLocked(boolean onBattery) {
final long startTimeMs = mClocks.uptimeMillis();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
@@ -12298,7 +12849,7 @@
mCpuUidClusterTimeReader.removeUid(uid);
return;
}
- final Uid u = getUidStatsLocked(uid);
+ final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs);
u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery);
});
@@ -12338,8 +12889,8 @@
m.arg1 = onBattery ? 1 : 0;
mHandler.sendMessage(m);
- final long uptime = mSecUptime * 1000;
- final long realtime = mSecRealtime * 1000;
+ final long uptimeUs = mSecUptime * 1000;
+ final long realtimeUs = mSecRealtime * 1000;
final int screenState = mScreenState;
if (onBattery) {
// We will reset our status if we are unplugging after the
@@ -12358,14 +12909,14 @@
// stats to be reported in the next checkin. Only do this if we have
// a sufficient amount of data to make it interesting.
if (getLowDischargeAmountSinceCharge() >= 20) {
- final long startTime = SystemClock.uptimeMillis();
+ final long startTimeMs = SystemClock.uptimeMillis();
final Parcel parcel = Parcel.obtain();
writeSummaryToParcel(parcel, true);
- final long initialTime = SystemClock.uptimeMillis() - startTime;
+ final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs;
BackgroundThread.getHandler().post(new Runnable() {
@Override public void run() {
synchronized (mCheckinFile) {
- final long startTime2 = SystemClock.uptimeMillis();
+ final long startTimeMs2 = SystemClock.uptimeMillis();
FileOutputStream stream = null;
try {
stream = mCheckinFile.startWrite();
@@ -12373,8 +12924,8 @@
stream.flush();
mCheckinFile.finishWrite(stream);
com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
- "batterystats-checkin",
- initialTime + SystemClock.uptimeMillis() - startTime2);
+ "batterystats-checkin", initialTimeMs
+ + SystemClock.uptimeMillis() - startTimeMs2);
} catch (IOException e) {
Slog.w("BatteryStats",
"Error writing checkin battery statistics", e);
@@ -12387,7 +12938,7 @@
});
}
doWrite = true;
- resetAllStatsLocked();
+ resetAllStatsLocked(mSecUptime, mSecRealtime);
if (chargeUAh > 0 && level > 0) {
// Only use the reported coulomb charge value if it is supported and reported.
mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0));
@@ -12434,7 +12985,7 @@
mDischargeAmountScreenOn = 0;
mDischargeAmountScreenDoze = 0;
mDischargeAmountScreenOff = 0;
- updateTimeBasesLocked(true, screenState, uptime, realtime);
+ updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs);
} else {
mLastChargingStateLevel = level;
mOnBattery = mOnBatteryInternal = false;
@@ -12450,14 +13001,14 @@
mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
}
updateDischargeScreenLevelsLocked(screenState, screenState);
- updateTimeBasesLocked(false, screenState, uptime, realtime);
+ updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs);
mChargeStepTracker.init();
mLastChargeStepLevel = level;
mMaxChargeStepLevel = level;
mInitStepMode = mCurStepMode;
mModStepMode = 0;
}
- if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
+ if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) {
if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) {
writeAsyncLocked();
}
@@ -12477,18 +13028,18 @@
}
}
- private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
- final long uptimeMs) {
+ private void recordCurrentTimeChangeLocked(final long currentTimeMs,
+ final long elapsedRealtimeMs, final long uptimeMs) {
if (mRecordingHistory) {
- mHistoryCur.currentTime = currentTime;
+ mHistoryCur.currentTime = currentTimeMs;
addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur);
mHistoryCur.currentTime = 0;
}
}
- private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
+ private void recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs) {
if (mRecordingHistory) {
- mHistoryCur.currentTime = System.currentTimeMillis();
+ mHistoryCur.currentTime = currentTimeMs;
addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur);
mHistoryCur.currentTime = 0;
}
@@ -12507,6 +13058,15 @@
public void setBatteryStateLocked(final int status, final int health, final int plugType,
final int level, /* not final */ int temp, final int volt, final int chargeUAh,
final int chargeFullUAh, final long chargeTimeToFullSeconds) {
+ setBatteryStateLocked(status, health, plugType, level, temp, volt, chargeUAh,
+ chargeFullUAh, chargeTimeToFullSeconds,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis(), System.currentTimeMillis());
+ }
+
+ public void setBatteryStateLocked(final int status, final int health, final int plugType,
+ final int level, /* not final */ int temp, final int volt, final int chargeUAh,
+ final int chargeFullUAh, final long chargeTimeToFullSeconds,
+ final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) {
// Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
temp = Math.max(0, temp);
@@ -12514,8 +13074,6 @@
status, plugType, level);
final boolean onBattery = isOnBattery(plugType, status);
- final long uptime = mClocks.uptimeMillis();
- final long elapsedRealtime = mClocks.elapsedRealtime();
if (!mHaveBatteryLevel) {
mHaveBatteryLevel = true;
// We start out assuming that the device is plugged in (not
@@ -12538,20 +13096,20 @@
mLastChargeStepLevel = mLastDischargeStepLevel = level;
mLastChargingStateLevel = level;
} else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
- recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
+ recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs);
}
int oldStatus = mHistoryCur.batteryStatus;
if (onBattery) {
mDischargeCurrentLevel = level;
if (!mRecordingHistory) {
mRecordingHistory = true;
- startRecordingHistory(elapsedRealtime, uptime, true);
+ startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
}
} else if (level < 96 &&
status != BatteryManager.BATTERY_STATUS_UNKNOWN) {
if (!mRecordingHistory) {
mRecordingHistory = true;
- startRecordingHistory(elapsedRealtime, uptime, true);
+ startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
}
}
mCurrentBatteryLevel = level;
@@ -12581,7 +13139,7 @@
}
}
mHistoryCur.batteryChargeUAh = chargeUAh;
- setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh);
+ setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUAh);
} else {
boolean changed = false;
if (mHistoryCur.batteryLevel != level) {
@@ -12641,9 +13199,9 @@
changed |= setChargingLocked(false);
if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
- modeBits, elapsedRealtime);
+ modeBits, elapsedRealtimeMs);
mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
- modeBits, elapsedRealtime);
+ modeBits, elapsedRealtimeMs);
mLastDischargeStepLevel = level;
mMinDischargeStepLevel = level;
mInitStepMode = mCurStepMode;
@@ -12681,9 +13239,9 @@
}
if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
- modeBits, elapsedRealtime);
+ modeBits, elapsedRealtimeMs);
mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
- modeBits, elapsedRealtime);
+ modeBits, elapsedRealtimeMs);
mMaxChargeStepLevel = level;
mInitStepMode = mCurStepMode;
mModStepMode = 0;
@@ -12691,7 +13249,7 @@
mLastChargeStepLevel = level;
}
if (changed) {
- addHistoryRecordLocked(elapsedRealtime, uptime);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
if (!onBattery &&
@@ -12737,7 +13295,7 @@
public long getAwakeTimeBattery() {
// This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked());
// for over a decade, but surely that was a mistake.
- return getBatteryUptimeLocked();
+ return getBatteryUptimeLocked(mClocks.uptimeMillis());
}
@UnsupportedAppUsage
@@ -12746,35 +13304,35 @@
}
@Override
- public long computeUptime(long curTime, int which) {
- return mUptime + (curTime - mUptimeStart);
+ public long computeUptime(long curTimeUs, int which) {
+ return mUptimeUs + (curTimeUs - mUptimeStartUs);
}
@Override
- public long computeRealtime(long curTime, int which) {
- return mRealtime + (curTime - mRealtimeStart);
+ public long computeRealtime(long curTimeUs, int which) {
+ return mRealtimeUs + (curTimeUs - mRealtimeStartUs);
}
@Override
@UnsupportedAppUsage
- public long computeBatteryUptime(long curTime, int which) {
- return mOnBatteryTimeBase.computeUptime(curTime, which);
+ public long computeBatteryUptime(long curTimeUs, int which) {
+ return mOnBatteryTimeBase.computeUptime(curTimeUs, which);
}
@Override
@UnsupportedAppUsage
- public long computeBatteryRealtime(long curTime, int which) {
- return mOnBatteryTimeBase.computeRealtime(curTime, which);
+ public long computeBatteryRealtime(long curTimeUs, int which) {
+ return mOnBatteryTimeBase.computeRealtime(curTimeUs, which);
}
@Override
- public long computeBatteryScreenOffUptime(long curTime, int which) {
- return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
+ public long computeBatteryScreenOffUptime(long curTimeUs, int which) {
+ return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which);
}
@Override
- public long computeBatteryScreenOffRealtime(long curTime, int which) {
- return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
+ public long computeBatteryScreenOffRealtime(long curTimeUs, int which) {
+ return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which);
}
private long computeTimePerLevel(long[] steps, int numSteps) {
@@ -12877,7 +13435,7 @@
/*@hide */
public CellularBatteryStats getCellularBatteryStats() {
final int which = STATS_SINCE_CHARGED;
- final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
+ final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000;
final ControllerActivityCounter counter = getModemControllerActivity();
final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which);
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
@@ -12887,13 +13445,13 @@
counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES];
for (int i = 0; i < timeInRatMs.length; i++) {
- timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000;
+ timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000;
}
long[] timeInRxSignalStrengthLevelMs =
new long[CellSignalStrength.getNumSignalStrengthLevels()];
for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) {
- timeInRxSignalStrengthLevelMs[i]
- = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000;
+ timeInRxSignalStrengthLevelMs[i] =
+ getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000;
}
long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS,
counter.getTxTimeCounters().length)];
@@ -12903,8 +13461,8 @@
totalTxTimeMs += txTimeMs[i];
}
- return new CellularBatteryStats(computeBatteryRealtime(rawRealTime, which) / 1000,
- getMobileRadioActiveTime(rawRealTime, which) / 1000,
+ return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000,
+ getMobileRadioActiveTime(rawRealTimeUs, which) / 1000,
getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which),
getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which),
getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which),
@@ -12917,7 +13475,7 @@
/*@hide */
public WifiBatteryStats getWifiBatteryStats() {
final int which = STATS_SINCE_CHARGED;
- final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
+ final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000;
final ControllerActivityCounter counter = getWifiControllerActivity();
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
@@ -12936,19 +13494,19 @@
}
long[] timeInStateMs = new long[NUM_WIFI_STATES];
for (int i=0; i<NUM_WIFI_STATES; i++) {
- timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000;
+ timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000;
}
long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES];
for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
- timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000;
+ timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000;
}
long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS];
for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
- timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000;
+ timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000;
}
return new WifiBatteryStats(
- computeBatteryRealtime(rawRealTime, which) / 1000,
- getWifiActiveTime(rawRealTime, which) / 1000,
+ computeBatteryRealtime(rawRealTimeUs, which) / 1000,
+ getWifiActiveTime(rawRealTimeUs, which) / 1000,
getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which),
getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which),
getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which),
@@ -12962,12 +13520,12 @@
public GpsBatteryStats getGpsBatteryStats() {
GpsBatteryStats s = new GpsBatteryStats();
final int which = STATS_SINCE_CHARGED;
- final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
- s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
+ final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000;
+ s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000);
s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs());
long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS];
for (int i=0; i<time.length; i++) {
- time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000;
+ time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000;
}
s.setTimeInGpsSignalQualityLevel(time);
return s;
@@ -12988,19 +13546,29 @@
return mDailyPackageChanges;
}
+ /**
+ * @return battery uptime in microseconds
+ */
protected long getBatteryUptimeLocked() {
- return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000);
+ return getBatteryUptimeLocked(mClocks.uptimeMillis());
+ }
+
+ /**
+ * @return battery uptime in microseconds
+ */
+ protected long getBatteryUptimeLocked(long uptimeMs) {
+ return mOnBatteryTimeBase.getUptime(uptimeMs * 1000);
}
@Override
- public long getBatteryUptime(long curTime) {
- return mOnBatteryTimeBase.getUptime(curTime);
+ public long getBatteryUptime(long curTimeUs) {
+ return mOnBatteryTimeBase.getUptime(curTimeUs);
}
@Override
@UnsupportedAppUsage
- public long getBatteryRealtime(long curTime) {
- return mOnBatteryTimeBase.getRealtime(curTime);
+ public long getBatteryRealtime(long curTimeUs) {
+ return mOnBatteryTimeBase.getRealtime(curTimeUs);
}
@Override
@@ -13188,22 +13756,22 @@
return 0;
}
- final long uidTimeAtCpuSpeed = systemUid.getTimeAtCpuSpeed(cluster, step,
+ final long uidTimeAtCpuSpeedUs = systemUid.getTimeAtCpuSpeed(cluster, step,
BatteryStats.STATS_SINCE_CHARGED);
- if (uidTimeAtCpuSpeed == 0) {
+ if (uidTimeAtCpuSpeedUs == 0) {
return 0;
}
- final long uidThreadTime =
+ final long uidThreadTimeUs =
threadTimesForCluster[step].getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
- if (uidThreadTime == 0) {
+ if (uidThreadTimeUs == 0) {
return 0;
}
- final long binderThreadTime = mBinderThreadCpuTimesUs[cluster][step].getCountLocked(
+ final long binderThreadTimeUs = mBinderThreadCpuTimesUs[cluster][step].getCountLocked(
BatteryStats.STATS_SINCE_CHARGED);
- return uidTimeAtCpuSpeed * binderThreadTime / uidThreadTime;
+ return uidTimeAtCpuSpeedUs * binderThreadTimeUs / uidThreadTimeUs;
}
/**
@@ -13211,9 +13779,13 @@
*/
@UnsupportedAppUsage
public Uid getUidStatsLocked(int uid) {
+ return getUidStatsLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
Uid u = mUidStats.get(uid);
if (u == null) {
- u = new Uid(this, uid);
+ u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs);
mUidStats.put(uid, u);
}
return u;
@@ -13229,10 +13801,14 @@
}
public void onCleanupUserLocked(int userId) {
+ onCleanupUserLocked(userId, mClocks.elapsedRealtime());
+ }
+
+ public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) {
final int firstUidForUser = UserHandle.getUid(userId, 0);
final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
mPendingRemovedUids.add(
- new UidToRemove(firstUidForUser, lastUidForUser, mClocks.elapsedRealtime()));
+ new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs));
}
public void onUserRemovedLocked(int userId) {
@@ -13256,12 +13832,19 @@
*/
@UnsupportedAppUsage
public void removeUidStatsLocked(int uid) {
+ removeUidStatsLocked(uid, mClocks.elapsedRealtime());
+ }
+
+ /**
+ * @see #removeUidStatsLocked(int)
+ */
+ public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) {
final Uid u = mUidStats.get(uid);
if (u != null) {
u.detachFromTimeBase();
}
mUidStats.remove(uid);
- mPendingRemovedUids.add(new UidToRemove(uid, mClocks.elapsedRealtime()));
+ mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs));
}
/**
@@ -13270,8 +13853,16 @@
*/
@UnsupportedAppUsage
public Uid.Proc getProcessStatsLocked(int uid, String name) {
+ return getProcessStatsLocked(uid, name, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ /**
+ * @see #getProcessStatsLocked(int, String)
+ */
+ public Uid.Proc getProcessStatsLocked(int uid, String name,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- Uid u = getUidStatsLocked(uid);
+ Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
return u.getProcessStatsLocked(name);
}
@@ -13281,8 +13872,16 @@
*/
@UnsupportedAppUsage
public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
+ return getPackageStatsLocked(uid, pkg, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ /**
+ * @see getPackageStatsLocked(int, String)
+ */
+ public Uid.Pkg getPackageStatsLocked(int uid, String pkg,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- Uid u = getUidStatsLocked(uid);
+ Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
return u.getPackageStatsLocked(pkg);
}
@@ -13292,13 +13891,19 @@
*/
@UnsupportedAppUsage
public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
+ return getServiceStatsLocked(uid, pkg, name,
+ mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+
+ public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name,
+ long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
- Uid u = getUidStatsLocked(uid);
+ Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs);
return u.getServiceStatsLocked(pkg, name);
}
public void shutdownLocked() {
- recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ recordShutdownLocked(System.currentTimeMillis(), mClocks.elapsedRealtime());
writeSyncLocked();
mShuttingDown = true;
}
@@ -13462,7 +14067,7 @@
mNumSingleUidCpuTimeReads = 0;
mNumBatchedSingleUidCpuTimeReads = 0;
- mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
+ mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis();
}
}
@@ -13471,7 +14076,7 @@
if (oldDelayMillis != newDelayMillis) {
mNumSingleUidCpuTimeReads = 0;
mNumBatchedSingleUidCpuTimeReads = 0;
- mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
+ mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis();
}
}
@@ -13569,11 +14174,11 @@
Uid uid = mUidStats.get(u);
double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage();
- long time = 0;
+ long timeUs = 0;
for (int cluster = 0; cluster < mSystemServerThreadCpuTimesUs.length; cluster++) {
int numSpeeds = mSystemServerThreadCpuTimesUs[cluster].length;
for (int speed = 0; speed < numSpeeds; speed++) {
- time += getSystemServiceTimeAtCpuSpeed(cluster, speed)
+ timeUs += getSystemServiceTimeAtCpuSpeed(cluster, speed)
* proportionalSystemServiceUsage;
}
}
@@ -13581,7 +14186,7 @@
pw.print(" ");
pw.print(u);
pw.print(": ");
- pw.println(time);
+ pw.println(timeUs / 1000);
}
}
}
@@ -13616,7 +14221,7 @@
Slog.d(TAG, "writeSummaryToParcel duration ms:"
+ (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize());
}
- mLastWriteTime = mClocks.elapsedRealtime();
+ mLastWriteTimeMs = mClocks.elapsedRealtime();
writeParcelToFileLocked(p, mStatsFile, sync);
}
@@ -13657,18 +14262,18 @@
mWriteLock.lock();
FileOutputStream fos = null;
try {
- final long startTime = SystemClock.uptimeMillis();
+ final long startTimeMs = SystemClock.uptimeMillis();
fos = file.startWrite();
fos.write(p.marshall());
fos.flush();
file.finishWrite(fos);
if (DEBUG) {
Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath()
- + " duration ms:" + (SystemClock.uptimeMillis() - startTime)
+ + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs)
+ " bytes:" + p.dataSize());
}
com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
- "batterystats", SystemClock.uptimeMillis() - startTime);
+ "batterystats", SystemClock.uptimeMillis() - startTimeMs);
} catch (IOException e) {
Slog.w(TAG, "Error writing battery statistics", e);
file.failWrite(fos);
@@ -13714,7 +14319,7 @@
}
} catch (Exception e) {
Slog.e(TAG, "Error reading battery statistics", e);
- resetAllStatsLocked();
+ resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime());
} finally {
stats.recycle();
}
@@ -13749,16 +14354,17 @@
if (mHistoryBuffer.dataPosition() > 0
|| mBatteryStatsHistory.getFilesNumbers().size() > 1) {
mRecordingHistory = true;
- final long elapsedRealtime = mClocks.elapsedRealtime();
- final long uptime = mClocks.uptimeMillis();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ final long uptimeMs = mClocks.uptimeMillis();
if (USE_OLD_HISTORY) {
- addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs,
+ HistoryItem.CMD_START, mHistoryCur);
}
- addHistoryBufferLocked(elapsedRealtime, HistoryItem.CMD_START, mHistoryCur);
- startRecordingHistory(elapsedRealtime, uptime, false);
+ addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur);
+ startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
}
- recordDailyStatsIfNeededLocked(false);
+ recordDailyStatsIfNeededLocked(false, System.currentTimeMillis());
}
public int describeContents() {
@@ -13799,27 +14405,27 @@
if (DEBUG_HISTORY) {
StringBuilder sb = new StringBuilder(128);
- sb.append("****************** OLD mHistoryBaseTime: ");
- TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ sb.append("****************** OLD mHistoryBaseTimeMs: ");
+ TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
Slog.i(TAG, sb.toString());
}
- mHistoryBaseTime = historyBaseTime;
+ mHistoryBaseTimeMs = historyBaseTime;
if (DEBUG_HISTORY) {
StringBuilder sb = new StringBuilder(128);
- sb.append("****************** NEW mHistoryBaseTime: ");
- TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ sb.append("****************** NEW mHistoryBaseTimeMs: ");
+ TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
Slog.i(TAG, sb.toString());
}
// We are just arbitrarily going to insert 1 minute from the sample of
// the last run until samples in this run.
- if (mHistoryBaseTime > 0) {
+ if (mHistoryBaseTimeMs > 0) {
long oldnow = mClocks.elapsedRealtime();
- mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
+ mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1;
if (DEBUG_HISTORY) {
StringBuilder sb = new StringBuilder(128);
- sb.append("****************** ADJUSTED mHistoryBaseTime: ");
- TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ sb.append("****************** ADJUSTED mHistoryBaseTimeMs: ");
+ TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
Slog.i(TAG, sb.toString());
}
}
@@ -13839,14 +14445,14 @@
void writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory) {
if (DEBUG_HISTORY) {
StringBuilder sb = new StringBuilder(128);
- sb.append("****************** WRITING mHistoryBaseTime: ");
- TimeUtils.formatDuration(mHistoryBaseTime, sb);
- sb.append(" mLastHistoryElapsedRealtime: ");
- TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
+ sb.append("****************** WRITING mHistoryBaseTimeMs: ");
+ TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
+ sb.append(" mLastHistoryElapsedRealtimeMs: ");
+ TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb);
Slog.i(TAG, sb.toString());
}
out.writeInt(VERSION);
- out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
+ out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs);
if (!inclData) {
out.writeInt(0);
out.writeInt(0);
@@ -13913,9 +14519,9 @@
}
mStartCount = in.readInt();
- mUptime = in.readLong();
- mRealtime = in.readLong();
- mStartClockTime = in.readLong();
+ mUptimeUs = in.readLong();
+ mRealtimeUs = in.readLong();
+ mStartClockTimeMs = in.readLong();
mStartPlatformVersion = in.readString();
mEndPlatformVersion = in.readString();
mOnBatteryTimeBase.readSummaryFromParcel(in);
@@ -13955,9 +14561,9 @@
} else {
mDailyPackageChanges = null;
}
- mDailyStartTime = in.readLong();
- mNextMinDailyDeadline = in.readLong();
- mNextMaxDailyDeadline = in.readLong();
+ mDailyStartTimeMs = in.readLong();
+ mNextMinDailyDeadlineMs = in.readLong();
+ mNextMaxDailyDeadlineMs = in.readLong();
mStartCount++;
@@ -13971,8 +14577,8 @@
mInteractiveTimer.readSummaryFromParcelLocked(in);
mPhoneOn = false;
mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
- mLongestLightIdleTime = in.readLong();
- mLongestFullIdleTime = in.readLong();
+ mLongestLightIdleTimeMs = in.readLong();
+ mLongestFullIdleTimeMs = in.readLong();
mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in);
mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in);
mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in);
@@ -14084,9 +14690,11 @@
if (NU > 10000) {
throw new ParcelFormatException("File corrupt: too many uids " + NU);
}
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ final long uptimeMs = mClocks.uptimeMillis();
for (int iu = 0; iu < NU; iu++) {
int uid = in.readInt();
- Uid u = new Uid(this, uid);
+ Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs);
mUidStats.put(uid, u);
u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
@@ -14329,9 +14937,9 @@
for (int ip = 0; ip < NP; ip++) {
String procName = in.readString();
Uid.Proc p = u.getProcessStatsLocked(procName);
- p.mUserTime = in.readLong();
- p.mSystemTime = in.readLong();
- p.mForegroundTime = in.readLong();
+ p.mUserTimeMs = in.readLong();
+ p.mSystemTimeMs = in.readLong();
+ p.mForegroundTimeMs = in.readLong();
p.mStarts = in.readInt();
p.mNumCrashes = in.readInt();
p.mNumAnrs = in.readInt();
@@ -14364,7 +14972,7 @@
for (int is = 0; is < NS; is++) {
String servName = in.readString();
Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
- s.mStartTime = in.readLong();
+ s.mStartTimeMs = in.readLong();
s.mStarts = in.readInt();
s.mLaunches = in.readInt();
}
@@ -14407,7 +15015,7 @@
out.writeInt(mStartCount);
out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
- out.writeLong(mStartClockTime);
+ out.writeLong(mStartClockTimeMs);
out.writeString(mStartPlatformVersion);
out.writeString(mEndPlatformVersion);
mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
@@ -14445,9 +15053,9 @@
} else {
out.writeInt(0);
}
- out.writeLong(mDailyStartTime);
- out.writeLong(mNextMinDailyDeadline);
- out.writeLong(mNextMaxDailyDeadline);
+ out.writeLong(mDailyStartTimeMs);
+ out.writeLong(mNextMinDailyDeadlineMs);
+ out.writeLong(mNextMaxDailyDeadlineMs);
mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -14456,8 +15064,8 @@
}
mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
- out.writeLong(mLongestLightIdleTime);
- out.writeLong(mLongestFullIdleTime);
+ out.writeLong(mLongestLightIdleTimeMs);
+ out.writeLong(mLongestFullIdleTimeMs);
mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -14852,9 +15460,9 @@
for (int ip=0; ip<NP; ip++) {
out.writeString(u.mProcessStats.keyAt(ip));
Uid.Proc ps = u.mProcessStats.valueAt(ip);
- out.writeLong(ps.mUserTime);
- out.writeLong(ps.mSystemTime);
- out.writeLong(ps.mForegroundTime);
+ out.writeLong(ps.mUserTimeMs);
+ out.writeLong(ps.mSystemTimeMs);
+ out.writeLong(ps.mForegroundTimeMs);
out.writeInt(ps.mStarts);
out.writeInt(ps.mNumCrashes);
out.writeInt(ps.mNumAnrs);
@@ -14880,7 +15488,7 @@
out.writeString(ps.mServiceStats.keyAt(is));
BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
long time = ss.getStartTimeToNowLocked(
- mOnBatteryTimeBase.getUptime(NOW_SYS));
+ mOnBatteryTimeBase.getUptime(NOW_SYS) / 1000);
out.writeLong(time);
out.writeInt(ss.mStarts);
out.writeInt(ss.mLaunches);
@@ -14904,13 +15512,13 @@
mBatteryStatsHistory.readFromParcel(in);
mStartCount = in.readInt();
- mStartClockTime = in.readLong();
+ mStartClockTimeMs = in.readLong();
mStartPlatformVersion = in.readString();
mEndPlatformVersion = in.readString();
- mUptime = in.readLong();
- mUptimeStart = in.readLong();
- mRealtime = in.readLong();
- mRealtimeStart = in.readLong();
+ mUptimeUs = in.readLong();
+ mUptimeStartUs = in.readLong();
+ mRealtimeUs = in.readLong();
+ mRealtimeStartUs = in.readLong();
mOnBattery = in.readInt() != 0;
mEstimatedBatteryCapacity = in.readInt();
mMinLearnedBatteryCapacity = in.readInt();
@@ -14931,8 +15539,8 @@
mPhoneOn = false;
mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
mOnBatteryTimeBase, in);
- mLongestLightIdleTime = in.readLong();
- mLongestFullIdleTime = in.readLong();
+ mLongestLightIdleTimeMs = in.readLong();
+ mLongestFullIdleTimeMs = in.readLong();
mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null,
mOnBatteryTimeBase, in);
mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null,
@@ -15030,7 +15638,7 @@
mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
- mLastWriteTime = in.readLong();
+ mLastWriteTimeMs = in.readLong();
mRpmStats.clear();
int NRPMS = in.readInt();
@@ -15096,9 +15704,11 @@
int numUids = in.readInt();
mUidStats.clear();
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ final long uptimeMs = mClocks.uptimeMillis();
for (int i = 0; i < numUids; i++) {
int uid = in.readInt();
- Uid u = new Uid(this, uid);
+ Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs);
u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
mUidStats.append(uid, u);
}
@@ -15137,13 +15747,13 @@
mBatteryStatsHistory.writeToParcel(out);
out.writeInt(mStartCount);
- out.writeLong(mStartClockTime);
+ out.writeLong(mStartClockTimeMs);
out.writeString(mStartPlatformVersion);
out.writeString(mEndPlatformVersion);
- out.writeLong(mUptime);
- out.writeLong(mUptimeStart);
- out.writeLong(mRealtime);
- out.writeLong(mRealtimeStart);
+ out.writeLong(mUptimeUs);
+ out.writeLong(mUptimeStartUs);
+ out.writeLong(mRealtimeUs);
+ out.writeLong(mRealtimeStartUs);
out.writeInt(mOnBattery ? 1 : 0);
out.writeInt(mEstimatedBatteryCapacity);
out.writeInt(mMinLearnedBatteryCapacity);
@@ -15158,8 +15768,8 @@
}
mInteractiveTimer.writeToParcel(out, uSecRealtime);
mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
- out.writeLong(mLongestLightIdleTime);
- out.writeLong(mLongestFullIdleTime);
+ out.writeLong(mLongestLightIdleTimeMs);
+ out.writeLong(mLongestFullIdleTimeMs);
mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime);
mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime);
mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime);
@@ -15227,7 +15837,7 @@
mDischargeScreenDozeCounter.writeToParcel(out);
mDischargeLightDozeCounter.writeToParcel(out);
mDischargeDeepDozeCounter.writeToParcel(out);
- out.writeLong(mLastWriteTime);
+ out.writeLong(mLastWriteTimeMs);
out.writeInt(mRpmStats.size());
for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) {
@@ -15472,7 +16082,7 @@
pw.print("Batched cpu time reads: ");
pw.println(mNumBatchedSingleUidCpuTimeReads);
pw.print("Batching Duration (min): ");
- pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000));
+ pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000));
pw.print("All UID cpu time reads since the later of device start or stats reset: ");
pw.println(mNumAllUidCpuTimeReads);
pw.print("UIDs removed since the later of device start or stats reset: ");
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 32e7fdc..5948e7e 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -86,9 +86,10 @@
*/
public class ZygoteInit {
- // TODO (chriswailes): Change this so it is set with Zygote or ZygoteSecondary as appropriate
private static final String TAG = "Zygote";
+ private static final boolean LOGGING_DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
private static final String PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING =
"ro.zygote.disable_gl_preload";
@@ -284,6 +285,7 @@
new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);
int count = 0;
+ int missingLambdaCount = 0;
String line;
while ((line = br.readLine()) != null) {
// Skip comments and blank lines.
@@ -302,24 +304,33 @@
Class.forName(line, true, null);
count++;
} catch (ClassNotFoundException e) {
- Log.w(TAG, "Class not found for preloading: " + line);
+ if (line.contains("$$Lambda$")) {
+ if (LOGGING_DEBUG) {
+ missingLambdaCount++;
+ }
+ } else {
+ Log.w(TAG, "Class not found for preloading: " + line);
+ }
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Problem preloading " + line + ": " + e);
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
- }
- if (t instanceof RuntimeException) {
+ } else if (t instanceof RuntimeException) {
throw (RuntimeException) t;
+ } else {
+ throw new RuntimeException(t);
}
- throw new RuntimeException(t);
}
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
}
Log.i(TAG, "...preloaded " + count + " classes in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
+ if (LOGGING_DEBUG && missingLambdaCount != 0) {
+ Log.i(TAG, "Unresolved lambda preloads: " + missingLambdaCount);
+ }
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
diff --git a/core/java/com/android/internal/policy/DecorContext.java b/core/java/com/android/internal/policy/DecorContext.java
index 51b4119..5e34c15 100644
--- a/core/java/com/android/internal/policy/DecorContext.java
+++ b/core/java/com/android/internal/policy/DecorContext.java
@@ -20,8 +20,10 @@
import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.res.AssetManager;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.view.ContextThemeWrapper;
+import android.view.Display;
import android.view.contentcapture.ContentCaptureManager;
import com.android.internal.annotations.VisibleForTesting;
@@ -47,9 +49,17 @@
public DecorContext(Context baseContext, PhoneWindow phoneWindow) {
super(null /* base */, null);
setPhoneWindow(phoneWindow);
- final Context displayContext = baseContext.createDisplayContext(
- // TODO(b/149790106): Non-activity context can be passed.
- phoneWindow.getContext().getDisplayNoVerify());
+ // TODO(b/149790106): Non-activity context can be passed.
+ final Display display = phoneWindow.getContext().getDisplayNoVerify();
+ final Context displayContext;
+ if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
+ // TODO(b/166174272): Creating a display context for the default display will result
+ // in additional resource creation.
+ displayContext = baseContext.createConfigurationContext(Configuration.EMPTY);
+ displayContext.updateDisplay(Display.DEFAULT_DISPLAY);
+ } else {
+ displayContext = baseContext.createDisplayContext(display);
+ }
attachBaseContext(displayContext);
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index b12c5e9..a6c3dd1 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -24,6 +24,7 @@
import static android.os.Build.VERSION_CODES.N;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.clearCompatInsets;
import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.getMode;
@@ -1097,10 +1098,12 @@
final Insets systemBarInsets = insets.getInsets(WindowInsets.Type.systemBars());
final Insets stableBarInsets = insets.getInsetsIgnoringVisibility(
WindowInsets.Type.systemBars());
- mLastTopInset = systemBarInsets.top;
- mLastBottomInset = systemBarInsets.bottom;
- mLastRightInset = systemBarInsets.right;
- mLastLeftInset = systemBarInsets.left;
+ final boolean clearCompatInsets = clearCompatInsets(attrs.type, attrs.flags,
+ getResources().getConfiguration().windowConfiguration.getWindowingMode());
+ mLastTopInset = clearCompatInsets ? 0 : systemBarInsets.top;
+ mLastBottomInset = clearCompatInsets ? 0 : systemBarInsets.bottom;
+ mLastRightInset = clearCompatInsets ? 0 : systemBarInsets.right;
+ mLastLeftInset = clearCompatInsets ? 0 : systemBarInsets.left;
// Don't animate if the presence of stable insets has changed, because that
// indicates that the window was either just added and received them for the
diff --git a/core/java/com/android/internal/policy/TaskResizingAlgorithm.java b/core/java/com/android/internal/policy/TaskResizingAlgorithm.java
index 1ec0206..64e0b91 100644
--- a/core/java/com/android/internal/policy/TaskResizingAlgorithm.java
+++ b/core/java/com/android/internal/policy/TaskResizingAlgorithm.java
@@ -51,8 +51,6 @@
public static final int CTRL_BOTTOM = 0x8;
// The minimal aspect ratio which needs to be met to count as landscape (or 1/.. for portrait).
- // Note: We do not use the 1.33 from the CDD here since the user is allowed to use what ever
- // aspect he desires.
@VisibleForTesting
public static final float MIN_ASPECT = 1.2f;
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index d41d307..25d1ae6 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -23,6 +23,7 @@
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.PhoneCapability;
+import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
@@ -68,4 +69,6 @@
void onRegistrationFailed(in CellIdentity cellIdentity,
String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
void onBarringInfoChanged(in BarringInfo barringInfo);
+ void onPhysicalChannelConfigurationChanged(in List<PhysicalChannelConfig> configs);
+
}
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index ea09fc8..313bd42 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -47,10 +47,10 @@
*/
@UnsupportedAppUsage
void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
- void listenWithFeature(String pkg, String featureId, IPhoneStateListener callback, int events,
+ void listenWithFeature(String pkg, String featureId, IPhoneStateListener callback, long events,
boolean notifyNow);
void listenForSubscriber(in int subId, String pkg, String featureId,
- IPhoneStateListener callback, int events, boolean notifyNow);
+ IPhoneStateListener callback, long events, boolean notifyNow);
@UnsupportedAppUsage
void notifyCallStateForAllSubs(int state, String incomingNumber);
void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber);
@@ -99,4 +99,6 @@
void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity,
String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo);
+ void notifyPhysicalChannelConfigurationForSubscriber(in int subId,
+ in List<PhysicalChannelConfig> configs);
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 7f3eb45..d5f54a1 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -18,13 +18,11 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.Point;
-import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.MergedConfiguration;
-import android.view.DisplayCutout;
import android.view.DragEvent;
import android.view.IScrollCaptureController;
import android.view.IWindow;
@@ -33,6 +31,7 @@
import android.view.InsetsState;
import android.view.PointerIcon;
import android.view.WindowInsets.Type.InsetsType;
+import android.window.ClientWindowFrames;
import com.android.internal.os.IResultReceiver;
@@ -51,11 +50,9 @@
}
@Override
- public void resized(Rect frame, Rect contentInsets, Rect visibleInsets,
- Rect stableInsets, boolean reportDraw,
- MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {
+ public void resized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration mergedConfiguration, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId) {
if (reportDraw) {
try {
mSession.finishDrawing(this, null /* postDrawTransaction */);
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 3f39478..5c4c509 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2407,6 +2407,79 @@
return AUDIO_JAVA_SUCCESS;
}
+static jint android_media_AudioSystem_setDevicesRoleForCapturePreset(
+ JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
+ jobjectArray jDeviceAddresses) {
+ AudioDeviceTypeAddrVector nDevices;
+ jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+ if (results != NO_ERROR) {
+ return results;
+ }
+ int status = check_AudioSystem_Command(
+ AudioSystem::setDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+ (device_role_t)role, nDevices));
+ return (jint)status;
+}
+
+static jint android_media_AudioSystem_addDevicesRoleForCapturePreset(
+ JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
+ jobjectArray jDeviceAddresses) {
+ AudioDeviceTypeAddrVector nDevices;
+ jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+ if (results != NO_ERROR) {
+ return results;
+ }
+ int status = check_AudioSystem_Command(
+ AudioSystem::addDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+ (device_role_t)role, nDevices));
+ return (jint)status;
+}
+
+static jint android_media_AudioSystem_removeDevicesRoleForCapturePreset(
+ JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes,
+ jobjectArray jDeviceAddresses) {
+ AudioDeviceTypeAddrVector nDevices;
+ jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+ if (results != NO_ERROR) {
+ return results;
+ }
+ int status = check_AudioSystem_Command(
+ AudioSystem::removeDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+ (device_role_t)role, nDevices));
+ return (jint)status;
+}
+
+static jint android_media_AudioSystem_clearDevicesRoleForCapturePreset(JNIEnv *env, jobject thiz,
+ jint capturePreset,
+ jint role) {
+ return (jint)check_AudioSystem_Command(
+ AudioSystem::clearDevicesRoleForCapturePreset((audio_source_t)capturePreset,
+ (device_role_t)role));
+}
+
+static jint android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv *env, jobject thiz,
+ jint capturePreset,
+ jint role,
+ jobject jDevices) {
+ AudioDeviceTypeAddrVector nDevices;
+ status_t status = check_AudioSystem_Command(
+ AudioSystem::getDevicesForRoleAndCapturePreset((audio_source_t)capturePreset,
+ (device_role_t)role, nDevices));
+ if (status != NO_ERROR) {
+ return (jint)status;
+ }
+ for (const auto &device : nDevices) {
+ jobject jAudioDeviceAttributes = NULL;
+ jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device);
+ if (jStatus != AUDIO_JAVA_SUCCESS) {
+ return jStatus;
+ }
+ env->CallBooleanMethod(jDevices, gListMethods.add, jAudioDeviceAttributes);
+ env->DeleteLocalRef(jAudioDeviceAttributes);
+ }
+ return AUDIO_JAVA_SUCCESS;
+}
+
static jint
android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz,
jobject jaa, jobjectArray jDeviceArray)
@@ -2558,6 +2631,16 @@
(void *)android_media_AudioSystem_removeDevicesRoleForStrategy},
{"getDevicesForRoleAndStrategy", "(IILjava/util/List;)I",
(void *)android_media_AudioSystem_getDevicesForRoleAndStrategy},
+ {"setDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
+ (void *)android_media_AudioSystem_setDevicesRoleForCapturePreset},
+ {"addDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
+ (void *)android_media_AudioSystem_addDevicesRoleForCapturePreset},
+ {"removeDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I",
+ (void *)android_media_AudioSystem_removeDevicesRoleForCapturePreset},
+ {"clearDevicesRoleForCapturePreset", "(II)I",
+ (void *)android_media_AudioSystem_clearDevicesRoleForCapturePreset},
+ {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I",
+ (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset},
{"getDevicesForAttributes",
"(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I",
(void *)android_media_AudioSystem_getDevicesForAttributes},
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index c51f334..c08363b 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -19,18 +19,16 @@
// To make sure cpu_set_t is included from sched.h
#define _GNU_SOURCE 1
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-#include <binder/ActivityManager.h>
+#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <processgroup/processgroup.h>
#include <processgroup/sched_policy.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
+#include <android-base/unique_fd.h>
#include <algorithm>
#include <array>
@@ -86,8 +84,6 @@
static pthread_key_t gBgKey = -1;
#endif
-static bool boot_completed = false;
-
// For both of these, err should be in the errno range (positive), not a status_t (negative)
static void signalExceptionForError(JNIEnv* env, int err, int tid) {
switch (err) {
@@ -584,20 +580,7 @@
}
#endif
- SchedPolicy policy;
- bool policy_changed = false;
- int rc = 0, curr_pri = getpriority(PRIO_PROCESS, pid);
-
- if (pri == curr_pri) {
- return;
- }
-
- if (!boot_completed) {
- boot_completed = android::base::GetBoolProperty("sys.boot_completed", false);
- }
-
- // Do not change sched policy cgroup after boot complete.
- rc = androidSetThreadPriorityAndPolicy(pid, pri, !boot_completed);
+ int rc = androidSetThreadPriority(pid, pri);
if (rc != 0) {
if (rc == INVALID_OPERATION) {
signalExceptionForPriorityError(env, errno, pid);
@@ -606,31 +589,6 @@
}
}
- // Only use async approach after boot complete.
- if (!boot_completed) {
- return;
- }
-
- // Change to background sched policy for the thread if setting to low priority.
- if (pri >= ANDROID_PRIORITY_BACKGROUND) {
- policy = SP_BACKGROUND;
- policy_changed = true;
- // Change to sched policy of the process if thread priority is raising from low priority.
- } else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) {
- // If we cannot get sched policy of the process, use SP_FOREGROUND as default.
- policy = SP_FOREGROUND;
- get_sched_policy(getpid(), &policy);
- policy_changed = true;
- }
-
- // Sched policy will only change in above 2 cases.
- if (policy_changed) {
- ActivityManager am;
- if (!am.setSchedPolicyCgroup(pid, policy)) {
- ALOGE("am.setThreadPriority failed: tid=%d priority=%d policy=%d", pid, pri, policy);
- }
- }
-
//ALOGI("Setting priority of %" PRId32 ": %" PRId32 ", getpriority returns %d\n",
// pid, pri, getpriority(PRIO_PROCESS, pid));
}
diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp
index 54567e5..8177ec6 100644
--- a/core/jni/android_view_KeyEvent.cpp
+++ b/core/jni/android_view_KeyEvent.cpp
@@ -20,6 +20,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
+#include <attestation/HmacKeyManager.h>
#include <input/Input.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 2e396f2..ce8b599 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -21,12 +21,13 @@
#include <android/graphics/matrix.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
-#include <utils/Log.h>
+#include <attestation/HmacKeyManager.h>
#include <input/Input.h>
#include <nativehelper/ScopedUtfChars.h>
+#include <utils/Log.h>
#include "android_os_Parcel.h"
-#include "android_view_MotionEvent.h"
#include "android_util_Binder.h"
+#include "android_view_MotionEvent.h"
#include "core_jni_helpers.h"
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 85b4fe1..4ef15d7 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1505,9 +1505,24 @@
return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
}
+static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jobject toTokenObj, jobject focusedTokenObj, jint displayId) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ if (toTokenObj == NULL) return;
+
+ sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj));
+ sp<IBinder> focusedToken;
+ if (focusedTokenObj != NULL) {
+ focusedToken = ibinderForJavaObject(env, focusedTokenObj);
+ }
+ transaction->setFocusedWindow(toToken, focusedToken, systemTime(SYSTEM_TIME_MONOTONIC),
+ displayId);
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod sSurfaceControlMethods[] = {
+ // clang-format off
{"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
(void*)nativeCreate },
{"nativeReadFromParcel", "(Landroid/os/Parcel;)J",
@@ -1686,7 +1701,11 @@
(void*)nativeSetGlobalShadowSettings },
{"nativeGetHandle", "(J)J",
(void*)nativeGetHandle },
- {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint},
+ {"nativeSetFixedTransformHint", "(JJI)V",
+ (void*)nativeSetFixedTransformHint},
+ {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Landroid/os/IBinder;I)V",
+ (void*)nativeSetFocusedWindow},
+ // clang-format on
};
int register_android_view_SurfaceControl(JNIEnv* env)
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 6212bcb..7fac615 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2748,4 +2748,7 @@
// CATEGORY: SETTINGS
// OS: R QPR
ADAPTIVE_CONNECTIVITY_CATEGORY = 1850;
+
+ // OS: R QPR2
+ BLUETOOTH_PAIRING_RECEIVER = 1851;
}
diff --git a/core/proto/android/providers/settings/config.proto b/core/proto/android/providers/settings/config.proto
index b0a70ef..d433c0e 100644
--- a/core/proto/android/providers/settings/config.proto
+++ b/core/proto/android/providers/settings/config.proto
@@ -31,11 +31,14 @@
repeated SettingProto activity_manager_settings = 4;
repeated SettingProto app_compat_settings = 5;
repeated SettingProto autofill_settings = 6;
+ repeated SettingProto blobstore_settings = 23;
repeated SettingProto connectivity_settings = 7;
repeated SettingProto content_capture_settings = 8;
- repeated SettingProto dex_boot_settings = 9;
+ repeated SettingProto device_idle_settings = 24;
+ reserved 9; // dex_boot_settings
repeated SettingProto game_driver_settings = 10;
repeated SettingProto input_native_boot_settings = 11;
+ repeated SettingProto job_scheduler_settings = 25;
repeated SettingProto netd_native_settings = 12;
repeated SettingProto privacy_settings = 13;
repeated SettingProto rollback_boot_settings = 14;
@@ -47,7 +50,8 @@
repeated SettingProto systemui_settings = 20;
repeated SettingProto telephony_settings = 21;
repeated SettingProto textclassifier_settings = 22;
- repeated SettingProto blobstore_settings = 23;
+
+ // Next tag: 26
message NamespaceProto {
optional string namespace = 1;
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 9fccdaf..3ec14c0 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -292,7 +292,7 @@
optional SettingProto name = 1;
optional SettingProto provisioned = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto provisioning_mobile_data_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto idle_constants = 4;
+ reserved 4; // idle_constants
optional SettingProto policy_constants = 5;
optional SettingProto demo_mode = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 3d12d07..7f743ef 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -219,6 +219,8 @@
optional SettingProto enhanced_voice_privacy_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto force_bold_text = 85 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
message Gesture {
optional SettingProto aware_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
@@ -615,5 +617,5 @@
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 85;
+ // Next tag = 86;
}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index ff0ba8d..3a59a16 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -316,6 +316,7 @@
optional bool front_of_task = 28;
optional int32 proc_id = 29;
optional bool translucent = 30;
+ optional bool pip_auto_enter_allowed = 31;
}
/* represents WindowToken */
diff --git a/core/proto/android/wifi/enums.proto b/core/proto/android/wifi/enums.proto
index 315c579..e676fef 100644
--- a/core/proto/android/wifi/enums.proto
+++ b/core/proto/android/wifi/enums.proto
@@ -48,3 +48,65 @@
*/
WIFI_MODE_FULL_LOW_LATENCY = 4;
}
+
+/**
+ * Wifi authentication type.
+ */
+enum WifiAuthType {
+ AUTH_TYPE_NONE = 0;
+
+ // WPA pre-shared key.
+ AUTH_TYPE_WPA_PSK = 1;
+ // WPA using EAP authentication. Generally used with an external authentication server.
+ AUTH_TYPE_WPA_EAP = 2;
+ // IEEE 802.1X using EAP authentication and (optionally) dynamically generated WEP keys.
+ AUTH_TYPE_IEEE8021X = 3;
+ // WPA2 pre-shared key for use with soft access point.
+ AUTH_TYPE_WPA2_PSK = 4;
+ // Hotspot 2.0 r2 OSEN.
+ AUTH_TYPE_OSEN = 5;
+ // IEEE 802.11r Fast BSS Transition with PSK authentication.
+ AUTH_TYPE_FT_PSK = 6;
+ // IEEE 802.11r Fast BSS Transition with EAP authentication.
+ AUTH_TYPE_FT_EAP = 7;
+ // Simultaneous Authentication of Equals.
+ AUTH_TYPE_SAE = 8;
+ // Opportunistic Wireless Encryption.
+ AUTH_TYPE_OWE = 9;
+ // SUITE_B_192 192 bit level
+ AUTH_TYPE_SUITE_B_192 = 10;
+ // WPA pre-shared key with stronger SHA256-based algorithms.
+ AUTH_TYPE_WPA_PSK_SHA256 = 11;
+ // WPA using EAP authentication with stronger SHA256-based algorithms.
+ AUTH_TYPE_WPA_EAP_SHA256 = 12;
+ // WAPI pre-shared key.
+ AUTH_TYPE_WAPI_PSK = 13;
+ // WAPI certificate to be specified.
+ AUTH_TYPE_WAPI_CERT = 14;
+ // IEEE 802.11ai FILS SK with SHA256.
+ AUTH_TYPE_FILS_SHA256 = 15;
+ // IEEE 802.11ai FILS SK with SHA384.
+ AUTH_TYPE_FILS_SHA384 = 16;
+}
+
+/**
+ * Bucketed wifi band.
+ */
+enum WifiBandBucket {
+ BAND_UNKNOWN = 0;
+
+ // All of 2.4GHz band
+ BAND_2G = 1;
+ // Frequencies in the range of [5150, 5250) GHz
+ BAND_5G_LOW = 2;
+ // Frequencies in the range of [5250, 5725) GHz
+ BAND_5G_MIDDLE = 3;
+ // Frequencies in the range of [5725, 5850) GHz
+ BAND_5G_HIGH = 4;
+ // Frequencies in the range of [5925, 6425) GHz
+ BAND_6G_LOW = 5;
+ // Frequencies in the range of [6425, 6875) GHz
+ BAND_6G_MIDDLE = 6;
+ // Frequencies in the range of [6875, 7125) GHz
+ BAND_6G_HIGH = 7;
+}
\ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cdcb24b..560e3c1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4691,6 +4691,12 @@
<permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows the holder to send category_car notifications.
+ @hide -->
+ <permission
+ android:name="android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"
+ android:protectionLevel="signature|privileged" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
@@ -5496,6 +5502,10 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
+ <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ProfcollectBGJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE" >
+ </service>
+
<service
android:name="com.android.server.autofill.AutofillCompatAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b6f6627..d0d7eca 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -272,9 +272,9 @@
<string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"وضع صامت"</string>
<string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"الصوت متوقف"</string>
<string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"الصوت قيد التفعيل"</string>
- <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"وضع الطائرة"</string>
- <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"وضع الطائرة قيد التفعيل"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"وضع الطائرة متوقف"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"وضع الطيران"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"وضع الطيران قيد التفعيل"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"وضع الطيران متوقف"</string>
<string name="global_action_settings" msgid="4671878836947494217">"الإعدادات"</string>
<string name="global_action_assist" msgid="2517047220311505805">"مساعدة"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"المساعد الصوتي"</string>
@@ -2156,7 +2156,7 @@
<string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"جدول بيانات: <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
<string name="mime_type_presentation" msgid="1145384236788242075">"عرض تقديمي"</string>
<string name="mime_type_presentation_ext" msgid="8761049335564371468">"عرض تقديمي: <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
- <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطائرة\"."</string>
+ <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطيران\"."</string>
<string name="car_loading_profile" msgid="8219978381196748070">"جارٍ التحميل"</string>
<plurals name="file_count" formatted="false" msgid="7063513834724389247">
<item quantity="zero"><xliff:g id="FILE_NAME_2">%s</xliff:g> و<xliff:g id="COUNT_3">%d</xliff:g> ملف</item>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0e176b5..755ee47 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -973,7 +973,7 @@
<string name="save_password_remember" msgid="6490888932657708341">"Zapamti"</string>
<string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemate odobrenje za otvaranje ove stranice."</string>
- <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međuspremnik."</string>
+ <string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međumemoriju."</string>
<string name="copied" msgid="4675902854553014676">"Kopirano"</string>
<string name="more_item_label" msgid="7419249600215749115">"Više"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Meni+"</string>
@@ -1283,7 +1283,7 @@
<string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznata vrsta mreže"</string>
<string name="accept" msgid="5447154347815825107">"Prihvati"</string>
<string name="decline" msgid="6490507610282145874">"Odbijte"</string>
- <string name="select_character" msgid="3352797107930786979">"Umetni karakter"</string>
+ <string name="select_character" msgid="3352797107930786979">"Umetni znak"</string>
<string name="sms_control_title" msgid="4748684259903148341">"Slanje SMS poruka"</string>
<string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> šalje veliki broj SMS poruka. Da li želite dozvoliti ovoj aplikaciji da nastavi slanje poruka?"</string>
<string name="sms_control_yes" msgid="4858845109269524622">"Dozvoli"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 84f3243..2308b5a 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -423,7 +423,7 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Esta app puede agregar, quitar o cambiar eventos del calendario en tu teléfono. Puede enviar mensajes que parecen proceder de propietarios del calendario o cambiar eventos sin notificarlos."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acceder a comandos adicionales del proveedor del lugar"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que la aplicación acceda a comandos adicionales del proveedor de ubicación. Esto puede permitirle a la aplicación interferir con el funcionamiento del GPS o de otras fuentes de ubicación."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder a la ubicación exacta solo en primer plano"</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder a la ubicación precisa solo en primer plano"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Mientras la usas, esta app puede obtener tu ubicación exacta mediante los Servicios de ubicación, siempre y cuando el dispositivo los tenga activados. Es posible que esto aumente el uso de batería."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acceder a la ubicación aproximada solo en primer plano"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Mientras la usas, esta app puede obtener tu ubicación aproximada mediante los Servicios de ubicación, siempre y cuando el dispositivo los tenga activados."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0004ff1..3b44295 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -309,7 +309,7 @@
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"hanganyag rögzítése"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Testmozgás"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"hozzáférés a testmozgási adatokhoz"</string>
- <string name="permgrouplab_camera" msgid="9090413408963547706">"Fényképezőgép"</string>
+ <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotók és videók készítése"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Hívásnaplók"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"hívásnapló olvasása és írása"</string>
@@ -1900,8 +1900,8 @@
<string name="profile_encrypted_message" msgid="1128512616293157802">"A feloldáshoz koppintson rá"</string>
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Csatlakoztatva a(z) <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> eszközhöz"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Koppintson ide a fájlok megtekintéséhez"</string>
- <string name="pin_target" msgid="8036028973110156895">"Rögzítés"</string>
- <string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> rögzítése"</string>
+ <string name="pin_target" msgid="8036028973110156895">"Kitűzés"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> kitűzése"</string>
<string name="unpin_target" msgid="3963318576590204447">"Feloldás"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> rögzítésének feloldása"</string>
<string name="app_info" msgid="6113278084877079851">"Alkalmazásinformáció"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 264a8fc..4f66b6e 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1979,7 +1979,7 @@
<string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Չհաջողվեց վերականգնել դյուրանցումը, քանի որ հավելվածների ստորագրությունները տարբեր են"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Չհաջողվեց վերականգնել դյուրանցումը"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Դյուրանցումն անջատված է"</string>
- <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ՀԵՌԱՑՆԵԼ"</string>
+ <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ԱՊԱՏԵՂԱԴՐԵԼ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ԲԱՑԵԼ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Հայտնաբերվել է վնասաբեր հավելված"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> հավելվածն ուզում է ցուցադրել հատվածներ <xliff:g id="APP_2">%2$s</xliff:g> հավելվածից"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 671863d..162b4d3 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1320,7 +1320,7 @@
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Майнаптуулугуна таасири тиет. Аны өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
<string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB портунда суюктук же урандылар бар"</string>
- <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн, таптап коюңуз."</string>
+ <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB порт автоматтык түрдө өчтү. Кененирээк маалымат алуу үчүн, таптап коюңуз."</string>
<string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"USB портун колдонууга болот"</string>
<string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Телефон суюктук менен урандыларды аныктаган жок."</string>
<string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index a65f80c..2c041dc 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1120,7 +1120,7 @@
<string name="yes" msgid="9069828999585032361">"ОК"</string>
<string name="no" msgid="5122037903299899715">"Цуцлах"</string>
<string name="dialog_alert_title" msgid="651856561974090712">"Анхаар"</string>
- <string name="loading" msgid="3138021523725055037">"Ачааллаж байна..."</string>
+ <string name="loading" msgid="3138021523725055037">"Ачаалж байна..."</string>
<string name="capital_on" msgid="2770685323900821829">"Идэвхтэй"</string>
<string name="capital_off" msgid="7443704171014626777">"Идэвхгүй"</string>
<string name="checked" msgid="9179896827054513119">"тэмдэглэсэн"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f63e647..95f7439 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1279,7 +1279,7 @@
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Nooit toestaan"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"Simkaart verwijderd"</string>
<string name="sim_removed_message" msgid="9051174064474904617">"Het mobiele netwerk is niet beschikbaar totdat u het apparaat opnieuw start met een geldige simkaart."</string>
- <string name="sim_done_button" msgid="6464250841528410598">"Gereed"</string>
+ <string name="sim_done_button" msgid="6464250841528410598">"Klaar"</string>
<string name="sim_added_title" msgid="7930779986759414595">"Simkaart aangesloten"</string>
<string name="sim_added_message" msgid="6602906609509958680">"Start je apparaat opnieuw voor toegang tot het mobiele netwerk."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"Opnieuw starten"</string>
@@ -1292,7 +1292,7 @@
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Tijd instellen"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Datum instellen"</string>
<string name="date_time_set" msgid="4603445265164486816">"Instellen"</string>
- <string name="date_time_done" msgid="8363155889402873463">"Gereed"</string>
+ <string name="date_time_done" msgid="8363155889402873463">"Klaar"</string>
<string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"NIEUW: "</font></string>
<string name="perms_description_app" msgid="2747752389870161996">"Geleverd door <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="5729199278862516390">"Geen rechten nodig"</string>
@@ -1379,7 +1379,7 @@
<string name="ext_media_status_removed" msgid="241223931135751691">"Verwijderd"</string>
<string name="ext_media_status_unmounted" msgid="8145812017295835941">"Uitgeworpen"</string>
<string name="ext_media_status_checking" msgid="159013362442090347">"Controleren…"</string>
- <string name="ext_media_status_mounted" msgid="3459448555811203459">"Gereed"</string>
+ <string name="ext_media_status_mounted" msgid="3459448555811203459">"Klaar"</string>
<string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Alleen lezen"</string>
<string name="ext_media_status_bad_removal" msgid="508448566481406245">"Onveilig verwijderd"</string>
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"Beschadigd"</string>
@@ -1404,7 +1404,7 @@
<string name="ime_action_search" msgid="4501435960587287668">"Zoeken"</string>
<string name="ime_action_send" msgid="8456843745664334138">"Verzenden"</string>
<string name="ime_action_next" msgid="4169702997635728543">"Volgende"</string>
- <string name="ime_action_done" msgid="6299921014822891569">"Gereed"</string>
+ <string name="ime_action_done" msgid="6299921014822891569">"Klaar"</string>
<string name="ime_action_previous" msgid="6548799326860401611">"Vorige"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Uitvoeren"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
@@ -1451,7 +1451,7 @@
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> van <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="one">1 overeenkomst</item>
</plurals>
- <string name="action_mode_done" msgid="2536182504764803222">"Gereed"</string>
+ <string name="action_mode_done" msgid="2536182504764803222">"Klaar"</string>
<string name="progress_erasing" msgid="6891435992721028004">"Gedeelde opslag wissen…"</string>
<string name="share" msgid="4157615043345227321">"Delen"</string>
<string name="find" msgid="5015737188624767706">"Vinden"</string>
@@ -1492,7 +1492,7 @@
<string name="keyboardview_keycode_alt" msgid="8997420058584292385">"Alt"</string>
<string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Annuleren"</string>
<string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Delete"</string>
- <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Gereed"</string>
+ <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Klaar"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Modus wijzigen"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
@@ -1645,7 +1645,7 @@
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Functies kiezen voor gebruik met de sneltoets via de volumeknop"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> is uitgeschakeld"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Snelkoppelingen bewerken"</string>
- <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gereed"</string>
+ <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Klaar"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Sneltoets uitschakelen"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
@@ -1774,7 +1774,7 @@
<string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt weergegeven"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Ik snap het"</string>
- <string name="done_label" msgid="7283767013231718521">"Gereed"</string>
+ <string name="done_label" msgid="7283767013231718521">"Klaar"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Ronde schuifregelaar voor uren"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Ronde schuifregelaar voor minuten"</string>
<string name="select_hours" msgid="5982889657313147347">"Uren selecteren"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2b51170..20ef017f 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2784,7 +2784,11 @@
exactly one parameter of type View. For instance, if you specify
<code>android:onClick="sayHello"</code>, you must declare a
<code>public void sayHello(View v)</code> method of your context
- (typically, your Activity). -->
+ (typically, your Activity).
+ {@deprecated View actually traverses the Context
+ hierarchy looking for the relevant method, which is fragile (an intermediate
+ ContextWrapper adding a same-named method would change behavior) and restricts
+ bytecode optimizers such as R8. Instead, use View.setOnClickListener.}-->
<attr name="onClick" format="string" />
<!-- Defines over-scrolling behavior. This property is used only if the
@@ -7505,7 +7509,11 @@
<attr name="enabled" />
<!-- Name of a method on the Context used to inflate the menu that will be
- called when the item is clicked. -->
+ called when the item is clicked.
+ {@deprecated Menu actually traverses the Context hierarchy looking for the
+ relevant method, which is fragile (an intermediate ContextWrapper adding a
+ same-named method would change behavior) and restricts bytecode optimizers
+ such as R8. Instead, use MenuItem.setOnMenuItemClickListener.} -->
<attr name="onClick" />
<!-- How this item should display in the Action Bar, if present. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5f2e4f9..550162a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2258,7 +2258,7 @@
<!-- Amount of time in ms the user needs to press the relevant keys to trigger the
screenshot chord -->
- <integer name="config_screenshotChordKeyTimeout">500</integer>
+ <integer name="config_screenshotChordKeyTimeout">0</integer>
<!-- Default width of a vertical scrollbar and height of a horizontal scrollbar.
Takes effect only if the scrollbar drawables have no intrinsic size. -->
@@ -2783,6 +2783,7 @@
<item>power</item>
<item>restart</item>
<item>logout</item>
+ <item>screenshot</item>
<item>bugreport</item>
</string-array>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index e17c312..6ae6faa 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -50,6 +50,7 @@
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
+ <uses-permission android:name="android.permission.DEVICE_POWER"/>
<uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 0490678..88faa0a 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -574,16 +574,16 @@
InstallParams(String outFileName, int rawResId) throws PackageParserException {
this.pkg = getParsedPackage(outFileName, rawResId);
- this.packageURI = Uri.fromFile(new File(pkg.getCodePath()));
+ this.packageURI = Uri.fromFile(new File(pkg.getPath()));
}
InstallParams(ParsingPackage pkg) {
- this.packageURI = Uri.fromFile(new File(pkg.getCodePath()));
+ this.packageURI = Uri.fromFile(new File(pkg.getPath()));
this.pkg = pkg;
}
long getApkSize() {
- File file = new File(pkg.getCodePath());
+ File file = new File(pkg.getPath());
return file.length();
}
}
@@ -1003,7 +1003,7 @@
try {
cleanUpInstall(ip.pkg.getPackageName());
} finally {
- File outFile = new File(ip.pkg.getCodePath());
+ File outFile = new File(ip.pkg.getPath());
if (outFile != null && outFile.exists()) {
outFile.delete();
}
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index eb69525..a5b7c61 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -16,9 +16,11 @@
package android.view;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.ImeInsetsSourceConsumer.areEditorsSimilar;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -86,6 +88,7 @@
false,
new DisplayCutout(
Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
+ TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
SOFT_INPUT_ADJUST_RESIZE, 0, 0);
mImeConsumer = (ImeInsetsSourceConsumer) mController.getSourceConsumer(ITYPE_IME);
});
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index de128ad..88e1f57 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
import static android.view.InsetsController.ANIMATION_TYPE_NONE;
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
@@ -30,6 +31,7 @@
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -169,6 +171,7 @@
false,
new DisplayCutout(
Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
+ TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
SOFT_INPUT_ADJUST_RESIZE, 0, 0);
mController.onFrameChanged(new Rect(0, 0, 100, 100));
});
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index c7d835c..4306e3e 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -16,6 +16,8 @@
package android.view;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.InsetsState.ISIDE_BOTTOM;
import static android.view.InsetsState.ISIDE_TOP;
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
@@ -30,9 +32,13 @@
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -78,7 +84,8 @@
mState.getSource(ITYPE_IME).setVisible(true);
SparseIntArray typeSideMap = new SparseIntArray();
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
- false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_RESIZE, 0, 0, typeSideMap);
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_RESIZE, 0, 0,
+ TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, typeSideMap);
assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets());
assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all()));
assertEquals(ISIDE_TOP, typeSideMap.get(ITYPE_STATUS_BAR));
@@ -97,7 +104,8 @@
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 100, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
- false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_RESIZE, 0, 0, null);
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_RESIZE, 0, 0,
+ TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
assertEquals(100, insets.getStableInsetBottom());
assertEquals(Insets.of(0, 0, 0, 100), insets.getInsetsIgnoringVisibility(Type.systemBars()));
assertEquals(Insets.of(0, 0, 0, 200), insets.getSystemWindowInsets());
@@ -116,7 +124,8 @@
mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
- false, DisplayCutout.NO_CUTOUT, 0, 0, 0, null);
+ false, DisplayCutout.NO_CUTOUT, 0, 0, 0, TYPE_APPLICATION,
+ WINDOWING_MODE_UNDEFINED, null);
assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
@@ -132,7 +141,8 @@
mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
mState.getSource(ITYPE_IME).setVisible(true);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
- false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, 0, 0, null);
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, 0, 0,
+ TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
assertEquals(0, insets.getSystemWindowInsetBottom());
assertEquals(100, insets.getInsets(ime()).bottom);
assertTrue(insets.isVisible(ime()));
@@ -149,11 +159,11 @@
mState.getSource(ITYPE_IME).setVisible(true);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, 0,
- SYSTEM_UI_FLAG_LAYOUT_STABLE, null);
+ SYSTEM_UI_FLAG_LAYOUT_STABLE, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
assertEquals(100, insets.getSystemWindowInsetTop());
insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false,
DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, 0,
- 0 /* legacySystemUiFlags */, null);
+ 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
assertEquals(0, insets.getSystemWindowInsetTop());
}
}
@@ -166,15 +176,37 @@
mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, FLAG_FULLSCREEN,
- SYSTEM_UI_FLAG_LAYOUT_STABLE, null);
+ SYSTEM_UI_FLAG_LAYOUT_STABLE, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
assertEquals(0, insets.getSystemWindowInsetTop());
insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false,
DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, 0,
- 0 /* legacySystemUiFlags */, null);
+ 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
assertEquals(0, insets.getSystemWindowInsetTop());
}
}
+ @Test
+ public void testCalculateInsets_flagLayoutNoLimits() {
+ mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+ mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+ WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS,
+ 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
+ assertEquals(0, insets.getSystemWindowInsetTop());
+ insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS,
+ 0 /* legacySystemUiFlags */, TYPE_SYSTEM_ERROR, WINDOWING_MODE_UNDEFINED, null);
+ assertEquals(100, insets.getSystemWindowInsetTop());
+ insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS,
+ 0 /* legacySystemUiFlags */, TYPE_WALLPAPER, WINDOWING_MODE_UNDEFINED, null);
+ assertEquals(100, insets.getSystemWindowInsetTop());
+ insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
+ false, DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS,
+ 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_FREEFORM, null);
+ assertEquals(100, insets.getSystemWindowInsetTop());
+ }
+
@Test
public void testCalculateInsets_captionStatusBarOverlap() throws Exception {
@@ -213,7 +245,8 @@
mState.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
mState.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setVisible(true);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
- false, DisplayCutout.NO_CUTOUT, 0, 0, 0, null);
+ false, DisplayCutout.NO_CUTOUT, 0, 0, 0, TYPE_APPLICATION,
+ WINDOWING_MODE_UNDEFINED, null);
assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
@@ -229,7 +262,8 @@
mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
- false, DisplayCutout.NO_CUTOUT, 0, 0, 0, null);
+ false, DisplayCutout.NO_CUTOUT, 0, 0, 0, TYPE_APPLICATION,
+ WINDOWING_MODE_UNDEFINED, null);
assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
@@ -244,7 +278,8 @@
mState.getSource(ITYPE_IME).setVisible(true);
mState.removeSource(ITYPE_IME);
WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false,
- DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_RESIZE, 0, 0, null);
+ DisplayCutout.NO_CUTOUT, SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION,
+ WINDOWING_MODE_UNDEFINED, null);
assertEquals(0, insets.getSystemWindowInsetBottom());
}
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 5c16772..4cf6715 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -24,6 +24,7 @@
import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
@@ -117,7 +118,15 @@
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
- // A window which fits system bars must fit IME, unless its type is toast or system alert.
+ assertEquals(Type.systemBars(), attrs.getFitInsetsTypes());
+ }
+
+ @Test
+ public void adjustLayoutParamsForCompatibility_fitSystemBarsAndIme() {
+ final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
+ attrs.softInputMode |= SOFT_INPUT_ADJUST_RESIZE;
+ ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+
assertEquals(Type.systemBars() | Type.ime(), attrs.getFitInsetsTypes());
}
diff --git a/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java b/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java
index fbf75df..a01459f 100644
--- a/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java
+++ b/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java
@@ -146,7 +146,7 @@
when(a.getTargetSdkVersion()).thenReturn(info.targetSdkVersion);
when(a.isOverlayIsStatic()).thenReturn(info.isStatic);
when(a.getOverlayPriority()).thenReturn(info.priority);
- when(a.getBaseCodePath()).thenReturn(info.path.getPath());
+ when(a.getBaseApkPath()).thenReturn(info.path.getPath());
f.accept(a, !info.path.getPath().contains("data/overlay"));
}
return null;
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java
new file mode 100644
index 0000000..e870d60
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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.internal.os;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.Build;
+import android.os.ConditionVariable;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import com.google.android.collect.Sets;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class BatteryInputSuspendTest {
+
+ public static final Set<String> SUPPORTED_DEVICES = Sets.newArraySet(
+ "blueline",
+ "crosshatch",
+ "coral"
+ );
+
+ private ChargerStateMonitor mChargerStateMonitor;
+
+ @Before
+ public void verifyCharging() {
+ if (!SUPPORTED_DEVICES.contains(Build.DEVICE)) {
+ return;
+ }
+
+ mChargerStateMonitor = new ChargerStateMonitor();
+
+ assertTrue("Device must be connected to USB", mChargerStateMonitor.isCharging());
+ }
+
+ @Test
+ public void testSuspendInput() {
+ if (!SUPPORTED_DEVICES.contains(Build.DEVICE)) {
+ return;
+ }
+
+ SystemUtil.runShellCommand("dumpsys battery suspend_input");
+
+ mChargerStateMonitor.waitForChargerState(/* isPluggedIn */false);
+ }
+
+ @After
+ public void reenableCharging() {
+ if (!SUPPORTED_DEVICES.contains(Build.DEVICE)) {
+ return;
+ }
+
+ mChargerStateMonitor.reset();
+
+ SystemUtil.runShellCommand("dumpsys battery reset");
+
+ mChargerStateMonitor.waitForChargerState(/* isPluggedIn */true);
+ }
+
+ private static class ChargerStateMonitor {
+ private final Intent mBatteryMonitor;
+ private final ConditionVariable mReady = new ConditionVariable();
+ private boolean mExpectedChargingState;
+
+ ChargerStateMonitor() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ mBatteryMonitor = context.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (isCharging(intent) == mExpectedChargingState) {
+ mReady.open();
+ }
+ }
+ }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ }
+
+ public boolean isCharging() {
+ return isCharging(mBatteryMonitor);
+ }
+
+ private boolean isCharging(Intent batteryMonitor) {
+ return batteryMonitor.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0;
+ }
+
+ void waitForChargerState(boolean isPluggedIn) {
+ mExpectedChargingState = isPluggedIn;
+
+ boolean charging = isCharging();
+ if (charging == mExpectedChargingState) {
+ return;
+ }
+
+ boolean success = mReady.block(100000);
+ assertTrue("Timed out waiting for charging state to change", success);
+ }
+
+ void reset() {
+ mReady.close();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
index 61d20df..3b27f18 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java
@@ -18,6 +18,7 @@
import android.os.BatteryStats;
import android.os.Parcel;
+import android.os.SystemClock;
import androidx.test.filters.SmallTest;
@@ -36,9 +37,9 @@
timer.onTimeStarted(100, 100, 100);
// First update is absorbed.
- timer.update(10, 1);
+ timer.update(10, 1, SystemClock.elapsedRealtime() * 1000);
- timer.update(20, 2);
+ timer.update(20, 2, SystemClock.elapsedRealtime() * 1000);
assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
assertEquals(10, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED));
@@ -62,7 +63,7 @@
timeBase);
// First once is absorbed.
- timer.update(10, 1);
+ timer.update(10, 1, SystemClock.elapsedRealtime() * 1000);
timer.add(10, 1);
@@ -71,7 +72,7 @@
// This is less than we currently have, so we will end the sample. Time isn't running, so
// nothing should happen.
- timer.update(0, 0);
+ timer.update(0, 0, SystemClock.elapsedRealtime() * 1000);
assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
assertEquals(0, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED));
@@ -86,7 +87,7 @@
// This is less than we currently have, so we should end our sample and continue with the
// entire amount updated here.
- timer.update(50, 5);
+ timer.update(50, 5, SystemClock.elapsedRealtime() * 1000);
assertEquals(150, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED));
assertEquals(15, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
@@ -106,7 +107,7 @@
// This should be absorbed because it is our first update and we don't know what
// was being counted before.
- timer.update(10, 1);
+ timer.update(10, 1, SystemClock.elapsedRealtime() * 1000);
assertEquals(0, timer.getTotalTimeLocked(10, BatteryStats.STATS_SINCE_CHARGED));
assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
@@ -115,7 +116,7 @@
timer.onTimeStarted(100, 100, 100);
// This should be absorbed.
- timer.update(10, 1);
+ timer.update(10, 1, SystemClock.elapsedRealtime() * 1000);
assertEquals(0, timer.getTotalTimeLocked(100, BatteryStats.STATS_SINCE_CHARGED));
assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
@@ -206,13 +207,13 @@
// Now, just like with a fresh timer, the first update should be absorbed to account for
// data being collected when we weren't recording.
- unparceledOnBatteryTimer.update(10, 10);
+ unparceledOnBatteryTimer.update(10, 10, SystemClock.elapsedRealtime() * 1000);
assertEquals(10, unparceledOnBatteryTimer.getTotalTimeLocked(0,
BatteryStats.STATS_SINCE_CHARGED));
assertEquals(1, unparceledOnBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
- unparceledOffBatteryTimer.update(10, 10);
+ unparceledOffBatteryTimer.update(10, 10, SystemClock.elapsedRealtime() * 1000);
assertEquals(10, unparceledOffBatteryTimer.getTotalTimeLocked(0,
BatteryStats.STATS_SINCE_CHARGED));
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java
index df549c5..80e066c 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java
@@ -36,22 +36,22 @@
}
void populate() {
- mStartTime = 1010;
- mRunningSince = 2021;
+ mStartTimeMs = 1010;
+ mRunningSinceMs = 2021;
mRunning = true;
mStarts = 4042;
- mLaunchedTime = 5053;
- mLaunchedSince = 6064;
+ mLaunchedTimeMs = 5053;
+ mLaunchedSinceMs = 6064;
mLaunched = true;
mLaunches = 8085;
}
long getStartTime() {
- return mStartTime;
+ return mStartTimeMs;
}
long getRunningSince() {
- return mRunningSince;
+ return mRunningSinceMs;
}
void setRunning(boolean val) {
@@ -67,11 +67,11 @@
}
long getLaunchedTime() {
- return mLaunchedTime;
+ return mLaunchedTimeMs;
}
long getLaunchedSince() {
- return mLaunchedSince;
+ return mLaunchedSinceMs;
}
void setLaunched(boolean val) {
@@ -173,7 +173,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
@@ -202,7 +207,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
@@ -229,7 +239,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
TestServ serv = new TestServ(bsi);
@@ -259,7 +274,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
TestServ serv = new TestServ(bsi);
@@ -316,7 +336,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
TestServ serv = new TestServ(bsi);
@@ -345,7 +370,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
TestServ serv = new TestServ(bsi);
@@ -374,7 +404,12 @@
MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() {
@Override
public long getBatteryUptimeLocked() {
- return 777777L;
+ return 777777L * 1000; // microseconds
+ }
+
+ @Override
+ public long getBatteryUptimeLocked(long uptimeMs) {
+ return 777777L * 1000; // microseconds
}
};
TestServ serv = new TestServ(bsi);
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java
index e5441c0..f016e75a 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java
@@ -41,29 +41,29 @@
public void populate(long uptime, long realtime, boolean running, long pastUptime,
long uptimeStart, long pastRealtime, long realtimeStart,
long unpluggedUptime, long unpluggedRealtime) {
- mUptime = uptime;
- mRealtime = realtime;
+ mUptimeUs = uptime;
+ mRealtimeUs = realtime;
mRunning = running;
- mPastUptime = pastUptime;
- mUptimeStart = uptimeStart;
- mPastRealtime = pastRealtime;
- mRealtimeStart = realtimeStart;
- mUnpluggedUptime = unpluggedUptime;
- mUnpluggedRealtime = unpluggedRealtime;
+ mPastUptimeUs = pastUptime;
+ mUptimeStartUs = uptimeStart;
+ mPastRealtimeUs = pastRealtime;
+ mRealtimeStartUs = realtimeStart;
+ mUnpluggedUptimeUs = unpluggedUptime;
+ mUnpluggedRealtimeUs = unpluggedRealtime;
}
public void verify(long uptime, long realtime, boolean running, long pastUptime,
long uptimeStart, long pastRealtime, long realtimeStart,
long unpluggedUptime, long unpluggedRealtime) {
- Assert.assertEquals(uptime, mUptime);
- Assert.assertEquals(realtime, mRealtime);
+ Assert.assertEquals(uptime, mUptimeUs);
+ Assert.assertEquals(realtime, mRealtimeUs);
Assert.assertEquals(running, mRunning);
- Assert.assertEquals(pastUptime, mPastUptime);
- Assert.assertEquals(uptimeStart, mUptimeStart);
- Assert.assertEquals(pastRealtime, mPastRealtime);
- Assert.assertEquals(realtimeStart, mRealtimeStart);
- Assert.assertEquals(unpluggedUptime, mUnpluggedUptime);
- Assert.assertEquals(unpluggedRealtime, mUnpluggedRealtime);
+ Assert.assertEquals(pastUptime, mPastUptimeUs);
+ Assert.assertEquals(uptimeStart, mUptimeStartUs);
+ Assert.assertEquals(pastRealtime, mPastRealtimeUs);
+ Assert.assertEquals(realtimeStart, mRealtimeStartUs);
+ Assert.assertEquals(unpluggedUptime, mUnpluggedUptimeUs);
+ Assert.assertEquals(unpluggedRealtime, mUnpluggedRealtimeUs);
}
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java
index 40e3a5f..11a01b3 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java
@@ -49,7 +49,8 @@
super(clocks, type, timeBase);
}
- protected long computeRunTimeLocked(long curBatteryRealtime) {
+ @Override
+ protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) {
lastComputeRunTimeRealtime = curBatteryRealtime;
return nextComputeRunTime;
}
@@ -67,19 +68,19 @@
}
public long getTotalTime() {
- return mTotalTime;
+ return mTotalTimeUs;
}
public void setTotalTime(long val) {
- mTotalTime = val;
+ mTotalTimeUs = val;
}
public long getTimeBeforeMark() {
- return mTimeBeforeMark;
+ return mTimeBeforeMarkUs;
}
public void setTimeBeforeMark(long val) {
- mTimeBeforeMark = val;
+ mTimeBeforeMarkUs = val;
}
}
diff --git a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
index 02870a5..7f4e9ad 100644
--- a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
@@ -20,6 +20,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import android.app.Activity;
import android.app.EmptyActivity;
@@ -41,6 +44,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mockito;
/**
* Tests {@link DecorContext}.
@@ -63,13 +67,18 @@
@Test
public void testDecorContextWithDefaultDisplay() {
+ final Context baseContext = Mockito.spy(mContext.getApplicationContext());
Display defaultDisplay = new Display(DisplayManagerGlobal.getInstance(), DEFAULT_DISPLAY,
new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
final Context defaultDisplayContext = mContext.createDisplayContext(defaultDisplay);
final PhoneWindow window = new PhoneWindow(defaultDisplayContext);
- DecorContext context = new DecorContext(mContext.getApplicationContext(), window);
+ DecorContext context = new DecorContext(baseContext, window);
assertDecorContextDisplay(DEFAULT_DISPLAY, context);
+
+ // TODO(b/166174272): Creating a display context for the default display will result
+ // in additional resource creation.
+ verify(baseContext, never()).createDisplayContext(any());
}
@Test
diff --git a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
index 359bd5e..f1cd89b 100644
--- a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
@@ -16,8 +16,16 @@
package com.android.internal.util;
+import static com.android.internal.util.HexDump.hexStringToByteArray;
+import static com.android.internal.util.HexDump.toHexString;
+
import junit.framework.TestCase;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Random;
+
public final class HexDumpTest extends TestCase {
public void testBytesToHexString() {
assertEquals("abcdef", HexDump.toHexString(
@@ -25,7 +33,143 @@
assertEquals("ABCDEF", HexDump.toHexString(
new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, true));
}
- public void testNullArray() {
- assertEquals("(null)", HexDump.toHexString(null));
+
+ public void testNullByteArray() {
+ assertThrows(
+ NullPointerException.class,
+ () -> HexDump.toHexString(null));
}
+
+ public void testBytesToHexString_allByteValues() {
+ byte[] bytes = new byte[256];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) (i % 256);
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (char firstChar : "0123456789ABCDEF".toCharArray()) {
+ for (char secondChar : "0123456789ABCDEF".toCharArray()) {
+ sb.append(firstChar).append(secondChar);
+ }
+ }
+ String expected = sb.toString();
+
+ assertEquals(expected, HexDump.toHexString(bytes));
+ }
+
+ public void testRoundTrip_fromBytes() {
+ Random deterministicRandom = new Random(31337); // arbitrary but deterministic
+ for (int length = 0; length < 100; length++) {
+ byte[] bytes = new byte[length];
+ deterministicRandom.nextBytes(bytes);
+ byte[] reconstruction = hexStringToByteArray(toHexString(bytes));
+
+ assertBytesEqual(bytes, reconstruction);
+ }
+ }
+
+ public void testRoundTrip_fromString() {
+ String hexString = "0123456789ABCDEF72f9a3438934c378d34f32a8b932";
+ for (int length = 0; length < hexString.length(); length += 2) {
+ String original = hexString.substring(0, length);
+ String reconstruction = toHexString(hexStringToByteArray(original));
+ assertEquals(original.toUpperCase(), reconstruction);
+ }
+ }
+
+ public void testToHexString_offsetLength() {
+ byte[] bytes = new byte[32];
+ for (int i = 0; i < 16; i++) {
+ bytes[i] = (byte) i;
+ bytes[16 + i] = (byte) (16 * i);
+ }
+ String expected = "000102030405060708090A0B0C0D0E0F00102030405060708090A0B0C0D0E0F0";
+ for (int offset = 0; offset < bytes.length; offset++) {
+ for (int len = 0; len < (bytes.length - offset); len++) {
+
+ byte[] subBytes = new byte[len];
+ System.arraycopy(bytes, offset, subBytes, 0, len);
+
+ String actual = toHexString(bytes, offset, len);
+ assertEquals(expected.substring(2 * offset, 2 * offset + 2 * len), actual);
+ assertEquals(toHexString(subBytes), actual);
+ }
+ }
+ }
+
+ public void testToHexString_case() {
+ byte[] bytes = new byte[32];
+ for (int i = 0; i < 16; i++) {
+ bytes[i] = (byte) i;
+ bytes[16 + i] = (byte) (16 * i);
+ }
+
+ String expected = "000102030405060708090A0B0C0D0E0F00102030405060708090A0B0C0D0E0F0";
+
+ assertEquals(expected.toUpperCase(), toHexString(bytes, true));
+ assertEquals(expected.toLowerCase(), toHexString(bytes, false));
+
+ // default is uppercase
+ assertEquals(expected.toUpperCase(), toHexString(bytes));
+ }
+
+ public void testHexStringToByteArray_empty() {
+ assertBytesEqual(new byte[0], HexDump.hexStringToByteArray(""));
+ }
+
+ public void testHexStringToByteArray_null() {
+ assertThrows(
+ NullPointerException.class,
+ () -> HexDump.hexStringToByteArray((String) null));
+ }
+
+ public void testHexStringToByteArray_invalidCharacters() {
+ // IllegalArgumentException would probably have been better than RuntimeException, but it
+ // might be too late to change now.
+ assertThrows(
+ RuntimeException.class,
+ () -> HexDump.hexStringToByteArray("GG"));
+ assertThrows(
+ RuntimeException.class,
+ () -> HexDump.hexStringToByteArray("\0\0"));
+ assertThrows(
+ RuntimeException.class,
+ () -> HexDump.hexStringToByteArray("abcdefgh"));
+ }
+
+ public void testHexStringToByteArray_oddLength() {
+ // IllegalArgumentException would probably have been better than
+ // StringIndexOutOfBoundsException, but it might be too late to change now.
+ assertThrows(
+ StringIndexOutOfBoundsException.class,
+ () -> HexDump.hexStringToByteArray("A"));
+ assertThrows(
+ StringIndexOutOfBoundsException.class,
+ () -> HexDump.hexStringToByteArray("123"));
+ assertThrows(
+ StringIndexOutOfBoundsException.class,
+ () -> HexDump.hexStringToByteArray("ABCDE"));
+ }
+
+ private static void assertBytesEqual(byte[] expected, byte[] actual) {
+ if (!Arrays.equals(expected, actual)) {
+ fail("Expected " + Arrays.toString(expected) + ", got " + Arrays.toString(actual));
+ }
+ }
+
+ private static void assertThrows(Class<? extends RuntimeException> clazz, Runnable runnable) {
+ try {
+ runnable.run();
+ fail();
+ } catch (RuntimeException expected) {
+ assertEquals(toStrackTrace(expected), clazz, expected.getClass());
+ }
+ }
+
+ private static String toStrackTrace(Throwable throwable) {
+ StringWriter stringWriter = new StringWriter();
+ throwable.printStackTrace(new PrintWriter(stringWriter));
+ return stringWriter.toString();
+ }
+
}
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 1cdc75a..9d95de7e 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -23,6 +23,8 @@
import static android.app.servertransaction.ActivityLifecycleItem.ON_START;
import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -30,7 +32,11 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
@@ -50,6 +56,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.testing.PollingCheck;
import android.view.WindowManagerGlobal;
import androidx.test.annotation.UiThreadTest;
@@ -63,6 +70,8 @@
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
+import java.util.concurrent.TimeUnit;
+
/**
* Test for verifying {@link android.app.ActivityThread} class.
*
@@ -76,6 +85,7 @@
@MediumTest
@Presubmit
public class ActivityThreadClientTest {
+ private static final long WAIT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);
@Test
@UiThreadTest
@@ -152,6 +162,63 @@
}
}
+ @Test
+ public void testLifecycleOfRelaunch() throws Exception {
+ try (ClientMockSession clientSession = new ClientMockSession()) {
+ ActivityThread activityThread = clientSession.mockThread();
+ ActivityClientRecord r = clientSession.stubActivityRecord();
+ final TestActivity[] activity = new TestActivity[1];
+
+ // Verify for ON_CREATE state. Activity should not be relaunched.
+ getInstrumentation().runOnMainSync(() -> {
+ activity[0] = (TestActivity) clientSession.launchActivity(r);
+ });
+ recreateAndVerifyNoRelaunch(activityThread, activity[0]);
+
+ // Verify for ON_START state. Activity should be relaunched.
+ getInstrumentation().runOnMainSync(() -> clientSession.startActivity(r));
+ recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_START);
+
+ // Verify for ON_RESUME state. Activity should be relaunched.
+ getInstrumentation().runOnMainSync(() -> clientSession.resumeActivity(r));
+ recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_RESUME);
+
+ // Verify for ON_PAUSE state. Activity should be relaunched.
+ getInstrumentation().runOnMainSync(() -> clientSession.pauseActivity(r));
+ recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_PAUSE);
+
+ // Verify for ON_STOP state. Activity should be relaunched.
+ getInstrumentation().runOnMainSync(() -> clientSession.stopActivity(r));
+ recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_STOP);
+
+ // Verify for ON_DESTROY state. Activity should not be relaunched.
+ getInstrumentation().runOnMainSync(() -> clientSession.destroyActivity(r));
+ recreateAndVerifyNoRelaunch(activityThread, activity[0]);
+ }
+ }
+
+ private void recreateAndVerifyNoRelaunch(ActivityThread activityThread, TestActivity activity) {
+ clearInvocations(activityThread);
+ getInstrumentation().runOnMainSync(() -> activity.recreate());
+
+ verify(activityThread, after(WAIT_TIMEOUT_MS).never())
+ .handleRelaunchActivity(any(), any());
+ }
+
+ private void recreateAndVerifyRelaunched(ActivityThread activityThread, TestActivity activity,
+ ActivityClientRecord r, int expectedState) throws Exception {
+ clearInvocations(activityThread);
+ getInstrumentation().runOnMainSync(() -> activity.recreate());
+
+ verify(activityThread, timeout(WAIT_TIMEOUT_MS)).handleRelaunchActivity(any(), any());
+
+ // Wait for the relaunch to complete.
+ PollingCheck.check("Waiting for the expected state " + expectedState + " timeout",
+ WAIT_TIMEOUT_MS,
+ () -> expectedState == r.getLifecycleState());
+ assertEquals(expectedState, r.getLifecycleState());
+ }
+
private class ClientMockSession implements AutoCloseable {
private MockitoSession mMockSession;
private ActivityThread mThread;
@@ -200,6 +267,11 @@
false /* getNonConfigInstance */, "test");
}
+ private ActivityThread mockThread() {
+ spyOn(mThread);
+ return mThread;
+ }
+
private ActivityClientRecord stubActivityRecord() {
ComponentName component = new ComponentName(
InstrumentationRegistry.getInstrumentation().getContext(), TestActivity.class);
diff --git a/core/tests/powertests/PowerStatsLoadTests/Android.bp b/core/tests/powertests/PowerStatsLoadTests/Android.bp
new file mode 100644
index 0000000..66c91ad
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/Android.bp
@@ -0,0 +1,13 @@
+android_test {
+ name: "PowerStatsLoadTests",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "compatibility-device-util-axt",
+ "junit",
+ ],
+ libs: ["android.test.runner"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml b/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml
new file mode 100644
index 0000000..b1c2a63
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.core.powerstatsloadtests">
+
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.BATTERY_STATS"/>
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.frameworks.core.powerstatsloadtests"
+ android:label="Power Stats Load Tests" />
+
+ <queries>
+ <!-- The load test resolves http://... intents. Let it do so. -->
+ <package android:name="com.android.chrome"/>
+ </queries>
+</manifest>
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java
new file mode 100644
index 0000000..ca29426
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ConnectivitySetupRule implements TestRule {
+
+ private final boolean mWifiEnabled;
+ private final ConnectivityManager mConnectivityManager;
+ private final WifiManager mWifiManager;
+ private boolean mInitialWifiState;
+
+ public ConnectivitySetupRule(boolean wifiEnabled) {
+ mWifiEnabled = wifiEnabled;
+
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ Context context = instrumentation.getContext();
+ mConnectivityManager = context.getSystemService(ConnectivityManager.class);
+ mWifiManager = context.getSystemService(WifiManager.class);
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ mInitialWifiState = isWiFiConnected();
+ setWiFiState(mWifiEnabled);
+ base.evaluate();
+ } finally {
+ setWiFiState(mInitialWifiState);
+ }
+ }
+ };
+ }
+
+ private void setWiFiState(final boolean enable) throws InterruptedException {
+ boolean wiFiConnected = isWiFiConnected();
+ if (enable == wiFiConnected) {
+ return;
+ }
+
+ NetworkTracker tracker = new NetworkTracker(!mWifiEnabled);
+ mConnectivityManager.registerNetworkCallback(
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED).build(),
+ tracker);
+
+ if (enable) {
+ SystemUtil.runShellCommand("svc wifi enable");
+ //noinspection deprecation
+ SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect,
+ android.Manifest.permission.NETWORK_SETTINGS);
+ } else {
+ SystemUtil.runShellCommand("svc wifi disable");
+ }
+
+ tracker.waitForExpectedState();
+
+ assertEquals("Wifi must be " + (enable ? "connected to" : "disconnected from")
+ + " an access point for this test.", enable, isWiFiConnected());
+
+ mConnectivityManager.unregisterNetworkCallback(tracker);
+ }
+
+ private boolean isWiFiConnected() {
+ return mWifiManager.isWifiEnabled() && mConnectivityManager.getActiveNetwork() != null
+ && !mConnectivityManager.isActiveNetworkMetered();
+ }
+
+ private class NetworkTracker extends ConnectivityManager.NetworkCallback {
+ private static final int MSG_CHECK_ACTIVE_NETWORK = 1;
+
+ private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
+
+ private final boolean mExpectedMetered;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_CHECK_ACTIVE_NETWORK) {
+ checkActiveNetwork();
+ }
+ }
+ };
+
+ private NetworkTracker(boolean expectedMetered) {
+ mExpectedMetered = expectedMetered;
+ }
+
+ @Override
+ public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
+ LinkProperties linkProperties, boolean blocked) {
+ checkActiveNetwork();
+ }
+
+ @Override
+ public void onLost(Network network) {
+ checkActiveNetwork();
+ }
+
+ boolean waitForExpectedState() throws InterruptedException {
+ checkActiveNetwork();
+ return mReceiveLatch.await(60, TimeUnit.SECONDS);
+ }
+
+ private void checkActiveNetwork() {
+ if (mReceiveLatch.getCount() == 0) {
+ return;
+ }
+
+ if (mConnectivityManager.getActiveNetwork() != null
+ && mConnectivityManager.isActiveNetworkMetered() == mExpectedMetered) {
+ mReceiveLatch.countDown();
+ } else {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
+ }
+ }
+ }
+}
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java
new file mode 100644
index 0000000..88cb719
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests;
+
+import android.os.Process;
+
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PowerMetrics {
+ private static final String PACKAGE_CALENDAR_PROVIDER = "com.android.providers.calendar";
+ private static final String PACKAGE_MEDIA_PROVIDER = "com.android.providers.media";
+ private static final String PACKAGE_SYSTEMUI = "com.android.systemui";
+ private static final String[] PACKAGES_SYSTEM = {PACKAGE_MEDIA_PROVIDER,
+ PACKAGE_CALENDAR_PROVIDER, PACKAGE_SYSTEMUI};
+
+ enum MetricKind {
+ POWER,
+ DURATION,
+ }
+
+ public static final String METRIC_APP_POWER = "appPower";
+ public static final String METRIC_APP_POWER_EXCLUDE_SYSTEM_FROM_TOTAL = "appPowerExcludeSystem";
+ public static final String METRIC_APP_POWER_EXCLUDE_SMEARED = "appPowerExcludeSmeared";
+ public static final String METRIC_SCREEN_POWER = "screenPower";
+ public static final String METRIC_WIFI_POWER = "wifiPower";
+ public static final String METRIC_SYSTEM_SERVICE_CPU_POWER = "systemService";
+ public static final String METRIC_OTHER_POWER = "otherPower";
+ public static final String METRIC_CPU_POWER = "cpuPower";
+ public static final String METRIC_RAM_POWER = "ramPower";
+ public static final String METRIC_WAKELOCK_POWER = "wakelockPower";
+ public static final String METRIC_MOBILE_RADIO_POWER = "mobileRadioPower";
+ public static final String METRIC_BLUETOOTH_POWER = "bluetoothPower";
+ public static final String METRIC_GPS_POWER = "gpsPower";
+ public static final String METRIC_CAMERA_POWER = "cameraPower";
+ public static final String METRIC_FLASHLIGHT_POWER = "flashlightPower";
+ public static final String METRIC_SENSORS_POWER = "sensorsPower";
+ public static final String METRIC_AUDIO_POWER = "audioPower";
+ public static final String METRIC_VIDEO_POWER = "videoPower";
+ public static final String METRIC_CPU_TIME = "cpuTime";
+ public static final String METRIC_CPU_FOREGROUND_TIME = "cpuForegroundTime";
+ public static final String METRIC_WAKELOCK_TIME = "wakelockTime";
+ public static final String METRIC_WIFI_RUNNING_TIME = "wifiRunningTime";
+ public static final String METRIC_BLUETOOTH_RUNNING_TIME = "bluetoothRunningTime";
+ public static final String METRIC_GPS_TIME = "gpsTime";
+ public static final String METRIC_CAMERA_TIME = "cameraTime";
+ public static final String METRIC_FLASHLIGHT_TIME = "flashlightTime";
+ public static final String METRIC_AUDIO_TIME = "audioTime";
+ public static final String METRIC_VIDEO_TIME = "videoTime";
+
+ public static class Metric {
+ public String metricType;
+ public MetricKind metricKind;
+ public String title;
+ public double value;
+ public double total;
+ }
+
+ private final double mMinDrainedPower;
+ private final double mMaxDrainedPower;
+
+ private List<Metric> mMetrics = new ArrayList<>();
+
+ public PowerMetrics(BatteryStatsHelper batteryStatsHelper, int uid) {
+ mMinDrainedPower = batteryStatsHelper.getMinDrainedPower();
+ mMaxDrainedPower = batteryStatsHelper.getMaxDrainedPower();
+
+ List<BatterySipper> usageList = batteryStatsHelper.getUsageList();
+
+ double totalPowerMah = 0;
+ double totalSmearedPowerMah = 0;
+ double totalPowerExcludeSystemMah = 0;
+ double totalScreenPower = 0;
+ double totalProportionalSmearMah = 0;
+ double totalCpuPowerMah = 0;
+ double totalSystemServiceCpuPowerMah = 0;
+ double totalUsagePowerMah = 0;
+ double totalWakeLockPowerMah = 0;
+ double totalMobileRadioPowerMah = 0;
+ double totalWifiPowerMah = 0;
+ double totalBluetoothPowerMah = 0;
+ double totalGpsPowerMah = 0;
+ double totalCameraPowerMah = 0;
+ double totalFlashlightPowerMah = 0;
+ double totalSensorPowerMah = 0;
+ double totalAudioPowerMah = 0;
+ double totalVideoPowerMah = 0;
+
+ long totalCpuTimeMs = 0;
+ long totalCpuFgTimeMs = 0;
+ long totalWakeLockTimeMs = 0;
+ long totalWifiRunningTimeMs = 0;
+ long totalBluetoothRunningTimeMs = 0;
+ long totalGpsTimeMs = 0;
+ long totalCameraTimeMs = 0;
+ long totalFlashlightTimeMs = 0;
+ long totalAudioTimeMs = 0;
+ long totalVideoTimeMs = 0;
+
+ BatterySipper uidSipper = null;
+ for (BatterySipper sipper : usageList) {
+ if (sipper.drainType == BatterySipper.DrainType.SCREEN) {
+ totalScreenPower = sipper.sumPower();
+ }
+
+ if (isHiddenDrainType(sipper.drainType)) {
+ continue;
+ }
+
+ if (sipper.drainType == BatterySipper.DrainType.APP && sipper.getUid() == uid) {
+ uidSipper = sipper;
+ }
+
+ totalPowerMah += sipper.sumPower();
+ totalSmearedPowerMah += sipper.totalSmearedPowerMah;
+ totalProportionalSmearMah += sipper.proportionalSmearMah;
+
+ if (!isSystemSipper(sipper)) {
+ totalPowerExcludeSystemMah += sipper.totalSmearedPowerMah;
+ }
+
+ totalCpuPowerMah += sipper.cpuPowerMah;
+ totalSystemServiceCpuPowerMah += sipper.systemServiceCpuPowerMah;
+ totalUsagePowerMah += sipper.usagePowerMah;
+ totalWakeLockPowerMah += sipper.wakeLockPowerMah;
+ totalMobileRadioPowerMah += sipper.mobileRadioPowerMah;
+ totalWifiPowerMah += sipper.wifiPowerMah;
+ totalBluetoothPowerMah += sipper.bluetoothPowerMah;
+ totalGpsPowerMah += sipper.gpsPowerMah;
+ totalCameraPowerMah += sipper.cameraPowerMah;
+ totalFlashlightPowerMah += sipper.flashlightPowerMah;
+ totalSensorPowerMah += sipper.sensorPowerMah;
+ totalAudioPowerMah += sipper.audioPowerMah;
+ totalVideoPowerMah += sipper.videoPowerMah;
+
+ totalCpuTimeMs += sipper.cpuTimeMs;
+ totalCpuFgTimeMs += sipper.cpuFgTimeMs;
+ totalWakeLockTimeMs += sipper.wakeLockTimeMs;
+ totalWifiRunningTimeMs += sipper.wifiRunningTimeMs;
+ totalBluetoothRunningTimeMs += sipper.bluetoothRunningTimeMs;
+ totalGpsTimeMs += sipper.gpsTimeMs;
+ totalCameraTimeMs += sipper.cameraTimeMs;
+ totalFlashlightTimeMs += sipper.flashlightTimeMs;
+ totalAudioTimeMs += sipper.audioTimeMs;
+ totalVideoTimeMs += sipper.videoTimeMs;
+ }
+
+ if (uidSipper == null) {
+ return;
+ }
+
+ addMetric(METRIC_APP_POWER, MetricKind.POWER, "Total power",
+ uidSipper.totalSmearedPowerMah, totalSmearedPowerMah);
+ addMetric(METRIC_APP_POWER_EXCLUDE_SYSTEM_FROM_TOTAL, MetricKind.POWER,
+ "Total power excluding system",
+ uidSipper.totalSmearedPowerMah, totalPowerExcludeSystemMah);
+ addMetric(METRIC_SCREEN_POWER, MetricKind.POWER, "Screen, smeared",
+ uidSipper.screenPowerMah, totalScreenPower);
+ addMetric(METRIC_OTHER_POWER, MetricKind.POWER, "Other, smeared",
+ uidSipper.proportionalSmearMah, totalProportionalSmearMah);
+ addMetric(METRIC_APP_POWER_EXCLUDE_SMEARED, MetricKind.POWER, "Excluding smeared",
+ uidSipper.totalPowerMah, totalPowerMah);
+ addMetric(METRIC_CPU_POWER, MetricKind.POWER, "CPU",
+ uidSipper.cpuPowerMah, totalCpuPowerMah);
+ addMetric(METRIC_SYSTEM_SERVICE_CPU_POWER, MetricKind.POWER, "System services",
+ uidSipper.systemServiceCpuPowerMah, totalSystemServiceCpuPowerMah);
+ addMetric(METRIC_RAM_POWER, MetricKind.POWER, "RAM",
+ uidSipper.usagePowerMah, totalUsagePowerMah);
+ addMetric(METRIC_WAKELOCK_POWER, MetricKind.POWER, "Wake lock",
+ uidSipper.wakeLockPowerMah, totalWakeLockPowerMah);
+ addMetric(METRIC_MOBILE_RADIO_POWER, MetricKind.POWER, "Mobile radio",
+ uidSipper.mobileRadioPowerMah, totalMobileRadioPowerMah);
+ addMetric(METRIC_WIFI_POWER, MetricKind.POWER, "WiFi",
+ uidSipper.wifiPowerMah, totalWifiPowerMah);
+ addMetric(METRIC_BLUETOOTH_POWER, MetricKind.POWER, "Bluetooth",
+ uidSipper.bluetoothPowerMah, totalBluetoothPowerMah);
+ addMetric(METRIC_GPS_POWER, MetricKind.POWER, "GPS",
+ uidSipper.gpsPowerMah, totalGpsPowerMah);
+ addMetric(METRIC_CAMERA_POWER, MetricKind.POWER, "Camera",
+ uidSipper.cameraPowerMah, totalCameraPowerMah);
+ addMetric(METRIC_FLASHLIGHT_POWER, MetricKind.POWER, "Flashlight",
+ uidSipper.flashlightPowerMah, totalFlashlightPowerMah);
+ addMetric(METRIC_SENSORS_POWER, MetricKind.POWER, "Sensors",
+ uidSipper.sensorPowerMah, totalSensorPowerMah);
+ addMetric(METRIC_AUDIO_POWER, MetricKind.POWER, "Audio",
+ uidSipper.audioPowerMah, totalAudioPowerMah);
+ addMetric(METRIC_VIDEO_POWER, MetricKind.POWER, "Video",
+ uidSipper.videoPowerMah, totalVideoPowerMah);
+
+ addMetric(METRIC_CPU_TIME, MetricKind.DURATION, "CPU time",
+ uidSipper.cpuTimeMs, totalCpuTimeMs);
+ addMetric(METRIC_CPU_FOREGROUND_TIME, MetricKind.DURATION, "CPU foreground time",
+ uidSipper.cpuFgTimeMs, totalCpuFgTimeMs);
+ addMetric(METRIC_WAKELOCK_TIME, MetricKind.DURATION, "Wake lock time",
+ uidSipper.wakeLockTimeMs, totalWakeLockTimeMs);
+ addMetric(METRIC_WIFI_RUNNING_TIME, MetricKind.DURATION, "WiFi running time",
+ uidSipper.wifiRunningTimeMs, totalWifiRunningTimeMs);
+ addMetric(METRIC_BLUETOOTH_RUNNING_TIME, MetricKind.DURATION, "Bluetooth time",
+ uidSipper.bluetoothRunningTimeMs, totalBluetoothRunningTimeMs);
+ addMetric(METRIC_GPS_TIME, MetricKind.DURATION, "GPS time",
+ uidSipper.gpsTimeMs, totalGpsTimeMs);
+ addMetric(METRIC_CAMERA_TIME, MetricKind.DURATION, "Camera time",
+ uidSipper.cameraTimeMs, totalCameraTimeMs);
+ addMetric(METRIC_FLASHLIGHT_TIME, MetricKind.DURATION, "Flashlight time",
+ uidSipper.flashlightTimeMs, totalFlashlightTimeMs);
+ addMetric(METRIC_AUDIO_TIME, MetricKind.DURATION, "Audio time",
+ uidSipper.audioTimeMs, totalAudioTimeMs);
+ addMetric(METRIC_VIDEO_TIME, MetricKind.DURATION, "Video time",
+ uidSipper.videoTimeMs, totalVideoTimeMs);
+ }
+
+ public List<Metric> getMetrics() {
+ return mMetrics;
+ }
+
+ public double getMinDrainedPower() {
+ return mMinDrainedPower;
+ }
+
+ public double getMaxDrainedPower() {
+ return mMaxDrainedPower;
+ }
+
+ protected boolean isHiddenDrainType(BatterySipper.DrainType drainType) {
+ return drainType == BatterySipper.DrainType.IDLE
+ || drainType == BatterySipper.DrainType.CELL
+ || drainType == BatterySipper.DrainType.SCREEN
+ || drainType == BatterySipper.DrainType.UNACCOUNTED
+ || drainType == BatterySipper.DrainType.OVERCOUNTED
+ || drainType == BatterySipper.DrainType.BLUETOOTH
+ || drainType == BatterySipper.DrainType.WIFI;
+ }
+
+ private boolean isSystemSipper(BatterySipper sipper) {
+ final int uid = sipper.uidObj == null ? -1 : sipper.getUid();
+ if (uid >= Process.ROOT_UID && uid < Process.FIRST_APPLICATION_UID) {
+ return true;
+ } else if (sipper.mPackages != null) {
+ for (final String packageName : sipper.mPackages) {
+ for (final String systemPackage : PACKAGES_SYSTEM) {
+ if (systemPackage.equals(packageName)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private void addMetric(String metricType, MetricKind metricKind, String title, double amount,
+ double totalAmount) {
+ Metric metric = new Metric();
+ metric.metricType = metricType;
+ metric.metricKind = metricKind;
+ metric.title = title;
+ metric.value = amount;
+ metric.total = totalAmount;
+ mMetrics.add(metric);
+ }
+}
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java
new file mode 100644
index 0000000..0cdb404
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests;
+
+import static org.junit.Assert.fail;
+
+import android.app.Instrumentation;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.BatteryStats;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.SystemClock;
+import android.os.UserManager;
+import android.util.Log;
+import android.util.TimeUtils;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.os.BatteryStatsHelper;
+import com.android.internal.os.LoggingPrintStream;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+public class PowerMetricsCollector implements TestRule {
+ private final String mTag;
+ private final float mBatteryDrainThresholdPct;
+ private final int mTimeoutMillis;
+
+ private final Context mContext;
+ private final UserManager mUserManager;
+ private final int mUid;
+ private final BatteryStatsHelper mStatsHelper;
+
+ private long mStartTime;
+ private volatile float mInitialBatteryLevel;
+ private volatile float mCurrentBatteryLevel;
+ private int mIterations;
+ private PowerMetrics mInitialPowerMetrics;
+ private PowerMetrics mFinalPowerMetrics;
+ private List<PowerMetrics.Metric> mPowerMetricsDelta;
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ disableCharger();
+ try {
+ prepareBatteryLevelMonitor();
+ mStartTime = SystemClock.uptimeMillis();
+ base.evaluate();
+ captureFinalPowerStatsData();
+ } finally {
+ enableCharger();
+ }
+ }
+ };
+ }
+
+ public PowerMetricsCollector(String tag, float batteryDrainThresholdPct, int timeoutMillis) {
+ mTag = tag;
+ mBatteryDrainThresholdPct = batteryDrainThresholdPct;
+ mTimeoutMillis = timeoutMillis;
+
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ mContext = instrumentation.getContext();
+ mUid = Process.myUid();
+ mUserManager = mContext.getSystemService(UserManager.class);
+ mStatsHelper = new BatteryStatsHelper(mContext, false /* collectBatteryBroadcast */);
+ mStatsHelper.create((Bundle) null);
+ }
+
+ private void disableCharger() {
+ // TODO(b/167636754): implement this method once the charger suspension API is available
+ }
+
+ private void enableCharger() {
+ // TODO(b/167636754): implement this method once the charger suspension API is available
+ }
+
+ private PowerMetrics readBatteryStatsData() {
+ mStatsHelper.clearStats();
+ mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
+ mUserManager.getUserProfiles());
+ return new PowerMetrics(mStatsHelper, mUid);
+ }
+
+ protected void prepareBatteryLevelMonitor() {
+ Intent batteryStatus = mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ handleBatteryStatus(intent);
+ }
+ }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+ handleBatteryStatus(batteryStatus);
+ mInitialBatteryLevel = mCurrentBatteryLevel;
+ }
+
+ protected void handleBatteryStatus(Intent intent) {
+ if (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0) {
+ fail("Device must remain disconnected from the power source "
+ + "for the duration of the test");
+ }
+
+ int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+ int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+
+ mCurrentBatteryLevel = level * 100 / (float) scale;
+ Log.i(mTag, "Battery level = " + mCurrentBatteryLevel);
+
+ // We delay tracking until the battery level drops. If the resolution of
+ // battery level is 1%, and the initially reported level is 73, we don't know whether
+ // it's 73.1 or 73.7. Once it drops to 72, we can be confident that the real battery
+ // level it is very close to 72.0 and can start tracking.
+ if (mInitialPowerMetrics == null && mCurrentBatteryLevel < mInitialBatteryLevel) {
+ mInitialBatteryLevel = mCurrentBatteryLevel;
+ mInitialPowerMetrics = readBatteryStatsData();
+ }
+ }
+
+ private void captureFinalPowerStatsData() {
+ if (mFinalPowerMetrics != null) {
+ return;
+ }
+
+ mFinalPowerMetrics = readBatteryStatsData();
+
+ mPowerMetricsDelta = new ArrayList<>();
+ List<PowerMetrics.Metric> initialPowerMetrics = mInitialPowerMetrics.getMetrics();
+ List<PowerMetrics.Metric> finalPowerMetrics = mFinalPowerMetrics.getMetrics();
+ for (PowerMetrics.Metric initialMetric : initialPowerMetrics) {
+ PowerMetrics.Metric finalMetric = null;
+ for (PowerMetrics.Metric metric : finalPowerMetrics) {
+ if (metric.title.equals(initialMetric.title)) {
+ finalMetric = metric;
+ break;
+ }
+ }
+
+ if (finalMetric != null) {
+ PowerMetrics.Metric delta = new PowerMetrics.Metric();
+ delta.metricType = initialMetric.metricType;
+ delta.metricKind = initialMetric.metricKind;
+ delta.title = initialMetric.title;
+ delta.total = finalMetric.total - initialMetric.total;
+ delta.value = finalMetric.value - initialMetric.value;
+ mPowerMetricsDelta.add(delta);
+ }
+ }
+ }
+
+ /**
+ * Returns false if sufficient data has been accumulated.
+ */
+ public boolean checkpoint() {
+ long elapsedTime = SystemClock.uptimeMillis() - mStartTime;
+ if (elapsedTime >= mTimeoutMillis) {
+ Log.i(mTag, "Timeout reached " + TimeUtils.formatDuration(elapsedTime));
+ captureFinalPowerStatsData();
+ return false;
+ }
+
+ if (mInitialPowerMetrics == null) {
+ return true;
+ }
+
+ if (mInitialBatteryLevel - mCurrentBatteryLevel >= mBatteryDrainThresholdPct) {
+ Log.i(mTag,
+ "Battery drain reached " + (mInitialBatteryLevel - mCurrentBatteryLevel) + "%");
+ captureFinalPowerStatsData();
+ return false;
+ }
+
+ mIterations++;
+ return true;
+ }
+
+
+ public int getIterationCount() {
+ return mIterations;
+ }
+
+ public void dumpMetrics() {
+ dumpMetrics(new LoggingPrintStream() {
+ @Override
+ protected void log(String line) {
+ Log.i(mTag, line);
+ }
+ });
+ }
+
+ public void dumpMetrics(PrintStream out) {
+ List<PowerMetrics.Metric> initialPowerMetrics = mInitialPowerMetrics.getMetrics();
+ List<PowerMetrics.Metric> finalPowerMetrics = mFinalPowerMetrics.getMetrics();
+
+ out.println("== Power metrics at test start");
+ dumpPowerStatsData(out, initialPowerMetrics);
+
+ out.println("== Power metrics at test end");
+ dumpPowerStatsData(out, finalPowerMetrics);
+
+ out.println("== Power metrics delta");
+ dumpPowerStatsData(out, mPowerMetricsDelta);
+ }
+
+ protected void dumpPowerStatsData(PrintStream out, List<PowerMetrics.Metric> metrics) {
+ Locale locale = Locale.getDefault();
+ for (PowerMetrics.Metric metric : metrics) {
+ double proportion = metric.total != 0 ? metric.value * 100 / metric.total : 0;
+ switch (metric.metricKind) {
+ case POWER:
+ out.println(
+ String.format(locale, " %-30s %7.1f mAh %4.1f%%", metric.title,
+ metric.value, proportion));
+ break;
+ case DURATION:
+ out.println(
+ String.format(locale, " %-30s %,7d ms %4.1f%%", metric.title,
+ (long) metric.value, proportion));
+ break;
+ }
+ }
+ }
+
+ public void dumpMetricAsPercentageOfDrainedPower(String metricType) {
+ double minDrainedPower =
+ mFinalPowerMetrics.getMinDrainedPower() - mInitialPowerMetrics.getMinDrainedPower();
+ double maxDrainedPower =
+ mFinalPowerMetrics.getMaxDrainedPower() - mInitialPowerMetrics.getMaxDrainedPower();
+
+ PowerMetrics.Metric metric = getMetric(metricType);
+ double metricDelta = metric.value;
+
+ if (maxDrainedPower - minDrainedPower < 0.1f) {
+ Log.i(mTag, String.format(Locale.getDefault(),
+ "%s power consumed by the test: %.1f of %.1f mAh (%.1f%%)",
+ metric.title, metricDelta, maxDrainedPower,
+ metricDelta / maxDrainedPower * 100));
+ } else {
+ Log.i(mTag, String.format(Locale.getDefault(),
+ "%s power consumed by the test: %.1f of %.1f - %.1f mAh (%.1f%% - %.1f%%)",
+ metric.title, metricDelta, minDrainedPower, maxDrainedPower,
+ metricDelta / minDrainedPower * 100, metricDelta / maxDrainedPower * 100));
+ }
+ }
+
+ public PowerMetrics.Metric getMetric(String metricType) {
+ for (PowerMetrics.Metric metric : mPowerMetricsDelta) {
+ if (metric.metricType.equals(metricType)) {
+ return metric;
+ }
+ }
+ return null;
+ }
+}
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java
new file mode 100644
index 0000000..911ccba
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.util.Log;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class SystemServiceCallLoadTest {
+ private static final String TAG = "SystemServiceCallLoadTest";
+ private static final int TIMEOUT_MILLIS = 60 * 60 * 1000;
+ private static final float BATTERY_DRAIN_THRESHOLD_PCT = 2.99f;
+
+ @Rule
+ public PowerMetricsCollector mPowerMetricsCollector = new PowerMetricsCollector(TAG,
+ BATTERY_DRAIN_THRESHOLD_PCT, TIMEOUT_MILLIS);
+
+ private PackageManager mPackageManager;
+
+ @Before
+ public void setup() {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ mPackageManager = instrumentation.getContext().getPackageManager();
+ }
+
+ @Test
+ public void test() {
+ while (mPowerMetricsCollector.checkpoint()) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setDataAndType(Uri.parse("http://example.com/"), "text/plain");
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0);
+ assertNotNull(resolveInfo);
+ }
+
+ mPowerMetricsCollector.dumpMetrics();
+
+ Log.i(TAG, "==");
+ Log.i(TAG, "Total system server calls made " + mPowerMetricsCollector.getIterationCount());
+
+ mPowerMetricsCollector.dumpMetricAsPercentageOfDrainedPower(
+ PowerMetrics.METRIC_SYSTEM_SERVICE_CPU_POWER);
+ }
+}
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java
new file mode 100644
index 0000000..90627192
--- /dev/null
+++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests;
+
+import android.util.Log;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+public class WiFiLoadTest {
+ private static final String TAG = "WiFiLoadTest";
+ private static final String DOWNLOAD_TEST_URL =
+ "https://i.ytimg.com/vi/l5mE3Tpjejs/maxresdefault.jpg";
+
+ private static final int TIMEOUT_MILLIS = 60 * 60 * 1000;
+ private static final float BATTERY_DRAIN_THRESHOLD_PCT = 0.99f;
+
+ @Rule
+ public PowerMetricsCollector mPowerMetricsCollector = new PowerMetricsCollector(TAG,
+ BATTERY_DRAIN_THRESHOLD_PCT, TIMEOUT_MILLIS);
+
+ @Rule
+ public ConnectivitySetupRule mConnectivitySetupRule =
+ new ConnectivitySetupRule(/* WiFi enabled */true);
+
+ @Test
+ public void test() throws IOException {
+ long totalBytesRead = 0;
+ URL url = new URL(DOWNLOAD_TEST_URL);
+ byte[] buffer = new byte[131072]; // Large buffer to minimize CPU usage
+
+ while (mPowerMetricsCollector.checkpoint()) {
+ try (InputStream inputStream = url.openStream()) {
+ while (true) {
+ int count = inputStream.read(buffer);
+ if (count < 0) {
+ break;
+ }
+ totalBytesRead += count;
+ }
+ }
+ }
+
+ mPowerMetricsCollector.dumpMetrics();
+
+ Log.i(TAG, "==");
+ Log.i(TAG, "WiFi running time: " + (long) mPowerMetricsCollector.getMetric(
+ PowerMetrics.METRIC_WIFI_RUNNING_TIME).value);
+ Log.i(TAG, "Total bytes read over WiFi: " + totalBytesRead);
+
+ mPowerMetricsCollector.dumpMetricAsPercentageOfDrainedPower(
+ PowerMetrics.METRIC_WIFI_POWER);
+ }
+}
diff --git a/data/etc/car/com.google.android.car.kitchensink.xml b/data/etc/car/com.google.android.car.kitchensink.xml
index 7292e07..59aa45e 100644
--- a/data/etc/car/com.google.android.car.kitchensink.xml
+++ b/data/etc/car/com.google.android.car.kitchensink.xml
@@ -40,6 +40,7 @@
<permission name="android.permission.REAL_GET_TASKS"/>
<permission name="android.permission.READ_LOGS"/>
<permission name="android.permission.REBOOT"/>
+ <permission name="android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"/>
<!-- use for CarServiceTest -->
<permission name="android.permission.SET_ACTIVITY_WATCHER"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index a2a2216..e693198 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1393,6 +1393,12 @@
"group": "WM_SHOW_SURFACE_ALLOC",
"at": "com\/android\/server\/wm\/BlackFrame.java"
},
+ "155482615": {
+ "message": "Focus requested for window=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/InputMonitor.java"
+ },
"174572959": {
"message": "DisplayArea info changed name=%s",
"level": "VERBOSE",
@@ -2635,6 +2641,12 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
},
+ "2081291430": {
+ "message": "Focus not requested for window=%s because it has no surface",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/InputMonitor.java"
+ },
"2083556954": {
"message": "Set mOrientationChanging of %s",
"level": "VERBOSE",
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 1ab4c63..fe6eeeb 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -28,12 +28,14 @@
label: 'A'
base: 'a'
shift, capslock: 'A'
+ shift+capslock: 'a'
}
key B {
label: 'B'
base: 'b'
shift, capslock: 'B'
+ shift+capslock: 'b'
}
key C {
@@ -42,12 +44,14 @@
shift, capslock: 'C'
alt: '\u00e7'
shift+alt: '\u00c7'
+ shift+capslock: 'c'
}
key D {
label: 'D'
base: 'd'
shift, capslock: 'D'
+ shift+capslock: 'd'
}
key E {
@@ -55,24 +59,28 @@
base: 'e'
shift, capslock: 'E'
alt: '\u0301'
+ shift+capslock: 'e'
}
key F {
label: 'F'
base: 'f'
shift, capslock: 'F'
+ shift+capslock: 'f'
}
key G {
label: 'G'
base: 'g'
shift, capslock: 'G'
+ shift+capslock: 'g'
}
key H {
label: 'H'
base: 'h'
shift, capslock: 'H'
+ shift+capslock: 'h'
}
key I {
@@ -80,30 +88,35 @@
base: 'i'
shift, capslock: 'I'
alt: '\u0302'
+ shift+capslock: 'i'
}
key J {
label: 'J'
base: 'j'
shift, capslock: 'J'
+ shift+capslock: 'j'
}
key K {
label: 'K'
base: 'k'
shift, capslock: 'K'
+ shift+capslock: 'k'
}
key L {
label: 'L'
base: 'l'
shift, capslock: 'L'
+ shift+capslock: 'l'
}
key M {
label: 'M'
base: 'm'
shift, capslock: 'M'
+ shift+capslock: 'm'
}
key N {
@@ -111,30 +124,35 @@
base: 'n'
shift, capslock: 'N'
alt: '\u0303'
+ shift+capslock: 'n'
}
key O {
label: 'O'
base: 'o'
shift, capslock: 'O'
+ shift+capslock: 'o'
}
key P {
label: 'P'
base: 'p'
shift, capslock: 'P'
+ shift+capslock: 'p'
}
key Q {
label: 'Q'
base: 'q'
shift, capslock: 'Q'
+ shift+capslock: 'q'
}
key R {
label: 'R'
base: 'r'
shift, capslock: 'R'
+ shift+capslock: 'r'
}
key S {
@@ -142,12 +160,14 @@
base: 's'
shift, capslock: 'S'
alt: '\u00df'
+ shift+capslock: 's'
}
key T {
label: 'T'
base: 't'
shift, capslock: 'T'
+ shift+capslock: 't'
}
key U {
@@ -155,36 +175,42 @@
base: 'u'
shift, capslock: 'U'
alt: '\u0308'
+ shift+capslock: 'u'
}
key V {
label: 'V'
base: 'v'
shift, capslock: 'V'
+ shift+capslock: 'v'
}
key W {
label: 'W'
base: 'w'
shift, capslock: 'W'
+ shift+capslock: 'w'
}
key X {
label: 'X'
base: 'x'
shift, capslock: 'X'
+ shift+capslock: 'x'
}
key Y {
label: 'Y'
base: 'y'
shift, capslock: 'Y'
+ shift+capslock: 'y'
}
key Z {
label: 'Z'
base: 'z'
shift, capslock: 'Z'
+ shift+capslock: 'z'
}
key 0 {
diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt
index 70dedb8..d8af726 100644
--- a/framework-jarjar-rules.txt
+++ b/framework-jarjar-rules.txt
@@ -1,6 +1,2 @@
rule android.hidl.** android.internal.hidl.@1
rule android.net.wifi.WifiAnnotations* android.internal.wifi.WifiAnnotations@1
-
-# Hide media mainline module implementation classes to avoid collisions with
-# app-bundled ExoPlayer classes.
-rule com.google.android.exoplayer2.** android.media.internal.exo.@1
diff --git a/libs/WindowManager/Jetpack/Android.bp b/libs/WindowManager/Jetpack/Android.bp
index 4f4364f..7fbbb61 100644
--- a/libs/WindowManager/Jetpack/Android.bp
+++ b/libs/WindowManager/Jetpack/Android.bp
@@ -24,14 +24,14 @@
static_libs: ["window-sidecar"],
installable: true,
sdk_version: "core_platform",
- vendor: true,
+ system_ext_specific: true,
libs: ["framework", "androidx.annotation_annotation",],
required: ["androidx.window.sidecar.xml",],
}
prebuilt_etc {
name: "androidx.window.sidecar.xml",
- vendor: true,
+ system_ext_specific: true,
sub_dir: "permissions",
src: "androidx.window.sidecar.xml",
filename_from_src: true,
diff --git a/libs/WindowManager/Jetpack/androidx.window.sidecar.xml b/libs/WindowManager/Jetpack/androidx.window.sidecar.xml
index f88a5f4..359e69f 100644
--- a/libs/WindowManager/Jetpack/androidx.window.sidecar.xml
+++ b/libs/WindowManager/Jetpack/androidx.window.sidecar.xml
@@ -17,5 +17,5 @@
<permissions>
<library
name="androidx.window.sidecar"
- file="/vendor/framework/androidx.window.sidecar.jar"/>
+ file="/system_ext/framework/androidx.window.sidecar.jar"/>
</permissions>
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 16b87c4..1591b06 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -105,6 +105,7 @@
static_libs: [
"protolog-lib",
"WindowManager-Shell-proto",
+ "androidx.appcompat_appcompat",
],
manifest: "AndroidManifest.xml",
}
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/forced_resizable_enter.xml b/libs/WindowManager/Shell/res/anim/forced_resizable_enter.xml
similarity index 100%
rename from packages/SystemUI/res/anim/forced_resizable_enter.xml
rename to libs/WindowManager/Shell/res/anim/forced_resizable_enter.xml
diff --git a/packages/SystemUI/res/anim/forced_resizable_exit.xml b/libs/WindowManager/Shell/res/anim/forced_resizable_exit.xml
similarity index 100%
rename from packages/SystemUI/res/anim/forced_resizable_exit.xml
rename to libs/WindowManager/Shell/res/anim/forced_resizable_exit.xml
diff --git a/packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png b/libs/WindowManager/Shell/res/drawable-hdpi/one_handed_tutorial.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png
rename to libs/WindowManager/Shell/res/drawable-hdpi/one_handed_tutorial.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/divider.xml b/libs/WindowManager/Shell/res/layout/divider.xml
similarity index 100%
rename from packages/SystemUI/res/layout/divider.xml
rename to libs/WindowManager/Shell/res/layout/divider.xml
diff --git a/packages/SystemUI/res/layout/docked_stack_divider.xml b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
similarity index 85%
rename from packages/SystemUI/res/layout/docked_stack_divider.xml
rename to libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
index 70e5451..ad87025 100644
--- a/packages/SystemUI/res/layout/docked_stack_divider.xml
+++ b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.stackdivider.DividerView
+<com.android.wm.shell.splitscreen.DividerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
@@ -24,15 +24,15 @@
android:id="@+id/docked_divider_background"
android:background="@color/docked_divider_background"/>
- <com.android.systemui.stackdivider.MinimizedDockShadow
+ <com.android.wm.shell.splitscreen.MinimizedDockShadow
style="@style/DockedDividerMinimizedShadow"
android:id="@+id/minimized_dock_shadow"
android:alpha="0"/>">
- <com.android.systemui.stackdivider.DividerHandleView
+ <com.android.wm.shell.splitscreen.DividerHandleView
style="@style/DockedDividerHandle"
android:id="@+id/docked_divider_handle"
android:contentDescription="@string/accessibility_divider"
android:background="@null"/>
-</com.android.systemui.stackdivider.DividerView>
+</com.android.wm.shell.splitscreen.DividerView>
diff --git a/packages/SystemUI/res/layout/forced_resizable_activity.xml b/libs/WindowManager/Shell/res/layout/forced_resizable_activity.xml
similarity index 100%
rename from packages/SystemUI/res/layout/forced_resizable_activity.xml
rename to libs/WindowManager/Shell/res/layout/forced_resizable_activity.xml
diff --git a/packages/SystemUI/res/xml/one_handed_tutorial.xml b/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml
similarity index 100%
rename from packages/SystemUI/res/xml/one_handed_tutorial.xml
rename to libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml
diff --git a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
index 7242793..a13e98c 100644
--- a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
+++ b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json
@@ -1,6 +1,12 @@
{
"version": "1.0.0",
"messages": {
+ "-1501874464": {
+ "message": "Fullscreen Task Appeared: #%d",
+ "level": "VERBOSE",
+ "group": "WM_SHELL_TASK_ORG",
+ "at": "com\/android\/wm\/shell\/FullscreenTaskListener.java"
+ },
"-1340279385": {
"message": "Remove listener=%s",
"level": "VERBOSE",
@@ -31,6 +37,12 @@
"group": "WM_SHELL_TASK_ORG",
"at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
},
+ "564235578": {
+ "message": "Fullscreen Task Vanished: #%d",
+ "level": "VERBOSE",
+ "group": "WM_SHELL_TASK_ORG",
+ "at": "com\/android\/wm\/shell\/FullscreenTaskListener.java"
+ },
"980952660": {
"message": "Task root back pressed taskId=%d",
"level": "VERBOSE",
diff --git a/libs/WindowManager/Shell/res/values-land/dimens.xml b/libs/WindowManager/Shell/res/values-land/dimens.xml
new file mode 100644
index 0000000..77a601d
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values-land/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2020, 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.
+*/
+-->
+<resources>
+ <dimen name="docked_divider_handle_width">2dp</dimen>
+ <dimen name="docked_divider_handle_height">16dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-land/styles.xml b/libs/WindowManager/Shell/res/values-land/styles.xml
new file mode 100644
index 0000000..863bb69
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values-land/styles.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="DockedDividerBackground">
+ <item name="android:layout_width">10dp</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_gravity">center_horizontal</item>
+ </style>
+
+ <style name="DockedDividerHandle">
+ <item name="android:layout_gravity">center_vertical</item>
+ <item name="android:layout_width">48dp</item>
+ <item name="android:layout_height">96dp</item>
+ </style>
+
+ <style name="DockedDividerMinimizedShadow">
+ <item name="android:layout_width">8dp</item>
+ <item name="android:layout_height">match_parent</item>
+ </style>
+</resources>
+
diff --git a/libs/WindowManager/Shell/res/values-sw600dp/config.xml b/libs/WindowManager/Shell/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..f194532f
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values-sw600dp/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2020, 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <!-- Animation duration when using long press on recents to dock -->
+ <integer name="long_press_dock_anim_duration">290</integer>
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
new file mode 100644
index 0000000..6a19083
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2020, 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.
+ */
+-->
+<resources>
+ <color name="docked_divider_background">#ff000000</color>
+ <color name="docked_divider_handle">#ffffff</color>
+ <drawable name="forced_resizable_background">#59000000</drawable>
+ <color name="minimize_dock_shadow_start">#60000000</color>
+ <color name="minimize_dock_shadow_end">#00000000</color>
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 245c072..63b0f6f 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -26,4 +26,10 @@
<!-- Allow PIP to enable round corner, see also R.dimen.pip_corner_radius -->
<bool name="config_pipEnableRoundCorner">false</bool>
+
+ <!-- Animation duration when using long press on recents to dock -->
+ <integer name="long_press_dock_anim_duration">250</integer>
+
+ <!-- Allow one handed to enable round corner -->
+ <bool name="config_one_handed_enable_round_corner">true</bool>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 1c12176..7fb641a 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -56,4 +56,14 @@
<dimen name="pip_resize_handle_size">12dp</dimen>
<dimen name="pip_resize_handle_margin">4dp</dimen>
<dimen name="pip_resize_handle_padding">0dp</dimen>
+
+ <!-- How high we lift the divider when touching -->
+ <dimen name="docked_stack_divider_lift_elevation">4dp</dimen>
+
+ <dimen name="docked_divider_handle_width">16dp</dimen>
+ <dimen name="docked_divider_handle_height">2dp</dimen>
+
+ <!-- One-Handed Mode -->
+ <!-- Threshold for dragging distance to enable one-handed mode -->
+ <dimen name="gestures_onehanded_drag_threshold">20dp</dimen>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/ids.xml b/libs/WindowManager/Shell/res/values/ids.xml
index ed20398..fb89238 100644
--- a/libs/WindowManager/Shell/res/values/ids.xml
+++ b/libs/WindowManager/Shell/res/values/ids.xml
@@ -16,4 +16,11 @@
-->
<resources>
<item type="id" name="action_pip_resize" />
+
+ <!-- Accessibility actions for the docked stack divider -->
+ <item type="id" name="action_move_tl_full" />
+ <item type="id" name="action_move_tl_70" />
+ <item type="id" name="action_move_tl_50" />
+ <item type="id" name="action_move_tl_30" />
+ <item type="id" name="action_move_rb_full" />
</resources>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 6752b56..b6668fb 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -53,4 +53,44 @@
<!-- TODO Deprecated. Label for PIP the drag to dismiss hint. DO NOT TRANSLATE [CHAR LIMIT=NONE]-->
<string name="pip_phone_dismiss_hint">Drag down to dismiss</string>
+
+ <!-- Multi-Window strings -->
+ <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed in split-screen and that things might crash/not work properly [CHAR LIMIT=NONE] -->
+ <string name="dock_forced_resizable">App may not work with split-screen.</string>
+ <!-- Warning message when we try to dock a non-resizeable task and launch it in fullscreen instead. -->
+ <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
+ <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed on a secondary display and that things might crash/not work properly [CHAR LIMIT=NONE] -->
+ <string name="forced_resizable_secondary_display">App may not work on a secondary display.</string>
+ <!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. -->
+ <string name="activity_launch_on_secondary_display_failed_text">App does not support launch on secondary displays.</string>
+
+ <!-- Accessibility label for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
+ <string name="accessibility_divider">Split-screen divider</string>
+
+ <!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_full">Left full screen</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen 70% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_70">Left 70%</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen 50% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_50">Left 50%</string>
+ <!-- Accessibility action for moving docked stack divider to make the left screen 30% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_left_30">Left 30%</string>
+ <!-- Accessibility action for moving docked stack divider to make the right screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_right_full">Right full screen</string>
+
+ <!-- Accessibility action for moving docked stack divider to make the top screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_full">Top full screen</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen 70% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_70">Top 70%</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen 50% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_50">Top 50%</string>
+ <!-- Accessibility action for moving docked stack divider to make the top screen 30% [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_top_30">Top 30%</string>
+ <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] -->
+ <string name="accessibility_action_divider_bottom_full">Bottom full screen</string>
+
+ <!-- One-Handed Tutorial title [CHAR LIMIT=60] -->
+ <string name="one_handed_tutorial_title">Using one-handed mode</string>
+ <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] -->
+ <string name="one_handed_tutorial_description">To exit, swipe up from the bottom of the screen or tap anywhere above the app</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
new file mode 100644
index 0000000..fffcd33
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Theme used for the activity that shows when the system forced an app to be resizable -->
+ <style name="ForcedResizableTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
+ <item name="android:windowBackground">@drawable/forced_resizable_background</item>
+ <item name="android:statusBarColor">@android:color/transparent</item>
+ <item name="android:windowAnimationStyle">@style/Animation.ForcedResizable</item>
+ </style>
+
+ <style name="Animation.ForcedResizable" parent="@android:style/Animation">
+ <item name="android:activityOpenEnterAnimation">@anim/forced_resizable_enter</item>
+
+ <!-- If the target stack doesn't have focus, we do a task to front animation. -->
+ <item name="android:taskToFrontEnterAnimation">@anim/forced_resizable_enter</item>
+ <item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
+ </style>
+
+ <style name="DockedDividerBackground">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">10dp</item>
+ <item name="android:layout_gravity">center_vertical</item>
+ </style>
+
+ <style name="DockedDividerMinimizedShadow">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">8dp</item>
+ </style>
+
+ <style name="DockedDividerHandle">
+ <item name="android:layout_gravity">center_horizontal</item>
+ <item name="android:layout_width">96dp</item>
+ <item name="android:layout_height">48dp</item>
+ </style>
+</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
new file mode 100644
index 0000000..d0051db
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 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.wm.shell;
+
+import android.app.ActivityManager;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.view.SurfaceControl;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
+class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
+ private static final String TAG = "FullscreenTaskOrg";
+
+ private final TransactionPool mTransactionPool;
+
+ private final ArraySet<Integer> mTasks = new ArraySet<>();
+
+ FullscreenTaskListener(TransactionPool transactionPool) {
+ mTransactionPool = transactionPool;
+ }
+
+ @Override
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+ synchronized (mTasks) {
+ if (mTasks.contains(taskInfo.taskId)) {
+ throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId);
+ }
+ mTasks.add(taskInfo.taskId);
+ final SurfaceControl.Transaction t = mTransactionPool.acquire();
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
+ taskInfo.taskId);
+ t.show(leash);
+ t.apply();
+ }
+ }
+
+ @Override
+ public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ synchronized (mTasks) {
+ if (!mTasks.remove(taskInfo.taskId)) {
+ Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
+ return;
+ }
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
+ taskInfo.taskId);
+ }
+ }
+
+ @Override
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index ea9576a..2d82fb1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -16,24 +16,27 @@
package com.android.wm.shell;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.WindowConfiguration;
-import android.content.Context;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.SurfaceControl;
+import android.window.ITaskOrganizerController;
import android.window.TaskOrganizer;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.protolog.ShellProtoLogImpl;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Unified task organizer for all components in the shell.
+ * TODO(b/167582004): may consider consolidating this class and TaskOrganizer
*/
public class ShellTaskOrganizer extends TaskOrganizer {
@@ -56,6 +59,18 @@
// require us to report to both old and new listeners)
private final SparseArray<Pair<RunningTaskInfo, SurfaceControl>> mTasks = new SparseArray<>();
+ public ShellTaskOrganizer(TransactionPool transactionPool) {
+ super();
+ addListener(new FullscreenTaskListener(transactionPool), WINDOWING_MODE_FULLSCREEN);
+ }
+
+ @VisibleForTesting
+ ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController,
+ TransactionPool transactionPool) {
+ super(taskOrganizerController);
+ addListener(new FullscreenTaskListener(transactionPool), WINDOWING_MODE_FULLSCREEN);
+ }
+
/**
* Adds a listener for tasks in a specific windowing mode.
*/
@@ -116,6 +131,7 @@
Pair<RunningTaskInfo, SurfaceControl> data = mTasks.get(taskInfo.taskId);
int winMode = getWindowingMode(taskInfo);
int prevWinMode = getWindowingMode(data.first);
+ mTasks.put(taskInfo.taskId, new Pair<>(taskInfo, data.second));
if (prevWinMode != -1 && prevWinMode != winMode) {
// TODO: We currently send vanished/appeared as the task moves between win modes, but
// we should consider adding a different mode-changed callback
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
index 13ed02e..9cb1250 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.common;
+import android.annotation.NonNull;
import android.os.Handler;
import android.util.Slog;
import android.view.SurfaceControl;
@@ -23,17 +24,13 @@
import android.window.WindowContainerTransactionCallback;
import android.window.WindowOrganizer;
-import androidx.annotation.NonNull;
-
-import com.android.wm.shell.common.TransactionPool;
-
import java.util.ArrayList;
/**
* Helper for serializing sync-transactions and corresponding callbacks.
*/
-class SyncTransactionQueue {
- private static final boolean DEBUG = SplitScreenController.DEBUG;
+public final class SyncTransactionQueue {
+ private static final boolean DEBUG = false;
private static final String TAG = "SyncTransactionQueue";
// Just a little longer than the sync-engine timeout of 5s
@@ -58,7 +55,7 @@
}
};
- SyncTransactionQueue(TransactionPool pool, Handler handler) {
+ public SyncTransactionQueue(TransactionPool pool, Handler handler) {
mTransactionPool = pool;
mHandler = handler;
}
@@ -66,7 +63,7 @@
/**
* Queues a sync transaction to be sent serially to WM.
*/
- void queue(WindowContainerTransaction wct) {
+ public void queue(WindowContainerTransaction wct) {
SyncCallback cb = new SyncCallback(wct);
synchronized (mQueue) {
if (DEBUG) Slog.d(TAG, "Queueing up " + wct);
@@ -82,7 +79,7 @@
* Otherwise just returns without queueing.
* @return {@code true} if queued, {@code false} if not.
*/
- boolean queueIfWaiting(WindowContainerTransaction wct) {
+ public boolean queueIfWaiting(WindowContainerTransaction wct) {
synchronized (mQueue) {
if (mQueue.isEmpty()) {
if (DEBUG) Slog.d(TAG, "Nothing in queue, so skip queueing up " + wct);
@@ -102,7 +99,7 @@
* Runs a runnable in sync with sync transactions (ie. when the current in-flight transaction
* returns. If there are no transactions in-flight, runnable executes immediately.
*/
- void runInSync(TransactionRunnable runnable) {
+ public void runInSync(TransactionRunnable runnable) {
synchronized (mQueue) {
if (DEBUG) Slog.d(TAG, "Run in sync. mInFlight=" + mInFlight);
if (mInFlight != null) {
@@ -127,7 +124,9 @@
t.close();
}
- interface TransactionRunnable {
+ /** Task to run with transaction. */
+ public interface TransactionRunnable {
+ /** Runs with transaction. */
void runWithTransaction(SurfaceControl.Transaction t);
}
@@ -154,7 +153,7 @@
@Override
public void onTransactionReady(int id,
- @androidx.annotation.NonNull SurfaceControl.Transaction t) {
+ @NonNull SurfaceControl.Transaction t) {
mHandler.post(() -> {
synchronized (mQueue) {
if (mId != id) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
index 8abe9ee..b4620e27 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
@@ -22,7 +22,6 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
-import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
import android.os.IBinder;
@@ -32,7 +31,6 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
-import android.view.DisplayCutout;
import android.view.DragEvent;
import android.view.IScrollCaptureController;
import android.view.IWindow;
@@ -47,6 +45,7 @@
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
+import android.window.ClientWindowFrames;
import com.android.internal.os.IResultReceiver;
@@ -274,22 +273,20 @@
@Override
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
- long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
- Rect outVisibleInsets, Rect outStableInsets,
- DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
+ long frameNumber, ClientWindowFrames outFrames,
+ MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
SurfaceControl outBLASTSurfaceControl) {
int res = super.relayout(window, seq, attrs, requestedWidth, requestedHeight,
- viewVisibility, flags, frameNumber, outFrame, outOverscanInsets,
- outContentInsets, outVisibleInsets, outStableInsets,
- cutout, mergedConfiguration, outSurfaceControl, outInsetsState,
+ viewVisibility, flags, frameNumber, outFrames,
+ mergedConfiguration, outSurfaceControl, outInsetsState,
outActiveControls, outSurfaceSize, outBLASTSurfaceControl);
if (res != 0) {
return res;
}
DisplayLayout dl = mDisplayController.getDisplayLayout(mDisplayId);
- outStableInsets.set(dl.stableInsets());
+ outFrames.stableInsets.set(dl.stableInsets());
return 0;
}
@@ -314,10 +311,9 @@
ContainerWindow() {}
@Override
- public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, Rect stableInsets,
- boolean reportDraw, MergedConfiguration newMergedConfiguration, Rect backDropFrame,
- boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {}
+ public void resized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration newMergedConfiguration, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId) {}
@Override
public void locationInParentDisplayChanged(Point offset) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
new file mode 100644
index 0000000..9c78fc5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.onehanded;
+
+import androidx.annotation.NonNull;
+
+import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
+
+import java.io.PrintWriter;
+
+/**
+ * Interface to engage one handed feature.
+ */
+public interface OneHanded {
+ /**
+ * Return whether the device has one handed feature or not.
+ */
+ boolean hasOneHandedFeature();
+
+ /**
+ * Return one handed settings enabled or not.
+ */
+ boolean isOneHandedEnabled();
+
+ /**
+ * Return swipe to notification settings enabled or not.
+ */
+ boolean isSwipeToNotificationEnabled();
+
+ /**
+ * Enters one handed mode.
+ */
+ void startOneHanded();
+
+ /**
+ * Exits one handed mode.
+ */
+ void stopOneHanded();
+
+ /**
+ * Exits one handed mode with {@link OneHandedEvents}.
+ */
+ void stopOneHanded(int event);
+
+ /**
+ * Set navigation 3 button mode enabled or disabled by users.
+ */
+ void setThreeButtonModeEnabled(boolean enabled);
+
+ /**
+ * Register callback to be notified after {@link OneHandedDisplayAreaOrganizer}
+ * transition start or finish
+ */
+ void registerTransitionCallback(OneHandedTransitionCallback callback);
+
+ /**
+ * Register callback for one handed gesture, this gesture callbcak will be activated on
+ * 3 button navigation mode only
+ */
+ void registerGestureCallback(OneHandedGestureEventCallback callback);
+
+ /**
+ * Dump one handed status.
+ */
+ void dump(@NonNull PrintWriter pw);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java
index 264ace7..6749f7e 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.view.SurfaceControl;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
index 9be1b5a..9639096 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.animation.Animator;
import android.animation.ValueAnimator;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
new file mode 100644
index 0000000..c84b478
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.onehanded;
+
+import static android.os.UserHandle.USER_CURRENT;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.database.ContentObserver;
+import android.graphics.Point;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages and manipulates the one handed states, transitions, and gesture for phones.
+ */
+public class OneHandedController implements OneHanded {
+ private static final String TAG = "OneHandedController";
+
+ private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
+ "persist.debug.one_handed_offset_percentage";
+ private static final String ONE_HANDED_MODE_GESTURAL_OVERLAY =
+ "com.android.internal.systemui.onehanded.gestural";
+
+ static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
+
+ private final boolean mHasOneHandedFeature;
+ private boolean mIsOneHandedEnabled;
+ private boolean mIsSwipeToNotificationEnabled;
+ private boolean mTaskChangeToExit;
+ private float mOffSetFraction;
+
+ private final Context mContext;
+ private final DisplayController mDisplayController;
+ private final OneHandedGestureHandler mGestureHandler;
+ private final OneHandedTimeoutHandler mTimeoutHandler;
+ private final OneHandedTouchHandler mTouchHandler;
+ private final OneHandedTutorialHandler mTutorialHandler;
+ private final IOverlayManager mOverlayManager;
+ private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+
+ private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
+
+ /**
+ * Handle rotation based on OnDisplayChangingListener callback
+ */
+ private final DisplayChangeController.OnDisplayChangingListener mRotationController =
+ (display, fromRotation, toRotation, wct) -> {
+ if (mDisplayAreaOrganizer != null) {
+ mDisplayAreaOrganizer.onRotateDisplay(fromRotation, toRotation);
+ }
+ };
+
+ private final ContentObserver mEnabledObserver = new ContentObserver(mMainHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ final boolean enabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
+ mContext.getContentResolver());
+ OneHandedEvents.writeEvent(enabled
+ ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_ON
+ : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_OFF);
+
+ setOneHandedEnabled(enabled);
+
+ // Also checks swipe to notification settings since they all need gesture overlay.
+ setEnabledGesturalOverlay(
+ enabled || OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
+ mContext.getContentResolver()));
+ }
+ };
+
+ private final ContentObserver mTimeoutObserver = new ContentObserver(mMainHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ final int newTimeout = OneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
+ mContext.getContentResolver());
+ int metricsId = OneHandedEvents.OneHandedSettingsTogglesEvent.INVALID.getId();
+ switch (newTimeout) {
+ case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER:
+ metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_NEVER;
+ break;
+ case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS:
+ metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_4;
+ break;
+ case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS:
+ metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_8;
+ break;
+ case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS:
+ metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_12;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ OneHandedEvents.writeEvent(metricsId);
+
+ if (mTimeoutHandler != null) {
+ mTimeoutHandler.setTimeout(newTimeout);
+ }
+ }
+ };
+
+ private final ContentObserver mTaskChangeExitObserver = new ContentObserver(mMainHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ final boolean enabled = OneHandedSettingsUtil.getSettingsTapsAppToExit(
+ mContext.getContentResolver());
+ OneHandedEvents.writeEvent(enabled
+ ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_ON
+ : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_OFF);
+
+ setTaskChangeToExit(enabled);
+ }
+ };
+
+ private final ContentObserver mSwipeToNotificationEnabledObserver =
+ new ContentObserver(mMainHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ final boolean enabled =
+ OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
+ mContext.getContentResolver());
+ setSwipeToNotificationEnabled(enabled);
+
+ // Also checks one handed mode settings since they all need gesture overlay.
+ setEnabledGesturalOverlay(
+ enabled || OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
+ mContext.getContentResolver()));
+ }
+ };
+
+ /**
+ * The static constructor method to create OneHnadedController.
+ */
+ public static OneHandedController create(
+ Context context, DisplayController displayController) {
+ OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context);
+ OneHandedAnimationController animationController =
+ new OneHandedAnimationController(context);
+ OneHandedTouchHandler touchHandler = new OneHandedTouchHandler();
+ OneHandedGestureHandler gestureHandler = new OneHandedGestureHandler(
+ context, displayController);
+ OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer(
+ context, displayController, animationController, tutorialHandler);
+ return new OneHandedController(context, displayController, organizer, touchHandler,
+ tutorialHandler, gestureHandler);
+ }
+
+ @VisibleForTesting
+ OneHandedController(Context context,
+ DisplayController displayController,
+ OneHandedDisplayAreaOrganizer displayAreaOrganizer,
+ OneHandedTouchHandler touchHandler,
+ OneHandedTutorialHandler tutorialHandler,
+ OneHandedGestureHandler gestureHandler) {
+ mHasOneHandedFeature = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
+ if (!mHasOneHandedFeature) {
+ Log.i(TAG, "Device config SUPPORT_ONE_HANDED_MODE off");
+ mContext = null;
+ mDisplayAreaOrganizer = null;
+ mDisplayController = null;
+ mTouchHandler = null;
+ mTutorialHandler = null;
+ mGestureHandler = null;
+ mTimeoutHandler = null;
+ mOverlayManager = null;
+ return;
+ }
+
+ mContext = context;
+ mDisplayAreaOrganizer = displayAreaOrganizer;
+ mDisplayController = displayController;
+ mTouchHandler = touchHandler;
+ mTutorialHandler = tutorialHandler;
+ mGestureHandler = gestureHandler;
+
+ mOverlayManager = IOverlayManager.Stub.asInterface(
+ ServiceManager.getService(Context.OVERLAY_SERVICE));
+ mOffSetFraction = SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f;
+ mIsOneHandedEnabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
+ context.getContentResolver());
+ mIsSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
+ context.getContentResolver());
+ mTimeoutHandler = OneHandedTimeoutHandler.get();
+
+ mDisplayController.addDisplayChangingController(mRotationController);
+
+ setupCallback();
+ setupSettingObservers();
+ setupTimeoutListener();
+ setupGesturalOverlay();
+ updateSettings();
+ }
+
+ /**
+ * Set one handed enabled or disabled when user update settings
+ */
+ void setOneHandedEnabled(boolean enabled) {
+ mIsOneHandedEnabled = enabled;
+ updateOneHandedEnabled();
+ }
+
+ /**
+ * Set one handed enabled or disabled by when user update settings
+ */
+ void setTaskChangeToExit(boolean enabled) {
+ mTaskChangeToExit = enabled;
+ }
+
+ /**
+ * Sets whether to enable swipe bottom to notification gesture when user update settings.
+ */
+ void setSwipeToNotificationEnabled(boolean enabled) {
+ mIsSwipeToNotificationEnabled = enabled;
+ updateOneHandedEnabled();
+ }
+
+ @Override
+ public boolean hasOneHandedFeature() {
+ return mHasOneHandedFeature;
+ }
+
+ @Override
+ public boolean isOneHandedEnabled() {
+ return mIsOneHandedEnabled;
+ }
+
+ @Override
+ public boolean isSwipeToNotificationEnabled() {
+ return mIsSwipeToNotificationEnabled;
+ }
+
+ @Override
+ public void startOneHanded() {
+ if (!mDisplayAreaOrganizer.isInOneHanded()) {
+ final int yOffSet = Math.round(getDisplaySize().y * mOffSetFraction);
+ mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
+ mTimeoutHandler.resetTimer();
+
+ OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_IN);
+ }
+ }
+
+ @Override
+ public void stopOneHanded() {
+ if (mDisplayAreaOrganizer.isInOneHanded()) {
+ mDisplayAreaOrganizer.scheduleOffset(0, 0);
+ mTimeoutHandler.removeTimer();
+ }
+ }
+
+ @Override
+ public void stopOneHanded(int event) {
+ if (!mTaskChangeToExit && event == OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_APP_TAPS_OUT) {
+ //Task change exit not enable, do nothing and return here.
+ return;
+ }
+
+ if (mDisplayAreaOrganizer.isInOneHanded()) {
+ OneHandedEvents.writeEvent(event);
+ }
+
+ stopOneHanded();
+ }
+
+ @Override
+ public void setThreeButtonModeEnabled(boolean enabled) {
+ mGestureHandler.onThreeButtonModeEnabled(enabled);
+ }
+
+ @Override
+ public void registerTransitionCallback(OneHandedTransitionCallback callback) {
+ mDisplayAreaOrganizer.registerTransitionCallback(callback);
+ }
+
+ @Override
+ public void registerGestureCallback(OneHandedGestureEventCallback callback) {
+ mGestureHandler.setGestureEventListener(callback);
+ }
+
+ private void setupCallback() {
+ mTouchHandler.registerTouchEventListener(() ->
+ stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_OVERSPACE_OUT));
+ mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler);
+ mDisplayAreaOrganizer.registerTransitionCallback(mGestureHandler);
+ mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
+ }
+
+ private void setupSettingObservers() {
+ OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_ENABLED,
+ mContext.getContentResolver(), mEnabledObserver);
+ OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
+ mContext.getContentResolver(), mTimeoutObserver);
+ OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.TAPS_APP_TO_EXIT,
+ mContext.getContentResolver(), mTaskChangeExitObserver);
+ OneHandedSettingsUtil.registerSettingsKeyObserver(
+ Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
+ mContext.getContentResolver(), mSwipeToNotificationEnabledObserver);
+ }
+
+ private void updateSettings() {
+ setOneHandedEnabled(OneHandedSettingsUtil
+ .getSettingsOneHandedModeEnabled(mContext.getContentResolver()));
+ mTimeoutHandler.setTimeout(OneHandedSettingsUtil
+ .getSettingsOneHandedModeTimeout(mContext.getContentResolver()));
+ setTaskChangeToExit(OneHandedSettingsUtil
+ .getSettingsTapsAppToExit(mContext.getContentResolver()));
+ setSwipeToNotificationEnabled(OneHandedSettingsUtil
+ .getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
+ }
+
+ private void setupTimeoutListener() {
+ mTimeoutHandler.registerTimeoutListener(timeoutTime -> {
+ stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_TIMEOUT_OUT);
+ });
+ }
+
+ /**
+ * Query the current display real size from {@link DisplayController}
+ *
+ * @return {@link DisplayController#getDisplay(int)#getDisplaySize()}
+ */
+ private Point getDisplaySize() {
+ Point displaySize = new Point();
+ if (mDisplayController != null && mDisplayController.getDisplay(DEFAULT_DISPLAY) != null) {
+ mDisplayController.getDisplay(DEFAULT_DISPLAY).getRealSize(displaySize);
+ }
+ return displaySize;
+ }
+
+ private void updateOneHandedEnabled() {
+ if (mDisplayAreaOrganizer.isInOneHanded()) {
+ stopOneHanded();
+ }
+ // TODO Be aware to unregisterOrganizer() after animation finished
+ mDisplayAreaOrganizer.unregisterOrganizer();
+ if (mIsOneHandedEnabled) {
+ mDisplayAreaOrganizer.registerOrganizer(
+ OneHandedDisplayAreaOrganizer.FEATURE_ONE_HANDED);
+ }
+ mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
+ mGestureHandler.onOneHandedEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);
+ }
+
+ private void setupGesturalOverlay() {
+ if (!OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(mContext.getContentResolver())) {
+ return;
+ }
+
+ OverlayInfo info = null;
+ try {
+ // TODO(b/157958539) migrate new RRO config file after S+
+ mOverlayManager.setHighestPriority(ONE_HANDED_MODE_GESTURAL_OVERLAY, USER_CURRENT);
+ info = mOverlayManager.getOverlayInfo(ONE_HANDED_MODE_GESTURAL_OVERLAY, USER_CURRENT);
+ } catch (RemoteException e) { /* Do nothing */ }
+
+ if (info != null && !info.isEnabled()) {
+ // Enable the default gestural one handed overlay.
+ setEnabledGesturalOverlay(true);
+ }
+ }
+
+ @VisibleForTesting
+ private void setEnabledGesturalOverlay(boolean enabled) {
+ try {
+ mOverlayManager.setEnabled(ONE_HANDED_MODE_GESTURAL_OVERLAY, enabled, USER_CURRENT);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
+ public void dump(@NonNull PrintWriter pw) {
+ final String innerPrefix = " ";
+ pw.println(TAG + "states: ");
+ pw.print(innerPrefix + "mOffSetFraction=");
+ pw.println(mOffSetFraction);
+
+ if (mDisplayAreaOrganizer != null) {
+ mDisplayAreaOrganizer.dump(pw);
+ }
+
+ if (mTouchHandler != null) {
+ mTouchHandler.dump(pw);
+ }
+
+ if (mTimeoutHandler != null) {
+ mTimeoutHandler.dump(pw);
+ }
+
+ if (mTutorialHandler != null) {
+ mTutorialHandler.dump(pw);
+ }
+
+ OneHandedSettingsUtil.dump(pw, innerPrefix, mContext.getContentResolver());
+
+ if (mOverlayManager != null) {
+ OverlayInfo info = null;
+ try {
+ info = mOverlayManager.getOverlayInfo(ONE_HANDED_MODE_GESTURAL_OVERLAY,
+ USER_CURRENT);
+ } catch (RemoteException e) { /* Do nothing */ }
+
+ if (info != null && !info.isEnabled()) {
+ pw.print(innerPrefix + "OverlayInfo=");
+ pw.println(info);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index ad9f7ea..9954618 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.systemui.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT;
-import static com.android.systemui.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER;
+import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT;
+import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER;
import android.content.Context;
import android.graphics.Point;
@@ -38,10 +38,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.os.SomeArgs;
-import com.android.systemui.Dumpable;
import com.android.wm.shell.common.DisplayController;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
@@ -58,7 +56,7 @@
*
* This class is also responsible for translating one handed operations within SysUI component
*/
-public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implements Dumpable {
+public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
private static final String TAG = "OneHandedDisplayAreaOrganizer";
private static final String ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION =
"persist.debug.one_handed_translate_animation_duration";
@@ -353,8 +351,7 @@
return args;
}
- @Override
- public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG + "states: ");
pw.print(innerPrefix + "mIsInOneHanded=");
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedEvents.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEvents.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedEvents.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEvents.java
index 327ed67..79ddd2b 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedEvents.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEvents.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
index f3be699..3b1e6cb 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import android.annotation.Nullable;
import android.content.Context;
@@ -39,8 +38,7 @@
import androidx.annotation.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
@@ -49,7 +47,6 @@
* others(e.g, 2-button, full gesture mode) are handled by Launcher quick steps.
*/
public class OneHandedGestureHandler implements OneHandedTransitionCallback,
- NavigationModeController.ModeChangedListener,
DisplayChangeController.OnDisplayChangingListener {
private static final String TAG = "OneHandedGestureHandler";
private static final boolean DEBUG_GESTURE = false;
@@ -66,7 +63,7 @@
private boolean mAllowGesture;
private boolean mIsEnabled;
private int mNavGestureHeight;
- private boolean mIsThreeButtonModeEnable;
+ private boolean mIsThreeButtonModeEnabled;
private int mRotation = Surface.ROTATION_0;
@VisibleForTesting
@@ -85,14 +82,10 @@
*
* @param context {@link Context}
* @param displayController {@link DisplayController}
- * @param navigationModeController {@link NavigationModeController}
*/
- public OneHandedGestureHandler(Context context, DisplayController displayController,
- NavigationModeController navigationModeController) {
+ public OneHandedGestureHandler(Context context, DisplayController displayController) {
mDisplayController = displayController;
displayController.addDisplayChangingController(this);
- final int NavBarMode = navigationModeController.addListener(this);
- mIsThreeButtonModeEnable = (NavBarMode == NAV_BAR_MODE_3BUTTON);
mNavGestureHeight = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_gesture_height);
mDragDistThreshold = context.getResources().getDimensionPixelSize(
@@ -115,6 +108,11 @@
updateIsEnabled();
}
+ void onThreeButtonModeEnabled(boolean isEnabled) {
+ mIsThreeButtonModeEnabled = isEnabled;
+ updateIsEnabled();
+ }
+
/**
* Register {@link OneHandedGestureEventCallback} to receive onStart(), onStop() callback
*/
@@ -199,7 +197,7 @@
private void updateIsEnabled() {
disposeInputChannel();
- if (mIsEnabled && mIsThreeButtonModeEnable) {
+ if (mIsEnabled && mIsThreeButtonModeEnabled) {
final Point displaySize = new Point();
if (mDisplayController != null) {
final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY);
@@ -212,7 +210,7 @@
displaySize.y);
mInputMonitor = InputManager.getInstance().monitorGestureInput(
"onehanded-gesture-offset", DEFAULT_DISPLAY);
- mInputEventReceiver = new SysUiInputEventReceiver(
+ mInputEventReceiver = new EventReceiver(
mInputMonitor.getInputChannel(), Looper.getMainLooper());
}
}
@@ -224,22 +222,13 @@
}
@Override
- public void onNavigationModeChanged(int mode) {
- if (DEBUG_GESTURE) {
- Log.d(TAG, "onNavigationModeChanged, mode =" + mode);
- }
- mIsThreeButtonModeEnable = (mode == NAV_BAR_MODE_3BUTTON);
- updateIsEnabled();
- }
-
- @Override
public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
WindowContainerTransaction t) {
mRotation = toRotation;
}
- private class SysUiInputEventReceiver extends InputEventReceiver {
- SysUiInputEventReceiver(InputChannel channel, Looper looper) {
+ private class EventReceiver extends InputEventReceiver {
+ EventReceiver(InputChannel channel, Looper looper) {
super(channel, looper);
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
index 0598f32..4d66f29 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.annotation.IntDef;
import android.content.ContentResolver;
@@ -22,8 +22,6 @@
import android.net.Uri;
import android.provider.Settings;
-import com.android.systemui.dagger.SysUISingleton;
-
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -31,7 +29,6 @@
/**
* APIs for querying or updating one handed settings .
*/
-@SysUISingleton
public final class OneHandedSettingsUtil {
private static final String TAG = "OneHandedSettingsUtil";
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSurfaceTransactionHelper.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java
index bc4a9b4..e7010db 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.SurfaceControl;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
/**
* Abstracts the common operations on {@link SurfaceControl.Transaction} for OneHanded transition.
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedThread.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java
index b7b814a..24d33ed 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedThread.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.os.Handler;
import android.os.HandlerThread;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTimeoutHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTimeoutHandler.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java
index 6bed304..9c97cd7 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTimeoutHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
import android.os.Handler;
import android.os.Looper;
@@ -25,9 +25,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.systemui.Dumpable;
-
-import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -36,7 +33,7 @@
/**
* Timeout handler for stop one handed mode operations.
*/
-public class OneHandedTimeoutHandler implements Dumpable {
+public class OneHandedTimeoutHandler {
private static final String TAG = "OneHandedTimeoutHandler";
private static boolean sIsDragging = false;
// Default timeout is ONE_HANDED_TIMEOUT_MEDIUM
@@ -150,8 +147,7 @@
}
}
- @Override
- public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG + "states: ");
pw.print(innerPrefix + "sTimeout=");
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java
index 8265da6..721382d 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -30,9 +30,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.systemui.Dumpable;
-
-import java.io.FileDescriptor;
import java.io.PrintWriter;
/**
@@ -40,7 +37,7 @@
* to exit, reset timer when user is in one-handed mode.
* Refer {@link OneHandedGestureHandler} to see start and stop one handed gesture
*/
-public class OneHandedTouchHandler implements OneHandedTransitionCallback, Dumpable {
+public class OneHandedTouchHandler implements OneHandedTransitionCallback {
private static final String TAG = "OneHandedTouchHandler";
private final Rect mLastUpdatedBounds = new Rect();
@@ -130,7 +127,7 @@
if (mIsEnabled) {
mInputMonitor = InputManager.getInstance().monitorGestureInput(
"onehanded-touch", DEFAULT_DISPLAY);
- mInputEventReceiver = new SysUiInputEventReceiver(
+ mInputEventReceiver = new EventReceiver(
mInputMonitor.getInputChannel(), Looper.getMainLooper());
}
}
@@ -146,16 +143,15 @@
mIsOnStopTransitioning = false;
}
- @Override
- public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG + "states: ");
pw.print(innerPrefix + "mLastUpdatedBounds=");
pw.println(mLastUpdatedBounds);
}
- private class SysUiInputEventReceiver extends InputEventReceiver {
- SysUiInputEventReceiver(InputChannel channel, Looper looper) {
+ private class EventReceiver extends InputEventReceiver {
+ EventReceiver(InputChannel channel, Looper looper) {
super(channel, looper);
}
@@ -170,11 +166,6 @@
*/
public interface OneHandedTouchEventCallback {
/**
- * Handle the start event.
- */
- void onStart();
-
- /**
* Handle the exit event.
*/
void onStop();
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTransitionCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTransitionCallback.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java
index 75eb0eb..3af7c4b 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTransitionCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.graphics.Rect;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
index 8ef9b09..b15b515 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import android.content.ContentResolver;
import android.content.Context;
@@ -33,10 +33,8 @@
import androidx.annotation.NonNull;
-import com.android.systemui.Dumpable;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
/**
@@ -45,7 +43,7 @@
* Refer {@link OneHandedGestureHandler} and {@link OneHandedTouchHandler} to see start and stop
* one handed gesture
*/
-public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Dumpable {
+public class OneHandedTutorialHandler implements OneHandedTransitionCallback {
private static final String TAG = "OneHandedTutorialHandler";
private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
"persist.debug.one_handed_offset_percentage";
@@ -81,7 +79,7 @@
mTargetViewContainer.setClipChildren(false);
mTutorialAreaHeight = Math.round(mDisplaySize.y
* (SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f));
- mTutorialView = LayoutInflater.from(context).inflate(R.xml.one_handed_tutorial, null);
+ mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null);
mTargetViewContainer.addView(mTutorialView);
mCanShowTutorial = (Settings.Secure.getInt(mContentResolver,
Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT)
@@ -170,8 +168,7 @@
return lp;
}
- @Override
- public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG + "states: ");
pw.print(innerPrefix + "mLastUpdatedBounds=");
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerHandleView.java
similarity index 76%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerHandleView.java
index 1559169..2cb1fff 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerHandleView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -28,43 +28,41 @@
import android.util.Property;
import android.view.View;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
/**
* View for the handle in the docked stack divider.
*/
-class DividerHandleView extends View {
+public class DividerHandleView extends View {
- private final static Property<DividerHandleView, Integer> WIDTH_PROPERTY
- = new Property<DividerHandleView, Integer>(Integer.class, "width") {
+ private static final Property<DividerHandleView, Integer> WIDTH_PROPERTY =
+ new Property<DividerHandleView, Integer>(Integer.class, "width") {
+ @Override
+ public Integer get(DividerHandleView object) {
+ return object.mCurrentWidth;
+ }
- @Override
- public Integer get(DividerHandleView object) {
- return object.mCurrentWidth;
- }
+ @Override
+ public void set(DividerHandleView object, Integer value) {
+ object.mCurrentWidth = value;
+ object.invalidate();
+ }
+ };
- @Override
- public void set(DividerHandleView object, Integer value) {
- object.mCurrentWidth = value;
- object.invalidate();
- }
- };
+ private static final Property<DividerHandleView, Integer> HEIGHT_PROPERTY =
+ new Property<DividerHandleView, Integer>(Integer.class, "height") {
+ @Override
+ public Integer get(DividerHandleView object) {
+ return object.mCurrentHeight;
+ }
- private final static Property<DividerHandleView, Integer> HEIGHT_PROPERTY
- = new Property<DividerHandleView, Integer>(Integer.class, "height") {
-
- @Override
- public Integer get(DividerHandleView object) {
- return object.mCurrentHeight;
- }
-
- @Override
- public void set(DividerHandleView object, Integer value) {
- object.mCurrentHeight = value;
- object.invalidate();
- }
- };
+ @Override
+ public void set(DividerHandleView object, Integer value) {
+ object.mCurrentHeight = value;
+ object.invalidate();
+ }
+ };
private final Paint mPaint = new Paint();
private final int mWidth;
@@ -86,7 +84,7 @@
mCircleDiameter = (mWidth + mHeight) / 3;
}
- public void setTouching(boolean touching, boolean animate) {
+ void setTouching(boolean touching, boolean animate) {
if (touching == mTouching) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java
index 64ee7ed5..ff617ed 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
@@ -22,6 +22,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.Handler;
import android.util.Slog;
@@ -29,9 +30,6 @@
import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import android.window.WindowOrganizer;
-
-import androidx.annotation.Nullable;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.TransactionPool;
@@ -45,6 +43,7 @@
private final SplitScreenTaskOrganizer mSplits;
private final TransactionPool mTransactionPool;
private final Handler mHandler;
+ private final TaskOrganizer mTaskOrganizer;
/**
* These are the y positions of the top of the IME surface when it is hidden and when it is
@@ -93,10 +92,12 @@
private boolean mPausedTargetAdjusted = false;
private boolean mAdjustedWhileHidden = false;
- DividerImeController(SplitScreenTaskOrganizer splits, TransactionPool pool, Handler handler) {
+ DividerImeController(SplitScreenTaskOrganizer splits, TransactionPool pool, Handler handler,
+ TaskOrganizer taskOrganizer) {
mSplits = splits;
mTransactionPool = pool;
mHandler = handler;
+ mTaskOrganizer = taskOrganizer;
}
private DividerView getView() {
@@ -112,7 +113,7 @@
}
private boolean getSecondaryHasFocus(int displayId) {
- WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId);
+ WindowContainerToken imeSplit = mTaskOrganizer.getImeTarget(displayId);
return imeSplit != null
&& (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
}
@@ -237,7 +238,7 @@
}
if (!mSplits.mSplitScreenController.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerState.java
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerState.java
index 8e79d51..23d86a0 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerState.java
@@ -11,15 +11,15 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
/**
* Class to hold state of divider that needs to persist across configuration changes.
*/
-public class DividerState {
+final class DividerState {
public boolean animateAfterRecentsDrawn;
public float mRatioPositionBeforeMinimized;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java
index 9bf7ea6..00146e9 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
@@ -62,7 +62,7 @@
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
import com.android.internal.policy.DockedDividerUtils;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.animation.Interpolators;
@@ -76,7 +76,7 @@
private static final String TAG = "DividerView";
private static final boolean DEBUG = SplitScreenController.DEBUG;
- public interface DividerCallbacks {
+ interface DividerCallbacks {
void onDraggingStart();
void onDraggingEnd();
}
@@ -187,7 +187,7 @@
if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
// Only show the middle target if there are more than 1 split target
info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
- mContext.getString(R.string.accessibility_action_divider_top_50)));
+ mContext.getString(R.string.accessibility_action_divider_top_50)));
}
if (snapAlgorithm.isLastSplitTargetAvailable()) {
info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
@@ -205,7 +205,7 @@
if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
// Only show the middle target if there are more than 1 split target
info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
- mContext.getString(R.string.accessibility_action_divider_left_50)));
+ mContext.getString(R.string.accessibility_action_divider_left_50)));
}
if (snapAlgorithm.isLastSplitTargetAvailable()) {
info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
@@ -373,6 +373,7 @@
}
}
+ /** Gets non-minimized secondary bounds of split screen. */
public Rect getNonMinimizedSplitScreenSecondaryBounds() {
mOtherTaskRect.set(mSplitLayout.mSecondary);
return mOtherTaskRect;
@@ -409,6 +410,7 @@
return mSurfaceHidden;
}
+ /** Starts dragging the divider bar. */
public boolean startDragging(boolean animate, boolean touching) {
cancelFlingAnimation();
if (touching) {
@@ -427,6 +429,7 @@
return inSplitMode();
}
+ /** Stops dragging the divider bar. */
public void stopDragging(int position, float velocity, boolean avoidDismissStart,
boolean logMetrics) {
mHandle.setTouching(false, true /* animate */);
@@ -616,7 +619,7 @@
mEntranceAnimationRunning = false;
mExitAnimationRunning = false;
if (!dismissed && !wasMinimizeInteraction) {
- WindowManagerProxy.applyResizeSplits(snapTarget.position, mSplitLayout);
+ mWindowManagerProxy.applyResizeSplits(snapTarget.position, mSplitLayout);
}
if (mCallback != null) {
mCallback.onDraggingEnd();
@@ -886,10 +889,10 @@
t.hide(sc).apply();
mTiles.releaseTransaction(t);
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
- WindowManagerProxy.applyResizeSplits(midPos, mSplitLayout);
+ mWindowManagerProxy.applyResizeSplits(midPos, mSplitLayout);
}
- public void setMinimizedDockStack(boolean minimized, long animDuration,
+ void setMinimizedDockStack(boolean minimized, long animDuration,
boolean isHomeStackResizable) {
if (DEBUG) Slog.d(TAG, "setMinDock: " + mDockedStackMinimized + "->" + minimized);
mHomeStackResizable = isHomeStackResizable;
@@ -925,7 +928,7 @@
}
}
- public void setAdjustedForIme(boolean adjustedForIme, long animDuration) {
+ void setAdjustedForIme(boolean adjustedForIme, long animDuration) {
if (mAdjustedForIme == adjustedForIme) {
return;
}
@@ -952,8 +955,8 @@
private void saveSnapTargetBeforeMinimized(SnapTarget target) {
mSnapTargetBeforeMinimized = target;
- mState.mRatioPositionBeforeMinimized = (float) target.position /
- (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
+ mState.mRatioPositionBeforeMinimized = (float) target.position
+ / (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
: mSplitLayout.mDisplayLayout.width());
}
@@ -971,8 +974,8 @@
}
private void repositionSnapTargetBeforeMinimized() {
- int position = (int) (mState.mRatioPositionBeforeMinimized *
- (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
+ int position = (int) (mState.mRatioPositionBeforeMinimized
+ * (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
: mSplitLayout.mDisplayLayout.width()));
// Set the snap target before minimized but do not save until divider is attached and not
@@ -1011,7 +1014,7 @@
containingRect.right, containingRect.bottom);
}
- public void calculateBoundsForPosition(int position, int dockSide, Rect outRect) {
+ private void calculateBoundsForPosition(int position, int dockSide, Rect outRect) {
DockedDividerUtils.calculateBoundsForPosition(position, dockSide, outRect,
mSplitLayout.mDisplayLayout.width(), mSplitLayout.mDisplayLayout.height(),
mDividerSize);
@@ -1240,8 +1243,8 @@
if (dismissTarget != null && fraction > 0f
&& isDismissing(splitTarget, position, dockSide)) {
fraction = calculateParallaxDismissingFraction(fraction, dockSide);
- int offsetPosition = (int) (start +
- fraction * (dismissTarget.position - splitTarget.position));
+ int offsetPosition = (int) (start + fraction
+ * (dismissTarget.position - splitTarget.position));
int width = taskRect.width();
int height = taskRect.height();
switch (dockSide) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java
index d869333..0b4e17c 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -37,7 +37,7 @@
/**
* Manages the window parameters of the docked stack divider.
*/
-public class DividerWindowManager {
+final class DividerWindowManager {
private static final String WINDOW_TITLE = "DockedStackDivider";
@@ -45,12 +45,12 @@
private WindowManager.LayoutParams mLp;
private View mView;
- public DividerWindowManager(SystemWindows systemWindows) {
+ DividerWindowManager(SystemWindows systemWindows) {
mSystemWindows = systemWindows;
}
/** Add a divider view */
- public void add(View view, int width, int height, int displayId) {
+ void add(View view, int width, int height, int displayId) {
mLp = new WindowManager.LayoutParams(
width, height, TYPE_DOCK_DIVIDER,
FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL
@@ -67,14 +67,14 @@
mView = view;
}
- public void remove() {
+ void remove() {
if (mView != null) {
mSystemWindows.removeView(mView);
}
mView = null;
}
- public void setSlippery(boolean slippery) {
+ void setSlippery(boolean slippery) {
boolean changed = false;
if (slippery && (mLp.flags & FLAG_SLIPPERY) == 0) {
mLp.flags |= FLAG_SLIPPERY;
@@ -88,7 +88,7 @@
}
}
- public void setTouchable(boolean touchable) {
+ void setTouchable(boolean touchable) {
if (mView == null) {
return;
}
@@ -106,7 +106,7 @@
}
/** Sets the touch region to `touchRegion`. Use null to unset.*/
- public void setTouchRegion(Region touchRegion) {
+ void setTouchRegion(Region touchRegion) {
if (mView == null) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ForcedResizableInfoActivity.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ForcedResizableInfoActivity.java
index 02f7505..7a16335 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ForcedResizableInfoActivity.java
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
@@ -29,7 +29,7 @@
import android.view.View.OnTouchListener;
import android.widget.TextView;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
/**
* Translucent activity that gets started on top of a task in multi-window to inform the user that
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ForcedResizableInfoActivityController.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ForcedResizableInfoActivityController.java
index 4c26694..1ef142d 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ForcedResizableInfoActivityController.java
@@ -11,13 +11,13 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
-import static com.android.systemui.stackdivider.ForcedResizableInfoActivity
- .EXTRA_FORCED_RESIZEABLE_REASON;
+
+import static com.android.wm.shell.splitscreen.ForcedResizableInfoActivity.EXTRA_FORCED_RESIZEABLE_REASON;
import android.app.ActivityOptions;
import android.content.Context;
@@ -27,7 +27,7 @@
import android.util.ArraySet;
import android.widget.Toast;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
import java.util.function.Consumer;
@@ -55,20 +55,20 @@
/** Record of force resized task that's pending to be handled. */
private class PendingTaskRecord {
- int taskId;
+ int mTaskId;
/**
* {@link android.app.ITaskStackListener#FORCED_RESIZEABLE_REASON_SPLIT_SCREEN} or
* {@link android.app.ITaskStackListener#FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY}
*/
- int reason;
+ int mReason;
PendingTaskRecord(int taskId, int reason) {
- this.taskId = taskId;
- this.reason = reason;
+ this.mTaskId = taskId;
+ this.mReason = reason;
}
}
- public ForcedResizableInfoActivityController(Context context,
+ ForcedResizableInfoActivityController(Context context,
SplitScreenController splitScreenController) {
mContext = context;
splitScreenController.registerInSplitScreenListener(mDockedStackExistsListener);
@@ -116,11 +116,11 @@
PendingTaskRecord pendingRecord = mPendingTasks.valueAt(i);
Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchTaskId(pendingRecord.taskId);
+ options.setLaunchTaskId(pendingRecord.mTaskId);
// Set as task overlay and allow to resume, so that when an app enters split-screen and
// becomes paused, the overlay will still be shown.
options.setTaskOverlay(true, true /* canResume */);
- intent.putExtra(EXTRA_FORCED_RESIZEABLE_REASON, pendingRecord.reason);
+ intent.putExtra(EXTRA_FORCED_RESIZEABLE_REASON, pendingRecord.mReason);
mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
}
mPendingTasks.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/MinimizedDockShadow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MinimizedDockShadow.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/MinimizedDockShadow.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MinimizedDockShadow.java
index ecff54f..06f4ef1 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/MinimizedDockShadow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MinimizedDockShadow.java
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import android.annotation.Nullable;
import android.content.Context;
@@ -27,7 +27,7 @@
import android.view.View;
import android.view.WindowManager;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
/**
* Shadow for the minimized dock state on homescreen.
@@ -42,7 +42,7 @@
super(context, attrs);
}
- public void setDockSide(int dockSide) {
+ void setDockSide(int dockSide) {
if (dockSide != mDockSide) {
mDockSide = dockSide;
updatePaint(getLeft(), getTop(), getRight(), getBottom());
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java
index a34e85517..3c0f939 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreen.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 93b1f86..184342f 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import android.graphics.Rect;
import android.window.WindowContainerToken;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 360b495..eed5092 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -29,12 +29,12 @@
import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
+import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import android.window.WindowOrganizer;
import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.systemui.R;
+import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
@@ -71,6 +71,7 @@
private final SystemWindows mSystemWindows;
final TransactionPool mTransactionPool;
private final WindowManagerProxy mWindowManagerProxy;
+ private final TaskOrganizer mTaskOrganizer;
private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
new ArrayList<>();
@@ -106,9 +107,12 @@
mHandler = handler;
mForcedResizableController = new ForcedResizableInfoActivityController(context, this);
mTransactionPool = transactionPool;
- mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler);
+ mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler,
+ shellTaskOrganizer);
+ mTaskOrganizer = shellTaskOrganizer;
mSplits = new SplitScreenTaskOrganizer(this, shellTaskOrganizer);
- mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler);
+ mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler,
+ shellTaskOrganizer);
mRotationController =
(display, fromRotation, toRotation, wct) -> {
if (!mSplits.isSplitScreenSupported() || mWindowManagerProxy == null) {
@@ -132,7 +136,7 @@
sdl.resizeSplits(target.position, t);
if (isSplitActive() && mHomeStackResizable) {
- WindowManagerProxy
+ mWindowManagerProxy
.applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
}
if (mWindowManagerProxy.queueSyncTransactionIfWaiting(t)) {
@@ -189,7 +193,7 @@
final WindowContainerTransaction tct = new WindowContainerTransaction();
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
mSplitLayout.resizeSplits(midPos, tct);
- WindowOrganizer.applyTransaction(tct);
+ mTaskOrganizer.applyTransaction(tct);
} catch (Exception e) {
Slog.e(TAG, "Failed to register docked stack listener", e);
removeDivider();
@@ -208,7 +212,7 @@
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
final WindowContainerTransaction tct = new WindowContainerTransaction();
mSplitLayout.resizeSplits(midPos, tct);
- WindowOrganizer.applyTransaction(tct);
+ mTaskOrganizer.applyTransaction(tct);
} else if (mSplitLayout.mDisplayLayout.rotation()
== mRotateSplitLayout.mDisplayLayout.rotation()) {
mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
@@ -372,7 +376,7 @@
// If we are only setting focusability, a sync transaction isn't necessary (in fact it
// can interrupt other animations), so see if it can be submitted on pending instead.
if (!mWindowManagerProxy.queueSyncTransactionIfWaiting(wct)) {
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java
index 325c559..30bc43b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -31,7 +31,6 @@
import android.view.Display;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
-import android.window.TaskOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -64,9 +63,9 @@
void init() throws RemoteException {
synchronized (this) {
try {
- mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
+ mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- mSecondary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
+ mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
} catch (Exception e) {
// teardown to prevent callbacks
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java
index 82b10bd..25827cd 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.stackdivider;
+package com.android.wm.shell.splitscreen;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -40,6 +40,7 @@
import android.window.WindowOrganizer;
import com.android.internal.annotations.GuardedBy;
+import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import java.util.ArrayList;
@@ -82,8 +83,12 @@
}
};
- WindowManagerProxy(TransactionPool transactionPool, Handler handler) {
+ private final TaskOrganizer mTaskOrganizer;
+
+ WindowManagerProxy(TransactionPool transactionPool, Handler handler,
+ TaskOrganizer taskOrganizer) {
mSyncTransactionQueue = new SyncTransactionQueue(transactionPool, handler);
+ mTaskOrganizer = taskOrganizer;
}
void dismissOrMaximizeDocked(final SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout,
@@ -112,18 +117,18 @@
mExecutor.execute(mSetTouchableRegionRunnable);
}
- static void applyResizeSplits(int position, SplitDisplayLayout splitLayout) {
+ void applyResizeSplits(int position, SplitDisplayLayout splitLayout) {
WindowContainerTransaction t = new WindowContainerTransaction();
splitLayout.resizeSplits(position, t);
- WindowOrganizer.applyTransaction(t);
+ new WindowOrganizer().applyTransaction(t);
}
- private static boolean getHomeAndRecentsTasks(List<ActivityManager.RunningTaskInfo> out,
+ private boolean getHomeAndRecentsTasks(List<ActivityManager.RunningTaskInfo> out,
WindowContainerToken parent) {
boolean resizable = false;
List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
- ? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
- : TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
+ ? mTaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
+ : mTaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
for (int i = 0, n = rootTasks.size(); i < n; ++i) {
final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
out.add(ti);
@@ -139,7 +144,7 @@
* split is minimized. This actually "sticks out" of the secondary split area, but when in
* minimized mode, the secondary split gets a 'negative' crop to expose it.
*/
- static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, WindowContainerToken parent,
+ boolean applyHomeTasksMinimized(SplitDisplayLayout layout, WindowContainerToken parent,
@NonNull WindowContainerTransaction wct) {
// Resize the home/recents stacks to the larger minimized-state size
final Rect homeBounds;
@@ -189,11 +194,11 @@
*/
boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
// Set launchtile first so that any stack created after
- // getAllStackInfos and before reparent (even if unlikely) are placed
+ // getAllRootTaskInfos and before reparent (even if unlikely) are placed
// correctly.
- TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
+ mTaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
List<ActivityManager.RunningTaskInfo> rootTasks =
- TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
+ mTaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
WindowContainerTransaction wct = new WindowContainerTransaction();
if (rootTasks.isEmpty()) {
return false;
@@ -229,7 +234,7 @@
return isHomeResizable;
}
- static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
+ boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
final int atype = ti.configuration.windowConfiguration.getActivityType();
return atype == ACTIVITY_TYPE_HOME || atype == ACTIVITY_TYPE_RECENTS;
}
@@ -244,18 +249,18 @@
boolean dismissOrMaximize) {
// Set launch root first so that any task created after getChildContainers and
// before reparent (pretty unlikely) are put into fullscreen.
- TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
+ mTaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
// TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
// plus specific APIs to clean this up.
List<ActivityManager.RunningTaskInfo> primaryChildren =
- TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
+ mTaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
List<ActivityManager.RunningTaskInfo> secondaryChildren =
- TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
+ mTaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
// In some cases (eg. non-resizable is launched), system-server will leave split-screen.
// as a result, the above will not capture any tasks; yet, we need to clean-up the
// home task bounds.
List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
- TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, HOME_AND_RECENTS);
+ mTaskOrganizer.getRootTasks(DEFAULT_DISPLAY, HOME_AND_RECENTS);
// Filter out the root split tasks
freeHomeAndRecents.removeIf(p -> p.token.equals(tiles.mSecondary.token)
|| p.token.equals(tiles.mPrimary.token));
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index 5879022..d7afa0e 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -18,7 +18,7 @@
name: "WMShellFlickerTests",
srcs: ["src/**/*.java", "src/**/*.kt"],
manifest: "AndroidManifest.xml",
- test_config: "AndroidTest.xml",
+ test_config: "AndroidTestPhysicalDevices.xml",
platform_apis: true,
certificate: "platform",
test_suites: ["device-tests"],
@@ -32,3 +32,21 @@
"launcher-aosp-tapl"
],
}
+
+android_test {
+ name: "WMShellFlickerTestsVirtual",
+ srcs: ["src/**/*.java", "src/**/*.kt"],
+ manifest: "AndroidManifest.xml",
+ test_config: "AndroidTestVirtualDevices.xml",
+ platform_apis: true,
+ certificate: "platform",
+ libs: ["android.test.runner"],
+ static_libs: [
+ "androidx.test.ext.junit",
+ "flickerlib",
+ "truth-prebuilt",
+ "app-helpers-core",
+ "launcher-helper-lib",
+ "launcher-aosp-tapl"
+ ],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml
similarity index 95%
copy from libs/WindowManager/Shell/tests/flicker/AndroidTest.xml
copy to libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml
index 526fc50..9dd9f42 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml
@@ -27,6 +27,7 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.wm.shell.flicker"/>
+ <option name="include-annotation" value="androidx.test.filters.RequiresDevice" />
<option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
<option name="shell-timeout" value="6600s" />
<option name="test-timeout" value="6000s" />
@@ -37,4 +38,4 @@
<option name="collect-on-run-ended-only" value="true" />
<option name="clean-up" value="true" />
</metrics_collector>
-</configuration>
+</configuration>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml
similarity index 95%
rename from libs/WindowManager/Shell/tests/flicker/AndroidTest.xml
rename to libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml
index 526fc50..afb1166 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml
@@ -27,6 +27,7 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.wm.shell.flicker"/>
+ <option name="exclude-annotation" value="androidx.test.filters.RequiresDevice" />
<option name="exclude-annotation" value="androidx.test.filters.FlakyTest" />
<option name="shell-timeout" value="6600s" />
<option name="test-timeout" value="6000s" />
@@ -37,4 +38,4 @@
<option name="collect-on-run-ended-only" value="true" />
<option name="clean-up" value="true" />
</metrics_collector>
-</configuration>
+</configuration>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
index 308a36e..47a62ce 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/FlickerAppHelper.kt
@@ -18,7 +18,7 @@
import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
abstract class FlickerAppHelper(
instr: Instrumentation,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 4b04449..c3c576d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -18,7 +18,7 @@
import android.view.Surface
import androidx.test.filters.FlakyTest
-import androidx.test.filters.LargeTest
+import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.helpers.closePipWindow
import com.android.server.wm.flicker.helpers.expandPipWindow
@@ -41,7 +41,7 @@
* Test Pip launch.
* To run this test: `atest FlickerTests:PipToAppTest`
*/
-@LargeTest
+@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 152738416)
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 692e2fa..937b00b 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -25,6 +25,7 @@
"androidx.test.ext.junit",
"mockito-target-extended-minus-junit4",
"truth-prebuilt",
+ "testables",
],
libs: [
"android.test.mock",
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 10672c8..7b499d4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -20,17 +20,26 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import android.app.ActivityManager.RunningTaskInfo;
-import android.content.res.Configuration;
+import android.os.RemoteException;
import android.view.SurfaceControl;
+import android.window.ITaskOrganizer;
+import android.window.ITaskOrganizerController;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.wm.shell.common.TransactionPool;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@@ -41,7 +50,11 @@
@RunWith(AndroidJUnit4.class)
public class ShellTaskOrganizerTests {
+ @Mock
+ private ITaskOrganizerController mTaskOrganizerController;
+
ShellTaskOrganizer mOrganizer;
+ private final TransactionPool mTransactionPool = mock(TransactionPool.class);
private class TrackingTaskListener implements ShellTaskOrganizer.TaskListener {
final ArrayList<RunningTaskInfo> appeared = new ArrayList<>();
@@ -71,7 +84,15 @@
@Before
public void setUp() {
- mOrganizer = new ShellTaskOrganizer();
+ MockitoAnnotations.initMocks(this);
+ mOrganizer = new ShellTaskOrganizer(mTaskOrganizerController, mTransactionPool);
+ }
+
+ @Test
+ public void registerOrganizer_sendRegisterTaskOrganizer() throws RemoteException {
+ mOrganizer.registerOrganizer();
+
+ verify(mTaskOrganizerController).registerTaskOrganizer(any(ITaskOrganizer.class));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java
similarity index 97%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java
index 7fabf82..a8a3a9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static org.junit.Assert.assertNotNull;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
similarity index 61%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedControllerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index 02d587d..1ce8b54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static com.google.common.truth.Truth.assertThat;
@@ -22,21 +22,20 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Display;
import androidx.test.filters.SmallTest;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -52,8 +51,6 @@
OneHandedTimeoutHandler mTimeoutHandler;
@Mock
- CommandQueue mCommandQueue;
- @Mock
DisplayController mMockDisplayController;
@Mock
OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
@@ -64,21 +61,20 @@
@Mock
OneHandedGestureHandler mMockGestureHandler;
@Mock
- SysUiState mMockSysUiState;
+ OneHandedTimeoutHandler mMockTimeoutHandler;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mDisplay = mContext.getDisplay();
- mOneHandedController = new OneHandedController(
- getContext(),
- mCommandQueue,
+ OneHandedController oneHandedController = new OneHandedController(
+ mContext,
mMockDisplayController,
mMockDisplayAreaOrganizer,
mMockTouchHandler,
mMockTutorialHandler,
- mMockGestureHandler,
- mMockSysUiState);
+ mMockGestureHandler);
+ mOneHandedController = Mockito.spy(oneHandedController);
mTimeoutHandler = Mockito.spy(OneHandedTimeoutHandler.get());
when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
@@ -97,7 +93,7 @@
@Test
public void testRegisterOrganizer() {
- verify(mMockDisplayAreaOrganizer).registerOrganizer(anyInt());
+ verify(mMockDisplayAreaOrganizer, atLeastOnce()).registerOrganizer(anyInt());
}
@Test
@@ -116,11 +112,22 @@
}
@Test
- public void testRegisterTransitionCallback() {
- verify(mMockDisplayAreaOrganizer, atLeastOnce()).registerTransitionCallback(any());
+ public void testRegisterTransitionCallbackAfterInit() {
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTouchHandler);
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockGestureHandler);
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTutorialHandler);
}
@Test
+ public void testRegisterTransitionCallback() {
+ OneHandedTransitionCallback callback = new OneHandedTransitionCallback() {};
+ mOneHandedController.registerTransitionCallback(callback);
+
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(callback);
+ }
+
+
+ @Test
public void testStopOneHanded_shouldRemoveTimer() {
mOneHandedController.stopOneHanded();
@@ -132,7 +139,7 @@
final boolean enabled = true;
mOneHandedController.setOneHandedEnabled(enabled);
- verify(mMockTouchHandler, times(2)).onOneHandedEnabled(enabled);
+ verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(enabled);
}
@Test
@@ -140,6 +147,44 @@
final boolean enabled = true;
mOneHandedController.setSwipeToNotificationEnabled(enabled);
- verify(mMockTouchHandler, times(2)).onOneHandedEnabled(enabled);
+ verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(enabled);
+ }
+
+ @Ignore("b/167943723, refactor it and fix it")
+ @Test
+ public void tesSettingsObserver_updateTapAppToExit() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.TAPS_APP_TO_EXIT, 1);
+
+ verify(mOneHandedController).setTaskChangeToExit(true);
+ }
+
+ @Ignore("b/167943723, refactor it and fix it")
+ @Test
+ public void tesSettingsObserver_updateEnabled() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ONE_HANDED_MODE_ENABLED, 1);
+
+ verify(mOneHandedController).setOneHandedEnabled(true);
+ }
+
+ @Ignore("b/167943723, refactor it and fix it")
+ @Test
+ public void tesSettingsObserver_updateTimeout() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
+ OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
+
+ verify(mMockTimeoutHandler).setTimeout(
+ OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
+ }
+
+ @Ignore("b/167943723, refactor it and fix it")
+ @Test
+ public void tesSettingsObserver_updateSwipeToNotification() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 1);
+
+ verify(mOneHandedController).setSwipeToNotificationEnabled(true);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
index a989cd1f..5ff94b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedEventsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedEventsTest.java
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedEventsTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedEventsTest.java
index 36c1174..492c34e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedEventsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedEventsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static org.junit.Assert.assertEquals;
@@ -22,7 +22,6 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.SysuiTestCase;
import org.junit.Before;
import org.junit.Test;
@@ -34,7 +33,7 @@
@RunWith(Parameterized.class)
@SmallTest
-public class OneHandedEventsTest extends SysuiTestCase {
+public class OneHandedEventsTest extends OneHandedTestCase {
private UiEventLoggerFake mUiEventLogger;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java
new file mode 100644
index 0000000..fb417c8
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.onehanded;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.common.DisplayController;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class OneHandedGestureHandlerTest extends OneHandedTestCase {
+ OneHandedTutorialHandler mTutorialHandler;
+ OneHandedGestureHandler mGestureHandler;
+ @Mock
+ DisplayController mMockDisplayController;
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mTutorialHandler = new OneHandedTutorialHandler(mContext);
+ mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController);
+ }
+
+ @Test
+ public void testSetGestureEventListener() {
+ OneHandedGestureHandler.OneHandedGestureEventCallback callback =
+ new OneHandedGestureHandler.OneHandedGestureEventCallback() {
+ @Override
+ public void onStart() {}
+
+ @Override
+ public void onStop() {}
+ };
+
+ mGestureHandler.setGestureEventListener(callback);
+ assertThat(mGestureHandler.mGestureEventCallback).isEqualTo(callback);
+ }
+
+ @Ignore("b/167943723, refactor it and fix it")
+ @Test
+ public void testReceiveNewConfig_whenThreeButtonModeEnabled() {
+ mGestureHandler.onOneHandedEnabled(true);
+ mGestureHandler.onThreeButtonModeEnabled(true);
+
+ assertThat(mGestureHandler.mInputMonitor).isNotNull();
+ assertThat(mGestureHandler.mInputEventReceiver).isNotNull();
+ }
+
+ @Test
+ public void testOneHandedDisabled_shouldDisposeInputChannel() {
+ mGestureHandler.onOneHandedEnabled(false);
+
+ assertThat(mGestureHandler.mInputMonitor).isNull();
+ assertThat(mGestureHandler.mInputEventReceiver).isNull();
+ }
+
+ @Test
+ public void testChangeNavBarToNon3Button_shouldDisposeInputChannel() {
+ mGestureHandler.onOneHandedEnabled(true);
+ mGestureHandler.onThreeButtonModeEnabled(false);
+
+ assertThat(mGestureHandler.mInputMonitor).isNull();
+ assertThat(mGestureHandler.mInputEventReceiver).isNull();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java
similarity index 83%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java
index 990eb63..7c11138 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS;
import static com.google.common.truth.Truth.assertThat;
@@ -59,24 +59,24 @@
@Test
public void testRegisterSecureKeyObserver() {
final Uri result = OneHandedSettingsUtil.registerSettingsKeyObserver(
- Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver);
+ Settings.Secure.TAPS_APP_TO_EXIT, mContentResolver, mContentObserver);
assertThat(result).isNotNull();
OneHandedSettingsUtil.registerSettingsKeyObserver(
- Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver);
+ Settings.Secure.TAPS_APP_TO_EXIT, mContentResolver, mContentObserver);
}
@Test
public void testUnregisterSecureKeyObserver() {
OneHandedSettingsUtil.registerSettingsKeyObserver(
- Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver);
+ Settings.Secure.TAPS_APP_TO_EXIT, mContentResolver, mContentObserver);
OneHandedSettingsUtil.unregisterSettingsKeyObserver(mContentResolver, mContentObserver);
assertThat(mOnChanged).isFalse();
Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ONE_HANDED_MODE_ENABLED, 0);
+ Settings.Secure.TAPS_APP_TO_EXIT, 0);
assertThat(mOnChanged).isFalse();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
similarity index 67%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTestCase.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
index 04ebf25..c7ae2a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTestCase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java
@@ -14,13 +14,21 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.wm.shell.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.os.SystemProperties;
import android.provider.Settings;
-import com.android.systemui.SysuiTestCase;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.After;
import org.junit.Before;
@@ -28,14 +36,26 @@
/**
* Base class that does One Handed specific setup.
*/
-public abstract class OneHandedTestCase extends SysuiTestCase {
+public abstract class OneHandedTestCase {
static boolean sOrigEnabled;
static boolean sOrigTapsAppToExitEnabled;
static int sOrigTimeout;
static boolean sOrigSwipeToNotification;
+ protected Context mContext;
+
@Before
public void setupSettings() {
+ final Context testContext =
+ InstrumentationRegistry.getInstrumentation().getTargetContext();
+ final DisplayManager dm = testContext.getSystemService(DisplayManager.class);
+ mContext = testContext.createDisplayContext(dm.getDisplay(DEFAULT_DISPLAY));
+
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity();
+
sOrigEnabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
getContext().getContentResolver());
sOrigTimeout = OneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
@@ -54,6 +74,11 @@
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 1);
}
+ @Before
+ public void assumeOneHandedModeSupported() {
+ assumeTrue(SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false));
+ }
+
@After
public void restoreSettings() {
Settings.Secure.putInt(getContext().getContentResolver(),
@@ -65,6 +90,15 @@
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
sOrigSwipeToNotification ? 1 : 0);
+
+ InstrumentationRegistry
+ .getInstrumentation()
+ .getUiAutomation()
+ .dropShellPermissionIdentity();
+ }
+
+ protected Context getContext() {
+ return mContext;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTimeoutHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java
similarity index 90%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTimeoutHandlerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java
index 7d63131..e2b70c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTimeoutHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER;
-import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS;
-import static com.android.systemui.onehanded.OneHandedTimeoutHandler.ONE_HANDED_TIMEOUT_STOP_MSG;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER;
+import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS;
+import static com.android.wm.shell.onehanded.OneHandedTimeoutHandler.ONE_HANDED_TIMEOUT_STOP_MSG;
import static com.google.common.truth.Truth.assertThat;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java
new file mode 100644
index 0000000..c69e385
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.onehanded;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class OneHandedTouchHandlerTest extends OneHandedTestCase {
+ OneHandedTouchHandler mTouchHandler;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mTouchHandler = new OneHandedTouchHandler();
+ }
+
+ @Test
+ public void testRegisterTouchEventListener() {
+ OneHandedTouchHandler.OneHandedTouchEventCallback callback = () -> {
+ };
+ mTouchHandler.registerTouchEventListener(callback);
+
+ assertThat(mTouchHandler.mTouchEventCallback).isEqualTo(callback);
+ }
+
+ @Test
+ public void testOneHandedDisabled_shouldDisposeInputChannel() {
+ mTouchHandler.onOneHandedEnabled(false);
+
+ assertThat(mTouchHandler.mInputMonitor).isNull();
+ assertThat(mTouchHandler.mInputEventReceiver).isNull();
+ }
+
+ @Ignore("b/167943723, refactor it and fix it")
+ @Test
+ public void testOneHandedEnabled_monitorInputChannel() {
+ mTouchHandler.onOneHandedEnabled(true);
+
+ assertThat(mTouchHandler.mInputMonitor).isNotNull();
+ assertThat(mTouchHandler.mInputEventReceiver).isNotNull();
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
similarity index 74%
rename from packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
index 1bffbf7..4a133d39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.onehanded;
+package com.android.wm.shell.onehanded;
import static org.mockito.Mockito.verify;
@@ -23,53 +23,40 @@
import androidx.test.filters.SmallTest;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
+ @Mock
OneHandedTouchHandler mTouchHandler;
OneHandedTutorialHandler mTutorialHandler;
OneHandedGestureHandler mGestureHandler;
OneHandedController mOneHandedController;
@Mock
- CommandQueue mCommandQueue;
- @Mock
DisplayController mMockDisplayController;
@Mock
- NavigationModeController mMockNavigationModeController;
- @Mock
OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
- @Mock
- SysUiState mMockSysUiState;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTouchHandler = new OneHandedTouchHandler();
- mTutorialHandler = Mockito.spy(new OneHandedTutorialHandler(mContext));
- mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController,
- mMockNavigationModeController);
+ mTutorialHandler = new OneHandedTutorialHandler(mContext);
+ mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController);
mOneHandedController = new OneHandedController(
getContext(),
- mCommandQueue,
mMockDisplayController,
mMockDisplayAreaOrganizer,
mTouchHandler,
mTutorialHandler,
- mGestureHandler,
- mMockSysUiState);
+ mGestureHandler);
}
@Test
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 76ec078..4dbce92 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -84,7 +84,6 @@
mGraphicsQueue = VK_NULL_HANDLE;
mAHBUploadQueue = VK_NULL_HANDLE;
- mPresentQueue = VK_NULL_HANDLE;
mDevice = VK_NULL_HANDLE;
mPhysicalDevice = VK_NULL_HANDLE;
mInstance = VK_NULL_HANDLE;
@@ -192,10 +191,6 @@
}
LOG_ALWAYS_FATAL_IF(mGraphicsQueueIndex == queueCount);
- // All physical devices and queue families on Android must be capable of
- // presentation with any native window. So just use the first one.
- mPresentQueueIndex = 0;
-
{
uint32_t extensionCount = 0;
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
@@ -289,31 +284,21 @@
queueNextPtr = &queuePriorityCreateInfo;
}
- const VkDeviceQueueCreateInfo queueInfo[2] = {
- {
- VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
- queueNextPtr, // pNext
- 0, // VkDeviceQueueCreateFlags
- mGraphicsQueueIndex, // queueFamilyIndex
- 2, // queueCount
- queuePriorities, // pQueuePriorities
- },
- {
- VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
- queueNextPtr, // pNext
- 0, // VkDeviceQueueCreateFlags
- mPresentQueueIndex, // queueFamilyIndex
- 1, // queueCount
- queuePriorities, // pQueuePriorities
- }};
- uint32_t queueInfoCount = (mPresentQueueIndex != mGraphicsQueueIndex) ? 2 : 1;
+ const VkDeviceQueueCreateInfo queueInfo = {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
+ queueNextPtr, // pNext
+ 0, // VkDeviceQueueCreateFlags
+ mGraphicsQueueIndex, // queueFamilyIndex
+ 2, // queueCount
+ queuePriorities, // pQueuePriorities
+ };
const VkDeviceCreateInfo deviceInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
&features, // pNext
0, // VkDeviceCreateFlags
- queueInfoCount, // queueCreateInfoCount
- queueInfo, // pQueueCreateInfos
+ 1, // queueCreateInfoCount
+ &queueInfo, // pQueueCreateInfos
0, // layerCount
nullptr, // ppEnabledLayerNames
(uint32_t)mDeviceExtensions.size(), // extensionCount
@@ -361,8 +346,6 @@
mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);
mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue);
- mGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue);
-
if (Properties::enablePartialUpdates && Properties::useBufferAge) {
mSwapBehavior = SwapBehavior::BufferAge;
}
@@ -555,8 +538,8 @@
void VulkanManager::destroySurface(VulkanSurface* surface) {
// Make sure all submit commands have finished before starting to destroy objects.
- if (VK_NULL_HANDLE != mPresentQueue) {
- mQueueWaitIdle(mPresentQueue);
+ if (VK_NULL_HANDLE != mGraphicsQueue) {
+ mQueueWaitIdle(mGraphicsQueue);
}
mDeviceWaitIdle(mDevice);
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 75c05b8..7a77466 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -163,8 +163,6 @@
uint32_t mGraphicsQueueIndex;
VkQueue mGraphicsQueue = VK_NULL_HANDLE;
VkQueue mAHBUploadQueue = VK_NULL_HANDLE;
- uint32_t mPresentQueueIndex;
- VkQueue mPresentQueue = VK_NULL_HANDLE;
// Variables saved to populate VkFunctorInitParams.
static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0);
diff --git a/libs/hwui/shader/BlurShader.cpp b/libs/hwui/shader/BlurShader.cpp
index 4d18cdd..fa10be1 100644
--- a/libs/hwui/shader/BlurShader.cpp
+++ b/libs/hwui/shader/BlurShader.cpp
@@ -26,7 +26,9 @@
SkImageFilters::Blur(
Blur::convertRadiusToSigma(radiusX),
Blur::convertRadiusToSigma(radiusY),
- inputShader ? inputShader->asSkImageFilter() : nullptr)
+ SkTileMode::kClamp,
+ inputShader ? inputShader->asSkImageFilter() : nullptr,
+ nullptr)
) { }
sk_sp<SkImageFilter> BlurShader::makeSkImageFilter() {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 6fc702e..04bcbfc 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -164,7 +164,7 @@
/**
* The fused location provider.
*
- * <p>This provider combines may combine inputs from several location sources to provide the
+ * <p>This provider may combine inputs from several location sources to provide the
* best possible location fix. It is implicitly used for all API's that involve the
* {@link LocationRequest} object.
*
diff --git a/location/java/android/location/timezone/LocationTimeZoneEvent.java b/location/java/android/location/timezone/LocationTimeZoneEvent.java
index 540bdff..55bc507 100644
--- a/location/java/android/location/timezone/LocationTimeZoneEvent.java
+++ b/location/java/android/location/timezone/LocationTimeZoneEvent.java
@@ -35,7 +35,8 @@
*/
public final class LocationTimeZoneEvent implements Parcelable {
- @IntDef({ EVENT_TYPE_UNKNOWN, EVENT_TYPE_SUCCESS, EVENT_TYPE_SUCCESS })
+ @IntDef({ EVENT_TYPE_UNKNOWN, EVENT_TYPE_PERMANENT_FAILURE, EVENT_TYPE_SUCCESS,
+ EVENT_TYPE_UNCERTAIN })
@interface EventType {}
/** Uninitialized value for {@link #mEventType} - must not be used for real events. */
@@ -43,7 +44,7 @@
/**
* Indicates there was a permanent failure. This is not generally expected, and probably means a
- * required backend service is no longer supported / available.
+ * required backend service has been turned down, or the client is unreasonably old.
*/
public static final int EVENT_TYPE_PERMANENT_FAILURE = 1;
@@ -54,8 +55,9 @@
public static final int EVENT_TYPE_SUCCESS = 2;
/**
- * Indicates the time zone is not known because there was a (temporary) error, e.g. when
- * detecting location, or when resolving the location to a time zone.
+ * Indicates the time zone is not known because of an expected runtime state or error, e.g. when
+ * the provider is unable to detect location, or there was a problem when resolving the location
+ * to a time zone.
*/
public static final int EVENT_TYPE_UNCERTAIN = 3;
diff --git a/media/java/android/media/AudioDeviceAttributes.java b/media/java/android/media/AudioDeviceAttributes.java
index 0ab62c1..6c8b500 100644
--- a/media/java/android/media/AudioDeviceAttributes.java
+++ b/media/java/android/media/AudioDeviceAttributes.java
@@ -72,6 +72,11 @@
private final @Role int mRole;
/**
+ * The internal audio device type
+ */
+ private final int mNativeType;
+
+ /**
* @hide
* Constructor from a valid {@link AudioDeviceInfo}
* @param deviceInfo the connected audio device from which to obtain the device-identifying
@@ -83,6 +88,7 @@
mRole = deviceInfo.isSink() ? ROLE_OUTPUT : ROLE_INPUT;
mType = deviceInfo.getType();
mAddress = deviceInfo.getAddress();
+ mNativeType = deviceInfo.getInternalType();
}
/**
@@ -101,9 +107,12 @@
}
if (role == ROLE_OUTPUT) {
AudioDeviceInfo.enforceValidAudioDeviceTypeOut(type);
- }
- if (role == ROLE_INPUT) {
+ mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(type);
+ } else if (role == ROLE_INPUT) {
AudioDeviceInfo.enforceValidAudioDeviceTypeIn(type);
+ mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(type);
+ } else {
+ mNativeType = AudioSystem.DEVICE_NONE;
}
mRole = role;
@@ -115,6 +124,7 @@
mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT;
mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType);
mAddress = address;
+ mNativeType = nativeType;
}
/**
@@ -147,6 +157,15 @@
return mAddress;
}
+ /**
+ * @hide
+ * Returns the internal device type of a device
+ * @return the internal device type
+ */
+ public int getInternalType() {
+ return mNativeType;
+ }
+
@Override
public int hashCode() {
return Objects.hash(mRole, mType, mAddress);
@@ -189,12 +208,14 @@
dest.writeInt(mRole);
dest.writeInt(mType);
dest.writeString(mAddress);
+ dest.writeInt(mNativeType);
}
private AudioDeviceAttributes(@NonNull Parcel in) {
mRole = in.readInt();
mType = in.readInt();
mAddress = in.readString();
+ mNativeType = in.readInt();
}
public static final @NonNull Parcelable.Creator<AudioDeviceAttributes> CREATOR =
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index d4fb1be..477519c 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -351,6 +351,14 @@
}
/**
+ * @hide
+ * @return the internal device tyoe
+ */
+ public int getInternalType() {
+ return mPort.type();
+ }
+
+ /**
* @return The internal device ID.
*/
public int getId() {
@@ -513,10 +521,21 @@
return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN);
}
+ /** @hide */
+ public static int convertDeviceTypeToInternalInputDevice(int deviceType) {
+ return EXT_TO_INT_INPUT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE);
+ }
+
private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING;
private static final SparseIntArray EXT_TO_INT_DEVICE_MAPPING;
+ /**
+ * EXT_TO_INT_INPUT_DEVICE_MAPPING aims at mapping external device type to internal input device
+ * type.
+ */
+ private static final SparseIntArray EXT_TO_INT_INPUT_DEVICE_MAPPING;
+
static {
INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray();
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE);
@@ -601,6 +620,32 @@
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER);
+
+ // privileges mapping to input device
+ EXT_TO_INT_INPUT_DEVICE_MAPPING = new SparseIntArray();
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+ TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+ TYPE_WIRED_HEADSET, AudioSystem.DEVICE_IN_WIRED_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_IN_HDMI);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_IN_TELEPHONY_RX);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+ TYPE_USB_ACCESSORY, AudioSystem.DEVICE_IN_USB_ACCESSORY);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_IN_USB_DEVICE);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_IN_USB_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_IN_LINE);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_IN_SPDIF);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+ TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_IN_BLUETOOTH_A2DP);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_IN_IP);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_IN_BUS);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+ TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_IN_REMOTE_SUBMIX);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_IN_BLE_HEADSET);
}
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
old mode 100755
new mode 100644
index a16e063..e1e55c2
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1949,6 +1949,349 @@
}
//====================================================================
+ // Audio Capture Preset routing
+
+ /**
+ * @hide
+ * Set the preferred device for a given capture preset, i.e. the audio routing to be used by
+ * this capture preset. Note that the device may not be available at the time the preferred
+ * device is set, but it will be used once made available.
+ * <p>Use {@link #clearPreferredDevicesForCapturePreset(int)} to cancel setting this preference
+ * for this capture preset.</p>
+ * @param capturePreset the audio capture preset whose routing will be affected
+ * @param device the audio device to route to when available
+ * @return true if the operation was successful, false otherwise
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public boolean setPreferredDeviceForCapturePreset(int capturePreset,
+ @NonNull AudioDeviceAttributes device) {
+ return setPreferredDevicesForCapturePreset(capturePreset, Arrays.asList(device));
+ }
+
+ /**
+ * @hide
+ * Remove all the preferred audio devices previously set
+ * @param capturePreset the audio capture preset whose routing will be affected
+ * @return true if the operation was successful, false otherwise (invalid capture preset, or no
+ * device set for example)
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public boolean clearPreferredDevicesForCapturePreset(int capturePreset) {
+ if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+ return false;
+ }
+ try {
+ final int status = getService().clearPreferredDevicesForCapturePreset(capturePreset);
+ return status == AudioSystem.SUCCESS;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ * Return the preferred devices for an audio capture preset, previously set with
+ * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)}
+ * @param capturePreset the capture preset to query
+ * @return a list that contains preferred devices for that capture preset.
+ */
+ @NonNull
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
+ if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+ return new ArrayList<AudioDeviceAttributes>();
+ }
+ try {
+ return getService().getPreferredDevicesForCapturePreset(capturePreset);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ private boolean setPreferredDevicesForCapturePreset(
+ int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
+ Objects.requireNonNull(devices);
+ if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+ return false;
+ }
+ if (devices.size() != 1) {
+ throw new IllegalArgumentException(
+ "Only support setting one preferred devices for capture preset");
+ }
+ for (AudioDeviceAttributes device : devices) {
+ Objects.requireNonNull(device);
+ }
+ try {
+ final int status =
+ getService().setPreferredDevicesForCapturePreset(capturePreset, devices);
+ return status == AudioSystem.SUCCESS;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ * Interface to be notified of changes in the preferred audio devices set for a given capture
+ * preset.
+ * <p>Note that this listener will only be invoked whenever
+ * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)} or
+ * {@link #clearPreferredDevicesForCapturePreset(int)} causes a change in
+ * preferred device. It will not be invoked directly after registration with
+ * {@link #addOnPreferredDevicesForCapturePresetChangedListener(
+ * Executor, OnPreferredDevicesForCapturePresetChangedListener)}
+ * to indicate which strategies had preferred devices at the time of registration.</p>
+ * @see #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
+ * @see #clearPreferredDevicesForCapturePreset(int)
+ * @see #getPreferredDevicesForCapturePreset(int)
+ */
+ @SystemApi
+ public interface OnPreferredDevicesForCapturePresetChangedListener {
+ /**
+ * Called on the listener to indicate that the preferred audio devices for the given
+ * capture preset has changed.
+ * @param capturePreset the capture preset whose preferred device changed
+ * @param devices a list of newly set preferred audio devices
+ */
+ void onPreferredDevicesForCapturePresetChanged(
+ int capturePreset, @NonNull List<AudioDeviceAttributes> devices);
+ }
+
+ /**
+ * @hide
+ * Adds a listener for being notified of changes to the capture-preset-preferred audio device.
+ * @param executor
+ * @param listener
+ * @throws SecurityException if the caller doesn't hold the required permission
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public void addOnPreferredDevicesForCapturePresetChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnPreferredDevicesForCapturePresetChangedListener listener)
+ throws SecurityException {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(listener);
+ int status = addOnDevRoleForCapturePresetChangedListener(
+ executor, listener, AudioSystem.DEVICE_ROLE_PREFERRED);
+ if (status == AudioSystem.ERROR) {
+ // This must not happen
+ throw new RuntimeException("Unknown error happened");
+ }
+ if (status == AudioSystem.BAD_VALUE) {
+ throw new IllegalArgumentException(
+ "attempt to call addOnPreferredDevicesForCapturePresetChangedListener() "
+ + "on a previously registered listener");
+ }
+ }
+
+ /**
+ * @hide
+ * Removes a previously added listener of changes to the capture-preset-preferred audio device.
+ * @param listener
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public void removeOnPreferredDevicesForCapturePresetChangedListener(
+ @NonNull OnPreferredDevicesForCapturePresetChangedListener listener) {
+ Objects.requireNonNull(listener);
+ int status = removeOnDevRoleForCapturePresetChangedListener(
+ listener, AudioSystem.DEVICE_ROLE_PREFERRED);
+ if (status == AudioSystem.ERROR) {
+ // This must not happen
+ throw new RuntimeException("Unknown error happened");
+ }
+ if (status == AudioSystem.BAD_VALUE) {
+ throw new IllegalArgumentException(
+ "attempt to call removeOnPreferredDevicesForCapturePresetChangedListener() "
+ + "on an unregistered listener");
+ }
+ }
+
+ private <T> int addOnDevRoleForCapturePresetChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull T listener, int deviceRole) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(listener);
+ DevRoleListeners<T> devRoleListeners =
+ (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole);
+ if (devRoleListeners == null) {
+ return AudioSystem.ERROR;
+ }
+ synchronized (devRoleListeners.mDevRoleListenersLock) {
+ if (devRoleListeners.hasDevRoleListener(listener)) {
+ return AudioSystem.BAD_VALUE;
+ }
+ // lazy initialization of the list of device role listener
+ if (devRoleListeners.mListenerInfos == null) {
+ devRoleListeners.mListenerInfos = new ArrayList<>();
+ }
+ final int oldCbCount = devRoleListeners.mListenerInfos.size();
+ devRoleListeners.mListenerInfos.add(new DevRoleListenerInfo<T>(executor, listener));
+ if (oldCbCount == 0 && devRoleListeners.mListenerInfos.size() > 0) {
+ // register binder for callbacks
+ synchronized (mDevRoleForCapturePresetListenersLock) {
+ int deviceRoleListenerStatus = mDeviceRoleListenersStatus;
+ mDeviceRoleListenersStatus |= (1 << deviceRole);
+ if (deviceRoleListenerStatus != 0) {
+ // There are already device role changed listeners active.
+ return AudioSystem.SUCCESS;
+ }
+ if (mDevicesRoleForCapturePresetDispatcherStub == null) {
+ mDevicesRoleForCapturePresetDispatcherStub =
+ new CapturePresetDevicesRoleDispatcherStub();
+ }
+ try {
+ getService().registerCapturePresetDevicesRoleDispatcher(
+ mDevicesRoleForCapturePresetDispatcherStub);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+ }
+ return AudioSystem.SUCCESS;
+ }
+
+ private <T> int removeOnDevRoleForCapturePresetChangedListener(
+ @NonNull T listener, int deviceRole) {
+ Objects.requireNonNull(listener);
+ DevRoleListeners<T> devRoleListeners =
+ (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole);
+ if (devRoleListeners == null) {
+ return AudioSystem.ERROR;
+ }
+ synchronized (devRoleListeners.mDevRoleListenersLock) {
+ if (!devRoleListeners.removeDevRoleListener(listener)) {
+ return AudioSystem.BAD_VALUE;
+ }
+ if (devRoleListeners.mListenerInfos.size() == 0) {
+ // unregister binder for callbacks
+ synchronized (mDevRoleForCapturePresetListenersLock) {
+ mDeviceRoleListenersStatus ^= (1 << deviceRole);
+ if (mDeviceRoleListenersStatus != 0) {
+ // There are some other device role changed listeners active.
+ return AudioSystem.SUCCESS;
+ }
+ try {
+ getService().unregisterCapturePresetDevicesRoleDispatcher(
+ mDevicesRoleForCapturePresetDispatcherStub);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+ }
+ return AudioSystem.SUCCESS;
+ }
+
+ private final Map<Integer, Object> mDevRoleForCapturePresetListeners = new HashMap<>(){{
+ put(AudioSystem.DEVICE_ROLE_PREFERRED,
+ new DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>());
+ }};
+
+ private class DevRoleListenerInfo<T> {
+ final @NonNull Executor mExecutor;
+ final @NonNull T mListener;
+ DevRoleListenerInfo(Executor executor, T listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+ }
+
+ private class DevRoleListeners<T> {
+ private final Object mDevRoleListenersLock = new Object();
+ @GuardedBy("mDevRoleListenersLock")
+ private @Nullable ArrayList<DevRoleListenerInfo<T>> mListenerInfos;
+
+ @GuardedBy("mDevRoleListenersLock")
+ private @Nullable DevRoleListenerInfo<T> getDevRoleListenerInfo(T listener) {
+ if (mListenerInfos == null) {
+ return null;
+ }
+ for (DevRoleListenerInfo<T> listenerInfo : mListenerInfos) {
+ if (listenerInfo.mListener == listener) {
+ return listenerInfo;
+ }
+ }
+ return null;
+ }
+
+ @GuardedBy("mDevRoleListenersLock")
+ private boolean hasDevRoleListener(T listener) {
+ return getDevRoleListenerInfo(listener) != null;
+ }
+
+ @GuardedBy("mDevRoleListenersLock")
+ private boolean removeDevRoleListener(T listener) {
+ final DevRoleListenerInfo<T> infoToRemove = getDevRoleListenerInfo(listener);
+ if (infoToRemove != null) {
+ mListenerInfos.remove(infoToRemove);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private final Object mDevRoleForCapturePresetListenersLock = new Object();
+ /**
+ * Record if there is a listener added for device role change. If there is a listener added for
+ * a specified device role change, the bit at position `1 << device_role` is set.
+ */
+ @GuardedBy("mDevRoleForCapturePresetListenersLock")
+ private int mDeviceRoleListenersStatus = 0;
+ @GuardedBy("mDevRoleForCapturePresetListenersLock")
+ private CapturePresetDevicesRoleDispatcherStub mDevicesRoleForCapturePresetDispatcherStub;
+
+ private final class CapturePresetDevicesRoleDispatcherStub
+ extends ICapturePresetDevicesRoleDispatcher.Stub {
+
+ @Override
+ public void dispatchDevicesRoleChanged(
+ int capturePreset, int role, List<AudioDeviceAttributes> devices) {
+ final Object listenersObj = mDevRoleForCapturePresetListeners.get(role);
+ if (listenersObj == null) {
+ return;
+ }
+ switch (role) {
+ case AudioSystem.DEVICE_ROLE_PREFERRED: {
+ final DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>
+ listeners =
+ (DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>)
+ listenersObj;
+ final ArrayList<DevRoleListenerInfo<
+ OnPreferredDevicesForCapturePresetChangedListener>> prefDevListeners;
+ synchronized (listeners.mDevRoleListenersLock) {
+ if (listeners.mListenerInfos.isEmpty()) {
+ return;
+ }
+ prefDevListeners = (ArrayList<DevRoleListenerInfo<
+ OnPreferredDevicesForCapturePresetChangedListener>>)
+ listeners.mListenerInfos.clone();
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ for (DevRoleListenerInfo<
+ OnPreferredDevicesForCapturePresetChangedListener> info :
+ prefDevListeners) {
+ info.mExecutor.execute(() ->
+ info.mListener.onPreferredDevicesForCapturePresetChanged(
+ capturePreset, devices));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ } break;
+ default:
+ break;
+ }
+ }
+ }
+
+ //====================================================================
// Offload query
/**
* Returns whether offloaded playback of an audio format is supported on the device.
@@ -6306,6 +6649,132 @@
}
}
+ /**
+ * Adjusts the volume of the most relevant stream, or the given fallback
+ * stream.
+ * <p>
+ * This method should only be used by applications that replace the
+ * platform-wide management of audio settings or the main telephony
+ * application.
+ * <p>
+ * This method has no effect if the device implements a fixed volume policy
+ * as indicated by {@link #isVolumeFixed()}.
+ * <p>This API checks if the caller has the necessary permissions based on the provided
+ * component name, uid, and pid values.
+ * See {@link #adjustSuggestedStreamVolume(int, int, int)}.
+ *
+ * @param suggestedStreamType The stream type that will be used if there
+ * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is
+ * valid here.
+ * @param direction The direction to adjust the volume. One of
+ * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE},
+ * {@link #ADJUST_SAME}, {@link #ADJUST_MUTE},
+ * {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}.
+ * @param flags One or more flags.
+ * @param packageName the package name of client application
+ * @param uid the uid of client application
+ * @param pid the pid of client application
+ * @param targetSdkVersion the target sdk version of client application
+ * @see #adjustVolume(int, int)
+ * @see #adjustStreamVolume(int, int, int)
+ * @see #setStreamVolume(int, int, int)
+ * @see #isVolumeFixed()
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void adjustSuggestedStreamVolumeForUid(int suggestedStreamType, int direction, int flags,
+ @NonNull String packageName, int uid, int pid, int targetSdkVersion) {
+ try {
+ getService().adjustSuggestedStreamVolumeForUid(suggestedStreamType, direction, flags,
+ packageName, uid, pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Adjusts the volume of a particular stream by one step in a direction.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
+ * <p>This method has no effect if the device implements a fixed volume policy
+ * as indicated by {@link #isVolumeFixed()}.
+ * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed
+ * unless the app has been granted Do Not Disturb Access.
+ * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+ * <p>This API checks if the caller has the necessary permissions based on the provided
+ * component name, uid, and pid values.
+ * See {@link #adjustStreamVolume(int, int, int)}.
+ *
+ * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
+ * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC},
+ * {@link #STREAM_ALARM} or {@link #STREAM_ACCESSIBILITY}.
+ * @param direction The direction to adjust the volume. One of
+ * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
+ * {@link #ADJUST_SAME}.
+ * @param flags One or more flags.
+ * @param packageName the package name of client application
+ * @param uid the uid of client application
+ * @param pid the pid of client application
+ * @param targetSdkVersion the target sdk version of client application
+ * @see #adjustVolume(int, int)
+ * @see #setStreamVolume(int, int, int)
+ * @throws SecurityException if the adjustment triggers a Do Not Disturb change
+ * and the caller is not granted notification policy access.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
+ @NonNull String packageName, int uid, int pid, int targetSdkVersion) {
+ try {
+ getService().adjustStreamVolumeForUid(streamType, direction, flags, packageName, uid,
+ pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Sets the volume index for a particular stream.
+ * <p>This method has no effect if the device implements a fixed volume policy
+ * as indicated by {@link #isVolumeFixed()}.
+ * <p>From N onward, volume adjustments that would toggle Do Not Disturb are not allowed unless
+ * the app has been granted Do Not Disturb Access.
+ * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+ * <p>This API checks if the caller has the necessary permissions based on the provided
+ * component name, uid, and pid values.
+ * See {@link #setStreamVolume(int, int, int)}.
+ *
+ * @param streamType The stream whose volume index should be set.
+ * @param index The volume index to set. See
+ * {@link #getStreamMaxVolume(int)} for the largest valid value.
+ * @param flags One or more flags.
+ * @param packageName the package name of client application
+ * @param uid the uid of client application
+ * @param pid the pid of client application
+ * @param targetSdkVersion the target sdk version of client application
+ * @see #getStreamMaxVolume(int)
+ * @see #getStreamVolume(int)
+ * @see #isVolumeFixed()
+ * @throws SecurityException if the volume change triggers a Do Not Disturb change
+ * and the caller is not granted notification policy access.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void setStreamVolumeForUid(int streamType, int index, int flags,
+ @NonNull String packageName, int uid, int pid, int targetSdkVersion) {
+ try {
+ getService().setStreamVolumeForUid(streamType, index, flags, packageName, uid, pid,
+ UserHandle.getUserHandleForUid(uid), targetSdkVersion);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
/** @hide
* TODO: make this a @SystemApi */
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index b44d7bb..c827932 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -28,15 +28,6 @@
*/
public abstract class AudioManagerInternal {
- public abstract void adjustSuggestedStreamVolumeForUid(int streamType, int direction,
- int flags, String callingPackage, int uid, int pid);
-
- public abstract void adjustStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid, int pid);
-
- public abstract void setStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid, int pid);
-
public abstract void setRingerModeDelegate(RingerModeDelegate delegate);
public abstract int getRingerModeInternal();
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 22f6250..279ba0a 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -27,6 +27,7 @@
import android.media.audiopolicy.AudioMix;
import android.telephony.TelephonyManager;
import android.util.Log;
+import android.util.Pair;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -1755,6 +1756,134 @@
public static native int getDevicesForRoleAndStrategy(
int strategy, int role, @NonNull List<AudioDeviceAttributes> devices);
+ // use case routing by capture preset
+
+ private static Pair<int[], String[]> populateInputDevicesTypeAndAddress(
+ @NonNull List<AudioDeviceAttributes> devices) {
+ int[] types = new int[devices.size()];
+ String[] addresses = new String[devices.size()];
+ for (int i = 0; i < devices.size(); ++i) {
+ types[i] = devices.get(i).getInternalType();
+ if (types[i] == AudioSystem.DEVICE_NONE) {
+ types[i] = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(
+ devices.get(i).getType());
+ }
+ addresses[i] = devices.get(i).getAddress();
+ }
+ return new Pair<int[], String[]>(types, addresses);
+ }
+
+ /**
+ * @hide
+ * Set devices as role for capture preset.
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @param devices the list of devices to be set as role for the given capture preset
+ * @return {@link #SUCCESS} if successfully set
+ */
+ public static int setDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+ if (devices.isEmpty()) {
+ return BAD_VALUE;
+ }
+ Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+ return setDevicesRoleForCapturePreset(
+ capturePreset, role, typeAddresses.first, typeAddresses.second);
+ }
+
+ /**
+ * @hide
+ * Set devices as role for capture preset.
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @param types all device types
+ * @param addresses all device addresses
+ * @return {@link #SUCCESS} if successfully set
+ */
+ private static native int setDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+ /**
+ * @hide
+ * Add devices as role for capture preset.
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @param devices the list of devices to be added as role for the given capture preset
+ * @return {@link #SUCCESS} if successfully add
+ */
+ public static int addDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+ if (devices.isEmpty()) {
+ return BAD_VALUE;
+ }
+ Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+ return addDevicesRoleForCapturePreset(
+ capturePreset, role, typeAddresses.first, typeAddresses.second);
+ }
+
+ /**
+ * @hide
+ * Add devices as role for capture preset.
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @param types all device types
+ * @param addresses all device addresses
+ * @return {@link #SUCCESS} if successfully set
+ */
+ private static native int addDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+ /**
+ * @hide
+ * Remove devices as role for the capture preset
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @param devices the devices to be removed
+ * @return {@link #SUCCESS} if successfully removed
+ */
+ public static int removeDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+ if (devices.isEmpty()) {
+ return BAD_VALUE;
+ }
+ Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+ return removeDevicesRoleForCapturePreset(
+ capturePreset, role, typeAddresses.first, typeAddresses.second);
+ }
+
+ /**
+ * @hide
+ * Remove devices as role for capture preset.
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @param types all device types
+ * @param addresses all device addresses
+ * @return {@link #SUCCESS} if successfully set
+ */
+ private static native int removeDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+ /**
+ * @hide
+ * Remove all devices as role for the capture preset
+ * @param capturePreset the capture preset to configure
+ * @param role the role of the devices
+ * @return {@link #SUCCESS} if successfully removed
+ */
+ public static native int clearDevicesRoleForCapturePreset(int capturePreset, int role);
+
+ /**
+ * @hide
+ * Query previously set devices as role for a capture preset
+ * @param capturePreset the capture preset to query for
+ * @param role the role of the devices
+ * @param devices a list that will contain the devices of role
+ * @return {@link #SUCCESS} if there is a preferred device and it was successfully retrieved
+ * and written to the array
+ */
+ public static native int getDevicesForRoleAndCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices);
+
// Items shared with audio service
/**
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index ef8b0ed..47e6000 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -17,6 +17,7 @@
package android.media;
import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioFocusInfo;
@@ -26,6 +27,7 @@
import android.media.IAudioFocusDispatcher;
import android.media.IAudioRoutesObserver;
import android.media.IAudioServerStateDispatcher;
+import android.media.ICapturePresetDevicesRoleDispatcher;
import android.media.IPlaybackConfigDispatcher;
import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
@@ -40,6 +42,7 @@
import android.media.audiopolicy.IAudioPolicyCallback;
import android.media.projection.IMediaProjection;
import android.net.Uri;
+import android.os.UserHandle;
import android.view.KeyEvent;
/**
@@ -307,4 +310,28 @@
// code via IAudioManager.h need to be added to the top section.
oneway void setMultiAudioFocusEnabled(in boolean enabled);
+
+ int setPreferredDevicesForCapturePreset(
+ in int capturePreset, in List<AudioDeviceAttributes> devices);
+
+ int clearPreferredDevicesForCapturePreset(in int capturePreset);
+
+ List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(in int capturePreset);
+
+ void registerCapturePresetDevicesRoleDispatcher(ICapturePresetDevicesRoleDispatcher dispatcher);
+
+ oneway void unregisterCapturePresetDevicesRoleDispatcher(
+ ICapturePresetDevicesRoleDispatcher dispatcher);
+
+ oneway void adjustStreamVolumeForUid(int streamType, int direction, int flags,
+ in String packageName, int uid, int pid, in UserHandle userHandle,
+ int targetSdkVersion);
+
+ oneway void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
+ in String packageName, int uid, int pid, in UserHandle userHandle,
+ int targetSdkVersion);
+
+ oneway void setStreamVolumeForUid(int streamType, int direction, int flags,
+ in String packageName, int uid, int pid, in UserHandle userHandle,
+ int targetSdkVersion);
}
diff --git a/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl b/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl
new file mode 100644
index 0000000..5e03e63
--- /dev/null
+++ b/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.media;
+
+import android.media.AudioDeviceAttributes;
+
+/**
+ * AIDL for AudioService to signal devices role for capture preset updates.
+ *
+ * {@hide}
+ */
+oneway interface ICapturePresetDevicesRoleDispatcher {
+
+ void dispatchDevicesRoleChanged(
+ int capturePreset, int role, in List<AudioDeviceAttributes> devices);
+
+}
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index a23191f..523a072 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -15,8 +15,10 @@
*/
package android.media;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.StringDef;
+import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.graphics.Bitmap;
@@ -738,15 +740,16 @@
/**
* Create a Builder using a {@link MediaMetadata} instance to set
- * initial values, but replace bitmaps with a scaled down copy if they
- * are larger than maxBitmapSize.
+ * initial values, but replace bitmaps with a scaled down copy if their width (or height)
+ * is larger than maxBitmapSize.
*
* @param source The original metadata to copy.
* @param maxBitmapSize The maximum height/width for bitmaps contained
* in the metadata.
* @hide
*/
- public Builder(MediaMetadata source, int maxBitmapSize) {
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public Builder(@NonNull MediaMetadata source, @IntRange(from = 1) int maxBitmapSize) {
this(source);
for (String key : mBundle.keySet()) {
Object value = mBundle.get(key);
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 36ae3ec..851c1ec 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -19,6 +19,8 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentProvider;
@@ -2092,6 +2094,8 @@
mOnInfoListener = null;
mOnVideoSizeChangedListener = null;
mOnTimedTextListener = null;
+ mOnImsRxNoticeListener = null;
+ mOnImsRxNoticeHandler = null;
synchronized (mTimeProviderLock) {
if (mTimeProvider != null) {
mTimeProvider.close();
@@ -3299,6 +3303,7 @@
private static final int MEDIA_META_DATA = 202;
private static final int MEDIA_DRM_INFO = 210;
private static final int MEDIA_TIME_DISCONTINUITY = 211;
+ private static final int MEDIA_IMS_RX_NOTICE = 300;
private static final int MEDIA_AUDIO_ROUTING_CHANGED = 10000;
private TimeProvider mTimeProvider;
@@ -3608,6 +3613,35 @@
}
return;
+ case MEDIA_IMS_RX_NOTICE:
+ final OnImsRxNoticeListener imsRxNoticeListener;
+ final Handler imsRxNoticeHandler;
+ imsRxNoticeListener = mOnImsRxNoticeListener;
+ imsRxNoticeHandler = mOnImsRxNoticeHandler;
+ if (imsRxNoticeListener == null) {
+ return;
+ }
+ if (msg.obj instanceof Parcel) {
+ Parcel parcel = (Parcel) msg.obj;
+ byte[] event;
+ try {
+ event = parcel.marshall();
+ } finally {
+ parcel.recycle();
+ }
+ if (imsRxNoticeHandler == null) {
+ imsRxNoticeListener.onImsRxNotice(mMediaPlayer, event);
+ } else {
+ imsRxNoticeHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ imsRxNoticeListener.onImsRxNotice(mMediaPlayer, event);
+ }
+ });
+ }
+ }
+ return;
+
default:
Log.e(TAG, "Unknown message type " + msg.what);
return;
@@ -4048,6 +4082,146 @@
}
/**
+ * Interface definition of a callback to be invoked when
+ * IMS Rx connection has a notice.
+ *
+ * @see MediaPlayer.setOnImsRxNoticeListener
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface OnImsRxNoticeListener
+ {
+ /**
+ * Called to indicate an IMS event noticed from native media frameworks.
+ * <p></p>
+ * Basic format. All TYPE and ARG are 4 bytes unsigned integer in native byte order.
+ * <pre>{@code
+ * 0 4 8 12
+ * +----------------+---------------+----------------+----------------+
+ * | TYPE | ARG1 | ARG2 | ARG3 |
+ * +----------------+---------------+----------------+----------------+
+ * | ARG4 | ARG5 | ...
+ * +----------------+---------------+-------------
+ * 16 20 24
+ *
+ *
+ * TYPE 100 - A notice of the first rtp packet received. No ARGs.
+ * 0
+ * +----------------+
+ * | 100 |
+ * +----------------+
+ *
+ *
+ * TYPE 101 - A notice of the first rtcp packet received. No ARGs.
+ * 0
+ * +----------------+
+ * | 101 |
+ * +----------------+
+ *
+ *
+ * TYPE 102 - A periodic report of a RTP statistics.
+ * TYPE 103 - An emergency report when serious packet loss has been detected
+ * in between TYPE 102 events.
+ * 0 4 8 12
+ * +----------------+---------------+----------------+----------------+
+ * | 102 or 103 | FB type=0 | Bitrate | Top #.Seq |
+ * +----------------+---------------+----------------+----------------+
+ * | Base #.Seq |Prev Expt #.Pkt| Recv #.Pkt |Prev Recv #.Pkt |
+ * +----------------+---------------+----------------+----------------+
+ * Feedback (FB) type
+ * - always 0.
+ * Bitrate
+ * - amount of data received in this period.
+ * Top number of sequence
+ * - highest RTP sequence number received in this period.
+ * - monotonically increasing value.
+ * Base number of sequence
+ * - the first RTP sequence number of the media stream.
+ * Previous Expected number of Packets
+ * - expected count of packets received in the previous report.
+ * Received number of packet
+ * - actual count of packets received in this report.
+ * Previous Received number of packet
+ * - actual count of packets received in the previous report.
+ *
+ *
+ * TYPE 205 - Transport layer Feedback message. (RFC-5104 Sec.4.2)
+ * 0 4 8 12
+ * +----------------+---------------+----------------+----------------+
+ * | 205 | SSRC | FB type(1 or 3)| value |
+ * +----------------+---------------+----------------+----------------+
+ * SSRC
+ * - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
+ * Feedback (FB) type: determines the type of the event.
+ * - if 1, we received a NACK request from the remote side.
+ * - if 3, we received a TMMBR (Temporary Maximum Media Stream Bit Rate Request) from
+ * the remote side.
+ * Value: the FCI (Feedback Control Information) depending on the value of FB type
+ * - if FB type is 1, the Generic NACK as specified in RFC-4585 Sec.6.2.1
+ * - if FB type is 3, the TMMBR as specified in RFC-5104 Sec.4.2.1.1
+ *
+ *
+ * TYPE 206 - Payload-specific Feedback message. (RFC-5104 Sec.4.3)
+ * 0 4 8
+ * +----------------+---------------+----------------+
+ * | 206 | SSRC | FB type(1 or 4)|
+ * +----------------+---------------+----------------+
+ * SSRC
+ * - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
+ * Feedback (FB) type: determines the type of the event.
+ * - if 1, we received a PLI request from the remote side.
+ * - if 4, we received a FIR request from the remote side.
+ *
+ *
+ * TYPE 300 - CVO (RTP Extension) message.
+ * 0 4
+ * +----------------+---------------+
+ * | 101 | value |
+ * +----------------+---------------+
+ * value
+ * - clockwise rotation degrees of a received video (6.2.3 of 3GPP R12 TS 26.114).
+ * - can be 0 (degree 0), 1 (degree 90), 2 (degree 180) or 3 (degree 270).
+ *
+ *
+ * TYPE 400 - Socket failed during receive. No ARGs.
+ * 0
+ * +----------------+
+ * | 400 |
+ * +----------------+
+ * }</pre>
+ *
+ * @param mp the {@code MediaPlayer} associated with this callback.
+ * @param event an IMS media event serialized as byte[] array.
+ */
+ void onImsRxNotice(@NonNull MediaPlayer mp, @NonNull byte[] event);
+ }
+
+ /**
+ * Register a callback to be invoked when IMS Rx connection has a notice.
+ * The callback required if mediaplayer configured for RTPSource by
+ * MediaPlayer.setDataSource(String8 rtpParams) of mediaplayer.h
+ *
+ * @see MediaPlayer.OnImsRxNoticeListener
+ *
+ * @param listener the callback that will be run
+ * @param handler Specifies Handler object for the thread on which to execute
+ * the callback. If null, the handler on the main looper will be used.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission("android.permission.BIND_IMS_SERVICE")
+ public void setOnImsRxNoticeListener(
+ @Nullable OnImsRxNoticeListener listener, @Nullable Handler handler) {
+ mOnImsRxNoticeListener = listener;
+ mOnImsRxNoticeHandler = handler;
+ }
+
+ private OnImsRxNoticeListener mOnImsRxNoticeListener;
+ private Handler mOnImsRxNoticeHandler;
+
+ /**
* Register a callback to be invoked when a selected track has timed metadata available.
* <p>
* Currently only HTTP live streaming data URI's embedded with timed ID3 tags generates
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 4198d79..1db02be 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -404,6 +404,32 @@
}
}
+ /**
+ * @hide
+ * @param source An audio source to test
+ * @return true if the source is a valid one
+ */
+ public static boolean isValidAudioSource(int source) {
+ switch(source) {
+ case AudioSource.MIC:
+ case AudioSource.VOICE_UPLINK:
+ case AudioSource.VOICE_DOWNLINK:
+ case AudioSource.VOICE_CALL:
+ case AudioSource.CAMCORDER:
+ case AudioSource.VOICE_RECOGNITION:
+ case AudioSource.VOICE_COMMUNICATION:
+ case AudioSource.REMOTE_SUBMIX:
+ case AudioSource.UNPROCESSED:
+ case AudioSource.VOICE_PERFORMANCE:
+ case AudioSource.ECHO_REFERENCE:
+ case AudioSource.RADIO_TUNER:
+ case AudioSource.HOTWORD:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/** @hide */
public static final String toLogFriendlyAudioSource(int source) {
switch(source) {
diff --git a/media/java/android/media/MediaTranscodeManager.java b/media/java/android/media/MediaTranscodeManager.java
index cf61152..451677f 100644
--- a/media/java/android/media/MediaTranscodeManager.java
+++ b/media/java/android/media/MediaTranscodeManager.java
@@ -27,6 +27,7 @@
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
+import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -102,7 +103,7 @@
*/
@TestApi
@SystemApi
-public final class MediaTranscodeManager implements AutoCloseable {
+public final class MediaTranscodeManager {
private static final String TAG = "MediaTranscodeManager";
private static final String MEDIA_TRANSCODING_SERVICE = "media.transcoding";
@@ -131,28 +132,6 @@
*/
public static final int TRANSCODING_TYPE_IMAGE = 2;
- @Override
- public void close() {
- release();
- }
-
- /**
- * Releases the MediaTranscodeManager.
- */
- private void release() {
- synchronized (mLock) {
- try {
- if (mTranscodingClient != null) {
- mTranscodingClient.unregister();
- }
- } catch (Exception ex) {
- Log.e(TAG, "Failed to unregister the client");
- } finally {
- mTranscodingClient = null;
- }
- }
- }
-
/** @hide */
@IntDef(prefix = {"TRANSCODING_TYPE_"}, value = {
TRANSCODING_TYPE_UNKNOWN,
@@ -182,6 +161,7 @@
* <p>Jobs with PRIORITY_OFFLINE will be scheduled behind PRIORITY_REALTIME. Always set to
* PRIORITY_OFFLINE if client does not need the result as soon as possible and could accept
* delay of the transcoding result.
+ * @hide
* TODO(hkuang): Add more description of this when priority is finalized.
*/
public static final int PRIORITY_OFFLINE = 2;
@@ -287,7 +267,7 @@
// Notifies client the progress update.
if (job.mProgressUpdateExecutor != null && job.mProgressUpdateListener != null) {
job.mProgressUpdateExecutor.execute(
- () -> job.mProgressUpdateListener.onProgressUpdate(newProgress));
+ () -> job.mProgressUpdateListener.onProgressUpdate(job, newProgress));
}
}
}
@@ -503,11 +483,6 @@
mTranscodingClient = registerClient(service);
}
- @Override
- protected void finalize() {
- release();
- }
-
public static final class TranscodingRequest {
/** Uri of the source media file. */
private @NonNull Uri mSourceUri;
@@ -840,6 +815,141 @@
return new TranscodingRequest(this);
}
}
+
+ /**
+ * Helper class for deciding if transcoding is needed, and if so, the track
+ * formats to use.
+ */
+ public static class MediaFormatResolver {
+ private static final int BIT_RATE = 20000000; // 20Mbps
+
+ private MediaFormat mSrcVideoFormatHint;
+ private MediaFormat mSrcAudioFormatHint;
+ private Bundle mClientCaps;
+
+ /**
+ * A key describing whether the client supports HEVC-encoded video.
+ *
+ * The value associated with this key is a boolean. If unspecified, it's up to
+ * the MediaFormatResolver to determine the default.
+ *
+ * @see #setClientCapabilities(Bundle)
+ */
+ public static final String CAPS_SUPPORTS_HEVC = "support-hevc";
+
+ /**
+ * Sets the abilities of the client consuming the media. Must be called
+ * before {@link #shouldTranscode()} or {@link #resolveVideoFormat()}.
+ *
+ * @param clientCaps A Bundle object containing the client's capabilities, such as
+ * {@link #CAPS_SUPPORTS_HEVC}.
+ * @return the same VideoFormatResolver instance.
+ * @hide
+ */
+ @NonNull
+ public MediaFormatResolver setClientCapabilities(@NonNull Bundle clientCaps) {
+ mClientCaps = clientCaps;
+ return this;
+ }
+
+ /**
+ * Sets the video format hint about the source. Must be called before
+ * {@link #shouldTranscode()} or {@link #resolveVideoFormat()}.
+ *
+ * @param format A MediaFormat object containing information about the source's
+ * video track format that could affect the transcoding decision.
+ * Such information could include video codec types, color spaces,
+ * whether special format info (eg. slow-motion markers) are present,
+ * etc.. If a particular information is not present, it will not be
+ * used to make the decision.
+ * @return the same MediaFormatResolver instance.
+ */
+ @NonNull
+ public MediaFormatResolver setSourceVideoFormatHint(@NonNull MediaFormat format) {
+ mSrcVideoFormatHint = format;
+ return this;
+ }
+
+ /**
+ * Sets the audio format hint about the source.
+ *
+ * @param format A MediaFormat object containing information about the source's
+ * audio track format that could affect the transcoding decision.
+ * @return the same MediaFormatResolver instance.
+ * @hide
+ */
+ @NonNull
+ public MediaFormatResolver setSourceAudioFormatHint(@NonNull MediaFormat format) {
+ mSrcAudioFormatHint = format;
+ return this;
+ }
+
+ /**
+ * Returns whether the source content should be transcoded.
+ *
+ * @return true if the source should be transcoded.
+ * @throws UnsupportedOperationException if {@link #setClientCapabilities(Bundle)}
+ * or {@link #setSourceVideoFormatHint(MediaFormat)} was not called.
+ */
+ public boolean shouldTranscode() {
+ if (mClientCaps == null) {
+ throw new UnsupportedOperationException(
+ "Client caps must be set!");
+ }
+ // Video src hint must be provided, audio src hint is not used right now.
+ if (mSrcVideoFormatHint == null) {
+ throw new UnsupportedOperationException(
+ "Source video format hint must be set!");
+ }
+ boolean supportHevc = mClientCaps.getBoolean(CAPS_SUPPORTS_HEVC, false);
+ if (!supportHevc && MediaFormat.MIMETYPE_VIDEO_HEVC.equals(
+ mSrcVideoFormatHint.getString(MediaFormat.KEY_MIME))) {
+ return true;
+ }
+ // TODO: add more checks as needed below.
+ return false;
+ }
+
+ /**
+ * Retrieves the video track format to be used on
+ * {@link Builder#setVideoTrackFormat(MediaFormat)} for this configuration.
+ *
+ * @return the video track format to be used if transcoding should be performed,
+ * and null otherwise.
+ * @throws UnsupportedOperationException if {@link #setClientCapabilities(Bundle)}
+ * or {@link #setSourceVideoFormatHint(MediaFormat)} was not called.
+ */
+ @Nullable
+ public MediaFormat resolveVideoFormat() {
+ if (!shouldTranscode()) {
+ return null;
+ }
+ // TODO(hkuang): Only modified the video codec type, and use fixed bitrate for now.
+ // May switch to transcoding profile when it's available.
+ MediaFormat videoTrackFormat = new MediaFormat(mSrcVideoFormatHint);
+ videoTrackFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
+ videoTrackFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
+ return videoTrackFormat;
+ }
+
+ /**
+ * Retrieves the audio track format to be used for transcoding.
+ *
+ * @return the audio track format to be used if transcoding should be performed, and
+ * null otherwise.
+ * @throws UnsupportedOperationException if {@link #setClientCapabilities(Bundle)}
+ * or {@link #setSourceVideoFormatHint(MediaFormat)} was not called.
+ * @hide
+ */
+ @Nullable
+ public MediaFormat resolveAudioFormat() {
+ if (!shouldTranscode()) {
+ return null;
+ }
+ // Audio transcoding is not supported yet, always return null.
+ return null;
+ }
+ }
}
/**
@@ -892,9 +1002,12 @@
/**
* Called when the progress changes. The progress is in percentage between 0 and 1,
* where 0 means that the job has not yet started and 100 means that it has finished.
+ *
+ * @param job The job associated with the progress.
* @param progress The new progress ranging from 0 ~ 100 inclusive.
*/
- void onProgressUpdate(@IntRange(from = 0, to = 100) int progress);
+ void onProgressUpdate(@NonNull TranscodingJob job,
+ @IntRange(from = 0, to = 100) int progress);
}
private final ITranscodingClient mJobOwner;
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index aa57233..24dacc4 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -16,8 +16,11 @@
package android.media.session;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -27,6 +30,7 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.media.VolumeProvider.ControlType;
import android.media.session.MediaSession.QueueItem;
import android.net.Uri;
import android.os.Bundle;
@@ -41,6 +45,8 @@
import android.util.Log;
import android.view.KeyEvent;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -950,6 +956,14 @@
* this session.
*/
public static final class PlaybackInfo implements Parcelable {
+
+ /**
+ * @hide
+ */
+ @IntDef({PLAYBACK_TYPE_LOCAL, PLAYBACK_TYPE_REMOTE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PlaybackType {}
+
/**
* The session uses local playback.
*/
@@ -959,7 +973,7 @@
*/
public static final int PLAYBACK_TYPE_REMOTE = 2;
- private final int mVolumeType;
+ private final int mPlaybackType;
private final int mVolumeControl;
private final int mMaxVolume;
private final int mCurrentVolume;
@@ -967,27 +981,35 @@
private final String mVolumeControlId;
/**
+ * Creates a new playback info.
+ *
+ * @param playbackType The playback type. Should be {@link #PLAYBACK_TYPE_LOCAL} or
+ * {@link #PLAYBACK_TYPE_REMOTE}
+ * @param volumeControl The volume control. Should be one of:
+ * {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE},
+ * {@link VolumeProvider#VOLUME_CONTROL_RELATIVE}, and
+ * {@link VolumeProvider#VOLUME_CONTROL_FIXED}.
+ * @param maxVolume The max volume. Should be equal or greater than zero.
+ * @param currentVolume The current volume. Should be in the interval [0, maxVolume].
+ * @param audioAttrs The audio attributes for this playback. Should not be null.
+ * @param volumeControlId The volume control ID. This is used for matching
+ * {@link RoutingSessionInfo} and {@link MediaSession}.
* @hide
*/
- public PlaybackInfo(int type, int control, int max, int current, AudioAttributes attrs) {
- this(type, control, max, current, attrs, null);
- }
-
- /**
- * @hide
- */
- public PlaybackInfo(int type, int control, int max, int current, AudioAttributes attrs,
- String volumeControlId) {
- mVolumeType = type;
- mVolumeControl = control;
- mMaxVolume = max;
- mCurrentVolume = current;
- mAudioAttrs = attrs;
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public PlaybackInfo(@PlaybackType int playbackType, @ControlType int volumeControl,
+ @IntRange(from = 0) int maxVolume, @IntRange(from = 0) int currentVolume,
+ @NonNull AudioAttributes audioAttrs, @Nullable String volumeControlId) {
+ mPlaybackType = playbackType;
+ mVolumeControl = volumeControl;
+ mMaxVolume = maxVolume;
+ mCurrentVolume = currentVolume;
+ mAudioAttrs = audioAttrs;
mVolumeControlId = volumeControlId;
}
PlaybackInfo(Parcel in) {
- mVolumeType = in.readInt();
+ mPlaybackType = in.readInt();
mVolumeControl = in.readInt();
mMaxVolume = in.readInt();
mCurrentVolume = in.readInt();
@@ -1005,7 +1027,7 @@
* @return The type of playback this session is using.
*/
public int getPlaybackType() {
- return mVolumeType;
+ return mPlaybackType;
}
/**
@@ -1016,8 +1038,7 @@
* <li>{@link VolumeProvider#VOLUME_CONTROL_FIXED}</li>
* </ul>
*
- * @return The type of volume control that may be used with this
- * session.
+ * @return The type of volume control that may be used with this session.
*/
public int getVolumeControl() {
return mVolumeControl;
@@ -1075,7 +1096,7 @@
@Override
public String toString() {
- return "volumeType=" + mVolumeType + ", volumeControl=" + mVolumeControl
+ return "playbackType=" + mPlaybackType + ", volumeControlType=" + mVolumeControl
+ ", maxVolume=" + mMaxVolume + ", currentVolume=" + mCurrentVolume
+ ", audioAttrs=" + mAudioAttrs + ", volumeControlId=" + mVolumeControlId;
}
@@ -1087,7 +1108,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mVolumeType);
+ dest.writeInt(mPlaybackType);
dest.writeInt(mVolumeControl);
dest.writeInt(mMaxVolume);
dest.writeInt(mCurrentVolume);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 549e793..624607b 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -828,9 +828,10 @@
}
/**
- * Gets the UID of this token.
+ * Gets the UID of the application that created the media session.
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public int getUid() {
return mUid;
}
diff --git a/media/tests/MediaTranscodingTest/build_and_run_unit_tests.sh b/media/tests/MediaTranscodingTest/build_and_run_unit_tests.sh
index 43db353..c8fb3a6 100644
--- a/media/tests/MediaTranscodingTest/build_and_run_unit_tests.sh
+++ b/media/tests/MediaTranscodingTest/build_and_run_unit_tests.sh
@@ -31,6 +31,9 @@
adb push --sync $file /data/user/0/com.android.mediatranscodingtest/cache/
done
-echo "[==========] running real transcoding tests"
+echo "[==========] running MediaTranscodeManagerTest"
adb shell am instrument -e class com.android.mediatranscodingtest.MediaTranscodeManagerTest -w com.android.mediatranscodingtest/.MediaTranscodingTestRunner
+echo "[==========] running MediaTranscodeManagerDiedTest"
+adb shell am instrument -e class com.android.mediatranscodingtest.MediaTranscodeManagerDiedTest -w com.android.mediatranscodingtest/.MediaTranscodingTestRunner
+
diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerDiedTest.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerDiedTest.java
new file mode 100644
index 0000000..f00c14d
--- /dev/null
+++ b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerDiedTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2020 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.mediatranscodingtest;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.media.MediaFormat;
+import android.media.MediaTranscodeManager;
+import android.media.MediaTranscodeManager.TranscodingJob;
+import android.media.MediaTranscodeManager.TranscodingRequest;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
+
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/*
+ * Service died tests for MediaTranscodeManager in the media framework.
+ *
+ * To run this test suite:
+ make frameworks/base/media/tests/MediaTranscodingTest
+ make mediatranscodingtest
+
+ adb install -r testcases/mediatranscodingtest/arm64/mediatranscodingtest.apk
+
+ adb shell am instrument -e class \
+ com.android.mediatranscodingtest.MediaTranscodeManagerDiedTest \
+ -w com.android.mediatranscodingtest/.MediaTranscodingTestRunner
+ *
+ */
+public class MediaTranscodeManagerDiedTest
+ extends ActivityInstrumentationTestCase2<MediaTranscodingTest> {
+ private static final String TAG = "MediaTranscodeManagerDiedTest";
+ /** The time to wait for the transcode operation to complete before failing the test. */
+ private static final int TRANSCODE_TIMEOUT_SECONDS = 10;
+
+ /** Maximum number of retry to connect to the service. */
+ private static final int CONNECT_SERVICE_RETRY_COUNT = 100;
+
+ /** Interval between trying to reconnect to the service. */
+ private static final int INTERVAL_CONNECT_SERVICE_RETRY_MS = 40;
+
+ private Context mContext;
+ private MediaTranscodeManager mMediaTranscodeManager = null;
+ private Uri mSourceHEVCVideoUri = null;
+ private Uri mSourceAVCVideoUri = null;
+ private Uri mDestinationUri = null;
+
+ // Setting for transcoding to H.264.
+ private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
+ private static final int BIT_RATE = 20000000; // 20Mbps
+ private static final int WIDTH = 1920;
+ private static final int HEIGHT = 1080;
+
+ public MediaTranscodeManagerDiedTest() {
+ super("com.android.MediaTranscodeManagerTest", MediaTranscodingTest.class);
+ }
+
+ // Copy the resource to cache.
+ private Uri resourceToUri(Context context, int resId, String name) throws IOException {
+ Uri resUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(context.getResources().getResourcePackageName(resId))
+ .appendPath(context.getResources().getResourceTypeName(resId))
+ .appendPath(context.getResources().getResourceEntryName(resId))
+ .build();
+
+ Uri cacheUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ + mContext.getCacheDir().getAbsolutePath() + "/" + name);
+
+ InputStream is = mContext.getResources().openRawResource(resId);
+ OutputStream os = mContext.getContentResolver().openOutputStream(cacheUri);
+
+ FileUtils.copy(is, os);
+
+ return cacheUri;
+ }
+
+ private static Uri generateNewUri(Context context, String filename) {
+ File outFile = new File(context.getExternalCacheDir(), filename);
+ return Uri.fromFile(outFile);
+ }
+
+ /**
+ * Creates a MediaFormat with the basic set of values.
+ */
+ private static MediaFormat createMediaFormat() {
+ MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, WIDTH, HEIGHT);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
+ return format;
+ }
+
+ private MediaTranscodeManager getManager() {
+ for (int count = 1; count <= CONNECT_SERVICE_RETRY_COUNT; count++) {
+ Log.d(TAG, "Trying to connect to service. Try count: " + count);
+ MediaTranscodeManager manager = mContext.getSystemService(MediaTranscodeManager.class);
+ if (manager != null) {
+ return manager;
+ }
+ try {
+ // Sleep a bit before retry.
+ Thread.sleep(INTERVAL_CONNECT_SERVICE_RETRY_MS);
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+
+ throw new UnsupportedOperationException("Failed to acquire MediaTranscodeManager");
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ Log.d(TAG, "setUp");
+ super.setUp();
+
+ mContext = getInstrumentation().getContext();
+ mMediaTranscodeManager = getManager();
+ assertNotNull(mMediaTranscodeManager);
+ androidx.test.InstrumentationRegistry.registerInstance(getInstrumentation(), new Bundle());
+
+ // Setup source HEVC file uri.
+ mSourceHEVCVideoUri = resourceToUri(mContext, R.raw.VideoOnlyHEVC, "VideoOnlyHEVC.mp4");
+
+ // Setup source AVC file uri.
+ mSourceAVCVideoUri = resourceToUri(mContext, R.raw.VideoOnlyAVC,
+ "VideoOnlyAVC.mp4");
+
+ // Setup destination file.
+ mDestinationUri = generateNewUri(mContext, "transcoded.mp4");
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // [[ $(adb shell whoami) == "root" ]]
+ private boolean checkIfRoot() {
+ try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation()
+ .executeShellCommand("whoami");
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(result.getFileDescriptor())))) {
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (line.contains("root")) {
+ return true;
+ }
+ }
+ } catch (IOException ie) {
+ return false;
+ }
+ return false;
+ }
+
+ private String executeShellCommand(String cmd) throws Exception {
+ return UiDevice.getInstance(
+ InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
+ }
+
+ @Test
+ public void testHandleTranscoderServiceDied() throws Exception {
+ if (!checkIfRoot()) {
+ throw new AssertionError("must be root to run this test; try adb root?");
+ }
+
+ Semaphore transcodeCompleteSemaphore = new Semaphore(0);
+ Semaphore jobStartedSemaphore = new Semaphore(0);
+
+ // Transcode a 15 seconds video, so that the transcoding is not finished when we kill the
+ // service.
+ Uri srcUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ + mContext.getCacheDir().getAbsolutePath() + "/longtest_15s.mp4");
+ Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ + mContext.getCacheDir().getAbsolutePath() + "/HevcTranscode.mp4");
+
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(mSourceHEVCVideoUri)
+ .setDestinationUri(destinationUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .build();
+ Executor listenerExecutor = Executors.newSingleThreadExecutor();
+
+ Log.i(TAG, "transcoding to " + createMediaFormat());
+
+ TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
+ transcodingJob -> {
+ Log.d(TAG, "Transcoding completed with result: " + transcodingJob.getResult());
+ transcodeCompleteSemaphore.release();
+ });
+ assertNotNull(job);
+
+ AtomicInteger progressUpdateCount = new AtomicInteger(0);
+
+ // Set progress update executor and use the same executor as result listener.
+ job.setOnProgressUpdateListener(listenerExecutor,
+ new TranscodingJob.OnProgressUpdateListener() {
+ @Override
+ public void onProgressUpdate(TranscodingJob job, int newProgress) {
+ if (newProgress > 0) {
+ jobStartedSemaphore.release();
+ }
+ }
+ });
+
+ // Wait for progress update so the job is in running state.
+ jobStartedSemaphore.tryAcquire(TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ assertTrue("Job is not running", job.getStatus() == TranscodingJob.STATUS_RUNNING);
+
+ // Kills the service and expects receiving failure of the job.
+ executeShellCommand("pkill -f media.transcoding");
+
+ Log.d(TAG, "testMediaTranscodeManager - Waiting for transcode result.");
+ boolean finishedOnTime = transcodeCompleteSemaphore.tryAcquire(
+ TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ assertTrue("Invalid job status", job.getStatus() == TranscodingJob.STATUS_FINISHED);
+ assertTrue("Invalid job result", job.getResult()== TranscodingJob.RESULT_ERROR);
+ }
+}
+
diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java
index a707c7a..33d6d64 100644
--- a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java
+++ b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java
@@ -16,12 +16,16 @@
package com.android.mediatranscodingtest;
+import static org.testng.Assert.assertThrows;
+
import android.content.ContentResolver;
import android.content.Context;
import android.media.MediaFormat;
import android.media.MediaTranscodeManager;
import android.media.MediaTranscodeManager.TranscodingJob;
import android.media.MediaTranscodeManager.TranscodingRequest;
+import android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver;
+import android.media.TranscodingTestConfig;
import android.net.Uri;
import android.os.Bundle;
import android.os.FileUtils;
@@ -180,6 +184,227 @@
super.tearDown();
}
+
+ /**
+ * Verify that setting null destination uri will throw exception.
+ */
+ @Test
+ public void testCreateTranscodingRequestWithNullDestinationUri() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(mSourceHEVCVideoUri)
+ .setDestinationUri(null)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .build();
+ });
+ }
+
+ /**
+ * Verify that setting null source uri will throw exception.
+ */
+ @Test
+ public void testCreateTranscodingRequestWithNullSourceUri() throws Exception {
+ assertThrows(IllegalArgumentException.class, () -> {
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(null)
+ .setDestinationUri(mDestinationUri)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .build();
+ });
+ }
+
+ /**
+ * Verify that not setting source uri will throw exception.
+ */
+ @Test
+ public void testCreateTranscodingRequestWithoutSourceUri() throws Exception {
+ assertThrows(UnsupportedOperationException.class, () -> {
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setDestinationUri(mDestinationUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .build();
+ });
+ }
+
+ /**
+ * Verify that not setting destination uri will throw exception.
+ */
+ @Test
+ public void testCreateTranscodingRequestWithoutDestinationUri() throws Exception {
+ assertThrows(UnsupportedOperationException.class, () -> {
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(mSourceHEVCVideoUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .build();
+ });
+ }
+
+ /**
+ * Verify that setting image transcoding mode will throw exception.
+ */
+ @Test
+ public void testCreateTranscodingRequestWithUnsupportedMode() throws Exception {
+ assertThrows(UnsupportedOperationException.class, () -> {
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(mSourceHEVCVideoUri)
+ .setDestinationUri(mDestinationUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_IMAGE)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .build();
+ });
+ }
+
+ /**
+ * Verify that setting video transcoding without setting video format will throw exception.
+ */
+ @Test
+ public void testCreateTranscodingRequestWithoutVideoFormat() throws Exception {
+ assertThrows(UnsupportedOperationException.class, () -> {
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(mSourceHEVCVideoUri)
+ .setDestinationUri(mDestinationUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .build();
+ });
+ }
+
+ void testTranscodingWithExpectResult(Uri srcUri, Uri dstUri, int expectedResult)
+ throws Exception {
+ Semaphore transcodeCompleteSemaphore = new Semaphore(0);
+ TranscodingTestConfig testConfig = new TranscodingTestConfig();
+ testConfig.passThroughMode = true;
+ testConfig.processingTotalTimeMs = 300; // minimum time spent on transcoding.
+
+ TranscodingRequest request =
+ new TranscodingRequest.Builder()
+ .setSourceUri(srcUri)
+ .setDestinationUri(dstUri)
+ .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+ .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+ .setVideoTrackFormat(createMediaFormat())
+ .setTestConfig(testConfig)
+ .build();
+ Executor listenerExecutor = Executors.newSingleThreadExecutor();
+
+ TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
+ transcodingJob -> {
+ Log.d(TAG, "Transcoding completed with result: " + transcodingJob.getResult());
+ assertTrue("Transcoding should failed.",
+ transcodingJob.getResult() == expectedResult);
+ transcodeCompleteSemaphore.release();
+ });
+ assertNotNull(job);
+
+ if (job != null) {
+ Log.d(TAG, "testMediaTranscodeManager - Waiting for transcode to complete.");
+ boolean finishedOnTime = transcodeCompleteSemaphore.tryAcquire(
+ TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ assertTrue("Transcode failed to complete in time.", finishedOnTime);
+ }
+
+ if (expectedResult == TranscodingJob.RESULT_SUCCESS) {
+ // Checks the destination file get generated.
+ File file = new File(dstUri.getPath());
+ assertTrue("Failed to create destination file", file.exists());
+
+ // Removes the file.
+ file.delete();
+ }
+ }
+
+ // Tests transcoding from invalid a invalid and expects failure.
+ @Test
+ public void testTranscodingInvalidSrcUri() throws Exception {
+ Log.d(TAG, "Starting: testMediaTranscodeManager");
+
+ Uri invalidSrcUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
+ + mContext.getPackageName() + "/source.mp4");
+ Log.d(TAG, "Transcoding from source: " + invalidSrcUri);
+
+ // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
+ // The full path of this file is:
+ // /data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
+ Uri destinationUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
+ + mContext.getPackageName() + "/temp.mp4");
+ Log.d(TAG, "Transcoding to destination: " + destinationUri);
+
+ testTranscodingWithExpectResult(invalidSrcUri, destinationUri, TranscodingJob.RESULT_ERROR);
+ }
+
+ // Tests transcoding to a uri in res folder and expects failure as we could not write to res
+ // folder.
+ @Test
+ public void testTranscodingToResFolder() throws Exception {
+ Log.d(TAG, "Starting: testMediaTranscodeManager");
+
+ // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
+ // The full path of this file is:
+ // /data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
+ Uri destinationUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
+ + mContext.getPackageName() + "/temp.mp4");
+ Log.d(TAG, "Transcoding to destination: " + destinationUri);
+
+ testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
+ TranscodingJob.RESULT_ERROR);
+ }
+
+ // Tests transcoding to a uri in internal storage folder and expects success.
+ @Test
+ public void testTranscodingToCacheDir() throws Exception {
+ Log.d(TAG, "Starting: testMediaTranscodeManager");
+
+ // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
+ // The full path of this file is:
+ // /data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
+ Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ + mContext.getCacheDir().getAbsolutePath() + "/temp.mp4");
+
+ testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
+ TranscodingJob.RESULT_SUCCESS);
+ }
+
+ // Tests transcoding to a uri in internal files directory and expects success.
+ @Test
+ public void testTranscodingToInternalFilesDir() throws Exception {
+ Log.d(TAG, "Starting: testMediaTranscodeManager");
+
+ // Create a file Uri:
+ // file:///storage/emulated/0/Android/data/com.android.mediatranscodingtest/files/temp.mp4
+ Uri destinationUri = Uri.fromFile(new File(mContext.getFilesDir(), "temp.mp4"));
+ Log.i(TAG, "Transcoding to files dir: " + destinationUri);
+
+ testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
+ TranscodingJob.RESULT_SUCCESS);
+ }
+
+ // Tests transcoding to a uri in external files directory and expects success.
+ @Test
+ public void testTranscodingToExternalFilesDir() throws Exception {
+ Log.d(TAG, "Starting: testMediaTranscodeManager");
+
+ // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/files/temp.mp4
+ Uri destinationUri = Uri.fromFile(new File(mContext.getExternalFilesDir(null), "temp.mp4"));
+ Log.i(TAG, "Transcoding to files dir: " + destinationUri);
+
+ testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
+ TranscodingJob.RESULT_SUCCESS);
+ }
+
@Test
public void testTranscodingFromHevcToAvc() throws Exception {
Semaphore transcodeCompleteSemaphore = new Semaphore(0);
@@ -190,17 +415,27 @@
Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
+ mContext.getCacheDir().getAbsolutePath() + "/HevcTranscode.mp4");
+ Bundle clientCaps = new Bundle();
+ clientCaps.putBoolean(MediaFormatResolver.CAPS_SUPPORTS_HEVC, false);
+ MediaFormatResolver resolver = new MediaFormatResolver()
+ .setSourceVideoFormatHint(MediaFormat.createVideoFormat(
+ MediaFormat.MIMETYPE_VIDEO_HEVC, WIDTH, HEIGHT))
+ .setClientCapabilities(clientCaps);
+ assertTrue(resolver.shouldTranscode());
+ MediaFormat videoTrackFormat = resolver.resolveVideoFormat();
+ assertNotNull(videoTrackFormat);
+
TranscodingRequest request =
new TranscodingRequest.Builder()
.setSourceUri(mSourceHEVCVideoUri)
.setDestinationUri(destinationUri)
.setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
.setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
+ .setVideoTrackFormat(videoTrackFormat)
.build();
Executor listenerExecutor = Executors.newSingleThreadExecutor();
- Log.i(TAG, "transcoding to " + createMediaFormat());
+ Log.i(TAG, "transcoding to " + videoTrackFormat);
TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
transcodingJob -> {
@@ -308,7 +543,7 @@
int mPreviousProgress = 0;
@Override
- public void onProgressUpdate(int newProgress) {
+ public void onProgressUpdate(TranscodingJob job, int newProgress) {
assertTrue("Invalid proress update", newProgress > mPreviousProgress);
assertTrue("Invalid proress update", newProgress <= 100);
if (newProgress > 0) {
@@ -354,73 +589,5 @@
return UiDevice.getInstance(
InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
}
-
- @Test
- public void testHandleTranscoderServiceDied() throws Exception {
- try {
- if (!checkIfRoot()) {
- throw new AssertionError("must be root to run this test; try adb root?");
- } else {
- Log.i(TAG, "Device is root");
- }
- } catch (IOException e) {
- throw new AssertionError(e);
- }
-
- Semaphore transcodeCompleteSemaphore = new Semaphore(0);
- Semaphore jobStartedSemaphore = new Semaphore(0);
-
- // Transcode a 15 seconds video, so that the transcoding is not finished when we kill the
- // service.
- Uri srcUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
- + mContext.getCacheDir().getAbsolutePath() + "/longtest_15s.mp4");
- Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
- + mContext.getCacheDir().getAbsolutePath() + "/HevcTranscode.mp4");
-
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(mSourceHEVCVideoUri)
- .setDestinationUri(destinationUri)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
- .build();
- Executor listenerExecutor = Executors.newSingleThreadExecutor();
-
- Log.i(TAG, "transcoding to " + createMediaFormat());
-
- TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
- transcodingJob -> {
- Log.d(TAG, "Transcoding completed with result: " + transcodingJob.getResult());
- assertEquals(transcodingJob.getResult(), TranscodingJob.RESULT_ERROR);
- transcodeCompleteSemaphore.release();
- });
- assertNotNull(job);
-
- AtomicInteger progressUpdateCount = new AtomicInteger(0);
-
- // Set progress update executor and use the same executor as result listener.
- job.setOnProgressUpdateListener(listenerExecutor,
- new TranscodingJob.OnProgressUpdateListener() {
- @Override
- public void onProgressUpdate(int newProgress) {
- if (newProgress > 0) {
- jobStartedSemaphore.release();
- }
- }
- });
-
- // Wait for progress update so the job is in running state.
- jobStartedSemaphore.tryAcquire(TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue("Job is not running", job.getStatus() == TranscodingJob.STATUS_RUNNING);
-
- // Kills the service and expects receiving failure of the job.
- executeShellCommand("pkill -f media.transcoding");
-
- Log.d(TAG, "testMediaTranscodeManager - Waiting for transcode result.");
- boolean finishedOnTime = transcodeCompleteSemaphore.tryAcquire(
- TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue("Invalid job status", job.getStatus() == TranscodingJob.STATUS_FINISHED);
- }
}
diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerWithMockServiceTest.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerWithMockServiceTest.java
deleted file mode 100644
index 167e474..0000000
--- a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerWithMockServiceTest.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2019 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.mediatranscodingtest;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.media.IMediaTranscodingService;
-import android.media.ITranscodingClient;
-import android.media.ITranscodingClientCallback;
-import android.media.MediaFormat;
-import android.media.MediaTranscodeManager;
-import android.media.MediaTranscodeManager.TranscodingJob;
-import android.media.MediaTranscodeManager.TranscodingRequest;
-import android.media.TranscodingJobParcel;
-import android.media.TranscodingRequestParcel;
-import android.media.TranscodingResultParcel;
-import android.media.TranscodingTestConfig;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import org.junit.Test;
-
-import java.io.File;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/*
- * Functional tests for MediaTranscodeManager in the media framework.
- * The test uses a mock Transcoding service as backend to test the API functionality.
- *
- * To run this test suite:
- make frameworks/base/media/tests/MediaTranscodingTest
- make mediatranscodingtest
-
- adb install -r testcases/mediatranscodingtest/arm64/mediatranscodingtest.apk
-
- adb shell am instrument -e class \
- com.android.mediatranscodingtest.MediaTranscodeManagerWithMockServiceTest \
- -w com.android.mediatranscodingtest/.MediaTranscodingTestRunner
- *
- */
-public class MediaTranscodeManagerWithMockServiceTest
- extends ActivityInstrumentationTestCase2<MediaTranscodingTest> {
- private static final String TAG = "MediaTranscodeManagerWithMockServiceTest";
- /** The time to wait for the transcode operation to complete before failing the test. */
- private static final int TRANSCODE_TIMEOUT_SECONDS = 2;
- private Context mContext;
- private MediaTranscodeManager mMediaTranscodeManager = null;
- private Uri mSourceHEVCVideoUri = null;
- private Uri mDestinationUri = null;
- // Use mock transcoding service for testing the api.
- private MockTranscodingService mTranscodingService = null;
-
- // Setting for transcoding to H.264.
- private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
- private static final int BIT_RATE = 2000000; // 2Mbps
- private static final int WIDTH = 1920;
- private static final int HEIGHT = 1080;
-
- // A mock transcoding service that will take constant 300ms to process each transcoding job.
- // Instead of doing real transcoding, it will return the dst uri directly.
- class MockTranscodingService extends IMediaTranscodingService.Stub {
- private final ScheduledExecutorService mJobScheduler = Executors.newScheduledThreadPool(1);
- private int mNumOfClients = 0;
- private AtomicInteger mJobId = new AtomicInteger();
-
- // A runnable that will process the job.
- private class ProcessingJobRunnable implements Runnable {
- private TranscodingJobParcel mJob;
- private ITranscodingClientCallback mCallback;
- private ConcurrentMap<Integer, ScheduledFuture<?>> mJobMap;
-
- ProcessingJobRunnable(ITranscodingClientCallback callback,
- TranscodingJobParcel job,
- ConcurrentMap<Integer, ScheduledFuture<?>> jobMap) {
- mJob = job;
- mCallback = callback;
- mJobMap = jobMap;
- }
-
- @Override
- public void run() {
- Log.d(TAG, "Start to process job " + mJob.jobId);
- TranscodingResultParcel result = new TranscodingResultParcel();
- try {
- // Try to open the source fd.
- ParcelFileDescriptor sourceFd = mCallback.openFileDescriptor(
- mJob.request.sourceFilePath, "r");
- if (sourceFd == null) {
- Log.d(TAG, "Failed to open sourceFd");
- // TODO(hkuang): Pass the correct error code.
- mCallback.onTranscodingFailed(mJob.jobId, 1);
- return;
- } else {
- Log.d(TAG, "Successfully open sourceFd");
- }
-
- // Try to write to the destination fd.
- ParcelFileDescriptor destinationFd = mCallback.openFileDescriptor(
- mJob.request.destinationFilePath, "w");
- if (destinationFd == null) {
- Log.d(TAG, "Failed to open destinationFd");
- // TODO(hkuang): Pass the correct error code.
- mCallback.onTranscodingFailed(mJob.jobId, 1);
- return;
- } else {
- Log.d(TAG, "Successfully open destinationFd");
- }
-
- mCallback.onTranscodingFinished(mJob.jobId, result);
- // Removes the job from job map.
- mJobMap.remove(mJob.jobId);
- } catch (RemoteException re) {
- Log.e(TAG, "Failed to callback to client");
- }
- }
- }
-
- @Override
- public ITranscodingClient registerClient(ITranscodingClientCallback callback,
- String clientName, String opPackageName, int clientUid, int clientPid)
- throws RemoteException {
- Log.d(TAG, "MockTranscodingService creates one client");
-
- ITranscodingClient client = new ITranscodingClient.Stub() {
- private final ConcurrentMap<Integer, ScheduledFuture<?>> mPendingTranscodingJobs =
- new ConcurrentHashMap<Integer, ScheduledFuture<?>>();
-
- @Override
- public boolean submitRequest(TranscodingRequestParcel inRequest,
- TranscodingJobParcel outjob) {
- Log.d(TAG, "Mock client gets submitRequest");
- try {
- outjob.request = inRequest;
- outjob.jobId = mJobId.getAndIncrement();
- Log.i(TAG, "Generate new job " + outjob.jobId);
- Log.i(TAG, "Source Uri " + inRequest.sourceFilePath);
- Log.i(TAG, "Destination Uri " + inRequest.destinationFilePath);
-
- // Schedules the job to run after inRequest.processingDelayMs.
- ScheduledFuture<?> transcodingFuture = mJobScheduler.schedule(
- new ProcessingJobRunnable(callback, outjob,
- mPendingTranscodingJobs),
- inRequest.testConfig == null ? 0
- : inRequest.testConfig.processingTotalTimeMs,
- TimeUnit.MILLISECONDS);
- mPendingTranscodingJobs.put(outjob.jobId, transcodingFuture);
- } catch (RejectedExecutionException e) {
- Log.e(TAG, "Failed to schedule transcoding job: " + e);
- return false;
- }
-
- return true;
- }
-
- @Override
- public boolean cancelJob(int jobId) throws RemoteException {
- Log.d(TAG, "Mock client gets cancelJob " + jobId);
- // Cancels the job is still in the mPendingTranscodingJobs.
- if (mPendingTranscodingJobs.containsKey(jobId)) {
- // Cancel the future task for transcoding.
- mPendingTranscodingJobs.get(jobId).cancel(true);
-
- // Remove the job from the mPendingTranscodingJobs.
- mPendingTranscodingJobs.remove(jobId);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean getJobWithId(int jobId, TranscodingJobParcel job)
- throws RemoteException {
- // This will be implemented this if needed in the test.
- return true;
- }
-
- @Override
- public void unregister() throws RemoteException {
- Log.d(TAG, "Mock client gets unregister");
- // This will be implemented this if needed in the test.
- mNumOfClients--;
- }
- };
- mNumOfClients++;
- return client;
- }
-
- @Override
- public int getNumOfClients() throws RemoteException {
- return mNumOfClients;
- }
- }
-
- public MediaTranscodeManagerWithMockServiceTest() {
- super("com.android.MediaTranscodeManagerWithMockServiceTest", MediaTranscodingTest.class);
- }
-
- private static Uri resourceToUri(Context context, int resId) {
- Uri uri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
- .authority(context.getResources().getResourcePackageName(resId))
- .appendPath(context.getResources().getResourceTypeName(resId))
- .appendPath(context.getResources().getResourceEntryName(resId))
- .build();
- return uri;
- }
-
- private static Uri generateNewUri(Context context, String filename) {
- File outFile = new File(context.getExternalCacheDir(), filename);
- return Uri.fromFile(outFile);
- }
-
- // Generates a invalid uri which will let the mock service return transcoding failure.
- private static Uri generateInvalidTranscodingUri(Context context) {
- File outFile = new File(context.getExternalCacheDir(), "InvalidUri.mp4");
- return Uri.fromFile(outFile);
- }
-
- /**
- * Creates a MediaFormat with the basic set of values.
- */
- private static MediaFormat createMediaFormat() {
- MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, WIDTH, HEIGHT);
- format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
- return format;
- }
-
- @Override
- public void setUp() throws Exception {
- Log.d(TAG, "setUp");
- super.setUp();
- mTranscodingService = new MockTranscodingService();
- mContext = getInstrumentation().getContext();
- mMediaTranscodeManager = mContext.getSystemService(MediaTranscodeManager.class);
- assertNotNull(mMediaTranscodeManager);
-
- // Setup source HEVC file uri.
- mSourceHEVCVideoUri = resourceToUri(mContext, R.raw.VideoOnlyHEVC);
-
- // Setup destination file.
- mDestinationUri = generateNewUri(mContext, "transcoded.mp4");
- }
-
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- /**
- * Verify that setting null destination uri will throw exception.
- */
- @Test
- public void testCreateTranscodingRequestWithNullDestinationUri() throws Exception {
- assertThrows(IllegalArgumentException.class, () -> {
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(mSourceHEVCVideoUri)
- .setDestinationUri(null)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
- .build();
- });
- }
-
- /**
- * Verify that setting null source uri will throw exception.
- */
- @Test
- public void testCreateTranscodingRequestWithNullSourceUri() throws Exception {
- assertThrows(IllegalArgumentException.class, () -> {
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(null)
- .setDestinationUri(mDestinationUri)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .build();
- });
- }
-
- /**
- * Verify that not setting source uri will throw exception.
- */
- @Test
- public void testCreateTranscodingRequestWithoutSourceUri() throws Exception {
- assertThrows(UnsupportedOperationException.class, () -> {
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setDestinationUri(mDestinationUri)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
- .build();
- });
- }
-
- /**
- * Verify that not setting destination uri will throw exception.
- */
- @Test
- public void testCreateTranscodingRequestWithoutDestinationUri() throws Exception {
- assertThrows(UnsupportedOperationException.class, () -> {
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(mSourceHEVCVideoUri)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
- .build();
- });
- }
-
- /**
- * Verify that setting image transcoding mode will throw exception.
- */
- @Test
- public void testCreateTranscodingRequestWithUnsupportedMode() throws Exception {
- assertThrows(UnsupportedOperationException.class, () -> {
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(mSourceHEVCVideoUri)
- .setDestinationUri(mDestinationUri)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_IMAGE)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
- .build();
- });
- }
-
- /**
- * Verify that setting video transcoding without setting video format will throw exception.
- */
- @Test
- public void testCreateTranscodingRequestWithoutVideoFormat() throws Exception {
- assertThrows(UnsupportedOperationException.class, () -> {
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(mSourceHEVCVideoUri)
- .setDestinationUri(mDestinationUri)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .build();
- });
- }
-
- void testTranscodingWithExpectResult(Uri srcUri, Uri dstUri, int expectedResult)
- throws Exception {
- Semaphore transcodeCompleteSemaphore = new Semaphore(0);
- TranscodingTestConfig testConfig = new TranscodingTestConfig();
- testConfig.passThroughMode = true;
- testConfig.processingTotalTimeMs = 300; // minimum time spent on transcoding.
-
- TranscodingRequest request =
- new TranscodingRequest.Builder()
- .setSourceUri(srcUri)
- .setDestinationUri(dstUri)
- .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
- .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
- .setVideoTrackFormat(createMediaFormat())
- .setTestConfig(testConfig)
- .build();
- Executor listenerExecutor = Executors.newSingleThreadExecutor();
-
- TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
- transcodingJob -> {
- Log.d(TAG, "Transcoding completed with result: " + transcodingJob.getResult());
- assertTrue("Transcoding should failed.",
- transcodingJob.getResult() == expectedResult);
- transcodeCompleteSemaphore.release();
- });
- assertNotNull(job);
-
- if (job != null) {
- Log.d(TAG, "testMediaTranscodeManager - Waiting for transcode to complete.");
- boolean finishedOnTime = transcodeCompleteSemaphore.tryAcquire(
- TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue("Transcode failed to complete in time.", finishedOnTime);
- }
-
- if (expectedResult == TranscodingJob.RESULT_SUCCESS) {
- // Checks the destination file get generated.
- File file = new File(dstUri.getPath());
- assertTrue("Failed to create destination file", file.exists());
-
- // Removes the file.
- file.delete();
- }
- }
-
- // Tests transcoding from invalid a invalid and expects failure.
- @Test
- public void testTranscodingInvalidSrcUri() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
-
- Uri invalidSrcUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
- + mContext.getPackageName() + "/source.mp4");
- Log.d(TAG, "Transcoding from source: " + invalidSrcUri);
-
- // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
- // The full path of this file is:
- // /data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
- Uri destinationUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
- + mContext.getPackageName() + "/temp.mp4");
- Log.d(TAG, "Transcoding to destination: " + destinationUri);
-
- testTranscodingWithExpectResult(invalidSrcUri, destinationUri, TranscodingJob.RESULT_ERROR);
- }
-
- // Tests transcoding to a uri in res folder and expects failure as we could not write to res
- // folder.
- @Test
- public void testTranscodingToResFolder() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
-
- // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
- // The full path of this file is:
- // /data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
- Uri destinationUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
- + mContext.getPackageName() + "/temp.mp4");
- Log.d(TAG, "Transcoding to destination: " + destinationUri);
-
- testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
- TranscodingJob.RESULT_ERROR);
- }
-
- // Tests transcoding to a uri in internal storage folder and expects success.
- @Test
- public void testTranscodingToCacheDir() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
-
- // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
- // The full path of this file is:
- // /data/user/0/com.android.mediatranscodingtest/cache/temp.mp4
- Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://"
- + mContext.getCacheDir().getAbsolutePath() + "/temp.mp4");
-
- testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
- TranscodingJob.RESULT_SUCCESS);
- }
-
- // Tests transcoding to a uri in internal files directory and expects success.
- @Test
- public void testTranscodingToInternalFilesDir() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
-
- // Create a file Uri:
- // file:///storage/emulated/0/Android/data/com.android.mediatranscodingtest/files/temp.mp4
- Uri destinationUri = Uri.fromFile(new File(mContext.getFilesDir(), "temp.mp4"));
- Log.i(TAG, "Transcoding to files dir: " + destinationUri);
-
- testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
- TranscodingJob.RESULT_SUCCESS);
- }
-
- // Tests transcoding to a uri in external files directory and expects success.
- @Test
- public void testTranscodingToExternalFilesDir() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
-
- // Create a file Uri: file:///data/user/0/com.android.mediatranscodingtest/files/temp.mp4
- Uri destinationUri = Uri.fromFile(new File(mContext.getExternalFilesDir(null), "temp.mp4"));
- Log.i(TAG, "Transcoding to files dir: " + destinationUri);
-
- testTranscodingWithExpectResult(mSourceHEVCVideoUri, destinationUri,
- TranscodingJob.RESULT_SUCCESS);
- }
-
- @Test
- public void testTranscodingOneVideo() throws Exception {
- Log.d(TAG, "Starting: testMediaTranscodeManager");
- testTranscodingWithExpectResult(mSourceHEVCVideoUri, mDestinationUri,
- TranscodingJob.RESULT_SUCCESS);
- }
-}
diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingTestRunner.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingTestRunner.java
index 53b2392..bd1551f 100644
--- a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingTestRunner.java
+++ b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingTestRunner.java
@@ -36,8 +36,8 @@
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(MediaTranscodeManagerDiedTest.class);
suite.addTestSuite(MediaTranscodeManagerTest.class);
- suite.addTestSuite(MediaTranscodeManagerWithMockServiceTest.class);
suite.addTestSuite(MediaTranscodingBenchmark.class);
return suite;
}
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index e1b3151..26a0ad9 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -1005,7 +1005,7 @@
field public static final int numericModifiers = 16844111; // 0x101054f
field public static final int numericShortcut = 16843236; // 0x10101e4
field public static final int offset = 16844052; // 0x1010514
- field public static final int onClick = 16843375; // 0x101026f
+ field @Deprecated public static final int onClick = 16843375; // 0x101026f
field public static final int oneshot = 16843159; // 0x1010197
field public static final int opacity = 16843550; // 0x101031e
field public static final int opticalInsetBottom = 16844171; // 0x101058b
@@ -6188,6 +6188,7 @@
method public android.app.PictureInPictureParams build();
method public android.app.PictureInPictureParams.Builder setActions(java.util.List<android.app.RemoteAction>);
method public android.app.PictureInPictureParams.Builder setAspectRatio(android.util.Rational);
+ method @NonNull public android.app.PictureInPictureParams.Builder setAutoEnterAllowed(boolean);
method public android.app.PictureInPictureParams.Builder setSourceRectHint(android.graphics.Rect);
}
@@ -6531,6 +6532,7 @@
method public android.graphics.Bitmap takeScreenshot();
method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
field public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 1; // 0x1
+ field public static final int FLAG_DONT_USE_ACCESSIBILITY = 2; // 0x2
field public static final int ROTATION_FREEZE_0 = 0; // 0x0
field public static final int ROTATION_FREEZE_180 = 2; // 0x2
field public static final int ROTATION_FREEZE_270 = 3; // 0x3
@@ -46546,7 +46548,8 @@
method public boolean isVoiceCapable();
method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
method public boolean isWorldPhone();
- method public void listen(android.telephony.PhoneStateListener, int);
+ method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
+ method public void listen(long, @NonNull android.telephony.PhoneStateListener);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
method public void sendDialerSpecialCode(String);
@@ -50981,6 +50984,7 @@
method public final boolean isFunctionPressed();
method public static final boolean isGamepadButton(int);
method public final boolean isLongPress();
+ method public static final boolean isMediaSessionKey(int);
method public final boolean isMetaPressed();
method public static boolean isModifierKey(int);
method public final boolean isNumLockOn();
diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt
index 8892a29..f7f42d0 100644
--- a/non-updatable-api/module-lib-current.txt
+++ b/non-updatable-api/module-lib-current.txt
@@ -35,17 +35,32 @@
package android.media {
public class AudioManager {
+ method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
+ method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
+ method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
field public static final int FLAG_FROM_KEY = 4096; // 0x1000
}
+ public static final class MediaMetadata.Builder {
+ ctor public MediaMetadata.Builder(@NonNull android.media.MediaMetadata, @IntRange(from=1) int);
+ }
+
}
package android.media.session {
+ public static final class MediaController.PlaybackInfo implements android.os.Parcelable {
+ ctor public MediaController.PlaybackInfo(int, int, @IntRange(from=0) int, @IntRange(from=0) int, @NonNull android.media.AudioAttributes, @Nullable String);
+ }
+
public final class MediaSession {
field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000
}
+ public static final class MediaSession.Token implements android.os.Parcelable {
+ method public int getUid();
+ }
+
public final class MediaSessionManager {
method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent);
method public boolean dispatchMediaKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent);
@@ -84,6 +99,14 @@
}
+package android.provider {
+
+ public final class DeviceConfig {
+ field public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
+ }
+
+}
+
package android.util {
public class AtomicFile {
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index f64be2b..8fae240 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -205,6 +205,7 @@
field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION";
+ field public static final String SEND_CATEGORY_CAR_NOTIFICATIONS = "android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS";
field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS";
field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
@@ -4139,8 +4140,10 @@
public class AudioManager {
method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException;
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException;
method public void clearAudioServerStateCallback();
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
@@ -4151,6 +4154,7 @@
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -4159,6 +4163,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
@@ -4168,6 +4173,7 @@
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
@@ -4197,6 +4203,10 @@
method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
}
+ public static interface AudioManager.OnPreferredDevicesForCapturePresetChangedListener {
+ method public void onPreferredDevicesForCapturePresetChanged(int, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
+ }
+
public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener {
method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
}
@@ -4268,17 +4278,22 @@
method @NonNull public android.media.HwAudioSource.Builder setAudioDeviceInfo(@NonNull android.media.AudioDeviceInfo);
}
+ public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
+ method @RequiresPermission("android.permission.BIND_IMS_SERVICE") public void setOnImsRxNoticeListener(@Nullable android.media.MediaPlayer.OnImsRxNoticeListener, @Nullable android.os.Handler);
+ }
+
+ public static interface MediaPlayer.OnImsRxNoticeListener {
+ method public void onImsRxNotice(@NonNull android.media.MediaPlayer, @NonNull byte[]);
+ }
+
public final class MediaRecorder.AudioSource {
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int ECHO_REFERENCE = 1997; // 0x7cd
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) public static final int HOTWORD = 1999; // 0x7cf
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int RADIO_TUNER = 1998; // 0x7ce
}
- public final class MediaTranscodeManager implements java.lang.AutoCloseable {
- method public void close();
+ public final class MediaTranscodeManager {
method @NonNull public android.media.MediaTranscodeManager.TranscodingJob enqueueRequest(@NonNull android.media.MediaTranscodeManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodeManager.OnTranscodingFinishedListener) throws java.io.FileNotFoundException;
- method protected void finalize();
- field public static final int PRIORITY_OFFLINE = 2; // 0x2
field public static final int PRIORITY_REALTIME = 1; // 0x1
field public static final int TRANSCODING_TYPE_VIDEO = 1; // 0x1
}
@@ -4307,7 +4322,7 @@
}
@java.lang.FunctionalInterface public static interface MediaTranscodeManager.TranscodingJob.OnProgressUpdateListener {
- method public void onProgressUpdate(@IntRange(from=0, to=100) int);
+ method public void onProgressUpdate(@NonNull android.media.MediaTranscodeManager.TranscodingJob, @IntRange(from=0, to=100) int);
}
public static final class MediaTranscodeManager.TranscodingRequest {
@@ -4328,6 +4343,14 @@
method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.Builder setVideoTrackFormat(@NonNull android.media.MediaFormat);
}
+ public static class MediaTranscodeManager.TranscodingRequest.MediaFormatResolver {
+ ctor public MediaTranscodeManager.TranscodingRequest.MediaFormatResolver();
+ method @Nullable public android.media.MediaFormat resolveVideoFormat();
+ method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver setSourceVideoFormatHint(@NonNull android.media.MediaFormat);
+ method public boolean shouldTranscode();
+ field public static final String CAPS_SUPPORTS_HEVC = "support-hevc";
+ }
+
public class PlayerProxy {
method public void pause();
method public void setPan(float);
@@ -6798,6 +6821,8 @@
field public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 8; // 0x8
field public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 128; // 0x80
field public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 16384; // 0x4000
+ field public static final int BSS_CAPABILITY_DMG_ESS = 3; // 0x3
+ field public static final int BSS_CAPABILITY_DMG_IBSS = 1; // 0x1
field public static final int BSS_CAPABILITY_DSSS_OFDM = 8192; // 0x2000
field public static final int BSS_CAPABILITY_ESS = 1; // 0x1
field public static final int BSS_CAPABILITY_IBSS = 2; // 0x2
@@ -6867,7 +6892,7 @@
method @NonNull public java.util.List<android.net.wifi.nl80211.NativeScanResult> getScanResults(@NonNull String, int);
method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String);
method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]);
- method public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback);
+ method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback);
method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback);
method public void setOnServiceDeadCallback(@NonNull Runnable);
method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback);
@@ -6918,10 +6943,10 @@
field public final int txBitrateMbps;
}
- public static interface WifiNl80211Manager.SoftApCallback {
- method public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean);
- method public void onFailure();
- method public void onSoftApChannelSwitched(int, int);
+ @Deprecated public static interface WifiNl80211Manager.SoftApCallback {
+ method @Deprecated public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean);
+ method @Deprecated public void onFailure();
+ method @Deprecated public void onSoftApChannelSwitched(int, int);
}
public static class WifiNl80211Manager.TxPacketCounters {
@@ -9742,6 +9767,7 @@
method @Deprecated public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onPhysicalChannelConfigurationChanged(@NonNull java.util.List<android.telephony.PhysicalChannelConfig>);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
@@ -9749,12 +9775,29 @@
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
+ field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final long LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 4294967296L; // 0x100000000L
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
}
+ public final class PhysicalChannelConfig implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getCellBandwidthDownlink();
+ method public int getChannelNumber();
+ method public int getConnectionStatus();
+ method public int getNetworkType();
+ method @IntRange(from=0, to=1007) public int getPhysicalCellId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff
+ field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
+ field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2
+ field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhysicalChannelConfig> CREATOR;
+ field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
+ }
+
public final class PreciseCallState implements android.os.Parcelable {
ctor public PreciseCallState(int, int, int, int, int);
method public int describeContents();
diff --git a/non-updatable-api/system-lint-baseline.txt b/non-updatable-api/system-lint-baseline.txt
index 395ddc1..4db55e7 100644
--- a/non-updatable-api/system-lint-baseline.txt
+++ b/non-updatable-api/system-lint-baseline.txt
@@ -6,7 +6,8 @@
BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex):
Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex)
-
+ExecutorRegistration: android.media.MediaPlayer#setOnImsRxNoticeListener(android.media.MediaPlayer.OnImsRxNoticeListener, android.os.Handler):
+
GenericException: android.app.prediction.AppPredictor#finalize():
GenericException: android.hardware.location.ContextHubClient#finalize():
@@ -181,6 +182,8 @@
SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
+SamShouldBeLast: android.media.MediaPlayer#setOnImsRxNoticeListener(android.media.MediaPlayer.OnImsRxNoticeListener, android.os.Handler):
+
SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
diff --git a/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml b/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml
index 469ac91..656e94a 100644
--- a/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml
+++ b/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml
@@ -27,20 +27,20 @@
android:width="@dimen/system_bar_icon_drawing_size"
android:height="@dimen/system_bar_icon_drawing_size"/>
<solid
- android:color="#3C4043"/>
+ android:color="@color/hvac_temperature_adjust_button_color"/>
</shape>
</aapt:attr>
</item>
<item android:gravity="center"
- android:width="48dp"
- android:height="48dp">
+ android:width="@dimen/system_bar_icon_drawing_size"
+ android:height="@dimen/system_bar_icon_drawing_size">
<aapt:attr name="android:drawable">
- <vector android:width="48dp"
- android:height="48dp"
+ <vector android:width="@dimen/system_bar_icon_drawing_size"
+ android:height="@dimen/system_bar_icon_drawing_size"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#8AB4F8"
+ android:fillColor="@color/hvac_temperature_decrease_arrow_color"
android:pathData="M14,7l-5,5 5,5V7z"/>
</vector>
</aapt:attr>
diff --git a/packages/CarSystemUI/res/drawable/hvac_increase_button.xml b/packages/CarSystemUI/res/drawable/hvac_increase_button.xml
index a3fca22..57c07c8 100644
--- a/packages/CarSystemUI/res/drawable/hvac_increase_button.xml
+++ b/packages/CarSystemUI/res/drawable/hvac_increase_button.xml
@@ -27,20 +27,20 @@
android:width="@dimen/system_bar_icon_drawing_size"
android:height="@dimen/system_bar_icon_drawing_size"/>
<solid
- android:color="#3C4043"/>
+ android:color="@color/hvac_temperature_adjust_button_color"/>
</shape>
</aapt:attr>
</item>
<item android:gravity="center"
- android:width="48dp"
- android:height="48dp">
+ android:width="@dimen/system_bar_icon_drawing_size"
+ android:height="@dimen/system_bar_icon_drawing_size">
<aapt:attr name="android:drawable">
- <vector android:width="48dp"
- android:height="48dp"
+ <vector android:width="@dimen/system_bar_icon_drawing_size"
+ android:height="@dimen/system_bar_icon_drawing_size"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#F28B82"
+ android:fillColor="@color/hvac_temperature_increase_arrow_color"
android:pathData="M10,17l5,-5 -5,-5v10z"/>
</vector>
</aapt:attr>
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
index d9c1491..b8ac2b4 100644
--- a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
@@ -56,8 +56,6 @@
android:textAppearance="@style/TextAppearance.CarStatus"
systemui:hvacAreaId="49"
systemui:hvacPivotOffset="60dp"
- systemui:hvacPropertyId="358614275"
- systemui:hvacTempFormat="%.0f\u00B0"
/>
</FrameLayout>
@@ -130,8 +128,6 @@
android:textAppearance="@style/TextAppearance.CarStatus"
systemui:hvacAreaId="68"
systemui:hvacPivotOffset="60dp"
- systemui:hvacPropertyId="358614275"
- systemui:hvacTempFormat="%.0f\u00B0"
/>
</FrameLayout>
</RelativeLayout>
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index 1e15aff..c390cc8 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -37,6 +37,11 @@
<color name="status_bar_background_color">#33000000</color>
<drawable name="system_bar_background">@color/status_bar_background_color</drawable>
+ <!-- colors for hvac temperature view -->
+ <color name="hvac_temperature_adjust_button_color">#3C4043</color>
+ <color name="hvac_temperature_decrease_arrow_color">#8AB4F8</color>
+ <color name="hvac_temperature_increase_arrow_color">#F28B82</color>
+
<!-- The background color of the notification shade -->
<color name="notification_shade_background_color">#D6000000</color>
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index 1fe2760..949a0fa 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -53,6 +53,14 @@
<integer name="config_rightSystemBarZOrder">0</integer>
<integer name="config_bottomSystemBarZOrder">10</integer>
+ <!-- If set to true, the corresponding system bar will be hidden when Keyboard (IME) appears.
+ NOTE: hideBottomSystemBarKeyboard must not be overlaid directly here. To change its value,
+ overlay config_automotiveHideNavBarForKeyboard in framework/base/core/res/res. -->
+ <bool name="config_hideTopSystemBarForKeyboard">false</bool>
+ <bool name="config_hideBottomSystemBarForKeyboard">@*android:bool/config_automotiveHideNavBarForKeyboard</bool>
+ <bool name="config_hideLeftSystemBarForKeyboard">false</bool>
+ <bool name="config_hideRightSystemBarForKeyboard">false</bool>
+
<!-- Disable normal notification rendering; we handle that ourselves -->
<bool name="config_renderNotifications">false</bool>
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index f02a8e7..28b8ead 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -48,8 +48,14 @@
<dimen name="system_bar_user_icon_padding">16dp</dimen>
<dimen name="system_bar_user_icon_drawing_size">36dp</dimen>
+ <!-- Padding on either side of the group of all system bar buttons -->
<dimen name="system_bar_button_group_padding">64dp</dimen>
<dimen name="system_bar_icon_drawing_size">44dp</dimen>
+ <dimen name="system_bar_button_size">76dp</dimen>
+ <!-- Margin between the system bar buttons -->
+ <dimen name="system_bar_button_margin">32dp</dimen>
+ <!-- Padding between the system bar button and the icon within it -->
+ <dimen name="system_bar_button_padding">16dp</dimen>
<!-- The amount by which to scale up the status bar icons. -->
<item name="status_bar_icon_scale_factor" format="float" type="dimen">1.75</item>
@@ -61,8 +67,8 @@
<dimen name="hvac_temperature_text_padding">8dp</dimen>
<dimen name="hvac_temperature_button_size">76dp</dimen>
<!--These values represent MIN and MAX for hvac-->
- <item name="hvac_min_value_celsius" format="float" type="dimen">0</item>
- <item name="hvac_max_value_celsius" format="float" type="dimen">126</item>
+ <item name="hvac_min_value_celsius" format="float" type="dimen">10</item>
+ <item name="hvac_max_value_celsius" format="float" type="dimen">35</item>
<!-- Largest size an avatar might need to be drawn in the user picker, status bar, or
quick settings header -->
diff --git a/packages/CarSystemUI/res/values/styles.xml b/packages/CarSystemUI/res/values/styles.xml
index 0db17ac..f242db0 100644
--- a/packages/CarSystemUI/res/values/styles.xml
+++ b/packages/CarSystemUI/res/values/styles.xml
@@ -43,10 +43,10 @@
</style>
<style name="NavigationBarButton">
- <item name="android:layout_height">76dp</item>
- <item name="android:layout_width">76dp</item>
- <item name="android:layout_marginEnd">32dp</item>
- <item name="android:padding">16dp</item>
+ <item name="android:layout_height">@dimen/system_bar_button_size</item>
+ <item name="android:layout_width">@dimen/system_bar_button_size</item>
+ <item name="android:layout_marginEnd">@dimen/system_bar_button_margin</item>
+ <item name="android:padding">@dimen/system_bar_button_padding</item>
<item name="android:gravity">center</item>
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 616e562..3def945 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -28,7 +28,6 @@
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
-import com.android.systemui.onehanded.OneHandedUI;
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
@@ -94,12 +93,6 @@
@ClassKey(LatencyTester.class)
public abstract SystemUI bindLatencyTester(LatencyTester sysui);
- /** Inject into OneHandedUI. */
- @Binds
- @IntoMap
- @ClassKey(OneHandedUI.class)
- public abstract SystemUI bindOneHandedUI(OneHandedUI sysui);
-
/** Inject into PowerUI. */
@Binds
@IntoMap
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java
index 4cac445..85d4ceb 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java
@@ -35,22 +35,27 @@
*/
public class AdjustableTemperatureView extends LinearLayout implements TemperatureView {
- private HvacController mHvacController;
- private float mCurrentTempC;
+ private final int mAreaId;
private TextView mTempTextView;
+ private float mMinTempC;
+ private float mMaxTempC;
+ private String mTempFormat;
private boolean mDisplayInFahrenheit = false;
- private final float mMinTempC;
- private final float mMaxTempC;
- private final int mAreaId;
- private final String mTempFormat;
+ private HvacController mHvacController;
+ private float mCurrentTempC;
public AdjustableTemperatureView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1);
+ }
- LayoutInflater.from(context).inflate(R.layout.adjustable_temperature_view, /* root= */this);
+ @Override
+ public void onFinishInflate() {
+ super.onFinishInflate();
+ LayoutInflater.from(getContext()).inflate(R.layout.adjustable_temperature_view,
+ /* root= */ this);
mTempFormat = getResources().getString(R.string.hvac_temperature_format);
mMinTempC = getResources().getFloat(R.dimen.hvac_min_value_celsius);
mMaxTempC = getResources().getFloat(R.dimen.hvac_max_value_celsius);
@@ -63,7 +68,7 @@
}
@Override
- public void setTemperatureView(float tempC) {
+ public void setTemp(float tempC) {
if (tempC > mMaxTempC || tempC < mMinTempC) {
return;
}
@@ -78,7 +83,7 @@
@Override
public void setDisplayInFahrenheit(boolean displayFahrenheit) {
mDisplayInFahrenheit = displayFahrenheit;
- setTemperatureView(mCurrentTempC);
+ setTemp(mCurrentTempC);
}
@Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java
index 567baa9..b98b680 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java
@@ -189,7 +189,7 @@
* @param temp - The current temp or NaN
*/
@Override
- public void setTemperatureView(float temp) {
+ public void setTemp(float temp) {
if (mDisplayInFahrenheit) {
temp = convertToFahrenheit(temp);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java
index f7451dc..10a361c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java
@@ -30,6 +30,7 @@
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.UiBackground;
import java.util.ArrayList;
import java.util.HashMap;
@@ -37,6 +38,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -49,6 +51,7 @@
public static final String TAG = "HvacController";
private static final boolean DEBUG = true;
+ private final Executor mBackgroundExecutor;
private final CarServiceProvider mCarServiceProvider;
private final Set<TemperatureView> mRegisteredViews = new HashSet<>();
@@ -68,7 +71,7 @@
Log.d(TAG, "onChangeEvent: " + areaId + ":" + value);
}
for (TemperatureView view : temperatureViews) {
- view.setTemperatureView(newTemp);
+ view.setTemp(newTemp);
}
}
} catch (Exception e) {
@@ -117,8 +120,10 @@
};
@Inject
- public HvacController(CarServiceProvider carServiceProvider) {
+ public HvacController(CarServiceProvider carServiceProvider,
+ @UiBackground Executor backgroundExecutor) {
mCarServiceProvider = carServiceProvider;
+ mBackgroundExecutor = backgroundExecutor;
}
/**
@@ -171,14 +176,14 @@
}
if (mCarPropertyManager == null || !mCarPropertyManager.isPropertyAvailable(
HVAC_TEMPERATURE_SET, zone)) {
- view.setTemperatureView(Float.NaN);
+ view.setTemp(Float.NaN);
return;
}
- view.setTemperatureView(
+ view.setTemp(
mCarPropertyManager.getFloatProperty(HVAC_TEMPERATURE_SET, zone));
view.setHvacController(this);
} catch (Exception e) {
- view.setTemperatureView(Float.NaN);
+ view.setTemp(Float.NaN);
Log.e(TAG, "Failed to get value from hvac service", e);
}
}
@@ -213,7 +218,8 @@
public void setTemperature(float tempC, int zone) {
if (mCarPropertyManager != null) {
// Internally, all temperatures are represented in floating point Celsius
- mCarPropertyManager.setFloatProperty(HVAC_TEMPERATURE_SET, zone, tempC);
+ mBackgroundExecutor.execute(
+ () -> mCarPropertyManager.setFloatProperty(HVAC_TEMPERATURE_SET, zone, tempC));
}
}
@@ -234,6 +240,6 @@
* @return Temperature in Celsius.
*/
public static float convertToCelsius(float tempF) {
- return (float) ((tempF - 32) * 0.55555555556);
+ return (tempF - 32) * 5f / 9f;
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java
index 252f783..90df15c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java
@@ -56,7 +56,7 @@
* @param temp - The current temp or NaN
*/
@Override
- public void setTemperatureView(float temp) {
+ public void setTemp(float temp) {
if (Float.isNaN(temp)) {
setText("--");
return;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java
index 3c0e0ac..6edf254 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java
@@ -33,7 +33,7 @@
*
* @param temp - The current temp in Celsius or NaN
*/
- void setTemperatureView(float temp);
+ void setTemp(float temp);
/**
* Render the displayed temperature in Fahrenheit
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
index dadbc22..3af7507 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
@@ -30,7 +30,6 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.R;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.navigationbar.CarNavigationBarController;
@@ -40,6 +39,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.KeyguardBouncer.Factory;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -66,7 +66,7 @@
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
private final ViewMediatorCallback mViewMediatorCallback;
private final CarNavigationBarController mCarNavigationBarController;
- private final KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+ private final Factory mKeyguardBouncerFactory;
// Needed to instantiate mBouncer.
private final KeyguardBouncer.BouncerExpansionCallback
mExpansionCallback = new KeyguardBouncer.BouncerExpansionCallback() {
@@ -107,7 +107,7 @@
Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
ViewMediatorCallback viewMediatorCallback,
CarNavigationBarController carNavigationBarController,
- KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory) {
+ KeyguardBouncer.Factory keyguardBouncerFactory) {
super(R.id.keyguard_stub, overlayViewGlobalStateController);
@@ -118,7 +118,7 @@
mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
mViewMediatorCallback = viewMediatorCallback;
mCarNavigationBarController = carNavigationBarController;
- mKeyguardBouncerComponentFactory = keyguardBouncerComponentFactory;
+ mKeyguardBouncerFactory = keyguardBouncerFactory;
registerUserSwitchedListener();
}
@@ -130,9 +130,8 @@
@Override
public void onFinishInflate() {
- mBouncer = mKeyguardBouncerComponentFactory
- .build(getLayout().findViewById(R.id.keyguard_container), mExpansionCallback)
- .createKeyguardBouncer();
+ mBouncer = mKeyguardBouncerFactory
+ .create(getLayout().findViewById(R.id.keyguard_container), mExpansionCallback);
mBiometricUnlockControllerLazy.get().setKeyguardViewController(this);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
index aa6da89..2dc4756 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
@@ -16,7 +16,7 @@
package com.android.systemui.car.navigationbar;
-import android.app.ActivityManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -97,27 +97,27 @@
* The StackInfo is expected to be supplied in order of recency and StackInfo will only be used
* for consideration if it has the same displayId as the CarNavigationButton.
*
- * @param stackInfoList of the currently running application
+ * @param taskInfoList of the currently running application
* @param validDisplay index of the valid display
*/
- protected void taskChanged(List<ActivityManager.StackInfo> stackInfoList, int validDisplay) {
- ActivityManager.StackInfo validStackInfo = null;
- for (ActivityManager.StackInfo stackInfo : stackInfoList) {
+ protected void taskChanged(List<RootTaskInfo> taskInfoList, int validDisplay) {
+ RootTaskInfo validTaskInfo = null;
+ for (RootTaskInfo taskInfo : taskInfoList) {
// Find the first stack info with a topActivity in the primary display.
// TODO: We assume that CarFacetButton will launch an app only in the primary display.
// We need to extend the functionality to handle the multiple display properly.
- if (stackInfo.topActivity != null && stackInfo.displayId == validDisplay) {
- validStackInfo = stackInfo;
+ if (taskInfo.topActivity != null && taskInfo.displayId == validDisplay) {
+ validTaskInfo = taskInfo;
break;
}
}
- if (validStackInfo == null) {
+ if (validTaskInfo == null) {
// No stack was found that was on the same display as the buttons thus return
return;
}
- int displayId = validStackInfo.displayId;
+ int displayId = validTaskInfo.displayId;
mSelectedButtons.forEach(carNavigationButton -> {
if (carNavigationButton.getDisplayId() == displayId) {
@@ -126,7 +126,7 @@
});
mSelectedButtons.clear();
- HashSet<CarNavigationButton> selectedButtons = findSelectedButtons(validStackInfo);
+ HashSet<CarNavigationButton> selectedButtons = findSelectedButtons(validTaskInfo);
if (selectedButtons != null) {
selectedButtons.forEach(carNavigationButton -> {
@@ -141,10 +141,10 @@
/**
* Defaults to Display.DEFAULT_DISPLAY when no parameter is provided for the validDisplay.
*
- * @param stackInfoList
+ * @param taskInfoList
*/
- protected void taskChanged(List<ActivityManager.StackInfo> stackInfoList) {
- taskChanged(stackInfoList, Display.DEFAULT_DISPLAY);
+ protected void taskChanged(List<RootTaskInfo> taskInfoList) {
+ taskChanged(taskInfoList, Display.DEFAULT_DISPLAY);
}
/**
@@ -171,12 +171,11 @@
mRegisteredViews.add(carNavigationButton);
}
- private HashSet<CarNavigationButton> findSelectedButtons(
- ActivityManager.StackInfo validStackInfo) {
- String packageName = validStackInfo.topActivity.getPackageName();
+ private HashSet<CarNavigationButton> findSelectedButtons(RootTaskInfo validTaskInfo) {
+ String packageName = validTaskInfo.topActivity.getPackageName();
HashSet<CarNavigationButton> selectedButtons =
- findButtonsByComponentName(validStackInfo.topActivity);
+ findButtonsByComponentName(validTaskInfo.topActivity);
if (selectedButtons == null) {
selectedButtons = mButtonsByPackage.get(packageName);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
index d6216ba..f74bd4f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
@@ -43,9 +43,9 @@
public void onTaskStackChanged() {
try {
mButtonSelectionStateController.taskChanged(
- ActivityTaskManager.getService().getAllStackInfos());
+ ActivityTaskManager.getService().getAllRootTaskInfos());
} catch (Exception e) {
- Log.e(TAG, "Getting StackInfo from activity manager failed", e);
+ Log.e(TAG, "Getting RootTaskInfo from activity task manager failed", e);
}
}
@@ -53,9 +53,9 @@
public void onTaskDisplayChanged(int taskId, int newDisplayId) {
try {
mButtonSelectionStateController.taskChanged(
- ActivityTaskManager.getService().getAllStackInfos());
+ ActivityTaskManager.getService().getAllRootTaskInfos());
} catch (Exception e) {
- Log.e(TAG, "Getting StackInfo from activity manager failed", e);
+ Log.e(TAG, "Getting RootTaskInfo from activity task manager failed", e);
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index bf8cda3..c7db3f6 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
@@ -91,7 +91,11 @@
private ActivityManagerWrapper mActivityManagerWrapper;
// If the nav bar should be hidden when the soft keyboard is visible.
- private boolean mHideNavBarForKeyboard;
+ private boolean mHideTopBarForKeyboard;
+ private boolean mHideLeftBarForKeyboard;
+ private boolean mHideRightBarForKeyboard;
+ private boolean mHideBottomBarForKeyboard;
+
private boolean mBottomNavBarVisible;
// Nav bar views.
@@ -160,8 +164,13 @@
@Override
public void start() {
// Set initial state.
- mHideNavBarForKeyboard = mResources.getBoolean(
- com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
+ mHideTopBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP);
+ mHideBottomBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(
+ SystemBarConfigs.BOTTOM);
+ mHideLeftBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.LEFT);
+ mHideRightBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(
+ SystemBarConfigs.RIGHT);
+
mBottomNavBarVisible = false;
// Connect into the status bar manager service
@@ -411,17 +420,30 @@
@Override
public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) {
- if (!mHideNavBarForKeyboard) {
- return;
- }
-
if (mContext.getDisplayId() != displayId) {
return;
}
boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
- mCarNavigationBarController.setBottomWindowVisibility(
- isKeyboardVisible ? View.GONE : View.VISIBLE);
+
+ if (mHideTopBarForKeyboard) {
+ mCarNavigationBarController.setTopWindowVisibility(
+ isKeyboardVisible ? View.GONE : View.VISIBLE);
+ }
+
+ if (mHideBottomBarForKeyboard) {
+ mCarNavigationBarController.setBottomWindowVisibility(
+ isKeyboardVisible ? View.GONE : View.VISIBLE);
+ }
+
+ if (mHideLeftBarForKeyboard) {
+ mCarNavigationBarController.setLeftWindowVisibility(
+ isKeyboardVisible ? View.GONE : View.VISIBLE);
+ }
+ if (mHideRightBarForKeyboard) {
+ mCarNavigationBarController.setRightWindowVisibility(
+ isKeyboardVisible ? View.GONE : View.VISIBLE);
+ }
}
@Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
index 529083f4b..4fb5220 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
@@ -83,9 +83,7 @@
* Hides all system bars.
*/
public void hideBars() {
- if (mTopView != null) {
- mTopView.setVisibility(View.GONE);
- }
+ setTopWindowVisibility(View.GONE);
setBottomWindowVisibility(View.GONE);
setLeftWindowVisibility(View.GONE);
setRightWindowVisibility(View.GONE);
@@ -95,9 +93,7 @@
* Shows all system bars.
*/
public void showBars() {
- if (mTopView != null) {
- mTopView.setVisibility(View.VISIBLE);
- }
+ setTopWindowVisibility(View.VISIBLE);
setBottomWindowVisibility(View.VISIBLE);
setLeftWindowVisibility(View.VISIBLE);
setRightWindowVisibility(View.VISIBLE);
@@ -140,6 +136,11 @@
return mShowRight ? mNavigationBarViewFactory.getRightWindow() : null;
}
+ /** Toggles the top nav bar visibility. */
+ public boolean setTopWindowVisibility(@View.Visibility int visibility) {
+ return setWindowVisibility(getTopWindow(), visibility);
+ }
+
/** Toggles the bottom nav bar visibility. */
public boolean setBottomWindowVisibility(@View.Visibility int visibility) {
return setWindowVisibility(getBottomWindow(), visibility);
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
index 1418ace..e316139 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java
@@ -100,6 +100,7 @@
checkEnabledBarsHaveUniqueBarTypes();
checkAllOverlappingBarsHaveDifferentZOrders();
checkSystemBarEnabledForNotificationPanel();
+ checkHideBottomBarForKeyboardConfigSync();
setInsetPaddingsForOverlappingCorners();
sortSystemBarSidesByZOrder();
}
@@ -124,6 +125,11 @@
}
}
+ protected boolean getHideForKeyboardBySide(@SystemBarSide int side) {
+ return mSystemBarConfigMap.get(side) != null
+ && mSystemBarConfigMap.get(side).getHideForKeyboard();
+ }
+
protected void insetSystemBar(@SystemBarSide int side, CarNavigationBarView view) {
if (mSystemBarConfigMap.get(side) == null) return;
@@ -213,6 +219,8 @@
com.android.internal.R.dimen.status_bar_height))
.setBarType(mResources.getInteger(R.integer.config_topSystemBarType))
.setZOrder(mResources.getInteger(R.integer.config_topSystemBarZOrder))
+ .setHideForKeyboard(mResources.getBoolean(
+ R.bool.config_hideTopSystemBarForKeyboard))
.build();
mSystemBarConfigMap.put(TOP, topBarConfig);
}
@@ -226,6 +234,8 @@
.setBarType(mResources.getInteger(R.integer.config_bottomSystemBarType))
.setZOrder(
mResources.getInteger(R.integer.config_bottomSystemBarZOrder))
+ .setHideForKeyboard(mResources.getBoolean(
+ R.bool.config_hideBottomSystemBarForKeyboard))
.build();
mSystemBarConfigMap.put(BOTTOM, bottomBarConfig);
}
@@ -238,6 +248,8 @@
R.dimen.car_left_navigation_bar_width))
.setBarType(mResources.getInteger(R.integer.config_leftSystemBarType))
.setZOrder(mResources.getInteger(R.integer.config_leftSystemBarZOrder))
+ .setHideForKeyboard(mResources.getBoolean(
+ R.bool.config_hideLeftSystemBarForKeyboard))
.build();
mSystemBarConfigMap.put(LEFT, leftBarConfig);
}
@@ -250,6 +262,8 @@
R.dimen.car_right_navigation_bar_width))
.setBarType(mResources.getInteger(R.integer.config_rightSystemBarType))
.setZOrder(mResources.getInteger(R.integer.config_rightSystemBarZOrder))
+ .setHideForKeyboard(mResources.getBoolean(
+ R.bool.config_hideRightSystemBarForKeyboard))
.build();
mSystemBarConfigMap.put(RIGHT, rightBarConfig);
}
@@ -304,6 +318,24 @@
}
}
+ private void checkHideBottomBarForKeyboardConfigSync() throws RuntimeException {
+ if (mBottomNavBarEnabled) {
+ boolean actual = mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard);
+ boolean expected = mResources.getBoolean(
+ com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
+
+ if (actual != expected) {
+ throw new RuntimeException("config_hideBottomSystemBarForKeyboard must not be "
+ + "overlaid directly and should always refer to"
+ + "config_automotiveHideNavBarForKeyboard. However, their values "
+ + "currently do not sync. Set config_hideBottomSystemBarForKeyguard to "
+ + "@*android:bool/config_automotiveHideNavBarForKeyboard. To change its "
+ + "value, overlay config_automotiveHideNavBarForKeyboard in "
+ + "framework/base/core/res/res.");
+ }
+ }
+ }
+
private void setInsetPaddingsForOverlappingCorners() {
Map<@SystemBarSide Integer, Boolean> systemBarVisibilityOnInit =
getSystemBarsVisibilityOnInit();
@@ -410,14 +442,17 @@
private final int mBarType;
private final int mGirth;
private final int mZOrder;
+ private final boolean mHideForKeyboard;
private int[] mPaddings = new int[]{0, 0, 0, 0};
- private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder) {
+ private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder,
+ boolean hideForKeyboard) {
mSide = side;
mBarType = barType;
mGirth = girth;
mZOrder = zOrder;
+ mHideForKeyboard = hideForKeyboard;
}
private int getSide() {
@@ -436,6 +471,10 @@
return mZOrder;
}
+ private boolean getHideForKeyboard() {
+ return mHideForKeyboard;
+ }
+
private int[] getPaddings() {
return mPaddings;
}
@@ -473,6 +512,7 @@
private int mBarType;
private int mGirth;
private int mZOrder;
+ private boolean mHideForKeyboard;
private SystemBarConfigBuilder setSide(@SystemBarSide int side) {
mSide = side;
@@ -494,8 +534,13 @@
return this;
}
+ private SystemBarConfigBuilder setHideForKeyboard(boolean hide) {
+ mHideForKeyboard = hide;
+ return this;
+ }
+
private SystemBarConfig build() {
- return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder);
+ return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder, mHideForKeyboard);
}
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
index eb32edb..f96ee0f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java
@@ -17,7 +17,7 @@
package com.android.systemui.car.sideloaded;
import android.annotation.NonNull;
-import android.app.ActivityManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
@@ -78,10 +78,10 @@
return false;
}
- boolean isSafe(@NonNull ActivityManager.StackInfo stackInfo) {
- ComponentName componentName = stackInfo.topActivity;
+ boolean isSafe(@NonNull RootTaskInfo taskInfo) {
+ ComponentName componentName = taskInfo.topActivity;
if (componentName == null) {
- Log.w(TAG, "Stack info does not have top activity: " + stackInfo.stackId);
+ Log.w(TAG, "Task info does not have top activity: " + taskInfo.taskId);
return false;
}
return isSafe(componentName.getPackageName());
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java
index c8c1a40..db7718b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java
@@ -16,8 +16,7 @@
package com.android.systemui.car.sideloaded;
-import android.app.ActivityManager;
-import android.app.ActivityManager.StackInfo;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityTaskManager;
import android.app.TaskStackListener;
import android.content.ComponentName;
@@ -56,15 +55,15 @@
public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
super.onTaskCreated(taskId, componentName);
- List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfos();
- ActivityManager.StackInfo stackInfo = getStackInfo(stackInfoList, taskId);
- if (stackInfo == null) {
+ List<RootTaskInfo> taskInfoList = mActivityTaskManager.getAllRootTaskInfos();
+ RootTaskInfo taskInfo = getStackInfo(taskInfoList, taskId);
+ if (taskInfo == null) {
Log.e(TAG, "Stack info was not available for taskId: " + taskId);
return;
}
- if (!mSideLoadedAppDetector.isSafe(stackInfo)) {
- Display display = mDisplayManager.getDisplay(stackInfo.displayId);
+ if (!mSideLoadedAppDetector.isSafe(taskInfo)) {
+ Display display = mDisplayManager.getDisplay(taskInfo.displayId);
mSideLoadedAppStateController.onUnsafeTaskCreatedOnDisplay(display);
}
}
@@ -75,18 +74,18 @@
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
- // Note that the stackInfoList is ordered by recency.
- List<StackInfo> stackInfoList =
- mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId());
+ // Note that the taskInfoList is ordered by recency.
+ List<RootTaskInfo> taskInfoList =
+ mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId());
- if (stackInfoList == null) {
+ if (taskInfoList == null) {
continue;
}
- StackInfo stackInfo = getTopVisibleStackInfo(stackInfoList);
- if (stackInfo == null) {
+ RootTaskInfo taskInfo = getTopVisibleStackInfo(taskInfoList);
+ if (taskInfo == null) {
continue;
}
- if (mSideLoadedAppDetector.isSafe(stackInfo)) {
+ if (mSideLoadedAppDetector.isSafe(taskInfo)) {
mSideLoadedAppStateController.onSafeTaskDisplayedOnDisplay(display);
} else {
mSideLoadedAppStateController.onUnsafeTaskDisplayedOnDisplay(display);
@@ -97,18 +96,17 @@
/**
* Returns stack info for a given taskId.
*/
- private ActivityManager.StackInfo getStackInfo(
- List<ActivityManager.StackInfo> stackInfoList, int taskId) {
- if (stackInfoList == null) {
+ private RootTaskInfo getStackInfo(List<RootTaskInfo> taskInfoList, int taskId) {
+ if (taskInfoList == null) {
return null;
}
- for (ActivityManager.StackInfo stackInfo : stackInfoList) {
- if (stackInfo.taskIds == null) {
+ for (RootTaskInfo taskInfo : taskInfoList) {
+ if (taskInfo.childTaskIds == null) {
continue;
}
- for (int stackTaskId : stackInfo.taskIds) {
- if (taskId == stackTaskId) {
- return stackInfo;
+ for (int taskTaskId : taskInfo.childTaskIds) {
+ if (taskId == taskTaskId) {
+ return taskInfo;
}
}
}
@@ -118,11 +116,10 @@
/**
* Returns the first visible stackInfo.
*/
- private ActivityManager.StackInfo getTopVisibleStackInfo(
- List<ActivityManager.StackInfo> stackInfoList) {
- for (ActivityManager.StackInfo stackInfo : stackInfoList) {
- if (stackInfo.visible) {
- return stackInfo;
+ private RootTaskInfo getTopVisibleStackInfo(List<RootTaskInfo> taskInfoList) {
+ for (RootTaskInfo taskInfo : taskInfoList) {
+ if (taskInfo.visible) {
+ return taskInfo;
}
}
return null;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java
index 5ef8aa1..1b1a118 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UserNameViewController.java
@@ -59,6 +59,8 @@
}
};
+ private boolean mUserLifecycleListenerRegistered = false;
+
private final CarUserManager.UserLifecycleListener mUserLifecycleListener =
new CarUserManager.UserLifecycleListener() {
@Override
@@ -100,9 +102,13 @@
* Clean up the controller and unregister receiver.
*/
public void removeAll() {
- mBroadcastDispatcher.unregisterReceiver(mUserUpdateReceiver);
- if (mCarUserManager != null) {
- mCarUserManager.removeListener(mUserLifecycleListener);
+ mUserNameView = null;
+ if (mUserLifecycleListenerRegistered) {
+ mBroadcastDispatcher.unregisterReceiver(mUserUpdateReceiver);
+ if (mCarUserManager != null) {
+ mCarUserManager.removeListener(mUserLifecycleListener);
+ }
+ mUserLifecycleListenerRegistered = false;
}
}
@@ -112,6 +118,7 @@
mCarUserManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
if (mCarUserManager != null) {
mCarUserManager.addListener(Runnable::run, mUserLifecycleListener);
+ mUserLifecycleListenerRegistered = true;
} else {
Log.e(TAG, "CarUserManager could not be obtained.");
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java
index e8850de..a3a55aa 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java
@@ -46,9 +46,12 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.concurrent.Executor;
+
@CarSystemUiTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -64,6 +67,8 @@
private Car mCar;
@Mock
private CarPropertyManager mCarPropertyManager;
+ @Mock
+ private Executor mExecutor;
@Before
public void setUp() {
@@ -72,9 +77,10 @@
when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mHvacController = new HvacController(carServiceProvider);
+ mHvacController = new HvacController(carServiceProvider, mExecutor);
mHvacController.connectToCarService();
mAdjustableTemperatureView = new AdjustableTemperatureView(getContext(), /* attrs= */ null);
+ mAdjustableTemperatureView.onFinishInflate();
mAdjustableTemperatureView.setHvacController(mHvacController);
}
@@ -118,6 +124,9 @@
mAdjustableTemperatureView.findViewById(R.id.hvac_increase_button).callOnClick();
+ ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mExecutor).execute(setTempRunnableCaptor.capture());
+ setTempRunnableCaptor.getValue().run();
verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
eq(TEMP_CELSIUS + 1));
}
@@ -132,6 +141,9 @@
mAdjustableTemperatureView.findViewById(R.id.hvac_decrease_button).callOnClick();
+ ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mExecutor).execute(setTempRunnableCaptor.capture());
+ setTempRunnableCaptor.getValue().run();
verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
eq(TEMP_CELSIUS - 1));
}
@@ -150,6 +162,9 @@
mAdjustableTemperatureView.findViewById(R.id.hvac_increase_button).callOnClick();
+ ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mExecutor).execute(setTempRunnableCaptor.capture());
+ setTempRunnableCaptor.getValue().run();
verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
eq(convertToCelsius(convertToFahrenheit(TEMP_CELSIUS) + 1)));
}
@@ -168,6 +183,9 @@
mAdjustableTemperatureView.findViewById(R.id.hvac_decrease_button).callOnClick();
+ ArgumentCaptor<Runnable> setTempRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mExecutor).execute(setTempRunnableCaptor.capture());
+ setTempRunnableCaptor.getValue().run();
verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(),
eq(convertToCelsius(convertToFahrenheit(TEMP_CELSIUS) - 1)));
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java
index 9912657..52f07df 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java
@@ -40,6 +40,8 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.CarSystemUiTest;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +72,8 @@
when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mHvacController = new HvacController(carServiceProvider);
+ mHvacController = new HvacController(carServiceProvider,
+ new FakeExecutor(new FakeSystemClock()));
mHvacController.connectToCarService();
}
@@ -86,31 +89,31 @@
TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP);
mHvacController.addTemperatureViewToController(v);
- verify(v).setTemperatureView(TEMP);
+ verify(v).setTemp(TEMP);
}
@Test
public void addTemperatureViewToController_usingSameTemperatureView_registersFirstView() {
TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP);
mHvacController.addTemperatureViewToController(v);
- verify(v).setTemperatureView(TEMP);
+ verify(v).setTemp(TEMP);
resetTemperatureView(v, AREA_ID);
mHvacController.addTemperatureViewToController(v);
- verify(v, never()).setTemperatureView(TEMP);
+ verify(v, never()).setTemp(TEMP);
}
@Test
public void addTemperatureViewToController_usingDifferentTemperatureView_registersBothViews() {
TemperatureTextView v1 = setupMockTemperatureTextView(AREA_ID, TEMP);
mHvacController.addTemperatureViewToController(v1);
- verify(v1).setTemperatureView(TEMP);
+ verify(v1).setTemp(TEMP);
TemperatureTextView v2 = setupMockTemperatureTextView(
AREA_ID + 1,
TEMP + 1);
mHvacController.addTemperatureViewToController(v2);
- verify(v2).setTemperatureView(TEMP + 1);
+ verify(v2).setTemp(TEMP + 1);
}
@Test
@@ -124,7 +127,7 @@
mHvacController.addTemperatureViewToController(v);
verify(v).setDisplayInFahrenheit(true);
- verify(v).setTemperatureView(TEMP);
+ verify(v).setTemp(TEMP);
}
private TemperatureTextView setupMockTemperatureTextView(int areaId, float value) {
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java
index e97d9d9..3ed8111 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java
@@ -40,6 +40,8 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.CarSystemUiTest;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -72,7 +74,8 @@
when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
- mHvacController = new HvacController(carServiceProvider);
+ mHvacController = new HvacController(carServiceProvider,
+ new FakeExecutor(new FakeSystemClock()));
mHvacController.connectToCarService();
mTextView = new TemperatureTextView(getContext(), /* attrs= */ null);
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
index 63d4004..062ab41 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
@@ -36,7 +36,6 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarServiceProvider;
@@ -67,9 +66,7 @@
@Mock
private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
@Mock
- private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
- @Mock
- private KeyguardBouncerComponent mKeyguardBouncerComponent;
+ private KeyguardBouncer.Factory mKeyguardBouncerFactory;
@Mock
private KeyguardBouncer mBouncer;
@@ -77,11 +74,10 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mKeyguardBouncerComponentFactory.build(
+ when(mKeyguardBouncerFactory.create(
any(ViewGroup.class),
any(KeyguardBouncer.BouncerExpansionCallback.class)))
- .thenReturn(mKeyguardBouncerComponent);
- when(mKeyguardBouncerComponent.createKeyguardBouncer()).thenReturn(mBouncer);
+ .thenReturn(mBouncer);
mCarKeyguardViewController = new CarKeyguardViewController(
Handler.getMain(),
@@ -92,7 +88,7 @@
() -> mock(BiometricUnlockController.class),
mock(ViewMediatorCallback.class),
mock(CarNavigationBarController.class),
- mKeyguardBouncerComponentFactory
+ mKeyguardBouncerFactory
);
mCarKeyguardViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.sysui_overlay_window, /* root= */ null));
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
index f623c26..bd017cd 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
@@ -18,7 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
-import android.app.ActivityManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -71,7 +71,7 @@
public void onTaskChanged_buttonDetectableByComponentName_selectsAssociatedButton() {
CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_component_name);
mComponentName = new ComponentName(TEST_COMPONENT_NAME_PACKAGE, TEST_COMPONENT_NAME_CLASS);
- List<ActivityManager.StackInfo> testStack = createTestStack(mComponentName);
+ List<RootTaskInfo> testStack = createTestStack(mComponentName);
testButton.setSelected(false);
mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1);
@@ -82,7 +82,7 @@
public void onTaskChanged_buttonDetectableByCategory_selectsAssociatedButton() {
CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_category);
mComponentName = new ComponentName(TEST_CATEGORY, TEST_CATEGORY_CLASS);
- List<ActivityManager.StackInfo> testStack = createTestStack(mComponentName);
+ List<RootTaskInfo> testStack = createTestStack(mComponentName);
testButton.setSelected(false);
mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1);
@@ -93,7 +93,7 @@
public void onTaskChanged_buttonDetectableByPackage_selectsAssociatedButton() {
CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_package);
mComponentName = new ComponentName(TEST_PACKAGE, TEST_PACKAGE_CLASS);
- List<ActivityManager.StackInfo> testStack = createTestStack(mComponentName);
+ List<RootTaskInfo> testStack = createTestStack(mComponentName);
testButton.setSelected(false);
mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1);
@@ -104,12 +104,12 @@
public void onTaskChanged_deselectsPreviouslySelectedButton() {
CarNavigationButton oldButton = mTestView.findViewById(R.id.detectable_by_component_name);
mComponentName = new ComponentName(TEST_COMPONENT_NAME_PACKAGE, TEST_COMPONENT_NAME_CLASS);
- List<ActivityManager.StackInfo> oldStack = createTestStack(mComponentName);
+ List<RootTaskInfo> oldStack = createTestStack(mComponentName);
oldButton.setSelected(false);
mButtonSelectionStateController.taskChanged(oldStack, /* validDisplay= */ -1);
mComponentName = new ComponentName(TEST_PACKAGE, TEST_PACKAGE_CLASS);
- List<ActivityManager.StackInfo> newStack = createTestStack(mComponentName);
+ List<RootTaskInfo> newStack = createTestStack(mComponentName);
mButtonSelectionStateController.taskChanged(newStack, /* validDisplay= */ -1);
assertButtonUnselected(oldButton);
@@ -125,12 +125,12 @@
assertThat(button.getAlpha()).isEqualTo(CarNavigationButton.DEFAULT_UNSELECTED_ALPHA);
}
- private List<ActivityManager.StackInfo> createTestStack(ComponentName componentName) {
- ActivityManager.StackInfo validStackInfo = new ActivityManager.StackInfo();
+ private List<RootTaskInfo> createTestStack(ComponentName componentName) {
+ RootTaskInfo validStackInfo = new RootTaskInfo();
validStackInfo.displayId = -1; // No display is assigned to this test view
validStackInfo.topActivity = componentName;
- List<ActivityManager.StackInfo> testStack = new ArrayList<>();
+ List<RootTaskInfo> testStack = new ArrayList<>();
testStack.add(validStackInfo);
return testStack;
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
index 072358b..7eb41de 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.car.navigationbar;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -97,6 +98,16 @@
mSystemBarConfigs = new SystemBarConfigs(mResources);
}
+ @Test(expected = RuntimeException.class)
+ public void onInit_hideBottomSystemBarForKeyboardValueDoNotSync_throwsRuntimeException() {
+ when(mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard)).thenReturn(false);
+ when(mResources.getBoolean(
+ com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard)).thenReturn(
+ true);
+
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+ }
+
@Test
public void getTopSystemBarLayoutParams_topBarEnabled_returnsTopSystemBarLayoutParams() {
mSystemBarConfigs = new SystemBarConfigs(mResources);
@@ -117,6 +128,26 @@
}
@Test
+ public void getTopSystemBarHideForKeyboard_hideBarForKeyboard_returnsTrue() {
+ when(mResources.getBoolean(R.bool.config_hideTopSystemBarForKeyboard)).thenReturn(true);
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+
+ boolean hideKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP);
+
+ assertTrue(hideKeyboard);
+ }
+
+ @Test
+ public void getTopSystemBarHideForKeyboard_topBarNotEnabled_returnsFalse() {
+ when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false);
+ mSystemBarConfigs = new SystemBarConfigs(mResources);
+
+ boolean hideKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP);
+
+ assertFalse(hideKeyboard);
+ }
+
+ @Test
public void topSystemBarHasHigherZOrderThanHuns_topSystemBarIsNavigationBarPanelType() {
when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn(
SystemBarConfigs.getHunZOrder() + 1);
@@ -198,5 +229,14 @@
when(mResources.getInteger(R.integer.config_bottomSystemBarZOrder)).thenReturn(10);
when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(2);
when(mResources.getInteger(R.integer.config_rightSystemBarZOrder)).thenReturn(3);
+
+ when(mResources.getBoolean(R.bool.config_hideTopSystemBarForKeyboard)).thenReturn(false);
+ when(mResources.getBoolean(
+ com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard)).thenReturn(
+ false);
+ when(mResources.getBoolean(R.bool.config_hideLeftSystemBarForKeyboard)).thenReturn(
+ false);
+ when(mResources.getBoolean(R.bool.config_hideRightSystemBarForKeyboard)).thenReturn(
+ false);
}
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java
index 421e210..bf9ac30 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java
@@ -23,7 +23,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
-import android.app.ActivityManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
@@ -79,8 +79,8 @@
@Test
public void isSafe_systemApp_returnsTrue() throws Exception {
- ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
- stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
+ RootTaskInfo taskInfo = new RootTaskInfo();
+ taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.packageName = APP_PACKAGE_NAME;
@@ -89,13 +89,13 @@
when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
.thenReturn(applicationInfo);
- assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isTrue();
+ assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue();
}
@Test
public void isSafe_updatedSystemApp_returnsTrue() throws Exception {
- ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
- stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
+ RootTaskInfo taskInfo = new RootTaskInfo();
+ taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.packageName = APP_PACKAGE_NAME;
@@ -104,7 +104,7 @@
when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any()))
.thenReturn(applicationInfo);
- assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isTrue();
+ assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue();
}
@Test
@@ -113,8 +113,8 @@
/* initiatingPackageSigningInfo= */null,
/* originatingPackageName= */ null,
/* installingPackageName= */ null);
- ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
- stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
+ RootTaskInfo taskInfo = new RootTaskInfo();
+ taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.packageName = APP_PACKAGE_NAME;
@@ -123,7 +123,7 @@
.thenReturn(applicationInfo);
when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo);
- assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isTrue();
+ assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue();
}
@Test
@@ -132,8 +132,8 @@
/* initiatingPackageSigningInfo= */null,
/* originatingPackageName= */ null,
/* installingPackageName= */ null);
- ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
- stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
+ RootTaskInfo taskInfo = new RootTaskInfo();
+ taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.packageName = APP_PACKAGE_NAME;
@@ -142,7 +142,7 @@
.thenReturn(applicationInfo);
when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo);
- assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isFalse();
+ assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isFalse();
}
@Test
@@ -151,8 +151,8 @@
/* initiatingPackageSigningInfo= */null,
/* originatingPackageName= */ null,
/* installingPackageName= */ null);
- ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
- stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
+ RootTaskInfo taskInfo = new RootTaskInfo();
+ taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.packageName = APP_PACKAGE_NAME;
@@ -161,6 +161,6 @@
.thenReturn(applicationInfo);
when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo);
- assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isFalse();
+ assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isFalse();
}
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
index 67f222b..0b5f68f 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java
@@ -21,7 +21,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.ActivityManager.StackInfo;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.hardware.display.DisplayManager;
@@ -81,22 +81,22 @@
int displayId = 123;
ComponentName componentName = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
- StackInfo stackInfo1 = createTask(1, /* isVisible= */ true);
- stackInfo1.taskIds = new int[] { 11, 22, 33 };
+ RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ true);
+ taskInfo1.childTaskIds = new int[] { 11, 22, 33 };
- StackInfo stackInfo2 = createTask(2, /* isVisible= */ true);
- stackInfo2.taskIds = new int[] { 111, 222, 333, taskId };
- stackInfo2.displayId = displayId;
+ RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
+ taskInfo2.childTaskIds = new int[] { 111, 222, 333, taskId };
+ taskInfo2.displayId = displayId;
- List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2);
+ List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2);
- when(mActivityTaskManager.getAllStackInfos()).thenReturn(stackInfoList);
- when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(true);
+ when(mActivityTaskManager.getAllRootTaskInfos()).thenReturn(taskInfoList);
+ when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true);
mSideLoadedAppListener.onTaskCreated(taskId, componentName);
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1);
- verify(mSideLoadedAppDetector).isSafe(stackInfo2);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo2);
verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any());
@@ -109,23 +109,23 @@
int displayId = 123;
ComponentName componentName = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME);
- StackInfo stackInfo1 = createTask(1, /* isVisible= */ true);
- stackInfo1.taskIds = new int[] { 11, 22, 33 };
- StackInfo stackInfo2 = createTask(2, /* isVisible= */ true);
- stackInfo2.taskIds = new int[] { 111, 222, 333, taskId };
- stackInfo2.displayId = displayId;
- List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2);
+ RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ true);
+ taskInfo1.childTaskIds = new int[] { 11, 22, 33 };
+ RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
+ taskInfo2.childTaskIds = new int[] { 111, 222, 333, taskId };
+ taskInfo2.displayId = displayId;
+ List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2);
Display display = createDisplay(displayId);
- when(mActivityTaskManager.getAllStackInfos()).thenReturn(stackInfoList);
- when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(false);
+ when(mActivityTaskManager.getAllRootTaskInfos()).thenReturn(taskInfoList);
+ when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(false);
when(mDisplayManager.getDisplay(displayId)).thenReturn(display);
mSideLoadedAppListener.onTaskCreated(taskId, componentName);
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1);
- verify(mSideLoadedAppDetector).isSafe(stackInfo2);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo2);
verify(mSideLoadedAppStateController).onUnsafeTaskCreatedOnDisplay(display);
verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any());
@@ -135,21 +135,21 @@
@Test
public void onTaskStackChanged_safeTask_callsSafeTaskDisplayed() throws Exception {
Display display = createDisplay(123);
- StackInfo stackInfo1 = createTask(1, /* isVisible= */ false);
- StackInfo stackInfo2 = createTask(2, /* isVisible= */ true);
- StackInfo stackInfo3 = createTask(3, /* isVisible= */ true);
- List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2, stackInfo3);
+ RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false);
+ RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
+ RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true);
+ List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2, taskInfo3);
- when(mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId()))
- .thenReturn(stackInfoList);
- when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(true);
+ when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId()))
+ .thenReturn(taskInfoList);
+ when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true);
when(mDisplayManager.getDisplays()).thenReturn(new Display[] { display });
mSideLoadedAppListener.onTaskStackChanged();
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1);
- verify(mSideLoadedAppDetector).isSafe(stackInfo2);
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo3);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo2);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3);
verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display);
@@ -159,21 +159,21 @@
@Test
public void onTaskStackChanged_unsafeTask_callsUnsafeTaskDisplayed() throws Exception {
Display display = createDisplay(123);
- StackInfo stackInfo1 = createTask(1, /* isVisible= */ false);
- StackInfo stackInfo2 = createTask(2, /* isVisible= */ true);
- StackInfo stackInfo3 = createTask(3, /* isVisible= */ true);
- List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2, stackInfo3);
+ RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false);
+ RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
+ RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true);
+ List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2, taskInfo3);
- when(mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId()))
- .thenReturn(stackInfoList);
- when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(false);
+ when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId()))
+ .thenReturn(taskInfoList);
+ when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(false);
when(mDisplayManager.getDisplays()).thenReturn(new Display[] { display });
mSideLoadedAppListener.onTaskStackChanged();
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1);
- verify(mSideLoadedAppDetector).isSafe(stackInfo2);
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo3);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo2);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3);
verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any());
@@ -183,40 +183,40 @@
@Test
public void onTaskStackChanged_multiDisplay_callsTasksDisplayed() throws Exception {
Display display1 = createDisplay(1);
- StackInfo stackInfo1 = createTask(1, /* isVisible= */ false);
- StackInfo stackInfo2 = createTask(2, /* isVisible= */ true);
- StackInfo stackInfo3 = createTask(3, /* isVisible= */ true);
- List<StackInfo> display1Stack = Arrays.asList(stackInfo1, stackInfo2, stackInfo3);
+ RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false);
+ RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true);
+ RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true);
+ List<RootTaskInfo> display1Tasks = Arrays.asList(taskInfo1, taskInfo2, taskInfo3);
Display display2 = createDisplay(2);
- StackInfo stackInfo4 = createTask(4, /* isVisible= */ true);
- List<StackInfo> display2Stack = Collections.singletonList(stackInfo4);
+ RootTaskInfo taskInfo4 = createTask(4, /* isVisible= */ true);
+ List<RootTaskInfo> display2Tasks = Collections.singletonList(taskInfo4);
Display display3 = createDisplay(3);
- StackInfo stackInfo5 = createTask(5, /* isVisible= */ true);
- List<StackInfo> display3Stack = Collections.singletonList(stackInfo5);
+ RootTaskInfo taskInfo5 = createTask(5, /* isVisible= */ true);
+ List<RootTaskInfo> display3Tasks = Collections.singletonList(taskInfo5);
- when(mActivityTaskManager.getAllStackInfosOnDisplay(display1.getDisplayId()))
- .thenReturn(display1Stack);
- when(mActivityTaskManager.getAllStackInfosOnDisplay(display2.getDisplayId()))
- .thenReturn(display2Stack);
- when(mActivityTaskManager.getAllStackInfosOnDisplay(display3.getDisplayId()))
- .thenReturn(display3Stack);
+ when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display1.getDisplayId()))
+ .thenReturn(display1Tasks);
+ when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display2.getDisplayId()))
+ .thenReturn(display2Tasks);
+ when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display3.getDisplayId()))
+ .thenReturn(display3Tasks);
- when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(true);
- when(mSideLoadedAppDetector.isSafe(stackInfo4)).thenReturn(false);
- when(mSideLoadedAppDetector.isSafe(stackInfo5)).thenReturn(true);
+ when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true);
+ when(mSideLoadedAppDetector.isSafe(taskInfo4)).thenReturn(false);
+ when(mSideLoadedAppDetector.isSafe(taskInfo5)).thenReturn(true);
when(mDisplayManager.getDisplays())
.thenReturn(new Display[] { display1, display2, display3});
mSideLoadedAppListener.onTaskStackChanged();
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1);
- verify(mSideLoadedAppDetector).isSafe(stackInfo2);
- verify(mSideLoadedAppDetector, never()).isSafe(stackInfo3);
- verify(mSideLoadedAppDetector).isSafe(stackInfo4);
- verify(mSideLoadedAppDetector).isSafe(stackInfo5);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo2);
+ verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo4);
+ verify(mSideLoadedAppDetector).isSafe(taskInfo5);
verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any());
verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display1);
@@ -234,10 +234,10 @@
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
}
- private StackInfo createTask(int id, boolean isVisible) {
- StackInfo stackInfo = new StackInfo();
- stackInfo.stackId = id;
- stackInfo.visible = isVisible;
- return stackInfo;
+ private RootTaskInfo createTask(int id, boolean isVisible) {
+ RootTaskInfo taskInfo = new RootTaskInfo();
+ taskInfo.taskId = id;
+ taskInfo.visible = isVisible;
+ return taskInfo;
}
}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java
index 8f9e56e..ac7edd3 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/statusbar/UserNameViewControllerTest.java
@@ -109,6 +109,13 @@
}
@Test
+ public void removeAll_withNoRegisteredListener_doesNotUnregister() {
+ mUserNameViewController.removeAll();
+
+ verifyZeroInteractions(mCarUserManager);
+ }
+
+ @Test
public void userLifecycleListener_onUserSwitchLifecycleEvent_updatesUserNameView() {
ArgumentCaptor<CarUserManager.UserLifecycleListener> userLifecycleListenerArgumentCaptor =
ArgumentCaptor.forClass(CarUserManager.UserLifecycleListener.class);
diff --git a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
index 47eeb83..2b9fa41 100644
--- a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
@@ -2,7 +2,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="keyguard_description" msgid="8582605799129954556">"Geef je wachtwoord op en ga door naar \'Dynamische systeemupdates\'"</string>
- <string name="notification_install_completed" msgid="6252047868415172643">"Dynamisch systeem is gereed. Start je apparaat opnieuw op om het te gebruiken."</string>
+ <string name="notification_install_completed" msgid="6252047868415172643">"Dynamisch systeem is klaar. Start je apparaat opnieuw op om het te gebruiken."</string>
<string name="notification_install_inprogress" msgid="7383334330065065017">"Installatie wordt uitgevoerd"</string>
<string name="notification_install_failed" msgid="4066039210317521404">"Installatie mislukt"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"Valideren van afbeelding mislukt. Installatie afbreken."</string>
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index f8952ac..4d31ce9 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -334,6 +334,11 @@
throw new IOException(
"Failed to start installation with requested size: " + mUserdataSize);
}
+ // Reset installation session and verify that installation completes successfully.
+ mInstallationSession = null;
+ if (!mDynSystem.closePartition()) {
+ throw new IOException("Failed to complete partition installation: userdata");
+ }
}
private void installImages()
@@ -503,6 +508,12 @@
imageValidationThrowOrWarning(new KeyRevokedException(publicKey));
}
}
+
+ // Reset installation session and verify that installation completes successfully.
+ mInstallationSession = null;
+ if (!mDynSystem.closePartition()) {
+ throw new IOException("Failed to complete partition installation: " + partitionName);
+ }
}
private static String toHexString(byte[] bytes) {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_czech_qwerty.kcm b/packages/InputDevices/res/raw/keyboard_layout_czech_qwerty.kcm
new file mode 100644
index 0000000..457d4da
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_czech_qwerty.kcm
@@ -0,0 +1,365 @@
+# Copyright (C) 2020 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.
+
+#
+# Czech (EU - qwerty) keyboard layout.
+#
+
+type OVERLAY
+
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: ';'
+ base: ';'
+ shift: '\u00b0'
+ ralt: '\u0060'
+ shift+ralt: '\u007e'
+}
+
+key 1 {
+ label: '1'
+ base: '+'
+ shift: '1'
+ ralt: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '\u011b'
+ capslock: '\u011a'
+ shift: '2'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '\u0161'
+ capslock: '\u0160'
+ shift: '3'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '\u010d'
+ capslock: '\u010c'
+ shift: '4'
+ ralt: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '\u0159'
+ capslock: '\u0158'
+ shift: '5'
+ ralt: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '\u017e'
+ capslock: '\u017d'
+ shift: '6'
+ ralt: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '\u00fd'
+ capslock: '\u00dd'
+ shift: '7'
+ ralt: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '\u00e1'
+ capslock: '\u00c1'
+ shift: '8'
+ ralt: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '\u00ed'
+ capslock: '\u00cd'
+ shift: '9'
+ ralt: '('
+}
+
+key 0 {
+ label: '0'
+ base: '\u00e9'
+ capslock: '\u00c9'
+ shift: '0'
+ ralt: ')'
+}
+
+key MINUS {
+ label: '='
+ base: '='
+ shift: '%'
+ ralt: '-'
+ ralt+shift: '_'
+}
+
+key EQUALS {
+ label: '\u00b4'
+ base: '\u0301'
+ shift: '\u030c'
+ ralt: '='
+ ralt+shift: '+'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u20ac'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u00fa'
+ base: '\u00fa'
+ capslock: '\u00da'
+ shift: '/'
+ ralt: '['
+ ralt+shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: ')'
+ base: ')'
+ shift: '('
+ ralt: ']'
+ ralt+shift: '}'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u016f'
+ base: '\u016f'
+ capslock: '\u016e'
+ shift: '"'
+ ralt: ';'
+ ralt+shift: ':'
+}
+
+key APOSTROPHE {
+ label: '\u00a7'
+ base: '\u00a7'
+ shift: '!'
+ ralt: '\u00a4'
+ ralt+shift: '\u005e'
+}
+
+key BACKSLASH {
+ label: '\u0308'
+ base: '\u0308'
+ shift: '\''
+ ralt: '\\'
+ ralt+shift: '|'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '\\'
+ base: '\\'
+ shift: '|'
+ ralt: '\u00df'
+ shift+ralt: '\u02dd'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+ ralt: '@'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+ ralt: '\u00b5'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '?'
+ ralt: '<'
+ shift+ralt: '\u00d7'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: ':'
+ ralt: '>'
+ shift+ralt: '\u00f7'
+}
+
+key SLASH {
+ label: '-'
+ base: '-'
+ shift: '_'
+ ralt: '/'
+ ralt+shift: '?'
+}
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 9878146..e95a159 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -75,6 +75,9 @@
<!-- Czech keyboard layout label. [CHAR LIMIT=35] -->
<string name="keyboard_layout_czech">Czech</string>
+ <!-- Czech qwerty keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_czech_qwerty">Czech QWERTY style</string>
+
<!-- Estonian keyboard layout label. [CHAR LIMIT=35] -->
<string name="keyboard_layout_estonian">Estonian</string>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 0d7a13b..aa599ae 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -92,6 +92,10 @@
android:label="@string/keyboard_layout_czech"
android:keyboardLayout="@raw/keyboard_layout_czech" />
+ <keyboard-layout android:name="keyboard_layout_czech_qwerty"
+ android:label="@string/keyboard_layout_czech_qwerty"
+ android:keyboardLayout="@raw/keyboard_layout_czech_qwerty" />
+
<keyboard-layout android:name="keyboard_layout_estonian"
android:label="@string/keyboard_layout_estonian"
android:keyboardLayout="@raw/keyboard_layout_estonian" />
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index 87f89ce..c840374 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -57,7 +57,7 @@
<string name="uninstall_application_text_all_users" msgid="575491774380227119">"هل تريد إزالة هذا التطبيق "<b>"لكل"</b>" المستخدمين؟ ستتم إزالة التطبيق وبياناته من "<b>"كل"</b>" المستخدمين على هذا الجهاز."</string>
<string name="uninstall_application_text_user" msgid="498072714173920526">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string>
<string name="uninstall_update_text" msgid="863648314632448705">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string>
- <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
+ <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد إعادة ضبط هذا التطبيق على الإعدادات الأصلية؟ سؤدي ذلك إلى إزالة جميع البيانات، كما سيؤثر على جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"الاحتفاظ بالحجم <xliff:g id="SIZE">%1$s</xliff:g> من بيانات التطبيق."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"عمليات إلغاء التثبيت الجارية"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"عمليات إلغاء التثبيت غير الناجحة"</string>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index 108c86f..d3a9589 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="7488448184431507488">"Pakket-installatie"</string>
<string name="install" msgid="711829760615509273">"Installeren"</string>
- <string name="done" msgid="6632441120016885253">"Gereed"</string>
+ <string name="done" msgid="6632441120016885253">"Klaar"</string>
<string name="cancel" msgid="1018267193425558088">"Annuleren"</string>
<string name="installing" msgid="4921993079741206516">"Installeren…"</string>
<string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeren…"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 8f71509..7f6237d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -212,7 +212,7 @@
<string name="adb_wireless_settings" msgid="2295017847215680229">"Адладка па Wi-Fi"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Каб праглядаць і выкарыстоўваць даступныя прылады, уключыце адладку па Wi-Fi"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Спалучыць прыладу з дапамогай QR-кода"</string>
- <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кода"</string>
+ <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кодаў"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Спалучыць прыладу з дапамогай кода спалучэння"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Спалучаць новыя прылады з дапамогай шасцізначнага кода"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Спалучаныя прылады"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 7c2a0fd..775cd15 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -187,7 +187,7 @@
<item msgid="97587758561106269">"Isključeno"</item>
<item msgid="7126170197336963369">"Međuspremnici svih zapisnika"</item>
<item msgid="7167543126036181392">"Međuspremnici svih zapisnika osim radija"</item>
- <item msgid="5135340178556563979">"samo međuspremnik zapisnika kernela"</item>
+ <item msgid="5135340178556563979">"samo međumemorija zapisnika kernela"</item>
</string-array>
<string-array name="window_animation_scale_entries">
<item msgid="2675263395797191850">"Animacija isključena"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index dcdadbd..4a11aa7 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -400,7 +400,7 @@
<string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktibo. Aldatzeko, sakatu hau."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Egonean moduko aplikazioaren egoera: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Abian diren zerbitzuak"</string>
- <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ikusi eta kontrolatu unean abian diren zerbitzuak"</string>
+ <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ikusi eta kontrolatu une honetan abian diren zerbitzuak"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView inplementazioa"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Ezarri WebView inplementazioa"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Jada ez dago erabilgarri aukera hori. Saiatu berriro."</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 743017c..7a4e71b 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -243,7 +243,7 @@
</string-array>
<string-array name="track_frame_time_entries">
<item msgid="634406443901014984">"OFF"</item>
- <item msgid="1288760936356000927">"バーとして画面に表示"</item>
+ <item msgid="1288760936356000927">"棒グラフとして画面に表示"</item>
<item msgid="5023908510820531131">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g> 内"</item>
</string-array>
<string-array name="debug_hw_overdraw_entries">
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index c4b5f7e..419c18f 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -396,8 +396,8 @@
<item msgid="1282170165150762976">"Санарип мазмун үчүн оптималдаштырылган түстөр"</item>
</string-array>
<string name="inactive_apps_title" msgid="5372523625297212320">"Көшүү режиминдеги колдонмолор"</string>
- <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Иштеген жок. Которуштуруу үчүн таптап коюңуз."</string>
- <string name="inactive_app_active_summary" msgid="8047630990208722344">"Иштеп турат. Которуштуруу үчүн таптап коюңуз."</string>
+ <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Иштеген жок. Күйгүзүү үчүн басып коюңуз."</string>
+ <string name="inactive_app_active_summary" msgid="8047630990208722344">"Иштеп турат. Өчүрүү үчүн басып коюңуз."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Көшүү режиминдеги колдонмонун абалы:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"Иштеп жаткан кызматтар"</string>
<string name="runningservices_settings_summary" msgid="1046080643262665743">"Учурда иштеп жаткан кызматтарды көрүп, көзөмөлдөп турасыз"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index fb7b634..58d4af1 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -204,10 +204,10 @@
<string name="tethering_settings_not_available" msgid="266821736434699780">"Поставките за спојување не се достапни за овој корисник"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"Поставките за името на пристапната точка не се достапни за овој корисник"</string>
<string name="enable_adb" msgid="8072776357237289039">"Отстранување грешки на USB"</string>
- <string name="enable_adb_summary" msgid="3711526030096574316">"Режим на отстранување грешки кога е поврзано USB"</string>
+ <string name="enable_adb_summary" msgid="3711526030096574316">"Режим за отстранување грешки кога е поврзано USB"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"Отповикај овластувања за отстранување грешки од USB"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Безжично отстранување грешки"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим на отстранување грешки кога е поврзано Wi‑Fi"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим за отстранување грешки кога е поврзано Wi‑Fi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Грешка"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Безжично отстранување грешки"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"За да ги гледате и користите достапните уреди, вклучете го безжичното отстранување грешки"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index b280806..2fd46d9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -13,6 +13,7 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -29,6 +30,10 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
+import androidx.annotation.NonNull;
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.UserIcons;
import com.android.launcher3.icons.IconFactory;
@@ -504,4 +509,25 @@
== NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
return !isInIwlan;
}
+
+ /**
+ * Returns a bitmap with rounded corner.
+ *
+ * @param context application context.
+ * @param source bitmap to apply round corner.
+ * @param cornerRadius corner radius value.
+ */
+ public static Bitmap convertCornerRadiusBitmap(@NonNull Context context,
+ @NonNull Bitmap source, @NonNull float cornerRadius) {
+ final Bitmap roundedBitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(),
+ Bitmap.Config.ARGB_8888);
+ final RoundedBitmapDrawable drawable =
+ RoundedBitmapDrawableFactory.create(context.getResources(), source);
+ drawable.setAntiAlias(true);
+ drawable.setCornerRadius(cornerRadius);
+ final Canvas canvas = new Canvas(roundedBitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return roundedBitmap;
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 68f7289..8f8f859 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -18,6 +18,7 @@
import android.util.Pair;
import androidx.annotation.DrawableRes;
+import androidx.core.graphics.drawable.IconCompat;
import com.android.settingslib.R;
import com.android.settingslib.widget.AdaptiveIcon;
@@ -216,6 +217,23 @@
}
/**
+ * Create an Icon pointing to a drawable.
+ */
+ public static IconCompat createIconWithDrawable(Drawable drawable) {
+ Bitmap bitmap;
+ if (drawable instanceof BitmapDrawable) {
+ bitmap = ((BitmapDrawable) drawable).getBitmap();
+ } else {
+ final int width = drawable.getIntrinsicWidth();
+ final int height = drawable.getIntrinsicHeight();
+ bitmap = createBitmap(drawable,
+ width > 0 ? width : 1,
+ height > 0 ? height : 1);
+ }
+ return IconCompat.createWithBitmap(bitmap);
+ }
+
+ /**
* Build device icon with advanced outline
*/
public static Drawable buildAdvancedDrawable(Context context, Drawable drawable) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index c5e66be..a81a05f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -116,6 +116,16 @@
*/
public static final int HIGHER_FREQ_5GHZ = 5900;
+ /**
+ * Lower bound on the 60 GHz (802.11ad) WIGIG channels
+ */
+ public static final int LOWER_FREQ_60GHZ = 58320;
+
+ /**
+ * Upper bound on the 60 GHz (802.11ad) WIGIG channels
+ */
+ public static final int HIGHER_FREQ_60GHZ = 70200;
+
/** The key which identifies this AccessPoint grouping. */
private String mKey;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
index 1ace0b4..15b146d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
@@ -93,6 +93,7 @@
StringBuilder visibility = new StringBuilder();
StringBuilder scans24GHz = new StringBuilder();
StringBuilder scans5GHz = new StringBuilder();
+ StringBuilder scans60GHz = new StringBuilder();
String bssid = null;
if (accessPoint.isActive() && info != null) {
@@ -115,9 +116,11 @@
int maxRssi5 = INVALID_RSSI;
int maxRssi24 = INVALID_RSSI;
+ int maxRssi60 = INVALID_RSSI;
final int maxDisplayedScans = 4;
int num5 = 0; // number of scanned BSSID on 5GHz band
int num24 = 0; // number of scanned BSSID on 2.4Ghz band
+ int num60 = 0; // number of scanned BSSID on 60Ghz band
int numBlockListed = 0;
// TODO: sort list by RSSI or age
@@ -152,6 +155,19 @@
verboseScanResultSummary(accessPoint, result, bssid,
nowMs));
}
+ } else if (result.frequency >= AccessPoint.LOWER_FREQ_60GHZ
+ && result.frequency <= AccessPoint.HIGHER_FREQ_60GHZ) {
+ // Strictly speaking: [60000, 61000]
+ num60++;
+
+ if (result.level > maxRssi60) {
+ maxRssi60 = result.level;
+ }
+ if (num60 <= maxDisplayedScans) {
+ scans60GHz.append(
+ verboseScanResultSummary(accessPoint, result, bssid,
+ nowMs));
+ }
}
}
visibility.append(" [");
@@ -170,6 +186,14 @@
}
visibility.append(scans5GHz.toString());
}
+ visibility.append(";");
+ if (num60 > 0) {
+ visibility.append("(").append(num60).append(")");
+ if (num60 > maxDisplayedScans) {
+ visibility.append("max=").append(maxRssi60).append(",");
+ }
+ visibility.append(scans60GHz.toString());
+ }
if (numBlockListed > 0) {
visibility.append("!").append(numBlockListed);
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a293148..dd2aa3b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -58,10 +58,14 @@
ConfigSettingsProto.CONNECTIVITY_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
ConfigSettingsProto.CONTENT_CAPTURE_SETTINGS);
+ namespaceToFieldMap.put(DeviceConfig.NAMESPACE_DEVICE_IDLE,
+ ConfigSettingsProto.DEVICE_IDLE_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_GAME_DRIVER,
ConfigSettingsProto.GAME_DRIVER_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
ConfigSettingsProto.INPUT_NATIVE_BOOT_SETTINGS);
+ namespaceToFieldMap.put(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
+ ConfigSettingsProto.JOB_SCHEDULER_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_NETD_NATIVE,
ConfigSettingsProto.NETD_NATIVE_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_PRIVACY,
@@ -564,9 +568,6 @@
Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
GlobalSettingsProto.Device.PROVISIONING_MOBILE_DATA_ENABLED);
dumpSetting(s, p,
- Settings.Global.DEVICE_IDLE_CONSTANTS,
- GlobalSettingsProto.Device.IDLE_CONSTANTS);
- dumpSetting(s, p,
Settings.Global.DEVICE_POLICY_CONSTANTS,
GlobalSettingsProto.Device.POLICY_CONSTANTS);
dumpSetting(s, p,
@@ -1776,6 +1777,9 @@
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
SecureSettingsProto.Accessibility.HIGH_TEXT_CONTRAST_ENABLED);
dumpSetting(s, p,
+ Settings.Secure.FORCE_BOLD_TEXT,
+ SecureSettingsProto.FORCE_BOLD_TEXT);
+ dumpSetting(s, p,
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
SecureSettingsProto.Accessibility.LARGE_POINTER_ICON);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index f219aec..d8f772d 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -230,7 +230,6 @@
Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM,
Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
Settings.Global.DEVICE_DEMO_MODE,
- Settings.Global.DEVICE_IDLE_CONSTANTS,
Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS,
Settings.Global.BATTERY_SAVER_CONSTANTS,
Settings.Global.BATTERY_TIP_CONSTANTS,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 319b44c..190015c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -217,6 +217,9 @@
<!-- Permission needed for CTS test - UnsupportedErrorDialogTests -->
<uses-permission android:name="android.permission.RESET_APP_ERRORS" />
+ <!-- Permission needed for CTS test - CtsSystemUiTestCases:PipNotificationTests -->
+ <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
+
<!-- Permission needed to run keyguard manager tests in CTS -->
<uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
diff --git a/packages/SimAppDialog/Android.bp b/packages/SimAppDialog/Android.bp
index 1c680bb..176035f 100644
--- a/packages/SimAppDialog/Android.bp
+++ b/packages/SimAppDialog/Android.bp
@@ -7,8 +7,7 @@
static_libs: [
"androidx.legacy_legacy-support-v4",
- "setupcompat",
- "setupdesign",
+ "setup-wizard-lib",
],
resource_dirs: ["res"],
diff --git a/packages/SimAppDialog/AndroidManifest.xml b/packages/SimAppDialog/AndroidManifest.xml
index e7368f3..873f6c5 100644
--- a/packages/SimAppDialog/AndroidManifest.xml
+++ b/packages/SimAppDialog/AndroidManifest.xml
@@ -23,7 +23,7 @@
android:name=".InstallCarrierAppActivity"
android:exported="true"
android:permission="android.permission.NETWORK_SETTINGS"
- android:theme="@style/SudThemeGlif.Light">
+ android:theme="@style/SuwThemeGlif.Light">
</activity>
</application>
</manifest>
diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
index 68113db..12f9bb6 100644
--- a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
+++ b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
@@ -14,17 +14,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.google.android.setupdesign.GlifLayout
+<com.android.setupwizardlib.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_signal_cellular_alt_rounded"
- app:sucHeaderText="@string/install_carrier_app_title">
+ app:suwHeaderText="@string/install_carrier_app_title"
+ app:suwFooter="@layout/install_carrier_app_footer">
<LinearLayout
- style="@style/SudContentFrame"
+ style="@style/SuwContentFrame"
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -32,12 +33,12 @@
<TextView
android:id="@+id/install_carrier_app_description"
- style="@style/SudDescription.Glif"
+ style="@style/SuwDescription.Glif"
android:text="@string/install_carrier_app_description_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- <com.google.android.setupdesign.view.FillContentLayout
+ <com.android.setupwizardlib.view.FillContentLayout
android:id="@+id/illo_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -46,12 +47,12 @@
<ImageView
android:src="@drawable/illo_sim_app_dialog"
- style="@style/SudContentIllustration"
+ style="@style/SuwContentIllustration"
android:contentDescription="@string/install_carrier_app_image_content_description"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- </com.google.android.setupdesign.view.FillContentLayout>
- </LinearLayout>
+ </com.android.setupwizardlib.view.FillContentLayout>
+</LinearLayout>
-</com.google.android.setupdesign.GlifLayout>
+</com.android.setupwizardlib.GlifLayout>
diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml b/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml
new file mode 100644
index 0000000..10dcb77
--- /dev/null
+++ b/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<com.android.setupwizardlib.view.ButtonBarLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/footer"
+ style="@style/SuwGlifButtonBar.Stackable"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/skip_button"
+ style="@style/SuwGlifButton.Secondary"
+ android:text="@string/install_carrier_app_defer_action"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <Button
+ android:id="@+id/download_button"
+ style="@style/SuwGlifButton.Primary"
+ android:text="@string/install_carrier_app_download_action"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+</com.android.setupwizardlib.view.ButtonBarLayout>
diff --git a/packages/SimAppDialog/res/values/styles.xml b/packages/SimAppDialog/res/values/styles.xml
deleted file mode 100644
index 824e380..0000000
--- a/packages/SimAppDialog/res/values/styles.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2020 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.
--->
-<resources>
-
- <style name="SetupWizardPartnerResource">
- <!-- Disable to use partner overlay theme for outside setupwizard flow. -->
- <item name="sucUsePartnerResource">false</item>
- <!-- Enable heavy theme style inside setupwizard flow. -->
- <item name="sudUsePartnerHeavyTheme">true</item>
- </style>
-
-</resources>
diff --git a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
index 0b6f9bb..abe82a8 100644
--- a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
+++ b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
@@ -17,17 +17,14 @@
import android.app.Activity;
import android.content.Intent;
-import android.content.res.Resources;
import android.os.Bundle;
import android.sysprop.SetupWizardProperties;
import android.text.TextUtils;
import android.view.View;
+import android.widget.Button;
import android.widget.TextView;
-import com.google.android.setupcompat.template.FooterBarMixin;
-import com.google.android.setupcompat.template.FooterButton;
-import com.google.android.setupdesign.GlifLayout;
-import com.google.android.setupdesign.util.ThemeResolver;
+import com.android.setupwizardlib.util.WizardManagerHelper;
/**
* Activity that gives a user the choice to download the SIM app or defer until a later time
@@ -38,7 +35,7 @@
* Can display the carrier app name if its passed into the intent with key
* {@link #BUNDLE_KEY_CARRIER_NAME}
*/
-public class InstallCarrierAppActivity extends Activity {
+public class InstallCarrierAppActivity extends Activity implements View.OnClickListener {
/**
* Key for the carrier app name that will be displayed as the app to download. If unset, a
* default description will be used
@@ -53,33 +50,20 @@
protected void onCreate(Bundle icicle) {
// Setup theme for aosp/pixel
setTheme(
- new ThemeResolver.Builder()
- .setDefaultTheme(R.style.SudThemeGlifV3_Light)
- .build()
- .resolve(SetupWizardProperties.theme().orElse(""),
- /* suppressDayNight= */ false));
+ WizardManagerHelper.getThemeRes(
+ SetupWizardProperties.theme().orElse(""),
+ R.style.SuwThemeGlif_Light
+ )
+ );
super.onCreate(icicle);
setContentView(R.layout.install_carrier_app_activity);
- GlifLayout layout = findViewById(R.id.setup_wizard_layout);
- FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
- mixin.setSecondaryButton(
- new FooterButton.Builder(this)
- .setText(R.string.install_carrier_app_defer_action)
- .setListener(this::onSkipButtonClick)
- .setButtonType(FooterButton.ButtonType.SKIP)
- .setTheme(R.style.SudGlifButton_Secondary)
- .build());
+ Button notNowButton = findViewById(R.id.skip_button);
+ notNowButton.setOnClickListener(this);
- mixin.setPrimaryButton(
- new FooterButton.Builder(this)
- .setText(R.string.install_carrier_app_download_action)
- .setListener(this::onDownloadButtonClick)
- .setButtonType(FooterButton.ButtonType.OTHER)
- .setTheme(R.style.SudGlifButton_Primary)
- .build());
-
+ Button downloadButton = findViewById(R.id.download_button);
+ downloadButton.setOnClickListener(this);
// Show/hide illo depending on whether one was provided in a resource overlay
boolean showIllo = getResources().getBoolean(R.bool.show_sim_app_dialog_illo);
@@ -98,17 +82,15 @@
}
@Override
- protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
- theme.applyStyle(R.style.SetupWizardPartnerResource, true);
- super.onApplyThemeResource(theme, resid, first);
- }
-
- protected void onSkipButtonClick(View view) {
- finish(DEFER_RESULT);
- }
-
- protected void onDownloadButtonClick(View view) {
- finish(DOWNLOAD_RESULT);
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.skip_button:
+ finish(DEFER_RESULT);
+ break;
+ case R.id.download_button:
+ finish(DOWNLOAD_RESULT);
+ break;
+ }
}
private void finish(int resultCode) {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6db3d0b..06a97b1 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -390,7 +390,7 @@
</activity-alias>
<activity
- android:name=".stackdivider.ForcedResizableInfoActivity"
+ android:name="com.android.wm.shell.splitscreen.ForcedResizableInfoActivity"
android:theme="@style/ForcedResizableTheme"
android:excludeFromRecents="true"
android:stateNotNeeded="true"
@@ -711,10 +711,9 @@
<service android:name=".controls.controller.AuxiliaryPersistenceWrapper$DeletionJobService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
- <!-- started from ControlsFavoritingActivity -->
+ <!-- started from ControlsRequestReceiver -->
<activity
android:name=".controls.management.ControlsRequestDialog"
- android:exported="true"
android:theme="@style/Theme.ControlsRequestDialog"
android:finishOnCloseSystemDialogs="true"
android:showForAllUsers="true"
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index bd93c39..ee8d023 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -111,10 +111,6 @@
Shows UI for keyboard shortcuts (triggered by keyboard shortcut).
-### [com.android.systemui.onehanded.OneHandedUI](/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java)
-
-Shows the overlay controls when One handed is triggered.
-
### [com.android.systemui.shortcut.ShortcutKeyDispatcher](/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java)
Dispatches shortcut to System UI components.
diff --git a/packages/SystemUI/docs/camera.md b/packages/SystemUI/docs/camera.md
new file mode 100644
index 0000000..7a7a5aa
--- /dev/null
+++ b/packages/SystemUI/docs/camera.md
@@ -0,0 +1,33 @@
+# How double-click power launches the camera
+
+_as of august 2020_
+
+
+## Sequence of events
+
+
+
+1. [PhoneWindowManager.java](/services/core/java/com/android/server/policy/PhoneWindowManager.java) is responsible for all power button presses (see `interceptPowerKeyDown`).
+2. Even though PWMgr has a lot of logic to detect all manner of power button multipresses and gestures, it also checks with GestureLauncherService, which is also [offered the chance](/services/core/java/com/android/server/policy/PhoneWindowManager.java#943) to [intercept](/services/core/java/com/android/server/GestureLauncherService.java#358) the power key.
+3. GLS is responsible for the camera timeout, and if it detects one, it [forwards it to the StatusBarManagerService](/services/core/java/com/android/server/GestureLauncherService.java#475) (which hands it off to SystemUI).
+4. Inside SystemUI, [onCameraLaunchDetected](/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java#3927) looks at the keyguard state and determines
+ 1. whether the camera is even allowed
+ 2. whether the screen is on; if not, we need to delay until that happens
+ 3. whether the device is locked (defined as "keyuguard is showing").
+5. If the device is unlocked (no keyguard), the camera is launched immediately. [Callsite](/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java#3949).
+6. If the keyguard is up, however, [KeyguardBottomAreaView.launchCamera](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#477) takes over to handle the "secure camera" (a different intent, usually directing to the same app, but giving that app the cue to not allow access to the photo roll, etc).
+7. If the intent [would have to launch a resolver](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#480) (the user has multiple cameras installed and hasn’t chosen one to always launch for the `SECURE_CAMERA_INTENT`),
+ 1. In order to show the resolver, the lockscreen "bouncer" (authentication method) [is first presented](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#523).
+8. Otherwise (just one secure camera), [it is launched](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#501) (with some window animation gymnastics).
+
+
+## Which intent launches?
+
+
+
+* If the keyguard is not showing (device is unlocked)
+ * `KeyguardBottomAreaView.INSECURE_CAMERA_INTENT`, defined to be `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA`.
+ * [Callsite](/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java#3950) in StatusBar.java.
+* If the keyguard is showing (device locked)
+ * [KeyguardBottomAreaView.getCameraIntent()](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#366) is consulted, which allows the "keyguard right button" (which we don’t actually show) to control the camera intent. The [default implementation](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#831) returns one of `KeyguardBottomAreaView.INSECURE_CAMERA_INTENT` or `KeyguardBottomAreaView.SECURE_CAMERA_INTENT`, which are `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA` and `MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE`, respectively.
+ * [Callsite](/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java#523) in KeyguardBottomAreaView.java.
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 6d86a78..65e3f0d 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -112,7 +112,7 @@
<string name="kg_pin_accepted" msgid="1625501841604389716">"تم قبول الرمز"</string>
<string name="keyguard_carrier_default" msgid="6359808469637388586">"لا تتوفر خدمة."</string>
<string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تبديل أسلوب الإدخال"</string>
- <string name="airplane_mode" msgid="2528005343938497866">"وضع الطائرة"</string>
+ <string name="airplane_mode" msgid="2528005343938497866">"وضع الطيران"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"يجب رسم النقش بعد إعادة تشغيل الجهاز"</string>
<string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز"</string>
<string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز"</string>
diff --git a/packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml b/packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml
new file mode 100644
index 0000000..998db3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="22"
+ android:viewportHeight="17"
+ android:width="22dp"
+ android:height="17dp">
+ <group>
+ <group>
+ <path android:fillColor="#FF000000"
+ android:pathData="M19.98,3.54v2.81c0,0.47 -0.15,0.84 -0.44,1.11s-0.69,0.41 -1.2,0.41c-0.5,0 -0.89,-0.13 -1.19,-0.4s-0.44,-0.63 -0.45,-1.09V3.54h0.88v2.82c0,0.28 0.07,0.48 0.2,0.61c0.13,0.13 0.32,0.19 0.56,0.19c0.49,0 0.75,-0.26 0.75,-0.78V3.54H19.98z"/>
+ <path android:fillColor="#FF000000"
+ android:pathData="M19.42,12.25l0.57,-3.04h0.88l-0.95,4.27h-0.88l-0.69,-2.85l-0.69,2.85h-0.88l-0.95,-4.27h0.88l0.58,3.03l0.7,-3.03h0.74L19.42,12.25z"/>
+ </group>
+ <group>
+ <path android:fillColor="#FF000000"
+ android:pathData="M0.94,8.49l0.43,-4.96H5.7v1.17H2.39L2.15,7.41c0.41,-0.29 0.85,-0.43 1.33,-0.43c0.77,0 1.38,0.3 1.83,0.9c0.44,0.6 0.66,1.41 0.66,2.43c0,1.03 -0.24,1.84 -0.72,2.43c-0.48,0.59 -1.14,0.88 -1.98,0.88c-0.75,0 -1.36,-0.24 -1.83,-0.73c-0.47,-0.49 -0.74,-1.16 -0.81,-2.02h1.13c0.07,0.57 0.23,1 0.49,1.29c0.26,0.29 0.59,0.43 1.01,0.43c0.47,0 0.84,-0.2 1.1,-0.61c0.26,-0.41 0.4,-0.96 0.4,-1.65c0,-0.65 -0.14,-1.18 -0.43,-1.59C4.05,8.32 3.67,8.11 3.19,8.11c-0.4,0 -0.72,0.1 -0.96,0.31L1.9,8.75L0.94,8.49z"/>
+ </group>
+ <path android:fillColor="#FF000000"
+ android:pathData="M13.86,12.24l-0.22,0.27c-0.63,0.73 -1.55,1.1 -2.76,1.1c-1.08,0 -1.92,-0.36 -2.53,-1.07c-0.61,-0.71 -0.93,-1.72 -0.94,-3.02V7.56c0,-1.39 0.28,-2.44 0.84,-3.13c0.56,-0.7 1.39,-1.04 2.51,-1.04c0.95,0 1.69,0.26 2.22,0.79c0.54,0.53 0.83,1.28 0.89,2.26h-1.25c-0.05,-0.62 -0.22,-1.1 -0.52,-1.45c-0.29,-0.35 -0.74,-0.52 -1.34,-0.52c-0.72,0 -1.24,0.23 -1.57,0.7C8.85,5.63 8.68,6.37 8.66,7.4v2.03c0,1 0.19,1.77 0.57,2.31c0.38,0.54 0.93,0.8 1.65,0.8c0.67,0 1.19,-0.16 1.54,-0.49l0.18,-0.17V9.59h-1.82V8.52h3.07V12.24z"/>
+ </group>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml b/packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml
new file mode 100644
index 0000000..998db3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="22"
+ android:viewportHeight="17"
+ android:width="22dp"
+ android:height="17dp">
+ <group>
+ <group>
+ <path android:fillColor="#FF000000"
+ android:pathData="M19.98,3.54v2.81c0,0.47 -0.15,0.84 -0.44,1.11s-0.69,0.41 -1.2,0.41c-0.5,0 -0.89,-0.13 -1.19,-0.4s-0.44,-0.63 -0.45,-1.09V3.54h0.88v2.82c0,0.28 0.07,0.48 0.2,0.61c0.13,0.13 0.32,0.19 0.56,0.19c0.49,0 0.75,-0.26 0.75,-0.78V3.54H19.98z"/>
+ <path android:fillColor="#FF000000"
+ android:pathData="M19.42,12.25l0.57,-3.04h0.88l-0.95,4.27h-0.88l-0.69,-2.85l-0.69,2.85h-0.88l-0.95,-4.27h0.88l0.58,3.03l0.7,-3.03h0.74L19.42,12.25z"/>
+ </group>
+ <group>
+ <path android:fillColor="#FF000000"
+ android:pathData="M0.94,8.49l0.43,-4.96H5.7v1.17H2.39L2.15,7.41c0.41,-0.29 0.85,-0.43 1.33,-0.43c0.77,0 1.38,0.3 1.83,0.9c0.44,0.6 0.66,1.41 0.66,2.43c0,1.03 -0.24,1.84 -0.72,2.43c-0.48,0.59 -1.14,0.88 -1.98,0.88c-0.75,0 -1.36,-0.24 -1.83,-0.73c-0.47,-0.49 -0.74,-1.16 -0.81,-2.02h1.13c0.07,0.57 0.23,1 0.49,1.29c0.26,0.29 0.59,0.43 1.01,0.43c0.47,0 0.84,-0.2 1.1,-0.61c0.26,-0.41 0.4,-0.96 0.4,-1.65c0,-0.65 -0.14,-1.18 -0.43,-1.59C4.05,8.32 3.67,8.11 3.19,8.11c-0.4,0 -0.72,0.1 -0.96,0.31L1.9,8.75L0.94,8.49z"/>
+ </group>
+ <path android:fillColor="#FF000000"
+ android:pathData="M13.86,12.24l-0.22,0.27c-0.63,0.73 -1.55,1.1 -2.76,1.1c-1.08,0 -1.92,-0.36 -2.53,-1.07c-0.61,-0.71 -0.93,-1.72 -0.94,-3.02V7.56c0,-1.39 0.28,-2.44 0.84,-3.13c0.56,-0.7 1.39,-1.04 2.51,-1.04c0.95,0 1.69,0.26 2.22,0.79c0.54,0.53 0.83,1.28 0.89,2.26h-1.25c-0.05,-0.62 -0.22,-1.1 -0.52,-1.45c-0.29,-0.35 -0.74,-0.52 -1.34,-0.52c-0.72,0 -1.24,0.23 -1.57,0.7C8.85,5.63 8.68,6.37 8.66,7.4v2.03c0,1 0.19,1.77 0.57,2.31c0.38,0.54 0.93,0.8 1.65,0.8c0.67,0 1.19,-0.16 1.54,-0.49l0.18,-0.17V9.59h-1.82V8.52h3.07V12.24z"/>
+ </group>
+</vector>
+
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 316fa8a..eae2cbb 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Wys laeprioriteit-kennisgewingikone"</string>
<string name="other" msgid="429768510980739978">"Ander"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Skermverdeler"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Volskerm links"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Links 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Links 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Links 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Volskerm regs"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Volskerm bo"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Bo 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Bo 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Bo 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Volskerm onder"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dubbeltik om te wysig."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dubbeltik om by te voeg."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Skuif <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Skuif <xliff:g id="TILE_NAME">%1$s</xliff:g> na posisie <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kitsinstellingswysiger."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-kennisgewing: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Program sal dalk nie met verdeelde skerm werk nie."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Program steun nie verdeelde skerm nie."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Program steun nie begin op sekondêre skerms nie."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Maak instellings oop."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Maak kitsinstellings oop."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Maak kitsinstellings toe."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e2a4dc6..e8326a7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"አነስተኛ ቅድሚያ ያላቸው የማሳወቂያ አዶዎችን አሳይ"</string>
<string name="other" msgid="429768510980739978">"ሌላ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"የተከፈለ የማያ ገጽ ከፋይ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"የግራ ሙሉ ማያ ገጽ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ግራ 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ግራ 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ግራ 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"የቀኝ ሙሉ ማያ ገጽ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"የላይ ሙሉ ማያ ገጽ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ከላይ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ከላይ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ከላይ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"የታች ሙሉ ማያ ገጽ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ቦታ <xliff:g id="POSITION">%1$d</xliff:g>፣ <xliff:g id="TILE_NAME">%2$s</xliff:g>። ለማርትዕ ሁለቴ መታ ያድርጉ።"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>። ለማከል ሁለቴ መታ ያድርጉ።"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ን ይውሰዱ"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ን ወደ አቀማመጥ <xliff:g id="POSITION">%2$d</xliff:g> አንቀሳቅስ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"የፈጣን ቅንብሮች አርታዒ።"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"የ<xliff:g id="ID_1">%1$s</xliff:g> ማሳወቂያ፦ <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ቅንብሮችን ክፈት።"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ፈጣን ቅንብሮችን ክፈት።"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ፈጣን ቅንብሮችን ዝጋ።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index b33c6c5..b020f17 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -232,7 +232,7 @@
<string name="not_default_data_content_description" msgid="6757881730711522517">"لم يتم الضبط على استخدام البيانات"</string>
<string name="cell_data_off" msgid="4886198950247099526">"غير مفعّلة"</string>
<string name="accessibility_bluetooth_tether" msgid="6327291292208790599">"التوصيل عبر البلوتوث"</string>
- <string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطائرة."</string>
+ <string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطيران."</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"الشبكة الافتراضية الخاصة (VPN) قيد التفعيل."</string>
<string name="accessibility_no_sims" msgid="5711270400476534667">"ليس هناك شريحة SIM."</string>
<string name="carrier_network_change_mode" msgid="5174141476991149918">"جارٍ تغيير شبكة مشغِّل شبكة الجوّال."</string>
@@ -267,10 +267,10 @@
<string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"تم تفعيل Wifi."</string>
<string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"الجوّال <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="533594896310663853">"البطارية <xliff:g id="STATE">%s</xliff:g>."</string>
- <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"إيقاف وضع الطائرة."</string>
- <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"تفعيل وضع الطائرة."</string>
- <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"تم إيقاف وضع الطائرة."</string>
- <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"تم تفعيل وضع الطائرة."</string>
+ <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"إيقاف وضع الطيران."</string>
+ <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"تفعيل وضع الطيران."</string>
+ <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"تم إيقاف وضع الطيران."</string>
+ <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"تم تفعيل وضع الطيران."</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"كتم الصوت تمامًا"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"المنبِّهات فقط"</string>
<string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"عدم الإزعاج"</string>
@@ -664,7 +664,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"إيثرنت"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"المنبّه"</string>
<string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string>
- <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطائرة"</string>
+ <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
<string name="add_tile" msgid="6239678623873086686">"إضافة فئة"</string>
<string name="broadcast_tile" msgid="5224010633596487481">"إرسال فئة"</string>
<string name="zen_alarm_warning_indef" msgid="5252866591716504287">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g> إلا إذا أوقفت هذا قبل الموعد"</string>
@@ -899,17 +899,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"إظهار رموز الإشعارات ذات الأولوية المنخفضة"</string>
<string name="other" msgid="429768510980739978">"غير ذلك"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"أداة تقسيم الشاشة"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"عرض النافذة اليسرى بملء الشاشة"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ضبط حجم النافذة اليسرى ليكون ٧٠%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ضبط حجم النافذة اليسرى ليكون ٣٠%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"عرض النافذة اليمنى بملء الشاشة"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"عرض النافذة العلوية بملء الشاشة"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ضبط حجم النافذة العلوية ليكون ٧٠%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ضبط حجم النافذة العلوية ليكون ٥٠%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ضبط حجم النافذة العلوية ليكون ٣٠%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"عرض النافذة السفلية بملء الشاشة"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"الموضع <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>. انقر مرّتين للتعديل."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. انقر مرّتين للإضافة."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"نقل <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -918,10 +907,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"نقل <xliff:g id="TILE_NAME">%1$s</xliff:g> إلى الموضع <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"برنامج تعديل الإعدادات السريعة."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"إشعار <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"يمكن ألا يعمل التطبيق مع وضع تقسيم الشاشة."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"التطبيق لا يتيح تقسيم الشاشة."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"فتح الإعدادات."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"فتح الإعدادات السريعة."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"إغلاق الإعدادات السريعة."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 5a3c659..31077da 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"কম গুৰুত্বপূৰ্ণ জাননীৰ আইকনসমূহ দেখুৱাওক"</string>
<string name="other" msgid="429768510980739978">"অন্যান্য"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"স্প্লিট স্ক্ৰীণৰ বিভাজক"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"বাওঁফালৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"বাওঁফালৰ স্ক্ৰীণখন ৭০% কৰক"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"বাওঁফালৰ স্ক্ৰীণখন ৫০% কৰক"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"বাওঁফালৰ স্ক্ৰীণখন ৩০% কৰক"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"সোঁফালৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"শীৰ্ষ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"শীর্ষ স্ক্ৰীণখন ৭০% কৰক"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"শীর্ষ স্ক্ৰীণখন ৫০% কৰক"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"শীর্ষ স্ক্ৰীণখন ৩০% কৰক"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"তলৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"অৱস্থান <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। সম্পাদনা কৰিবৰ বাবে দুবাৰ টিপক।"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। যোগ কৰিবলৈ দুবাৰ টিপক।"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> স্থানান্তৰ কৰক"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ক এই স্থান <xliff:g id="POSITION">%2$d</xliff:g>লৈ যাওক"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ক্ষিপ্ৰ ছেটিংসমূহৰ সম্পাদক।"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> জাননী: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"বিভাজিত স্ক্ৰীণৰ সৈতে এপে হয়তো কাম নকৰিব।"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"এপটোৱে বিভাজিত স্ক্ৰীণ সমৰ্থন নকৰে।"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ছেটিংসমূহ খোলক।"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ক্ষিপ্ৰ ছেটিংসমূহ খোলক।"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ক্ষিপ্ৰ ছেটিংসমূহ বন্ধ কৰক।"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 40df8cd..b596066 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Aşağı prioritet bildiriş işarələrini göstərin"</string>
<string name="other" msgid="429768510980739978">"Digər"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Bölünmüş ekran ayırıcısı"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Sol tam ekran"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Sol 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Sol 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Sol 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Sağ tam ekran"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Yuxarı tam ekran"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Yuxarı 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Yuxarı 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Yuxarı 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Aşağı tam ekran"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Redaktə etmək üçün iki dəfə tıklayın."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Əlavə etmək üçün iki dəfə tıklayın."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> köçürün"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> pozisiyasına <xliff:g id="TILE_NAME">%1$s</xliff:g> köçürün"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sürətli ayarlar redaktoru."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildiriş: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Tətbiq bölünmüş ekran ilə işləməyə bilər."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Tətbiq ekran bölünməsini dəstəkləmir."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Tətbiq ikinci ekranda işləməyə bilər."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları açın."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Cəld ayarları açın."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cəld ayarları bağlayın."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index a9725f3..aa141e6 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -884,17 +884,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obaveštenja niskog prioriteta"</string>
<string name="other" msgid="429768510980739978">"Drugo"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Razdelnik podeljenog ekrana"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Režim celog ekrana za levi ekran"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Levi ekran 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Levi ekran 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Levi ekran 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Režim celog ekrana za donji ekran"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Režim celog ekrana za gornji ekran"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gornji ekran 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gornji ekran 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gornji ekran 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Režim celog ekrana za donji ekran"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvaput dodirnite da biste izmenili."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dvaput dodirnite da biste dodali."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Premesti pločicu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -903,10 +892,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premestite „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ na poziciju <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija možda neće funkcionisati sa podeljenim ekranom."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podržava podeljeni ekran."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori Podešavanja."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvori Brza podešavanja."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvori Brza podešavanja."</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index b4c5eba..194f92b 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Паказваць значкі апавяшчэнняў з нізкім прыярытэтам"</string>
<string name="other" msgid="429768510980739978">"Іншае"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Раздзяляльнік падзеленага экрана"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Левы экран – поўнаэкранны рэжым"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Левы экран – 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Левы экран – 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Левы экран – 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Правы экран – поўнаэкранны рэжым"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Верхні экран – поўнаэкранны рэжым"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Верхні экран – 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Верхні экран – 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Верхні экран – 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ніжні экран – поўнаэкранны рэжым"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Месца: <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Краніце двойчы, каб рэдагаваць."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Краніце двойчы, каб дадаць."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Перамясціць <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Перамясціць \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" у наступнае месца: <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Рэдактар хуткіх налад."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Апавяшчэнне <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Праграма можа не працаваць у рэжыме дзялення экрана."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Праграма не падтрымлівае функцыю дзялення экрана."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Праграма можа не працаваць на дадатковых экранах."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Праграма не падтрымлівае запуск на дадатковых экранах."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Адкрыць налады."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Адкрыць хуткія налады."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрыць хуткія налады."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 52e8286..02eea8a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Показване на иконите за известията с нисък приоритет"</string>
<string name="other" msgid="429768510980739978">"Друго"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Разделител в режима за разделен екран"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ляв екран: Показване на цял екран"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ляв екран: 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ляв екран: 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ляв екран: 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Десен екран: Показване на цял екран"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Горен екран: Показване на цял екран"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Горен екран: 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Горен екран: 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Горен екран: 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Долен екран: Показване на цял екран"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>, „<xliff:g id="TILE_NAME">%2$s</xliff:g>“. Докоснете двукратно, за да редактирате."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"„<xliff:g id="TILE_NAME">%1$s</xliff:g>“. Докоснете двукратно, за да добавите."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Преместване на „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Преместете „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ на позиция <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор за бързи настройки."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Известие от <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Приложението може да не работи в режим на разделен екран."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Приложението не поддържа разделен екран."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Възможно е приложението да не работи на алтернативни дисплеи."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Приложението не поддържа използването на алтернативни дисплеи."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отваряне на настройките."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отваряне на бързите настройки."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затваряне на бързите настройки."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index d0de9cf..96a7368 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"কম-গুরুত্বপূর্ণ বিজ্ঞপ্তির আইকন দেখুন"</string>
<string name="other" msgid="429768510980739978">"অন্যান্য"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"বিভক্ত-স্ক্রিন বিভাজক"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"বাঁ দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"৭০% বাকি আছে"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"৫০% বাকি আছে"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"৩০% বাকি আছে"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ডান দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"উপর দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"শীর্ষ ৭০%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"শীর্ষ ৫০%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"শীর্ষ ৩০%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"নীচের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> লোকেশন, <xliff:g id="TILE_NAME">%2$s</xliff:g>৷ সম্পাদনা করতে দুবার আলতো চাপুন৷"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>৷ যোগ করতে দুবার আলতো চাপুন৷"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> সরান"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>-এ সরান"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"দ্রুত সেটিংস সম্পাদক৷"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> বিজ্ঞপ্তি: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"অ্যাপ্লিকেশানটি বিভক্ত স্ক্রীনে কাজ নাও করতে পারে৷"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"অ্যাপ্লিকেশান বিভক্ত-স্ক্রিন সমর্থন করে না৷"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"সেটিংস খুলুন।"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"দ্রুত সেটিংস খুলুন৷"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"দ্রুত সেটিংস বন্ধ করুন৷"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 57b7945..0a091aa 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -884,17 +884,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavještenja niskog prioriteta"</string>
<string name="other" msgid="429768510980739978">"Ostalo"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Razdjelnik ekrana"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lijevo cijeli ekran"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Lijevo 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Lijevo 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Lijevo 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Desno cijeli ekran"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Gore cijeli ekran"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gore 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gore 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gore 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Donji ekran kao cijeli ekran"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dodirnite dvaput za uređivanje."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> Dodirnite dvaput za dodavanje."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Pomjeri <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -903,10 +892,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premjesti <xliff:g id="TILE_NAME">%1$s</xliff:g> na poziciju <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivanje brzih postavki"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> obavještenje: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija možda neće raditi na podijeljenom ekranu"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podržava dijeljenje ekrana."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija možda neće raditi na sekundarnom ekranu."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori postavke."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvoriti brze postavke."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvoriti brze postavke."</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0489d18..d4e8bef 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -707,7 +707,7 @@
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactiva les notificacions"</string>
<string name="inline_keep_showing_app" msgid="4393429060390649757">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"Silenci"</string>
- <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string>
+ <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string>
<string name="notification_bubble_title" msgid="8330481035191903164">"Bombolla"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sense so ni vibració"</string>
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostra les icones de notificació amb prioritat baixa"</string>
<string name="other" msgid="429768510980739978">"Altres"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de pantalles"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla esquerra completa"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Pantalla esquerra al 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Pantalla esquerra al 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Pantalla esquerra al 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla dreta completa"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla superior completa"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Pantalla superior al 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Pantalla superior al 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Pantalla superior al 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla inferior completa"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posició <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Fes doble toc per editar-la."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Fes doble toc per afegir-ho."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mou <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mou <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuració ràpida."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificació de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"L\'aplicació no admet la pantalla dividida."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'aplicació no es pot obrir en pantalles secundàries."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Obre la configuració."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Obre la configuració ràpida."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tanca la configuració ràpida."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index acb6637..239a0f6 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Zobrazit ikony oznámení s nízkou prioritou"</string>
<string name="other" msgid="429768510980739978">"Jiné"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Čára rozdělující obrazovku"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Levá část na celou obrazovku"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % vlevo"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % vlevo"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % vlevo"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pravá část na celou obrazovku"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Horní část na celou obrazovku"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % nahoře"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % nahoře"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % nahoře"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Dolní část na celou obrazovku"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvojitým klepnutím ji upravíte."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dlaždici přidáte dvojitým klepnutím."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Přesunout dlaždici <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Přesunout dlaždici <xliff:g id="TILE_NAME">%1$s</xliff:g> na pozici <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rychlého nastavení"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Oznámení aplikace <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikace v režimu rozdělené obrazovky nemusí fungovat."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikace nepodporuje režim rozdělené obrazovky."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikace na sekundárním displeji nemusí fungovat."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikace nepodporuje spuštění na sekundárních displejích."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otevřít nastavení."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otevřít rychlé nastavení."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zavřít rychlé nastavení."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 8863695..7ce60ea 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for notifikationer med lav prioritet"</string>
<string name="other" msgid="429768510980739978">"Andet"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Adskiller til opdelt skærm"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vis venstre del i fuld skærm"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Venstre 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Venstre 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Venstre 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Vis højre del i fuld skærm"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Vis øverste del i fuld skærm"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Øverste 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Øverste 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Øverste 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Vis nederste del i fuld skærm"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tryk to gange for at redigere."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tryk to gange for at tilføje."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Flyt <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Flyt <xliff:g id="TILE_NAME">%1$s</xliff:g> til position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsværktøj til Kvikmenu."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-notifikation: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Appen fungerer muligvis ikke i opdelt skærm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Appen understøtter ikke opdelt skærm."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Appen fungerer muligvis ikke på sekundære skærme."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Appen kan ikke åbnes på sekundære skærme."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Åbn Indstillinger."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Åbn Kvikmenu."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Luk Kvikmenu."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8d990c6..093e1a2 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Symbole für Benachrichtigungen mit einer niedrigen Priorität anzeigen"</string>
<string name="other" msgid="429768510980739978">"Sonstiges"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Bildschirmteiler"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vollbild links"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % links"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % links"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % links"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Vollbild rechts"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Vollbild oben"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % oben"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % oben"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % oben"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Vollbild unten"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Zum Bearbeiten doppeltippen."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Zum Hinzufügen doppeltippen."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> verschieben"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> auf Position <xliff:g id="POSITION">%2$d</xliff:g> verschieben"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor für Schnelleinstellungen."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Benachrichtigung von <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Die App funktioniert unter Umständen bei geteiltem Bildschirm nicht."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Das Teilen des Bildschirms wird in dieser App nicht unterstützt."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Die App unterstützt den Start auf sekundären Displays nicht."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Einstellungen öffnen."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Schnelleinstellungen öffnen."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Schnelleinstellungen schließen."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 5ca236b..ac1a3ee 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Εμφάνιση εικονιδίων ειδοποιήσεων χαμηλής προτεραιότητας"</string>
<string name="other" msgid="429768510980739978">"Άλλο"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Διαχωριστικό οθόνης"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Αριστερή πλήρης οθόνη"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Αριστερή 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Αριστερή 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Αριστερή 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Δεξιά πλήρης οθόνη"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Πάνω πλήρης οθόνη"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Πάνω 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Πάνω 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Πάνω 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Κάτω πλήρης οθόνη"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Πατήστε δύο φορές για επεξεργασία."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Πατήστε δύο φορές για προσθήκη."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Μετακίνηση <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Μετακίνηση <xliff:g id="TILE_NAME">%1$s</xliff:g> στη θέση <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Επεξεργασία γρήγορων ρυθμίσεων."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Ειδοποίηση <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Δεν είναι δυνατή η λειτουργία της εφαρμογής με διαχωρισμό οθόνης."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Άνοιγμα ρυθμίσεων."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Άνοιγμα γρήγορων ρυθμίσεων."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Κλείσιμο γρήγορων ρυθμίσεων."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 8a7963a..3a76d75 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 7b2b25a..ac65193 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 8a7963a..3a76d75 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 8a7963a..3a76d75 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 15738f2..0a36dae 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
<string name="other" msgid="429768510980739978">"Other"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Split-screen divider"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string>
@@ -1082,6 +1067,8 @@
<string name="controls_added_tooltip" msgid="4842812921719153085">"Hold Power button to see new controls"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"Add controls"</string>
<string name="controls_menu_edit" msgid="890623986951347062">"Edit controls"</string>
- <string name="one_handed_tutorial_title" msgid="6312198435090726656">"Using one-handed mode"</string>
- <string name="one_handed_tutorial_description" msgid="7674850272340517174">"To exit, swipe up from the bottom of the screen or tap anywhere above the app"</string>
+ <!-- no translation found for one_handed_tutorial_title (6312198435090726656) -->
+ <skip />
+ <!-- no translation found for one_handed_tutorial_description (7674850272340517174) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index aa81ab8..ccc4626 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar íconos de notificaciones con prioridad baja"</string>
<string name="other" msgid="429768510980739978">"Otros"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de pantalla dividida"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla izquierda completa"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Izquierda: 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Izquierda: 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Izquierda: 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla derecha completa"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla superior completa"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Superior: 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Superior: 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Superior: 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla inferior completa"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Presiona dos veces para editarla."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Presiona dos veces para agregarlo."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posición <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de Configuración rápida"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Es posible que la app no funcione en el modo de pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"La app no es compatible con la función de pantalla dividida."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Es posible que la app no funcione en una pantalla secundaria."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"La app no puede iniciarse en pantallas secundarias."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir Configuración"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir la configuración rápida"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cerrar configuración rápida"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8638570..79c2fbd 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -98,7 +98,7 @@
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sonido de tu dispositivo, como música, llamadas y tonos de llamada"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Micrófono"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio y micrófono del dispositivo"</string>
- <string name="screenrecord_start" msgid="330991441575775004">"Empezar"</string>
+ <string name="screenrecord_start" msgid="330991441575775004">"Iniciar"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Grabando pantalla"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Grabando pantalla y audio"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques en la pantalla"</string>
@@ -395,7 +395,7 @@
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Conectado (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería)"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Conectando..."</string>
<string name="quick_settings_tethering_label" msgid="5257299852322475780">"Compartir conexión"</string>
- <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Zona Wi-Fi"</string>
+ <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Punto de acceso"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activando…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ahorro de datos activado"</string>
<plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
@@ -660,7 +660,7 @@
<string name="alarm_template" msgid="2234991538018805736">"a las <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="3561752195856839456">"el <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="accessibility_quick_settings_detail" msgid="544463655956179791">"Ajustes rápidos, <xliff:g id="TITLE">%s</xliff:g>."</string>
- <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Zona Wi-Fi"</string>
+ <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Punto de acceso"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconos de notificaciones con prioridad baja"</string>
<string name="other" msgid="429768510980739978">"Otros"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Dividir la pantalla"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla izquierda completa"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Izquierda 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Izquierda 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Izquierda 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla derecha completa"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla superior completa"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Superior 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Superior 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Superior 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla inferior completa"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toca dos veces para cambiarla."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toca dos veces para añadirlo."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posición <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de ajustes rápidos."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Es posible que la aplicación no funcione con la pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"La aplicación no admite la pantalla dividida."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Es posible que la aplicación no funcione en una pantalla secundaria."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"La aplicación no se puede abrir en pantallas secundarias."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir ajustes."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir ajustes rápidos."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cerrar ajustes rápidos."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f5ffad2..21189f1 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Kuva madala prioriteediga märguande ikoonid"</string>
<string name="other" msgid="429768510980739978">"Muu"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Ekraanijagaja"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vasak täisekraan"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vasak: 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vasak: 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vasak: 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Parem täisekraan"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ülemine täisekraan"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Ülemine: 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Ülemine: 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Ülemine: 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Alumine täisekraan"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Asend <xliff:g id="POSITION">%1$d</xliff:g>, paan <xliff:g id="TILE_NAME">%2$s</xliff:g>. Topeltpuudutage muutmiseks."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Topeltpuudutage lisamiseks."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Paani <xliff:g id="TILE_NAME">%1$s</xliff:g> teisaldamine"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Teisaldage <xliff:g id="TILE_NAME">%1$s</xliff:g> asendisse <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kiirseadete redigeerija."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Teenuse <xliff:g id="ID_1">%1$s</xliff:g> märguanne: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Rakendus ei pruugi poolitatud ekraaniga töötada."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Rakendus ei toeta jagatud ekraani."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Rakendus ei pruugi teisesel ekraanil töötada."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ava seaded."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ava kiirseaded."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Sule kiirseaded."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 23bcd2c..8a37236 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Erakutsi lehentasun txikiko jakinarazpenen ikonoak"</string>
<string name="other" msgid="429768510980739978">"Beste bat"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Pantaila-zatitzailea"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ezarri ezkerraldea pantaila osoan"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ezarri ezkerraldea % 70en"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ezarri ezkerraldea % 50en"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ezarri ezkerraldea % 30en"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Ezarri eskuinaldea pantaila osoan"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ezarri goialdea pantaila osoan"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Ezarri goialdea % 70en"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Ezarri goialdea % 50en"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Ezarri goialdea % 30en"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ezarri behealdea pantaila osoan"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. posizioa, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Editatzeko, sakatu birritan."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Gehitzeko, sakatu birritan."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mugitu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Eraman <xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>garren postura"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ezarpen bizkorren editorea."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> zerbitzuaren jakinarazpena: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikazioak ez du onartzen pantaila zatitua"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ireki ezarpenak."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ireki ezarpen bizkorrak."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Itxi ezarpen bizkorrak."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 55d8ab2..7f85959 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -808,7 +808,7 @@
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"برگشت"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"اعلانها"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"میانبرهای صفحهکلید"</string>
- <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر طرحبندی صفحهکلید"</string>
+ <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر جانمایی صفحهکلید"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"برنامهها"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"دستیار"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"مرورگر"</string>
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"نمایش نمادهای اعلان کماهمیت"</string>
<string name="other" msgid="429768510980739978">"موارد دیگر"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"تقسیمکننده صفحه"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"تمامصفحه چپ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"٪۷۰ چپ"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"٪۵۰ چپ"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"٪۳۰ چپ"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"تمامصفحه راست"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"تمامصفحه بالا"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"٪۷۰ بالا"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"٪۵۰ بالا"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"٪۳۰ بالا"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"تمامصفحه پایین"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"موقعیت <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>. برای ویرایش دو ضربه سریع بزنید."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. برای افزودن دو ضربه سریع بزنید."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"انتقال <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"انتقال <xliff:g id="TILE_NAME">%1$s</xliff:g> به موقعیت <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ویرایشگر تنظیمات سریع."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"اعلان <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ممکن است برنامه با تقسیم صفحه کار نکند."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"برنامه از تقسیم صفحه پشتیبانی نمیکند."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"برنامه از راهاندازی در نمایشگرهای ثانویه پشتیبانی نمیکند."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"باز کردن تنظیمات."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"باز کردن تنظیمات سریع."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"بستن تنظیمات سریع."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f30c44b..fd9bbd9 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Näytä vähemmän tärkeät ilmoituskuvakkeet"</string>
<string name="other" msgid="429768510980739978">"Muu"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Näytön jakaja"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vasen koko näytölle"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vasen 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vasen 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vasen 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Oikea koko näytölle"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Yläosa koko näytölle"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Yläosa 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Yläosa 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Yläosa 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Alaosa koko näytölle"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Muokkaa kaksoisnapauttamalla."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lisää kaksoisnapauttamalla."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Siirrä <xliff:g id="TILE_NAME">%1$s</xliff:g>."</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Siirrä <xliff:g id="TILE_NAME">%1$s</xliff:g> kohtaan <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Pika-asetusten muokkausnäkymä"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Ilmoitus kohteesta <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Sovellus ei ehkä toimi jaetulla näytöllä."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Sovellus ei tue jaetun näytön tilaa."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Avaa asetukset."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Avaa pika-asetukset."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Sulje pika-asetukset."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index f6196dd63..8817ceb 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification de faible priorité"</string>
<string name="other" msgid="429768510980739978">"Autre"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Séparateur d\'écran partagé"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Plein écran à la gauche"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % à la gauche"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % à la gauche"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % à la gauche"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Plein écran à la droite"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Plein écran dans le haut"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % dans le haut"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % dans le haut"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % dans le haut"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Plein écran dans le bas"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Touchez deux fois pour modifier."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Touchez deux fois pour ajouter."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Déplacer <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Déplacer <xliff:g id="TILE_NAME">%1$s</xliff:g> à la position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de paramètres rapides."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"L\'application n\'est pas compatible avec l\'écran partagé."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ouvrir les réglages rapides."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer les réglages rapides."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 0146ce4..35176c7 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification à faible priorité"</string>
<string name="other" msgid="429768510980739978">"Autre"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Séparateur d\'écran partagé"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Écran de gauche en plein écran"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Écran de gauche à 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Écran de gauche à 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Écran de gauche à 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Écran de droite en plein écran"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Écran du haut en plein écran"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Écran du haut à 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Écran du haut à 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Écran du haut à 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Écran du bas en plein écran"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, \"<xliff:g id="TILE_NAME">%2$s</xliff:g>\". Appuyer deux fois pour modifier."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Appuyer deux fois pour ajouter."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Déplacer \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\""</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Déplacer l\'élément \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" à la position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de configuration rapide."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Application incompatible avec l\'écran partagé."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ouvrir la fenêtre de configuration rapide."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer la fenêtre de configuration rapide."</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index fd4d3c6..7c62798 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconas das notificacións que teñan baixa prioridade"</string>
<string name="other" msgid="429768510980739978">"Outros"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de pantalla dividida"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla completa á esquerda"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % á esquerda"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % á esquerda"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % á esquerda"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla completa á dereita"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla completa arriba"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % arriba"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % arriba"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % arriba"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla completa abaixo"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toca dúas veces o elemento para editalo."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toca dúas veces o elemento para engadilo"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" á posición <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuración rápida."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Pode que a aplicación non funcione coa pantalla dividida."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"A aplicación non é compatible coa función de pantalla dividida."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"É posible que a aplicación non funcione nunha pantalla secundaria."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"A aplicación non se pode iniciar en pantallas secundarias."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configuración."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir configuración rápida."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Pechar a configuración rápida."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 46f7a2b..af0d7d3 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"ઓછી પ્રાધાન્યતાનું નોટિફિકેશન આઇકન બતાવો"</string>
<string name="other" msgid="429768510980739978">"અન્ય"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ડાબી પૂર્ણ સ્ક્રીન"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ડાબે 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ડાબે 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ડાબે 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"જમણી સ્ક્રીન સ્ક્રીન"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"શીર્ષ પૂર્ણ સ્ક્રીન"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"શીર્ષ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"શીર્ષ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"શીર્ષ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"તળિયાની પૂર્ણ સ્ક્રીન"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"સ્થિતિ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. સંપાદિત કરવા માટે બે વાર ટૅપ કરો."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ઉમેરવા માટે બે વાર ટૅપ કરો."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ખસેડો"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> જગ્યા પર <xliff:g id="TILE_NAME">%1$s</xliff:g>ને ખસેડો"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ્સ સંપાદક."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> નોટિફિકેશન: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"વિભાજિત-સ્ક્રીન સાથે ઍપ્લિકેશન કદાચ કામ ન કરે."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"સેટિંગ્સ ખોલો."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ઝડપી સેટિંગ્સ ખોલો."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ઝડપી સેટિંગ્સ બંધ કરો."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index e4a6ed7..0a7515d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -881,17 +881,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकता वाली सूचना के आइकॉन दिखाएं"</string>
<string name="other" msgid="429768510980739978">"अन्य"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"विभाजित स्क्रीन विभाजक"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"बाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"बाईं स्क्रीन को 70% बनाएं"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"बाईं स्क्रीन को 50% बनाएं"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"बाईं स्क्रीन को 30% बनाएं"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"दाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ऊपर की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ऊपर की स्क्रीन को 70% बनाएं"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ऊपर की स्क्रीन को 50% बनाएं"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ऊपर की स्क्रीन को 30% बनाएं"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"नीचे की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. में बदलाव करने के लिए दो बार छूएं."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. जोड़ने के लिए दो बार छूएं."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> को ले जाएं"</string>
@@ -900,10 +889,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> काे क्रम संख्या <xliff:g id="POSITION">%2$d</xliff:g> पर ले जाएं"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"त्वरित सेटिंग संपादक."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"हो सकता है कि ऐप्लिकेशन विभाजित स्क्रीन के साथ काम ना करे."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ऐप विभाजित स्क्रीन का समर्थन नहीं करता है."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिंग खोलें."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"क्विक सेटिंग खोलें."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"त्वरित सेटिंग बंद करें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index a27b066..27b6909 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -884,17 +884,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavijesti niskog prioriteta"</string>
<string name="other" msgid="429768510980739978">"Ostalo"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Razdjelnik podijeljenog zaslona"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lijevi zaslon u cijeli zaslon"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Lijevi zaslon na 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Lijevi zaslon na 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Lijevi zaslon na 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Desni zaslon u cijeli zaslon"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Gornji zaslon u cijeli zaslon"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gornji zaslon na 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gornji zaslon na 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gornji zaslon na 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Donji zaslon u cijeli zaslon"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dodirnite dvaput da biste uredili."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dodirnite dvaput da biste dodali."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Premjesti <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -903,10 +892,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premjestite pločicu <xliff:g id="TILE_NAME">%1$s</xliff:g> na položaj <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač brzih postavki."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> obavijest: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podržava podijeljeni zaslon."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvaranje postavki."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvaranje brzih postavki."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvaranje brzih postavki."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0d1f50a..1f52b2c 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -428,7 +428,7 @@
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string>
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Képernyő rögzítése"</string>
- <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Kezdés"</string>
+ <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Indítás"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Leállítás"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Eszköz"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Váltás az alkalmazások között felfelé csúsztatással"</string>
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Alacsony prioritású értesítési ikonok mutatása"</string>
<string name="other" msgid="429768510980739978">"Egyéb"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Elválasztó az osztott nézetben"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Bal oldali teljes képernyőre"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Bal oldali 70%-ra"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Bal oldali 50%-ra"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Bal oldali 30%-ra"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Jobb oldali teljes képernyőre"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Felső teljes képernyőre"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Felső 70%-ra"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Felső 50%-ra"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Felső 30%-ra"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Alsó teljes képernyőre"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. pozíció: <xliff:g id="TILE_NAME">%2$s</xliff:g>. Koppintson duplán a szerkesztéshez."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Koppintson duplán a hozzáadáshoz."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"A(z) <xliff:g id="TILE_NAME">%1$s</xliff:g> áthelyezése"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> áthelyezése a következő pozícióba: <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Gyorsbeállítások szerkesztője"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-értesítések: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Beállítások megnyitása."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Gyorsbeállítások megnyitása."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Gyorsbeállítások bezárása"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index f9a10fa..d4a093f 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Ցուցադրել ցածր առաջնահերթության ծանուցումների պատկերակները"</string>
<string name="other" msgid="429768510980739978">"Այլ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Տրոհված էկրանի բաժանիչ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ձախ էկրանը՝ լիաէկրան"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ձախ էկրանը՝ 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ձախ էկրանը՝ 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ձախ էկրանը՝ 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Աջ էկրանը՝ լիաէկրան"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Վերևի էկրանը՝ լիաէկրան"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Վերևի էկրանը՝ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Վերևի էկրանը՝ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Վերևի էկրանը՝ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ներքևի էկրանը՝ լիաէկրան"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Դիրք <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>: Կրկնակի հպեք՝ փոխելու համար:"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>: Կրկնակի հպեք՝ ավելացնելու համար:"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Տեղափոխել <xliff:g id="TILE_NAME">%1$s</xliff:g> սալիկը"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> սալիկը տեղափոխել դիրք <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Արագ կարգավորումների խմբագրիչ:"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ծանուցում՝ <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում:"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Բացել կարգավորումները:"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Բացել արագ կարգավորումները:"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Փակել արագ կարգավորումները:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f65be90..3b89b3d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Tampilkan ikon notifikasi prioritas rendah"</string>
<string name="other" msgid="429768510980739978">"Lainnya"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Pembagi layar terpisah"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Layar penuh di kiri"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kiri 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kiri 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kiri 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Layar penuh di kanan"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Layar penuh di atas"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Atas 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Atas 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Atas 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Layar penuh di bawah"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ketuk dua kali untuk mengedit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ketuk dua kali untuk menambahkan."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Pindahkan <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Pindahkan <xliff:g id="TILE_NAME">%1$s</xliff:g> ke posisi <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor setelan cepat."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notifikasi <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikasi mungkin tidak berfungsi dengan layar terpisah."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App tidak mendukung layar terpisah."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buka setelan."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Buka setelan cepat."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tutup setelan cepat."</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 66c9147..da8a092 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Sýna tákn fyrir tilkynningar með litlum forgangi"</string>
<string name="other" msgid="429768510980739978">"Annað"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Skjáskipting"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vinstri á öllum skjánum"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vinstri 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vinstri 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vinstri 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Hægri á öllum skjánum"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Efri á öllum skjánum"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Efri 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Efri 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Efri 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Neðri á öllum skjánum"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Staða <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ýttu tvisvar til að breyta."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ýttu tvisvar til að bæta við."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Færa <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Færa <xliff:g id="TILE_NAME">%1$s</xliff:g> í stöðu <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Flýtistillingaritill."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> tilkynning: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Hugsanlega virkar forritið ekki ef skjánum er skipt upp."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Forritið styður ekki að skjánum sé skipt."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Forrit styður ekki opnun á öðrum skjá."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Opna stillingar."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Opna flýtistillingar."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Loka flýtistillingum."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index b0e64a2..0ec9c23 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostra icone di notifiche con priorità bassa"</string>
<string name="other" msgid="429768510980739978">"Altro"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Strumento per schermo diviso"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Schermata sinistra a schermo intero"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Schermata sinistra al 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Schermata sinistra al 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Schermata sinistra al 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Schermata destra a schermo intero"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Schermata superiore a schermo intero"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Schermata superiore al 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Schermata superiore al 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Schermata superiore al 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Schermata inferiore a schermo intero"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tocca due volte per modificare."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tocca due volte per aggiungere."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Sposta <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Sposta il riquadro <xliff:g id="TILE_NAME">%1$s</xliff:g> nella posizione <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor di impostazioni rapide."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notifica di <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"L\'app potrebbe non funzionare con lo schermo diviso."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"L\'app non supporta la modalità Schermo diviso."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"L\'app potrebbe non funzionare su un display secondario."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'app non supporta l\'avvio su display secondari."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Apri le impostazioni."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Apri le impostazioni rapide."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Chiudi le impostazioni rapide."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 92fa09b..193c5f6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"הצגת סמלי התראות בעדיפות נמוכה"</string>
<string name="other" msgid="429768510980739978">"אחר"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"מחלק מסך מפוצל"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"מסך שמאלי מלא"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"שמאלה 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"שמאלה 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"שמאלה 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"מסך ימני מלא"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"מסך עליון מלא"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"עליון 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"עליון 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"עליון 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"מסך תחתון מלא"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. הקש פעמיים כדי לערוך."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. הקש פעמיים כדי להוסיף."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"הזזת <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"העברת <xliff:g id="TILE_NAME">%1$s</xliff:g> למיקום <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"עורך הגדרות מהירות."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"התראות <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ייתכן שהיישום לא יפעל עם מסך מפוצל."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"האפליקציה אינה תומכת במסך מפוצל."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ייתכן שהאפליקציה לא תפעל במסך משני."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"פתיחת הגדרות."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"פתיחה של \'הגדרות מהירות\'."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"סגירה של \'הגדרות מהירות\'."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index e427c8f..9aa9e76 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"優先度の低い通知アイコンを表示"</string>
<string name="other" msgid="429768510980739978">"その他"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"分割画面の分割線"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"左全画面"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"左 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"左 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"左 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"右全画面"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"上部全画面"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"上 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"上 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"上 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"下部全画面"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> の <xliff:g id="TILE_NAME">%2$s</xliff:g> を編集するにはダブルタップします。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> を追加するにはダブルタップします。"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> を移動します"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> をポジション <xliff:g id="POSITION">%2$d</xliff:g> に移動"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"クイック設定エディタ"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> の通知: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"アプリは分割画面では動作しないことがあります。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"アプリで分割画面がサポートされていません。"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"設定を開きます。"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"クイック設定を開きます。"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"クイック設定を閉じます。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index b86bf8c..aa6f35d 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"დაბალი პრიორიტეტის მქონე შეტყობინებების ხატულების ჩვენება"</string>
<string name="other" msgid="429768510980739978">"სხვა"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"მარცხენა ნაწილის სრულ ეკრანზე გაშლა"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"მარცხენა ეკრანი — 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"მარცხენა ეკრანი — 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"მარცხენა ეკრანი — 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"მარჯვენა ნაწილის სრულ ეკრანზე გაშლა"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ზედა ნაწილის სრულ ეკრანზე გაშლა"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ზედა ეკრანი — 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ზედა ეკრანი — 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ზედა ეკრანი — 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ქვედა ნაწილის სრულ ეკრანზე გაშლა"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"პოზიცია <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. რედაქტირებისთვის, შეეხეთ ორმაგად."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. დასამატებლად, შეეხეთ ორმაგად."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-ის გადატანა"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-ის გადატანა პოზიციაზე <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"სწრაფი პარამეტრების რედაქტორი."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> შეტყობინება: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"პარამეტრების გახსნა."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"სწრაფი პარამეტრების გახსნა."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"სწრაფი პარამეტრების დახურვა."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 1adaf2b..cafbc2b 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Маңызды емес хабарландыру белгішелерін көрсету"</string>
<string name="other" msgid="429768510980739978">"Басқа"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Бөлінген экран бөлгіші"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Сол жағын толық экранға шығару"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% сол жақта"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% сол жақта"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% сол жақта"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Оң жағын толық экранға шығару"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Жоғарғы жағын толық экранға шығару"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% жоғарғы жақта"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% жоғарғы жақта"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% жоғарғы жақта"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Төменгісін толық экранға шығару"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> орны, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Өңдеу үшін екі рет түртіңіз."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Қосу үшін екі рет түртіңіз."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> жылжыту"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> бөлшегін <xliff:g id="POSITION">%2$d</xliff:g>-позицияға жылжыту"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Жылдам параметрлер өңдегіші."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> хабарландыруы: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Қолданба бөлінген экранда жұмыс істемеуі мүмкін."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Қодланба бөлінген экранды қолдамайды."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Параметрлерді ашу."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Жылдам параметрлерді ашу."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Жылдам параметрлерді жабу."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 961a37b..5f16c76 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"បង្ហាញរូបការជូនដំណឹងដែលមានអាទិភាពទាប"</string>
<string name="other" msgid="429768510980739978">"ផ្សេងៗ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"កម្មវិធីចែកអេក្រង់បំបែក"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"អេក្រង់ពេញខាងឆ្វេង"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ឆ្វេង 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ឆ្វេង 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ឆ្វេង 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"អេក្រង់ពេញខាងស្តាំ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"អេក្រង់ពេញខាងលើ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ខាងលើ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ខាងលើ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ខាងលើ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"អេក្រង់ពេញខាងក្រោម"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ទីតាំង <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>, ប៉ះពីរដងដើម្បីកែ"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>, ប៉ះពីរដងដើម្បីបន្ថែម"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"ផ្លាស់ទី <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"ផ្លាស់ទី <xliff:g id="TILE_NAME">%1$s</xliff:g> ទៅទីតាំង <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"កម្មវិធីកែការកំណត់រហ័ស"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ការជូនដំណឹង៖ <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"កម្មវិធីអាចនឹងមិនដំណើរការនៅលើអេក្រង់បំបែកទេ"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"កម្មវិធីនេះប្រហែលជាមិនដំណើរការនៅលើអេក្រង់បន្ទាប់បន្សំទេ។"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"កម្មវិធីនេះមិនអាចចាប់ផ្តើមនៅលើអេក្រង់បន្ទាប់បន្សំបានទេ។"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"បើកការកំណត់"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"បើកការកំណត់រហ័ស"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"បិទការកំណត់រហ័ស"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 7ec6a9f..dff9ebd 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"ಕಡಿಮೆ-ಆದ್ಯತೆ ಸೂಚನೆಯ ಐಕಾನ್ಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="other" msgid="429768510980739978">"ಇತರ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ಎಡ ಪೂರ್ಣ ಪರದೆ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% ಎಡಕ್ಕೆ"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% ಎಡಕ್ಕೆ"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% ಎಡಕ್ಕೆ"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ಬಲ ಪೂರ್ಣ ಪರದೆ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ಮೇಲಿನ ಪೂರ್ಣ ಪರದೆ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% ಮೇಲಕ್ಕೆ"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% ಮೇಲಕ್ಕೆ"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% ಮೇಲಕ್ಕೆ"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ಕೆಳಗಿನ ಪೂರ್ಣ ಪರದೆ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ಸ್ಥಳ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. ಎಡಿಟ್ ಮಾಡಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ಸೇರಿಸಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ಸರಿಸಿ"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ಅನ್ನು <xliff:g id="POSITION">%2$d</xliff:g> ಗೆ ಸರಿಸಿ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳ ಎಡಿಟರ್."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ಅಧಿಸೂಚನೆ: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ವಿಭಜಿಸಿದ ಪರದೆಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮುಚ್ಚಿ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 840a98e..181888f 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"우선순위가 낮은 알림 아이콘 표시"</string>
<string name="other" msgid="429768510980739978">"기타"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"화면 분할기"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"왼쪽 화면 전체화면"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"왼쪽 화면 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"왼쪽 화면 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"왼쪽 화면 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"오른쪽 화면 전체화면"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"위쪽 화면 전체화면"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"위쪽 화면 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"위쪽 화면 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"위쪽 화면 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"아래쪽 화면 전체화면"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"위치 <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. 수정하려면 두 번 탭하세요."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. 추가하려면 두 번 탭하세요."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 이동"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 타일을 위치 <xliff:g id="POSITION">%2$d</xliff:g>(으)로 이동"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"빠른 설정 편집기"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 알림: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"앱이 분할 화면에서 작동하지 않을 수 있습니다."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"앱이 화면 분할을 지원하지 않습니다."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"설정 열기"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"빠른 설정 열기"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"빠른 설정 닫기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 14ee566..47fc3a8 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Анча маанилүү эмес билдирменин сүрөтчөлөрүн көрсөтүү"</string>
<string name="other" msgid="429768510980739978">"Башка"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Экранды бөлгүч"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Сол жактагы экранды толук экран режимине өткөрүү"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Сол жактагы экранды 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Сол жактагы экранды 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Сол жактагы экранды 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Оң жактагы экранды толук экран режимине өткөрүү"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Үстүнкү экранды толук экран режимине өткөрүү"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Үстүнкү экранды 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Үстүнкү экранды 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Үстүнкү экранды 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ылдыйкы экранды толук экран режимине өткөрүү"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Орду - <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Түзөтүү үчүн эки жолу таптаңыз."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Кошуу үчүн эки жолу таптаңыз."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> дегенди жылдыруу"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> плиткасы <xliff:g id="POSITION">%2$d</xliff:g>-позицияга кошулсун"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ыкчам жөндөөлөр түзөткүчү."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> эскертмеси: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Колдонмодо экран бөлүнбөшү мүмкүн."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Колдонмодо экран бөлүнбөйт."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Жөндөөлөрдү ачуу."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ыкчам жөндөөлөрдү ачуу."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Ыкчам жөндөөлөрдү жабуу."</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 553d0da..cb87555 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"ສະແດງໄອຄອນການແຈ້ງເຕືອນຄວາມສຳຄັນຕ່ຳ"</string>
<string name="other" msgid="429768510980739978">"ອື່ນໆ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ເຕັມໜ້າຈໍຊ້າຍ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ຊ້າຍ 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ຊ້າຍ 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ຊ້າຍ 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ເຕັມໜ້າຈໍຂວາ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ເຕັມໜ້າຈໍເທິງສຸດ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ເທິງສຸດ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ເທິງສຸດ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ເທິງສຸດ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ເຕັມໜ້າຈໍລຸ່ມສຸດ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. ແຕະສອງເທື່ອເພື່ອແກ້ໄຂ."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ແຕະສອງເທື່ອເພື່ອເພີ່ມ."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"ຍ້າຍ <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"ຍ້າຍ <xliff:g id="TILE_NAME">%1$s</xliff:g> ໄປຕຳແໜ່ງ <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"ການແຈ້ງເຕືອນ <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ເປີດການຕັ້ງຄ່າ."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ເປີດການຕັ້ງຄ່າດ່ວນ."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ປິດການຕັ້ງຄ່າດ່ວນ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 28d6e6b..ac90c0f 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Rodyti mažo prioriteto pranešimų piktogramas"</string>
<string name="other" msgid="429768510980739978">"Kita"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Skaidyto ekrano daliklis"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Kairysis ekranas viso ekrano režimu"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kairysis ekranas 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kairysis ekranas 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kairysis ekranas 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Dešinysis ekranas viso ekrano režimu"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Viršutinis ekranas viso ekrano režimu"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Viršutinis ekranas 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Viršutinis ekranas 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Viršutinis ekranas 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Apatinis ekranas viso ekrano režimu"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> padėtis, išklotinės elementas „<xliff:g id="TILE_NAME">%2$s</xliff:g>“. Dukart palieskite, kad redaguotumėte."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“. Dukart palieskite, kad pridėtumėte."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Perkelti išklotinės elementą „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Perkelti išklotinės elementą „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ į <xliff:g id="POSITION">%2$d</xliff:g> padėtį"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sparčiųjų nustatymų redagavimo priemonė."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"„<xliff:g id="ID_1">%1$s</xliff:g>“ pranešimas: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Programa gali neveikti naudojant skaidytą ekraną."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Programoje nepalaikomas skaidytas ekranas."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Programa gali neveikti antriniame ekrane."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Programa nepalaiko paleisties antriniuose ekranuose."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Atidaryti nustatymus."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Atidaryti sparčiuosius nustatymus."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Uždaryti sparčiuosius nustatymus."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 223a57f..2f5edd3 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -884,17 +884,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Rādīt zemas prioritātes paziņojumu ikonas"</string>
<string name="other" msgid="429768510980739978">"Citi"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Ekrāna sadalītājs"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Kreisā daļa pa visu ekrānu"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Pa kreisi 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Pa kreisi 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Pa kreisi 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Labā daļa pa visu ekrānu"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Augšdaļa pa visu ekrānu"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Augšdaļa 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Augšdaļa 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Augšdaļa 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Apakšdaļu pa visu ekrānu"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. pozīcija, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Lai rediģētu, veiciet dubultskārienu."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lai pievienotu, veiciet dubultskārienu."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Pārvietot elementu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -903,10 +892,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Pārvietot elementu “<xliff:g id="TILE_NAME">%1$s</xliff:g>” uz <xliff:g id="POSITION">%2$d</xliff:g>. pozīciju"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ātro iestatījumu redaktors."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> paziņojums: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Iespējams, lietotnē nedarbosies ekrāna sadalīšana."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Atvērt iestatījumus."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Atvērt ātros iestatījumus."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Aizvērt ātros iestatījumus."</string>
diff --git a/packages/SystemUI/res/values-mcc310-mnc004/strings.xml b/packages/SystemUI/res/values-mcc310-mnc004/strings.xml
new file mode 100644
index 0000000..f8ed0c0
--- /dev/null
+++ b/packages/SystemUI/res/values-mcc310-mnc004/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2020, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Content description of the data connection type 5G UW. [CHAR LIMIT=NONE] -->
+ <string name="data_connection_5g_plus" translatable="false">5G UW</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/strings.xml b/packages/SystemUI/res/values-mcc311-mnc480/strings.xml
new file mode 100644
index 0000000..f8ed0c0
--- /dev/null
+++ b/packages/SystemUI/res/values-mcc311-mnc480/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2020, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Content description of the data connection type 5G UW. [CHAR LIMIT=NONE] -->
+ <string name="data_connection_5g_plus" translatable="false">5G UW</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index a591031..de9cf0f 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Прикажувај икони за известувања со низок приоритет"</string>
<string name="other" msgid="429768510980739978">"Друго"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Разделник на поделен екран"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Левиот на цел екран"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Левиот 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Левиот 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Левиот 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Десниот на цел екран"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Горниот на цел екран"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Горниот 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Горниот 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Горниот 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Долниот на цел екран"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Место <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Допрете двапати за уредување."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Допрете двапати за додавање."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Преместете <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Преместете <xliff:g id="TILE_NAME">%1$s</xliff:g> на позицијата <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уредник за брзи поставки."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Известување од <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Апликацијата можеби нема да работи во поделен екран."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Апликацијата не поддржува поделен екран."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Апликацијата може да не функционира на друг екран."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Апликацијата не поддржува стартување на други екрани."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отворете ги поставките."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отворете ги брзите поставки."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затворете ги брзите поставки."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 47d220d..bd51874 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"പ്രാധാന്യം കുറഞ്ഞ അറിയിപ്പ് ചിഹ്നങ്ങൾ"</string>
<string name="other" msgid="429768510980739978">"മറ്റുള്ളവ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ഇടത് പൂർണ്ണ സ്ക്രീൻ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ഇടത് 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ഇടത് 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ഇടത് 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"വലത് പൂർണ്ണ സ്ക്രീൻ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"മുകളിൽ പൂർണ്ണ സ്ക്രീൻ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"മുകളിൽ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"മുകളിൽ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"മുകളിൽ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"താഴെ പൂർണ്ണ സ്ക്രീൻ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"സ്ഥാനം <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. എഡിറ്റുചെയ്യുന്നതിന് രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ചേർക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> നീക്കുക"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> സ്ഥാനത്തേയ്ക്ക് <xliff:g id="TILE_NAME">%1$s</xliff:g> നീക്കുക"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ദ്രുത ക്രമീകരണ എഡിറ്റർ."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> അറിയിപ്പ്: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"സ്പ്ലിറ്റ്-സ്ക്രീനിനൊപ്പം ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"രണ്ടാം ഡിസ്പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"രണ്ടാം ഡിസ്പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ക്രമീകരണം തുറക്കുക."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ദ്രുത ക്രമീകരണം തുറക്കുക."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ദ്രുത ക്രമീകരണം അടയ്ക്കുക."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 202f292..1440103 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Бага ач холбогдолтой мэдэгдлийн дүрс тэмдгийг харуулах"</string>
<string name="other" msgid="429768510980739978">"Бусад"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"\"Дэлгэц хуваах\" хуваагч"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Зүүн талын бүтэн дэлгэц"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Зүүн 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Зүүн 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Зүүн 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Баруун талын бүтэн дэлгэц"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Дээд талын бүтэн дэлгэц"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Дээд 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Дээд 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Дээд 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Доод бүтэн дэлгэц"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Байршил <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Засахын тулд 2 удаа дарна уу."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Нэмэхийн тулд 2 удаа дарна уу."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-г зөөх"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-г байрлал <xliff:g id="POSITION">%2$d</xliff:g> руу зөөх"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Түргэн тохиргоо засварлагч."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> мэдэгдэл: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Апп хуваагдсан дэлгэцэд ажиллахгүй."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Энэ апп нь дэлгэц хуваах тохиргоог дэмждэггүй."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Тохиргоог нээнэ үү."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Шуурхай тохиргоог нээнэ үү."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Хурдан тохиргоог хаана уу."</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index e412072..32fe7bd 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"कमी प्राधान्य सूचना आयकन दर्शवा"</string>
<string name="other" msgid="429768510980739978">"अन्य"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"विभाजित-स्क्रीन विभाजक"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"डावी फुल स्क्रीन"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"डावी 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"डावी 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"डावी 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"उजवी फुल स्क्रीन"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"शीर्ष फुल स्क्रीन"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"शीर्ष 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"शीर्ष 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"शीर्ष 10"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"तळाशी फुल स्क्रीन"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"स्थिती <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. संपादित करण्यासाठी दोनदा टॅप करा."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> . जोडण्यासाठी दोनदा टॅप करा."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> हलवा"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> स्थानावर हलवा"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिंग्ज संपादक."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"अॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"दुसऱ्या डिस्प्लेवर अॅप कदाचित चालणार नाही."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"दुसऱ्या डिस्प्लेवर अॅप लाँच होणार नाही."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिंग्ज उघडा."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"जलद सेटिंग्ज उघडा."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"जलद सेटिंग्ज बंद करा."</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 0331d26..fe246d1 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Tunjukkan ikon pemberitahuan keutamaan rendah"</string>
<string name="other" msgid="429768510980739978">"Lain-lain"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Pembahagi skrin pisah"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Skrin penuh kiri"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kiri 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kiri 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kiri 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Skrin penuh kanan"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Skrin penuh atas"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Atas 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Atas 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Atas 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Skrin penuh bawah"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dwiketik untuk mengedit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dwiketik untuk menambah."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Alihkan <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Alihkan <xliff:g id="TILE_NAME">%1$s</xliff:g> ke kedudukan <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor tetapan pantas."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Pemberitahuan <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Apl mungkin tidak berfungsi dengan skrin pisah."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Apl tidak menyokong skrin pisah."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Apl mungkin tidak berfungsi pada paparan kedua."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Apl tidak menyokong pelancaran pada paparan kedua."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buka tetapan."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Buka tetapan pantas."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tutup tetapan pantas."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 83272f2..53c02a5 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"အရေးမကြီးသော အကြောင်းကြားချက် သင်္ကေတများ ပြရန်"</string>
<string name="other" msgid="429768510980739978">"အခြား"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ဘယ်ဘက် မျက်နှာပြင်အပြည့်"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ဘယ်ဘက်မျက်နှာပြင် ၇၀%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ဘယ်ဘက် မျက်နှာပြင် ၃၀%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ညာဘက် မျက်နှာပြင်အပြည့်"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"အပေါ်ဘက် မျက်နှာပြင်အပြည့်"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"အပေါ်ဘက် မျက်နှာပြင် ၇၀%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"အပေါ်ဘက် မျက်နှာပြင် ၃၀%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"အောက်ခြေ မျက်နှာပြင်အပြည့်"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>၊ <xliff:g id="TILE_NAME">%2$s</xliff:g> နေရာ။ တည်းဖြတ်ရန် နှစ်ချက်တို့ပါ။"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>။ ပေါင်းထည့်ရန် နှစ်ချက်တို့ပါ။"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ကိုရွှေ့ပါ"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ကို အနေအထား <xliff:g id="POSITION">%2$d</xliff:g> သို့ ရွှေ့ရန်"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> အကြောင်းကြားချက် − <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"မျက်နှာပြင် ခွဲခြမ်းပြသမှုဖြင့် အက်ပ်သည် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ဆက်တင်များကို ဖွင့်ပါ။"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"အမြန်ဆက်တင်များကို ဖွင့်ပါ။"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"အမြန်ဆက်တင်များကို ပိတ်ပါ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 01859ef..5c9f63f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for varsler med lav prioritet"</string>
<string name="other" msgid="429768510980739978">"Annet"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Skilleelement for delt skjerm"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Utvid den venstre delen av skjermen til hele skjermen"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Sett størrelsen på den venstre delen av skjermen til 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Sett størrelsen på den venstre delen av skjermen til 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Utvid den høyre delen av skjermen til hele skjermen"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Utvid den øverste delen av skjermen til hele skjermen"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Sett størrelsen på den øverste delen av skjermen til 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Sett størrelsen på den øverste delen av skjermen til 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Utvid den nederste delen av skjermen til hele skjermen"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Plassering <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dobbelttrykk for å endre."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dobbelttrykk for å legge til."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Flytt <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Flytt <xliff:g id="TILE_NAME">%1$s</xliff:g> til posisjon <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsvindu for hurtiginnstillinger."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-varsel: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Det kan hende at appen ikke fungerer med delt skjerm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Appen støtter ikke delt skjerm."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Appen fungerer kanskje ikke på en sekundær skjerm."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Appen kan ikke kjøres på sekundære skjermer."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Åpne innstillingene."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Åpner hurtiginnstillingene."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Lukk hurtiginnstillingene."</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 196b4ad..791e4d3 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकताका सूचना आइकनहरू देखाउनुहोस्"</string>
<string name="other" msgid="429768510980739978">"अन्य"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"विभाजित-स्क्रिन छुट्याउने"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"बायाँ भाग फुल स्क्रिन"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"बायाँ भाग ७०%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"बायाँ भाग ५०%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"बायाँ भाग ३०%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"दायाँ भाग फुल स्क्रिन"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"माथिल्लो भाग फुल स्क्रिन"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"माथिल्लो भाग ७०%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"माथिल्लो भाग ५०%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"माथिल्लो भाग ३०%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"तल्लो भाग फुल स्क्रिन"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। सम्पादन गर्नाका लागि डबल ट्याप गर्नुहोस्।"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। थप्नका लागि डबल ट्याप गर्नुहोस्।"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> लाई सार्नुहोस्"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> लाई <xliff:g id="POSITION">%2$d</xliff:g> स्थितिमा सार्नुहोस्"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिङ सम्पादक।"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> को सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"अनुप्रयोगले विभाजित-स्क्रिनमा काम नगर्न सक्छ।"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"यो अनुप्रयोगले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिङहरूलाई खोल्नुहोस्।"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"द्रुत सेटिङहरूलाई खोल्नुहोस्।"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"द्रुत सेटिङहरूलाई बन्द गर्नुहोस्।"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index fa028c3..01d3fec 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -390,7 +390,7 @@
<string name="quick_settings_inversion_label" msgid="5078769633069667698">"Kleuren omkeren"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"Modus voor kleurcorrectie"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"Meer instellingen"</string>
- <string name="quick_settings_done" msgid="2163641301648855793">"Gereed"</string>
+ <string name="quick_settings_done" msgid="2163641301648855793">"Klaar"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"Verbonden"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Verbonden, batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Verbinding maken…"</string>
@@ -692,7 +692,7 @@
<string name="notification_channel_silenced" msgid="1995937493874511359">"Deze meldingen worden zonder geluid weergegeven"</string>
<string name="notification_channel_unsilenced" msgid="94878840742161152">"Deze meldingen stellen je op de hoogte"</string>
<string name="inline_blocking_helper" msgid="2891486013649543452">"Meestal sluit je deze meldingen. \nWil je ze blijven weergeven?"</string>
- <string name="inline_done_button" msgid="6043094985588909584">"Gereed"</string>
+ <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Toepassen"</string>
<string name="inline_keep_showing" msgid="8736001253507073497">"Deze meldingen blijven weergeven?"</string>
<string name="inline_stop_button" msgid="2453460935438696090">"Meldingen stoppen"</string>
@@ -747,7 +747,7 @@
<string name="notification_channel_switch_accessibility" msgid="8979885820432540252">"Meldingen van dit kanaal toestaan"</string>
<string name="notification_more_settings" msgid="4936228656989201793">"Meer instellingen"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"Aanpassen"</string>
- <string name="notification_done" msgid="6215117625922713976">"Gereed"</string>
+ <string name="notification_done" msgid="6215117625922713976">"Klaar"</string>
<string name="inline_undo" msgid="9026953267645116526">"Ongedaan maken"</string>
<string name="demote" msgid="6225813324237153980">"Deze melding markeren als geen gesprek"</string>
<string name="notification_conversation_favorite" msgid="1905240206975921907">"Belangrijk gesprek"</string>
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Pictogrammen voor meldingen met lage prioriteit weergeven"</string>
<string name="other" msgid="429768510980739978">"Overig"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Scheiding voor gesplitst scherm"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Linkerscherm op volledig scherm"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Linkerscherm 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Linkerscherm 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Linkerscherm 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Rechterscherm op volledig scherm"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Bovenste scherm op volledig scherm"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Bovenste scherm 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Bovenste scherm 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Bovenste scherm 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Onderste scherm op volledig scherm"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Positie <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dubbeltik om te bewerken."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dubbeltik om toe te voegen."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> verplaatsen"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> verplaatsen naar positie <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor voor \'Snelle instellingen\'."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-melding: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"App werkt mogelijk niet met gesplitst scherm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App biedt geen ondersteuning voor gesplitst scherm."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App werkt mogelijk niet op een secundair scherm."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App kan niet op secundaire displays worden gestart."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Instellingen openen."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Snelle instellingen openen."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Snelle instellingen sluiten."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 4c6ef48..c7de8ca 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"କମ୍-ଅଗ୍ରାଧିକାର ବିଜ୍ଞପ୍ତି ଆଇକନ୍ ଦେଖାନ୍ତୁ"</string>
<string name="other" msgid="429768510980739978">"ଅନ୍ୟାନ୍ୟ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ବାମ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ବାମ ପଟକୁ 70% କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ବାମ ପଟକୁ 50% କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ବାମ ପଟେ 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ଡାହାଣ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ଉପର ଆଡ଼କୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ଉପର ଆଡ଼କୁ 70% କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ଉପର ଆଡ଼କୁ 30% କରନ୍ତୁ"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ତଳ ଅଂଶର ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ଅବସ୍ଥାନ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। ଏଡିଟ୍ କରିବାକୁ ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। ଯୋଡ଼ିବା ପାଇଁ ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ନିଅନ୍ତୁ"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> ଅବସ୍ଥାନକୁ <xliff:g id="TILE_NAME">%1$s</xliff:g> ଘୁଞ୍ଚାନ୍ତୁ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଏଡିଟର୍।"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ବିଜ୍ଞପ୍ତି: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନରେ ଆପ୍ କାମ କରିନପାରେ।"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ଆପ୍ ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନକୁ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ କାମ ନକରିପାରେ।"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ।"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଂସ୍ ବନ୍ଦ କରନ୍ତୁ।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 98583c0..66333b9 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੇ ਸੂਚਨਾ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਦਿਖਾਓ"</string>
<string name="other" msgid="429768510980739978">"ਹੋਰ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ਖੱਬੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ਖੱਬੇ 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ਖੱਬੇ 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ਖੱਬੇ 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ਸੱਜੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ਉੱਪਰ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ਉੱਪਰ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ਉੱਪਰ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ਉੱਪਰ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ਹੇਠਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। ਸੰਪਾਦਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ ਤਬਦੀਲ ਕਰੋ"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ <xliff:g id="POSITION">%2$d</xliff:g> ਸਥਾਨ \'ਤੇ ਲਿਜਾਓ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ਸੂਚਨਾ: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਲ੍ਹੋ।"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬੰਦ ਕਰੋ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4d5a2ae..c68e3ac 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Pokazuj ikony powiadomień o niskim priorytecie"</string>
<string name="other" msgid="429768510980739978">"Inne"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Linia dzielenia ekranu"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lewa część ekranu na pełnym ekranie"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% lewej części ekranu"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% lewej części ekranu"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% lewej części ekranu"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Prawa część ekranu na pełnym ekranie"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Górna część ekranu na pełnym ekranie"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% górnej części ekranu"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% górnej części ekranu"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% górnej części ekranu"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Dolna część ekranu na pełnym ekranie"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Położenie <xliff:g id="POSITION">%1$d</xliff:g>, kafelek <xliff:g id="TILE_NAME">%2$s</xliff:g>. Kliknij dwukrotnie, by edytować."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"Kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g>. Kliknij dwukrotnie, by dodać."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Przenieś kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Przenieś kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g> w położenie <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Edytor szybkich ustawień."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Powiadomienie z aplikacji <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacja może nie działać przy podzielonym ekranie."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacja nie obsługuje dzielonego ekranu."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacja może nie działać na dodatkowym ekranie."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otwórz ustawienia."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otwórz szybkie ustawienia."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zamknij szybkie ustawienia."</string>
@@ -1016,7 +1001,7 @@
<string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Przenieś w lewy dolny róg"</string>
<string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Przenieś w prawy dolny róg"</string>
<string name="bubble_dismiss_text" msgid="1314082410868930066">"Zamknij dymek"</string>
- <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymku"</string>
+ <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymka"</string>
<string name="bubbles_user_education_title" msgid="5547017089271445797">"Czatuj, korzystając z dymków"</string>
<string name="bubbles_user_education_description" msgid="1160281719576715211">"Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść."</string>
<string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ef5c9ce..ff2ecd3 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string>
<string name="other" msgid="429768510980739978">"Outros"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de tela"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lado esquerdo em tela cheia"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Esquerda a 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Esquerda a 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Esquerda a 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Lado direito em tela cheia"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Parte superior em tela cheia"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Parte superior a 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Parte superior a 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Parte superior a 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Parte inferior em tela cheia"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"É possível que o app não funcione com o recurso de divisão de tela."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"O app não é compatível com a divisão de tela."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"É possível que o app não funcione em uma tela secundária."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"O app não é compatível com a inicialização em telas secundárias."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configurações."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir as configurações rápidas."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as configurações rápidas."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 541f12c..c39a5eb 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de prioridade baixa"</string>
<string name="other" msgid="429768510980739978">"Outro"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divisor do ecrã dividido"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ecrã esquerdo inteiro"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% no ecrã esquerdo"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% no ecrã esquerdo"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% no ecrã esquerdo"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Ecrã direito inteiro"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ecrã superior inteiro"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% no ecrã superior"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% no ecrã superior"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% no ecrã superior"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ecrã inferior inteiro"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de definições rápidas."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"A app pode não funcionar com o ecrã dividido."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"A app não é compatível com o ecrã dividido."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"A app pode não funcionar num ecrã secundário."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"A app não é compatível com o início em ecrãs secundários."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir as definições."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir as definições rápidas."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as definições rápidas."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ef5c9ce..ff2ecd3 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string>
<string name="other" msgid="429768510980739978">"Outros"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de tela"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lado esquerdo em tela cheia"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Esquerda a 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Esquerda a 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Esquerda a 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Lado direito em tela cheia"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Parte superior em tela cheia"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Parte superior a 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Parte superior a 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Parte superior a 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Parte inferior em tela cheia"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"É possível que o app não funcione com o recurso de divisão de tela."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"O app não é compatível com a divisão de tela."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"É possível que o app não funcione em uma tela secundária."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"O app não é compatível com a inicialização em telas secundárias."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configurações."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir as configurações rápidas."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as configurações rápidas."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 3e2373d..b793bcd 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -884,17 +884,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Afișați pictogramele de notificare cu prioritate redusă"</string>
<string name="other" msgid="429768510980739978">"Altele"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Separator pentru ecranul împărțit"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Partea stângă pe ecran complet"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Partea stângă: 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Partea stângă: 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Partea stângă: 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Partea dreaptă pe ecran complet"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Partea de sus pe ecran complet"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Partea de sus: 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Partea de sus: 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Partea de sus: 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Partea de jos pe ecran complet"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Atingeți de două ori pentru a edita."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Atingeți de două ori pentru a adăuga."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mutați <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -903,10 +892,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mutați <xliff:g id="TILE_NAME">%1$s</xliff:g> pe poziția <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editorul pentru setări rapide."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificare <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplicația nu acceptă ecranul împărțit."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplicația nu acceptă lansare pe ecrane secundare."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Deschideți setările."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Deschideți setările rapide."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Închideți setările rapide."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 7747724..7560f53 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Показывать значки уведомлений с низким приоритетом"</string>
<string name="other" msgid="429768510980739978">"Другое"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Разделитель экрана"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Левый во весь экран"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Левый на 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Левый на 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Левый на 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Правый во весь экран"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Верхний во весь экран"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Верхний на 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Верхний на 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Верхний на 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Нижний во весь экран"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>, кнопка \"<xliff:g id="TILE_NAME">%2$s</xliff:g>\". Чтобы изменить, нажмите дважды."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"Кнопка \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\". Чтобы добавить, нажмите дважды."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Переместить кнопку \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\""</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Переместить значок <xliff:g id="TILE_NAME">%1$s</xliff:g> на позицию <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор быстрых настроек."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Уведомление <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Приложение не поддерживает разделение экрана."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Приложение не поддерживает разделение экрана."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Приложение может не работать на дополнительном экране"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Приложение не поддерживает запуск на дополнительных экранах"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Открыть настройки."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Развернуть быстрые настройки."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Скрыть быстрые настройки."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index b8813f2..02f9c23 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"අඩු ප්රමුඛතා දැනුම්දීම් අයිකන පෙන්වන්න"</string>
<string name="other" msgid="429768510980739978">"වෙනත්"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"බෙදුම්-තිර වෙන්කරණය"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"වම් පූර්ණ තිරය"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"වම් 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"වම් 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"වම් 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"දකුණු පූර්ණ තිරය"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ඉහළම පූර්ණ තිරය"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ඉහළම 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ඉහළම 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ඉහළම 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"පහළ පූර්ණ තිරය"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. වෙනස් කිරීමට දෙවරක් තට්ටු කරන්න."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. එක් කිරීමට දෙවරක් තට්ටු කරන්න."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ගෙන යන්න"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> තත්ත්වයට <xliff:g id="POSITION">%2$d</xliff:g> ගෙන යන්න"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ඉක්මන් සැකසුම් සංස්කාරකය."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> දැනුම්දීම: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"යෙදුම බෙදුම්-තිරය සමග ක්රියා නොකළ හැකිය."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"යෙදුම බෙදුණු-තිරය සඳහා සහාය නොදක්වයි."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"යෙදුම ද්විතියික සංදර්ශකයක ක්රියා නොකළ හැකිය."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"සැකසීම් විවෘත කරන්න."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ඉක්මන් සැකසීම් විවෘත කරන්න."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ඉක්මන් සැකසීම් වසන්න."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0f9cb5f..54a32dd 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Zobraziť ikony upozornení s nízkou prioritou"</string>
<string name="other" msgid="429768510980739978">"Ďalšie"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Rozdeľovač obrazovky"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ľavá – na celú obrazovku"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ľavá – 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ľavá – 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ľavá – 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pravá– na celú obrazovku"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Horná – na celú obrazovku"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Horná – 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Horná – 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Horná – 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Dolná – na celú obrazovku"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozícia <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Upravíte ju dvojitým klepnutím."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Pridáte ju dvojitým klepnutím."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Presunúť dlaždicu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Presunúť <xliff:g id="TILE_NAME">%1$s</xliff:g> na pozíciu <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rýchlych nastavení"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Upozornenie <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikácia nemusí fungovať so zapnutou rozdelenou obrazovkou."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikácia nepodporuje rozdelenú obrazovku."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvoriť nastavenia"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvoriť rýchle nastavenia"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zavrieť rýchle nastavenia"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 18db332..32fce7d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Pokaži ikone obvestil z nizko stopnjo prednosti"</string>
<string name="other" msgid="429768510980739978">"Drugo"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Razdelilnik zaslonov"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Levi v celozaslonski način"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Levi 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Levi 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Levi 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Desni v celozaslonski način"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Zgornji v celozaslonski način"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Zgornji 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Zgornji 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Zgornji 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Spodnji v celozaslonski način"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Če želite urediti, se dvakrat dotaknite."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Če želite dodati, se dvakrat dotaknite."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Premik tega: <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premakni ploščico <xliff:g id="TILE_NAME">%1$s</xliff:g> na položaj <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Urejevalnik hitrih nastavitev."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obvestilo za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podpira načina razdeljenega zaslona."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Odpri nastavitve."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Odpri hitre nastavitve."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zapri hitre nastavitve."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 57ab1c3..c907bc2 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -480,7 +480,7 @@
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
- <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo!"</string>
+ <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string>
<string name="guest_notification_title" msgid="4434456703930764167">"Përdorues vizitor"</string>
<string name="guest_notification_text" msgid="4202692942089571351">"Për të fshirë aplikacionet dhe të dhënat, hiqe përdoruesin vizitor"</string>
<string name="guest_notification_remove_action" msgid="4153019027696868099">"HIQ VIZITORIN"</string>
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Shfaq ikonat e njoftimeve me përparësi të ulët"</string>
<string name="other" msgid="429768510980739978">"Të tjera"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Ndarësi i ekranit të ndarë"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ekrani i plotë majtas"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Majtas 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Majtas 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Majtas 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Ekrani i plotë djathtas"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ekrani i plotë lart"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Lart 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Lart 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Lart 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ekrani i plotë poshtë"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Trokit dy herë për ta redaktuar."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Trokit dy herë për ta shtuar."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Zhvendose <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Zhvendos <xliff:g id="TILE_NAME">%1$s</xliff:g> te pozicioni <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redaktori i cilësimeve të shpejta."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Njoftim nga <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacioni mund të mos funksionojë me ekranin e ndarë."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacioni nuk mbështet ekranin e ndarë."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Hap cilësimet."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Hap cilësimet e shpejta."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Mbyll cilësimet e shpejta."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ec763f6..8b7ce1f 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -884,17 +884,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Прикажи иконе обавештења ниског приоритета"</string>
<string name="other" msgid="429768510980739978">"Друго"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Разделник подељеног екрана"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Режим целог екрана за леви екран"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Леви екран 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Леви екран 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Леви екран 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Режим целог екрана за доњи екран"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Режим целог екрана за горњи екран"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Горњи екран 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Горњи екран 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Горњи екран 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Режим целог екрана за доњи екран"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Двапут додирните да бисте изменили."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Двапут додирните да бисте додали."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Премести плочицу <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -903,10 +892,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Преместите „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ на позицију <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Обавештења за <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Апликација можда неће функционисати са подељеним екраном."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Апликација не подржава подељени екран."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Апликација можда неће функционисати на секундарном екрану."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Апликација не подржава покретање на секундарним екранима."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отвори Подешавања."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отвори Брза подешавања."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затвори Брза подешавања."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index a0a563d..c4b7977 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Visa ikoner för aviseringar med låg prioritet"</string>
<string name="other" msgid="429768510980739978">"Annat"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Avdelare för delad skärm"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Helskärm på vänster skärm"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vänster 70 %"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vänster 50 %"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vänster 30 %"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Helskärm på höger skärm"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Helskärm på övre skärm"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Övre 70 %"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Övre 50 %"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Övre 30 %"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Helskärm på nedre skärm"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tryck snabbt två gånger för att redigera positionen."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lägg till genom att trycka snabbt två gånger."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Flytta <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Flytta <xliff:g id="TILE_NAME">%1$s</xliff:g> till position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigerare för snabbinställningar."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-avisering: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Appen kanske inte fungerar med delad skärm."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Appen har inte stöd för delad skärm."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Appen kanske inte fungerar på en sekundär skärm."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Appen kan inte köras på en sekundär skärm."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Öppna inställningarna."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Öppna snabbinställningarna."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Stäng snabbinställningarna"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7e264a4..b483fa8 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Onyesha aikoni za arifa zisizo muhimu"</string>
<string name="other" msgid="429768510980739978">"Nyingine"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Kitenganishi cha skrini inayogawanywa"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Skrini nzima ya kushoto"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kushoto 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kushoto 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kushoto 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Skrini nzima ya kulia"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Skrini nzima ya juu"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Juu 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Juu 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Juu 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Skrini nzima ya chini"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Gusa mara mbili ili ubadilishe."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Gusa mara mbili ili uongeze."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Hamisha <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Sogeza <xliff:g id="TILE_NAME">%1$s</xliff:g> kwenye nafasi ya <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kihariri cha Mipangilio ya haraka."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Arifa kutoka <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Programu haiwezi kutumia skrini iliyogawanywa."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Huenda programu isifanye kazi kwenye dirisha lingine."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Fungua mipangilio."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Fungua mipangilio ya haraka."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Funga mipangilio ya haraka."</string>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 5d20564..be66320 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -29,9 +29,6 @@
<!-- Nav bar button default ordering/layout -->
<string name="config_navBarLayout" translatable="false">left;back,home,recent;right</string>
- <!-- Animation duration when using long press on recents to dock -->
- <integer name="long_press_dock_anim_duration">290</integer>
-
<!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
<integer name="navigation_bar_deadzone_orientation">0</integer>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e0f20ce..2c025e7 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"குறைந்த முன்னுரிமை உள்ள அறிவிப்பு ஐகான்களைக் காட்டு"</string>
<string name="other" msgid="429768510980739978">"மற்றவை"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"திரையைப் பிரிக்கும் பிரிப்பான்"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"இடது புறம் முழுத் திரை"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"இடது புறம் 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"இடது புறம் 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"இடது புறம் 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"வலது புறம் முழுத் திரை"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"மேற்புறம் முழுத் திரை"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"மேலே 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"மேலே 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"மேலே 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"கீழ்ப்புறம் முழுத் திரை"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"நிலை <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. திருத்த, இருமுறை தட்டவும்."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. சேர்க்க, இருமுறை தட்டவும்."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ஐ நகர்த்தவும்"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"நிலைப்பாடு <xliff:g id="POSITION">%2$d</xliff:g>க்கு <xliff:g id="TILE_NAME">%1$s</xliff:g>ஐ நகர்த்தும்"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> அறிவிப்பு: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"திரைப் பிரிப்பில் ஆப்ஸ் வேலைசெய்யாமல் போகக்கூடும்."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"திரையைப் பிரிப்பதைப் ஆப்ஸ் ஆதரிக்கவில்லை."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"அமைப்புகளைத் திற."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"விரைவு அமைப்புகளைத் திற."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"விரைவு அமைப்புகளை மூடு."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 3e94b72..a49bb9b 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"తక్కువ ప్రాధాన్యత నోటిఫికేషన్ చిహ్నాలను చూపించు"</string>
<string name="other" msgid="429768510980739978">"ఇతరం"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"విభజన స్క్రీన్ విభాగిని"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ఎడమవైపు పూర్తి స్క్రీన్"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ఎడమవైపు 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ఎడమవైపు 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ఎడమవైపు 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"కుడివైపు పూర్తి స్క్రీన్"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ఎగువ పూర్తి స్క్రీన్"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ఎగువ 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ఎగువ 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ఎగువ 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"దిగువ పూర్తి స్క్రీన్"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. సవరించడానికి రెండుసార్లు నొక్కండి."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. జోడించడానికి రెండుసార్లు నొక్కండి."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ని తరలిస్తుంది"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"స్థానం <xliff:g id="POSITION">%2$d</xliff:g>కి <xliff:g id="TILE_NAME">%1$s</xliff:g>ని తరలించండి"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"శీఘ్ర సెట్టింగ్ల ఎడిటర్."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> నోటిఫికేషన్: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"స్క్రీన్ విభజనతో యాప్ పని చేయకపోవచ్చు."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"అనువర్తనంలో స్క్రీన్ విభజనకు మద్దతు లేదు."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ప్రత్యామ్నాయ డిస్ప్లేలో యాప్ పని చేయకపోవచ్చు."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ప్రత్యామ్నాయ డిస్ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"సెట్టింగ్లను తెరవండి."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"శీఘ్ర సెట్టింగ్లను తెరవండి."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"శీఘ్ర సెట్టింగ్లను మూసివేయండి."</string>
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 4a94038..6630401 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -39,7 +39,6 @@
<item>com.android.systemui.SizeCompatModeActivityController</item>
<item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
<item>com.android.systemui.toast.ToastUI</item>
- <item>com.android.systemui.onehanded.OneHandedUI</item>
<item>com.android.systemui.wmshell.WMShell</item>
</string-array>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 088b624..8fd8442 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"แสดงไอคอนการแจ้งเตือนลำดับความสำคัญต่ำ"</string>
<string name="other" msgid="429768510980739978">"อื่นๆ"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"เส้นแบ่งหน้าจอ"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"เต็มหน้าจอทางซ้าย"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ซ้าย 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ซ้าย 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ซ้าย 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"เต็มหน้าจอทางขวา"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"เต็มหน้าจอด้านบน"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ด้านบน 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ด้านบน 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ด้านบน 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"เต็มหน้าจอด้านล่าง"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g> <xliff:g id="TILE_NAME">%2$s</xliff:g> แตะ 2 ครั้งเพื่อแก้ไข"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> แตะ 2 ครั้งเพื่อเพิ่ม"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"ย้าย <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"ย้าย <xliff:g id="TILE_NAME">%1$s</xliff:g> ไปยังตำแหน่ง <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ตัวแก้ไขการตั้งค่าด่วน"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> การแจ้งเตือน: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"แอปอาจใช้ไม่ได้กับโหมดแยกหน้าจอ"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"แอปไม่สนับสนุนการแยกหน้าจอ"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"เปิดการตั้งค่า"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"เปิดการตั้งค่าด่วน"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ปิดการตั้งค่าด่วน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e787b17..5951ba2 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Ipakita ang mga icon ng notification na may mababang priority"</string>
<string name="other" msgid="429768510980739978">"Iba pa"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Divider ng split-screen"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"I-full screen ang nasa kaliwa"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Gawing 70% ang nasa kaliwa"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Gawing 50% ang nasa kaliwa"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Gawing 30% ang nasa kaliwa"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"I-full screen ang nasa kanan"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"I-full screen ang nasa itaas"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gawing 70% ang nasa itaas"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gawing 50% ang nasa itaas"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gawing 30% ang nasa itaas"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"I-full screen ang nasa ibaba"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posisyon <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. I-double tap upang i-edit."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. I-double tap upang idagdag."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Ilipat ang <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Ilipat ang <xliff:g id="TILE_NAME">%1$s</xliff:g> sa posisyong <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor ng Mga mabilisang setting."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification sa <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Maaaring hindi gumana ang app sa split-screen."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Hindi sinusuportahan ng app ang split-screen."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Maaaring hindi gumana ang app sa pangalawang display."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buksan ang mga setting."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Buksan ang mga mabilisang setting."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Isara ang mga mabilisang setting."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index e339445..2d2ccad 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Düşük öncelikli bildirim simgelerini göster"</string>
<string name="other" msgid="429768510980739978">"Diğer"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Bölünmüş ekran ayırıcı"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Solda tam ekran"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Solda %70"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Solda %50"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Solda %30"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Sağda tam ekran"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Üstte tam ekran"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Üstte %70"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Üstte %50"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Üstte %30"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Altta tam ekran"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. konum, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Düzenlemek için iki kez dokunun."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Eklemek için iki kez dokunun."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> kutusunu taşı"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> öğesini <xliff:g id="POSITION">%2$d</xliff:g> konumuna taşı"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirimi: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Uygulama bölünmüş ekranda çalışmayabilir."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Uygulama bölünmüş ekranı desteklemiyor."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Uygulama ikincil ekranda çalışmayabilir."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları aç."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Hızlı ayarları aç."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Hızlı ayarları kapat."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index f5419f1..1a8ce7b 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -889,17 +889,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Показувати значки сповіщень із низьким пріоритетом"</string>
<string name="other" msgid="429768510980739978">"Інше"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Розділювач екрана"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ліве вікно на весь екран"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ліве вікно на 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ліве вікно на 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ліве вікно на 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Праве вікно на весь екран"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Верхнє вікно на весь екран"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Верхнє вікно на 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Верхнє вікно на 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Верхнє вікно на 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Нижнє вікно на весь екран"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Двічі торкніться, щоб змінити."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Двічі торкніться, щоб додати."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Перемістити <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -908,10 +897,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Перемістити <xliff:g id="TILE_NAME">%1$s</xliff:g> на позицію <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор швидких налаштувань."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Сповіщення <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Додаток може не працювати в режимі розділеного екрана."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Додаток не підтримує розділення екрана."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Додаток може не працювати на додатковому екрані."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Додаток не підтримує запуск на додаткових екранах."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Відкрити налаштування."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Відкрити швидкі налаштування."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрити швидкі налаштування."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 2abf350..4f091d6 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"کم ترجیحی اطلاع کے آئیکنز دکھائیں"</string>
<string name="other" msgid="429768510980739978">"دیگر"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"سپلٹ اسکرین تقسیم کار"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"بائیں فل اسکرین"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"بائیں %70"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"بائیں %50"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"بائیں %30"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"دائیں فل اسکرین"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"بالائی فل اسکرین"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"اوپر %70"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"اوپر %50"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"اوپر %30"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"نچلی فل اسکرین"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>۔ ترمیم کرنے کیلئے دو بار تھپتھپائیں۔"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>۔ شامل کرنے کیلئے دو بار تھپتھپائیں۔"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> کو منتقل کریں"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> کو پوزیشن <xliff:g id="POSITION">%2$d</xliff:g> میں منتقل کریں"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"فوری ترتیبات کا ایڈیٹر۔"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> اطلاع: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"ممکن ہے کہ ایپ سپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ترتیبات کھولیں۔"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"فوری ترتیبات کھولیں۔"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"فوری ترتیبات بند کریں۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 61b10a4..26a691a 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Muhim boʻlmagan bildirishnoma ikonkalarini koʻrsatish"</string>
<string name="other" msgid="429768510980739978">"Boshqa"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Ekranni ikkiga bo‘lish chizig‘i"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Chapda to‘liq ekran"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Chapda 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Chapda 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Chapda 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"O‘ngda to‘liq ekran"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Tepada to‘liq ekran"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Tepada 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Tepada 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Tepada 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pastda to‘liq ekran"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>-joy, “<xliff:g id="TILE_NAME">%2$s</xliff:g>” tugmasi. Tahrirlash uchun ustiga ikki marta bosing."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasi. Qo‘shish uchun ustiga ikki marta bosing."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasini ko‘chirish"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g>-joyga buni ko‘chirish: <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Tezkor sozlamalar muharriri"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirishnomasi: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Ilova ekranni ikkiga bo‘lish rejimini qo‘llab-quvvatlamaydi."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Sozlamalarni ochish."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Tezkor sozlamalarni ochish."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tezkor sozlamalarni yopish."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 6107270..bea99a9 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Hiển thị biểu tượng thông báo có mức ưu tiên thấp"</string>
<string name="other" msgid="429768510980739978">"Khác"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Bộ chia chia đôi màn hình"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Toàn màn hình bên trái"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Trái 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Trái 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Trái 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Toàn màn hình bên phải"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Toàn màn hình phía trên"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Trên 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Trên 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Trên 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Toàn màn hình phía dưới"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Nhấn đúp để chỉnh sửa."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Nhấn đúp để thêm."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Di chuyển <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Di chuyển <xliff:g id="TILE_NAME">%1$s</xliff:g> đến vị trí <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Trình chỉnh sửa cài đặt nhanh."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Thông báo của <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Ứng dụng có thể không hoạt động với tính năng chia đôi màn hình."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Ứng dụng không hỗ trợ chia đôi màn hình."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Mở phần cài đặt."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Mở cài đặt nhanh."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Đóng cài đặt nhanh."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index ffd1995..8e73f36 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"显示低优先级的通知图标"</string>
<string name="other" msgid="429768510980739978">"其他"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"分屏分隔线"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"左侧全屏"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"左侧 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"左侧 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"左侧 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"右侧全屏"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"顶部全屏"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"顶部 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"顶部 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"顶部 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"底部全屏"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。点按两次即可修改。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。点按两次即可添加。"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"移动<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"将“<xliff:g id="TILE_NAME">%1$s</xliff:g>”移动到位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"应用可能无法在分屏模式下正常运行。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"应用不支持分屏。"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"应用可能无法在辅显示屏上正常运行。"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"应用不支持在辅显示屏上启动。"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"打开设置。"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"开启快捷设置。"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"关闭快捷设置。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 1575427..08bf63b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"顯示低優先順序通知圖示"</string>
<string name="other" msgid="429768510980739978">"其他"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"分割畫面分隔線"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"左邊全螢幕"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"左邊 70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"左邊 50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"左邊 30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"右邊全螢幕"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"頂部全螢幕"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"頂部 70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"頂部 50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"頂部 30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"底部全螢幕"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。輕按兩下即可編輯。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。輕按兩下即可新增。"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"移動 <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"將「<xliff:g id="TILE_NAME">%1$s</xliff:g>」移去位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯工具。"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"應用程式可能無法在分割畫面中運作。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"應用程式不支援分割畫面。"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"應用程式可能無法在次要顯示屏上運作。"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"應用程式無法在次要顯示屏上啟動。"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"開啟設定。"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"開啟快速設定。"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"關閉快速設定。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index bbd8355..3e7d2e4 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"顯示低優先順序通知圖示"</string>
<string name="other" msgid="429768510980739978">"其他"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"分割畫面分隔線"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"以全螢幕顯示左側畫面"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"以 70% 的螢幕空間顯示左側畫面"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"以 50% 的螢幕空間顯示左側畫面"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"以 30% 的螢幕空間顯示左側畫面"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"以全螢幕顯示右側畫面"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"以全螢幕顯示頂端畫面"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"以 70% 的螢幕空間顯示頂端畫面"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"以 50% 的螢幕空間顯示頂端畫面"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"以 30% 的螢幕空間顯示頂端畫面"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"以全螢幕顯示底部畫面"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。輕觸兩下即可編輯。"</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。輕觸兩下即可新增。"</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"移動 <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"將 <xliff:g id="TILE_NAME">%1$s</xliff:g> 移到位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯器。"</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"應用程式可能無法在分割畫面中運作。"</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"這個應用程式不支援分割畫面。"</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"應用程式可能無法在次要顯示器上運作。"</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"應用程式無法在次要顯示器上啟動。"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"開啟設定。"</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"開啟快速設定。"</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"關閉快速設定。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 63b4c61..f93ff1d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -879,17 +879,6 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Bonisa izithonjana zesaziso zokubaluleka okuncane"</string>
<string name="other" msgid="429768510980739978">"Okunye"</string>
- <string name="accessibility_divider" msgid="2830785970889237307">"Isihlukanisi sokuhlukanisa isikrini"</string>
- <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Isikrini esigcwele esingakwesokunxele"</string>
- <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kwesokunxele ngo-70%"</string>
- <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kwesokunxele ngo-50%"</string>
- <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kwesokunxele ngo-30%"</string>
- <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Isikrini esigcwele esingakwesokudla"</string>
- <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Isikrini esigcwele esiphezulu"</string>
- <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Okuphezulu okungu-70%"</string>
- <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Okuphezulu okungu-50%"</string>
- <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Okuphezulu okungu-30%"</string>
- <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ngaphansi kwesikrini esigcwele"</string>
<string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Isimo esingu-<xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Thepha kabili ukuze uhlele."</string>
<string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Thepha kabili ukuze ungeze."</string>
<string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Hambisa i-<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
@@ -898,10 +887,6 @@
<string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Hambisa i-<xliff:g id="TILE_NAME">%1$s</xliff:g> ukuze ubeke i-<xliff:g id="POSITION">%2$d</xliff:g>"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Isihleli sezilungiselelo ezisheshayo."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> isaziso: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="dock_forced_resizable" msgid="4689301323912928801">"Izinhlelo zokusebenza kungenzeka zingasebenzi ngesikrini esihlukanisiwe."</string>
- <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string>
- <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string>
- <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Vula izilungiselelo."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Vula izilungiselelo ezisheshayo."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Vala izilungiselelo ezisheshayo."</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 7faa2a4..ab09a96 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -161,9 +161,6 @@
<!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
<integer name="ambient_notification_extension_time">10000</integer>
- <!-- Animation duration when using long press on recents to dock -->
- <integer name="long_press_dock_anim_duration">250</integer>
-
<!-- Whether to enable KeyguardService or not -->
<bool name="config_enableKeyguardService">true</bool>
@@ -320,7 +317,6 @@
<item>com.android.systemui.accessibility.WindowMagnification</item>
<item>com.android.systemui.accessibility.SystemActions</item>
<item>com.android.systemui.toast.ToastUI</item>
- <item>com.android.systemui.onehanded.OneHandedUI</item>
<item>com.android.systemui.wmshell.WMShell</item>
</string-array>
@@ -564,9 +560,6 @@
<!-- If the config font scale is >= this value, potentially adjust the number of columns-->
<item name="controls_max_columns_adjust_above_font_scale" translatable="false" format="float" type="dimen">1.25</item>
- <!-- Allow one handed to enable round corner -->
- <bool name="config_one_handed_enable_round_corner">true</bool>
-
<!-- Show a separate icon for low and high volume on the volume dialog -->
<bool name="config_showLowMediaVolumeIcon">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 72ee004..875fe14 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -954,12 +954,6 @@
<dimen name="fab_elevation">12dp</dimen>
<dimen name="fab_press_translation_z">9dp</dimen>
- <!-- How high we lift the divider when touching -->
- <dimen name="docked_stack_divider_lift_elevation">4dp</dimen>
-
- <dimen name="docked_divider_handle_width">16dp</dimen>
- <dimen name="docked_divider_handle_height">2dp</dimen>
-
<dimen name="battery_detail_graph_space_top">27dp</dimen>
<dimen name="battery_detail_graph_space_bottom">27dp</dimen>
@@ -1372,8 +1366,4 @@
<dimen name="config_rounded_mask_size">@*android:dimen/rounded_corner_radius</dimen>
<dimen name="config_rounded_mask_size_top">@*android:dimen/rounded_corner_radius_top</dimen>
<dimen name="config_rounded_mask_size_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen>
-
- <!-- One-Handed Mode -->
- <!-- Threshold for dragging distance to enable one-handed mode -->
- <dimen name="gestures_onehanded_drag_threshold">20dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index a56f6f5..2f018b9 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -103,13 +103,6 @@
<item type="id" name="contains_transformed_view" />
<item type="id" name="is_clicked_heads_up_tag" />
- <!-- Accessibility actions for the docked stack divider -->
- <item type="id" name="action_move_tl_full" />
- <item type="id" name="action_move_tl_70" />
- <item type="id" name="action_move_tl_50" />
- <item type="id" name="action_move_tl_30" />
- <item type="id" name="action_move_rb_full" />
-
<item type="id" name="bottom_roundess_animator_tag"/>
<item type="id" name="bottom_roundess_animator_start_tag"/>
<item type="id" name="bottom_roundess_animator_end_tag"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bfa7532..cca70f9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2260,31 +2260,6 @@
<!-- SysUI Tuner: Other section -->
<string name="other">Other</string>
- <!-- Accessibility label for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
- <string name="accessibility_divider">Split-screen divider</string>
-
- <!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_left_full">Left full screen</string>
- <!-- Accessibility action for moving docked stack divider to make the left screen 70% [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_left_70">Left 70%</string>
- <!-- Accessibility action for moving docked stack divider to make the left screen 50% [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_left_50">Left 50%</string>
- <!-- Accessibility action for moving docked stack divider to make the left screen 30% [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_left_30">Left 30%</string>
- <!-- Accessibility action for moving docked stack divider to make the right screen full screen [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_right_full">Right full screen</string>
-
- <!-- Accessibility action for moving docked stack divider to make the top screen full screen [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_top_full">Top full screen</string>
- <!-- Accessibility action for moving docked stack divider to make the top screen 70% [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_top_70">Top 70%</string>
- <!-- Accessibility action for moving docked stack divider to make the top screen 50% [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_top_50">Top 50%</string>
- <!-- Accessibility action for moving docked stack divider to make the top screen 30% [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_top_30">Top 30%</string>
- <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] -->
- <string name="accessibility_action_divider_bottom_full">Bottom full screen</string>
-
<!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
<string name="accessibility_qs_edit_tile_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>, <xliff:g id="tile_name" example="Wi-Fi">%2$s</xliff:g>. Double tap to edit.</string>
@@ -2312,16 +2287,6 @@
<!-- Label for button that reports a touch that was wrongly rejected by the lockscreen. For debugging only. [CHAR LIMIT=NONE] -->
<string name="report_rejected_touch" translatable="false">Report rejected touch</string>
- <!-- Multi-Window strings -->
- <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed in split-screen and that things might crash/not work properly [CHAR LIMIT=NONE] -->
- <string name="dock_forced_resizable">App may not work with split-screen.</string>
- <!-- Warning message when we try to dock a non-resizeable task and launch it in fullscreen instead. -->
- <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
- <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed on a secondary display and that things might crash/not work properly [CHAR LIMIT=NONE] -->
- <string name="forced_resizable_secondary_display">App may not work on a secondary display.</string>
- <!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. -->
- <string name="activity_launch_on_secondary_display_failed_text">App does not support launch on secondary displays.</string>
-
<!-- accessibility label for button to open settings [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_settings">Open settings.</string>
@@ -2834,9 +2799,4 @@
<string name="udfps_hbm_enable_command" translatable="false"></string>
<!-- Device-specific payload for disabling the high-brightness mode -->
<string name="udfps_hbm_disable_command" translatable="false"></string>
-
- <!-- One-Handed Tutorial title [CHAR LIMIT=60] -->
- <string name="one_handed_tutorial_title">Using one-handed mode</string>
- <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] -->
- <string name="one_handed_tutorial_description">To exit, swipe up from the bottom of the screen or tap anywhere above the app</string>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ee07e61..58563f4 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -24,21 +24,6 @@
<item name="android:layout_marginBottom">0dp</item>
</style>
- <!-- Theme used for the activity that shows when the system forced an app to be resizable -->
- <style name="ForcedResizableTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
- <item name="android:windowBackground">@drawable/forced_resizable_background</item>
- <item name="android:statusBarColor">@*android:color/transparent</item>
- <item name="android:windowAnimationStyle">@style/Animation.ForcedResizable</item>
- </style>
-
- <style name="Animation.ForcedResizable" parent="@android:style/Animation">
- <item name="android:activityOpenEnterAnimation">@anim/forced_resizable_enter</item>
-
- <!-- If the target stack doesn't have focus, we do a task to front animation. -->
- <item name="android:taskToFrontEnterAnimation">@anim/forced_resizable_enter</item>
- <item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
- </style>
-
<style name="PipPhoneOverlayControlTheme" parent="@android:style/Theme.Material">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
@@ -483,23 +468,6 @@
<item name="android:background">@drawable/btn_borderless_rect</item>
</style>
- <style name="DockedDividerBackground">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">10dp</item>
- <item name="android:layout_gravity">center_vertical</item>
- </style>
-
- <style name="DockedDividerMinimizedShadow">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">8dp</item>
- </style>
-
- <style name="DockedDividerHandle">
- <item name="android:layout_gravity">center_horizontal</item>
- <item name="android:layout_width">96dp</item>
- <item name="android:layout_height">48dp</item>
- </style>
-
<style name="TunerSettings" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="android:windowActionBar">false</item>
<item name="preferenceTheme">@style/TunerPreferenceTheme</item>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java
index 2b1fce8..ffde841 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java
@@ -41,16 +41,6 @@
}
/**
- * Creates a dispatcher from the extras received as part on onInitialize
- */
- public static InputEventReceiver fromBundle(Bundle params, String key,
- Looper looper, Choreographer choreographer, InputEventListener listener) {
-
- InputChannel channel = params.getParcelable(key);
- return new InputEventReceiver(channel, looper, choreographer, listener);
- }
-
- /**
* Version of addBatch method which preserves time accuracy in nanoseconds instead of
* converting the time to milliseconds.
* @param src old MotionEvent where the target should be appended
@@ -69,11 +59,9 @@
public static class InputEventReceiver {
private final BatchedInputEventReceiver mReceiver;
- private final InputChannel mInputChannel;
public InputEventReceiver(InputChannel inputChannel, Looper looper,
Choreographer choreographer, final InputEventListener listener) {
- mInputChannel = inputChannel;
mReceiver = new BatchedInputEventReceiver(inputChannel, looper, choreographer) {
@Override
@@ -85,40 +73,17 @@
}
/**
+ * @see BatchedInputEventReceiver#setBatchingEnabled()
+ */
+ public void setBatchingEnabled(boolean batchingEnabled) {
+ mReceiver.setBatchingEnabled(batchingEnabled);
+ }
+
+ /**
* @see BatchedInputEventReceiver#dispose()
*/
public void dispose() {
mReceiver.dispose();
- mInputChannel.dispose();
- }
- }
-
- /**
- * @see InputEventSender
- */
- public static class InputEventDispatcher {
-
- private final InputChannel mInputChannel;
- private final InputEventSender mSender;
-
- public InputEventDispatcher(InputChannel inputChannel, Looper looper) {
- mInputChannel = inputChannel;
- mSender = new InputEventSender(inputChannel, looper) { };
- }
-
- /**
- * @see InputEventSender#sendInputEvent(int, InputEvent)
- */
- public void dispatch(InputEvent ev) {
- mSender.sendInputEvent(ev.getSequenceNumber(), ev);
- }
-
- /**
- * @see InputEventSender#dispose()
- */
- public void dispose() {
- mSender.dispose();
- mInputChannel.dispose();
}
}
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index d64bf77..067ac9e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -153,12 +153,9 @@
}
}
+ @Deprecated
public void setPipVisibility(final boolean visible) {
- try {
- WindowManagerGlobal.getWindowManagerService().setPipVisibility(visible);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to reach window manager", e);
- }
+ // To be removed
}
/**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index 57b3761..08e9cf6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -16,32 +16,11 @@
package com.android.keyguard;
-import android.app.ActivityManager;
import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
import android.graphics.Canvas;
-import android.media.AudioManager;
-import android.os.SystemClock;
-import android.service.trust.TrustAgentService;
-import android.telephony.TelephonyManager;
import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
import android.widget.FrameLayout;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.settingslib.Utils;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-
-import java.io.File;
-
/**
* Base class for keyguard view. {@link #reset} is where you should
* reset the state of your view. Use the {@link KeyguardViewCallback} via
@@ -51,59 +30,10 @@
* Handles intercepting of media keys that still work when the keyguard is
* showing.
*/
-public class KeyguardHostView extends FrameLayout implements SecurityCallback {
+public class KeyguardHostView extends FrameLayout {
- private AudioManager mAudioManager;
- private TelephonyManager mTelephonyManager = null;
protected ViewMediatorCallback mViewMediatorCallback;
- protected LockPatternUtils mLockPatternUtils;
- private OnDismissAction mDismissAction;
- private Runnable mCancelAction;
- private final KeyguardUpdateMonitorCallback mUpdateCallback =
- new KeyguardUpdateMonitorCallback() {
-
- @Override
- public void onUserSwitchComplete(int userId) {
- getSecurityContainer().showPrimarySecurityScreen(false /* turning off */);
- }
-
- @Override
- public void onTrustGrantedWithFlags(int flags, int userId) {
- if (userId != KeyguardUpdateMonitor.getCurrentUser()) return;
- if (!isAttachedToWindow()) return;
- boolean bouncerVisible = isVisibleToUser();
- boolean initiatedByUser =
- (flags & TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER) != 0;
- boolean dismissKeyguard =
- (flags & TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD) != 0;
-
- if (initiatedByUser || dismissKeyguard) {
- if (mViewMediatorCallback.isScreenOn() && (bouncerVisible || dismissKeyguard)) {
- if (!bouncerVisible) {
- // The trust agent dismissed the keyguard without the user proving
- // that they are present (by swiping up to show the bouncer). That's fine if
- // the user proved presence via some other way to the trust agent.
- Log.i(TAG, "TrustAgent dismissed Keyguard.");
- }
- dismiss(false /* authenticated */, userId,
- /* bypassSecondaryLockScreen */ false);
- } else {
- mViewMediatorCallback.playTrustedSound();
- }
- }
- }
- };
-
- // Whether the volume keys should be handled by keyguard. If true, then
- // they will be handled here for specific media types such as music, otherwise
- // the audio service will bring up the volume dialog.
- private static final boolean KEYGUARD_MANAGES_VOLUME = false;
- public static final boolean DEBUG = KeyguardConstants.DEBUG;
- private static final String TAG = "KeyguardViewBase";
-
- @VisibleForTesting
- protected KeyguardSecurityContainer mSecurityContainer;
public KeyguardHostView(Context context) {
this(context, null);
@@ -111,7 +41,6 @@
public KeyguardHostView(Context context, AttributeSet attrs) {
super(context, attrs);
- Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mUpdateCallback);
}
@Override
@@ -122,337 +51,7 @@
}
}
- /**
- * Sets an action to run when keyguard finishes.
- *
- * @param action
- */
- public void setOnDismissAction(OnDismissAction action, Runnable cancelAction) {
- if (mCancelAction != null) {
- mCancelAction.run();
- mCancelAction = null;
- }
- mDismissAction = action;
- mCancelAction = cancelAction;
- }
-
- public boolean hasDismissActions() {
- return mDismissAction != null || mCancelAction != null;
- }
-
- public void cancelDismissAction() {
- setOnDismissAction(null, null);
- }
-
- @Override
- protected void onFinishInflate() {
- mSecurityContainer =
- findViewById(R.id.keyguard_security_container);
- mLockPatternUtils = new LockPatternUtils(mContext);
- mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
- mSecurityContainer.setSecurityCallback(this);
- mSecurityContainer.showPrimarySecurityScreen(false);
- }
-
- /**
- * Called when the view needs to be shown.
- */
- public void showPrimarySecurityScreen() {
- if (DEBUG) Log.d(TAG, "show()");
- mSecurityContainer.showPrimarySecurityScreen(false);
- }
-
- public KeyguardSecurityView getCurrentSecurityView() {
- return mSecurityContainer != null ? mSecurityContainer.getCurrentSecurityView() : null;
- }
-
- /**
- * Show a string explaining why the security view needs to be solved.
- *
- * @param reason a flag indicating which string should be shown, see
- * {@link KeyguardSecurityView#PROMPT_REASON_NONE},
- * {@link KeyguardSecurityView#PROMPT_REASON_RESTART},
- * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}, and
- * {@link KeyguardSecurityView#PROMPT_REASON_PREPARE_FOR_UPDATE}.
- */
- public void showPromptReason(int reason) {
- mSecurityContainer.showPromptReason(reason);
- }
-
- public void showMessage(CharSequence message, ColorStateList colorState) {
- mSecurityContainer.showMessage(message, colorState);
- }
-
- public void showErrorMessage(CharSequence message) {
- showMessage(message, Utils.getColorError(mContext));
- }
-
- /**
- * Dismisses the keyguard by going to the next screen or making it gone.
- * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
- * @return True if the keyguard is done.
- */
- public boolean dismiss(int targetUserId) {
- return dismiss(false, targetUserId, false);
- }
-
- public boolean handleBackKey() {
- if (mSecurityContainer.getCurrentSecuritySelection() != SecurityMode.None) {
- mSecurityContainer.dismiss(false, KeyguardUpdateMonitor.getCurrentUser());
- return true;
- }
- return false;
- }
-
- protected KeyguardSecurityContainer getSecurityContainer() {
- return mSecurityContainer;
- }
-
- @Override
- public boolean dismiss(boolean authenticated, int targetUserId,
- boolean bypassSecondaryLockScreen) {
- return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId,
- bypassSecondaryLockScreen);
- }
-
- /**
- * Authentication has happened and it's time to dismiss keyguard. This function
- * should clean up and inform KeyguardViewMediator.
- *
- * @param strongAuth whether the user has authenticated with strong authentication like
- * pattern, password or PIN but not by trust agents or fingerprint
- * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
- */
- @Override
- public void finish(boolean strongAuth, int targetUserId) {
- // If there's a pending runnable because the user interacted with a widget
- // and we're leaving keyguard, then run it.
- boolean deferKeyguardDone = false;
- if (mDismissAction != null) {
- deferKeyguardDone = mDismissAction.onDismiss();
- mDismissAction = null;
- mCancelAction = null;
- }
- if (mViewMediatorCallback != null) {
- if (deferKeyguardDone) {
- mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
- } else {
- mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
- }
- }
- }
-
- @Override
- public void reset() {
- mViewMediatorCallback.resetKeyguard();
- }
-
- @Override
- public void onCancelClicked() {
- mViewMediatorCallback.onCancelClicked();
- }
-
- public void resetSecurityContainer() {
- mSecurityContainer.reset();
- }
-
- @Override
- public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
- if (mViewMediatorCallback != null) {
- mViewMediatorCallback.setNeedsInput(needsInput);
- }
- }
-
- public CharSequence getAccessibilityTitleForCurrentMode() {
- return mSecurityContainer.getTitle();
- }
-
- public void userActivity() {
- if (mViewMediatorCallback != null) {
- mViewMediatorCallback.userActivity();
- }
- }
-
- /**
- * Called when the Keyguard is not actively shown anymore on the screen.
- */
- public void onPause() {
- if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
- Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
- mSecurityContainer.showPrimarySecurityScreen(true);
- mSecurityContainer.onPause();
- clearFocus();
- }
-
- /**
- * Called when the Keyguard is actively shown on the screen.
- */
- public void onResume() {
- if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
- mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON);
- requestFocus();
- }
-
- /**
- * Starts the animation when the Keyguard gets shown.
- */
- public void startAppearAnimation() {
- mSecurityContainer.startAppearAnimation();
- }
-
- public void startDisappearAnimation(Runnable finishRunnable) {
- if (!mSecurityContainer.startDisappearAnimation(finishRunnable) && finishRunnable != null) {
- finishRunnable.run();
- }
- }
-
- /**
- * Called before this view is being removed.
- */
- public void cleanUp() {
- getSecurityContainer().onPause();
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (interceptMediaKey(event)) {
- return true;
- }
- return super.dispatchKeyEvent(event);
- }
-
- /**
- * Allows the media keys to work when the keyguard is showing.
- * The media keys should be of no interest to the actual keyguard view(s),
- * so intercepting them here should not be of any harm.
- * @param event The key event
- * @return whether the event was consumed as a media key.
- */
- public boolean interceptMediaKey(KeyEvent event) {
- final int keyCode = event.getKeyCode();
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_MEDIA_PLAY:
- case KeyEvent.KEYCODE_MEDIA_PAUSE:
- case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
- /* Suppress PLAY/PAUSE toggle when phone is ringing or
- * in-call to avoid music playback */
- if (mTelephonyManager == null) {
- mTelephonyManager = (TelephonyManager) getContext().getSystemService(
- Context.TELEPHONY_SERVICE);
- }
- if (mTelephonyManager != null &&
- mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
- return true; // suppress key event
- }
- case KeyEvent.KEYCODE_MUTE:
- case KeyEvent.KEYCODE_HEADSETHOOK:
- case KeyEvent.KEYCODE_MEDIA_STOP:
- case KeyEvent.KEYCODE_MEDIA_NEXT:
- case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
- case KeyEvent.KEYCODE_MEDIA_REWIND:
- case KeyEvent.KEYCODE_MEDIA_RECORD:
- case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
- case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
- handleMediaKeyEvent(event);
- return true;
- }
-
- case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_MUTE: {
- if (KEYGUARD_MANAGES_VOLUME) {
- synchronized (this) {
- if (mAudioManager == null) {
- mAudioManager = (AudioManager) getContext().getSystemService(
- Context.AUDIO_SERVICE);
- }
- }
- // Volume buttons should only function for music (local or remote).
- // TODO: Actually handle MUTE.
- mAudioManager.adjustSuggestedStreamVolume(
- keyCode == KeyEvent.KEYCODE_VOLUME_UP
- ? AudioManager.ADJUST_RAISE
- : AudioManager.ADJUST_LOWER /* direction */,
- AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */);
- // Don't execute default volume behavior
- return true;
- } else {
- return false;
- }
- }
- }
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_MUTE:
- case KeyEvent.KEYCODE_HEADSETHOOK:
- case KeyEvent.KEYCODE_MEDIA_PLAY:
- case KeyEvent.KEYCODE_MEDIA_PAUSE:
- case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
- case KeyEvent.KEYCODE_MEDIA_STOP:
- case KeyEvent.KEYCODE_MEDIA_NEXT:
- case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
- case KeyEvent.KEYCODE_MEDIA_REWIND:
- case KeyEvent.KEYCODE_MEDIA_RECORD:
- case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
- case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
- handleMediaKeyEvent(event);
- return true;
- }
- }
- }
- return false;
- }
-
- private void handleMediaKeyEvent(KeyEvent keyEvent) {
- synchronized (this) {
- if (mAudioManager == null) {
- mAudioManager = (AudioManager) getContext().getSystemService(
- Context.AUDIO_SERVICE);
- }
- }
- mAudioManager.dispatchMediaKeyEvent(keyEvent);
- }
-
- /**
- * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
- * some cases where we wish to disable it, notably when the menu button placement or technology
- * is prone to false positives.
- *
- * @return true if the menu key should be enabled
- */
- private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
- public boolean shouldEnableMenuKey() {
- final Resources res = getResources();
- final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
- final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
- final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
- return !configDisabled || isTestHarness || fileOverride;
- }
-
public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
mViewMediatorCallback = viewMediatorCallback;
- // Update ViewMediator with the current input method requirements
- mViewMediatorCallback.setNeedsInput(mSecurityContainer.needsInput());
- }
-
- public void setLockPatternUtils(LockPatternUtils utils) {
- mLockPatternUtils = utils;
- mSecurityContainer.setLockPatternUtils(utils);
- }
-
- public SecurityMode getSecurityMode() {
- return mSecurityContainer.getSecurityMode();
- }
-
- public SecurityMode getCurrentSecurityMode() {
- return mSecurityContainer.getCurrentSecurityMode();
- }
-
- /**
- * When bouncer was visible and is starting to become hidden.
- */
- public void onStartingToHide() {
- mSecurityContainer.onStartingToHide();
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
new file mode 100644
index 0000000..7aabb17
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2020 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.keyguard;
+
+import android.app.ActivityManager;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.media.AudioManager;
+import android.os.SystemClock;
+import android.service.trust.TrustAgentService;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.util.MathUtils;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnKeyListener;
+import android.view.ViewTreeObserver;
+
+import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.keyguard.dagger.KeyguardBouncerScope;
+import com.android.settingslib.Utils;
+import com.android.systemui.R;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.util.ViewController;
+
+import java.io.File;
+
+import javax.inject.Inject;
+
+/** Controller for a {@link KeyguardHostView}. */
+@KeyguardBouncerScope
+public class KeyguardHostViewController extends ViewController<KeyguardHostView> {
+ private static final String TAG = "KeyguardViewBase";
+ public static final boolean DEBUG = KeyguardConstants.DEBUG;
+ // Whether the volume keys should be handled by keyguard. If true, then
+ // they will be handled here for specific media types such as music, otherwise
+ // the audio service will bring up the volume dialog.
+ private static final boolean KEYGUARD_MANAGES_VOLUME = false;
+
+ private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
+
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final KeyguardSecurityContainerController mKeyguardSecurityContainerController;
+ private final TelephonyManager mTelephonyManager;
+ private final ViewMediatorCallback mViewMediatorCallback;
+ private final AudioManager mAudioManager;
+
+ private ActivityStarter.OnDismissAction mDismissAction;
+ private Runnable mCancelAction;
+
+ private final KeyguardUpdateMonitorCallback mUpdateCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onUserSwitchComplete(int userId) {
+ mKeyguardSecurityContainerController.showPrimarySecurityScreen(
+ false /* turning off */);
+ }
+
+ @Override
+ public void onTrustGrantedWithFlags(int flags, int userId) {
+ if (userId != KeyguardUpdateMonitor.getCurrentUser()) return;
+ boolean bouncerVisible = mView.isVisibleToUser();
+ boolean initiatedByUser =
+ (flags & TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER) != 0;
+ boolean dismissKeyguard =
+ (flags & TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD) != 0;
+
+ if (initiatedByUser || dismissKeyguard) {
+ if (mViewMediatorCallback.isScreenOn()
+ && (bouncerVisible || dismissKeyguard)) {
+ if (!bouncerVisible) {
+ // The trust agent dismissed the keyguard without the user proving
+ // that they are present (by swiping up to show the bouncer). That's
+ // fine if the user proved presence via some other way to the trust
+ //agent.
+ Log.i(TAG, "TrustAgent dismissed Keyguard.");
+ }
+ mSecurityCallback.dismiss(false /* authenticated */, userId,
+ /* bypassSecondaryLockScreen */ false);
+ } else {
+ mViewMediatorCallback.playTrustedSound();
+ }
+ }
+ }
+ };
+
+ private final SecurityCallback mSecurityCallback = new SecurityCallback() {
+
+ @Override
+ public boolean dismiss(boolean authenticated, int targetUserId,
+ boolean bypassSecondaryLockScreen) {
+ return mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
+ authenticated, targetUserId, bypassSecondaryLockScreen);
+ }
+
+ @Override
+ public void userActivity() {
+ mViewMediatorCallback.userActivity();
+ }
+
+ @Override
+ public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
+ mViewMediatorCallback.setNeedsInput(needsInput);
+ }
+
+ /**
+ * Authentication has happened and it's time to dismiss keyguard. This function
+ * should clean up and inform KeyguardViewMediator.
+ *
+ * @param strongAuth whether the user has authenticated with strong authentication like
+ * pattern, password or PIN but not by trust agents or fingerprint
+ * @param targetUserId a user that needs to be the foreground user at the dismissal
+ * completion.
+ */
+ @Override
+ public void finish(boolean strongAuth, int targetUserId) {
+ // If there's a pending runnable because the user interacted with a widget
+ // and we're leaving keyguard, then run it.
+ boolean deferKeyguardDone = false;
+ if (mDismissAction != null) {
+ deferKeyguardDone = mDismissAction.onDismiss();
+ mDismissAction = null;
+ mCancelAction = null;
+ }
+ if (mViewMediatorCallback != null) {
+ if (deferKeyguardDone) {
+ mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
+ } else {
+ mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
+ }
+ }
+ }
+
+ @Override
+ public void reset() {
+ mViewMediatorCallback.resetKeyguard();
+ }
+
+ @Override
+ public void onCancelClicked() {
+ mViewMediatorCallback.onCancelClicked();
+ }
+ };
+
+ private OnKeyListener mOnKeyListener = (v, keyCode, event) -> interceptMediaKey(event);
+
+ @Inject
+ public KeyguardHostViewController(KeyguardHostView view,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ KeyguardSecurityContainerController keyguardSecurityContainerController,
+ AudioManager audioManager,
+ TelephonyManager telephonyManager,
+ ViewMediatorCallback viewMediatorCallback) {
+ super(view);
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mKeyguardSecurityContainerController = keyguardSecurityContainerController;
+ mAudioManager = audioManager;
+ mTelephonyManager = telephonyManager;
+ mViewMediatorCallback = viewMediatorCallback;
+ }
+
+ /** Initialize the Controller. */
+ public void init() {
+ super.init();
+ mView.setViewMediatorCallback(mViewMediatorCallback);
+ // Update ViewMediator with the current input method requirements
+ mViewMediatorCallback.setNeedsInput(mKeyguardSecurityContainerController.needsInput());
+ mKeyguardSecurityContainerController.init();
+ mKeyguardSecurityContainerController.setSecurityCallback(mSecurityCallback);
+ mKeyguardSecurityContainerController.showPrimarySecurityScreen(false);
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
+ mView.setOnKeyListener(mOnKeyListener);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mKeyguardUpdateMonitor.removeCallback(mUpdateCallback);
+ mView.setOnKeyListener(null);
+ }
+
+ /** Called before this view is being removed. */
+ public void cleanUp() {
+ mKeyguardSecurityContainerController.onPause();
+ }
+
+ public void resetSecurityContainer() {
+ mKeyguardSecurityContainerController.reset();
+ }
+
+ /**
+ * Dismisses the keyguard by going to the next screen or making it gone.
+ * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
+ * @return True if the keyguard is done.
+ */
+ public boolean dismiss(int targetUserId) {
+ return mSecurityCallback.dismiss(false, targetUserId, false);
+ }
+
+ /**
+ * Called when the Keyguard is actively shown on the screen.
+ */
+ public void onResume() {
+ if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+ mKeyguardSecurityContainerController.onResume(KeyguardSecurityView.SCREEN_ON);
+ mView.requestFocus();
+ }
+
+ public CharSequence getAccessibilityTitleForCurrentMode() {
+ return mKeyguardSecurityContainerController.getTitle();
+ }
+
+ /**
+ * Starts the animation when the Keyguard gets shown.
+ */
+ public void appear(int statusBarHeight) {
+ // We might still be collapsed and the view didn't have time to layout yet or still
+ // be small, let's wait on the predraw to do the animation in that case.
+ if (mView.getHeight() != 0 && mView.getHeight() != statusBarHeight) {
+ mKeyguardSecurityContainerController.startAppearAnimation();
+ } else {
+ mView.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ mView.getViewTreeObserver().removeOnPreDrawListener(this);
+ mKeyguardSecurityContainerController.startAppearAnimation();
+ return true;
+ }
+ });
+ mView.requestLayout();
+ }
+ }
+
+ /**
+ * Show a string explaining why the security view needs to be solved.
+ *
+ * @param reason a flag indicating which string should be shown, see
+ * {@link KeyguardSecurityView#PROMPT_REASON_NONE},
+ * {@link KeyguardSecurityView#PROMPT_REASON_RESTART},
+ * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}, and
+ * {@link KeyguardSecurityView#PROMPT_REASON_PREPARE_FOR_UPDATE}.
+ */
+ public void showPromptReason(int reason) {
+ mKeyguardSecurityContainerController.showPromptReason(reason);
+ }
+
+ public void showMessage(CharSequence message, ColorStateList colorState) {
+ mKeyguardSecurityContainerController.showMessage(message, colorState);
+ }
+
+ public void showErrorMessage(CharSequence customMessage) {
+ showMessage(customMessage, Utils.getColorError(mView.getContext()));
+ }
+
+ /**
+ * Sets an action to run when keyguard finishes.
+ *
+ * @param action
+ */
+ public void setOnDismissAction(ActivityStarter.OnDismissAction action, Runnable cancelAction) {
+ if (mCancelAction != null) {
+ mCancelAction.run();
+ mCancelAction = null;
+ }
+ mDismissAction = action;
+ mCancelAction = cancelAction;
+ }
+
+ public void cancelDismissAction() {
+ setOnDismissAction(null, null);
+ }
+
+ public void startDisappearAnimation(Runnable finishRunnable) {
+ if (!mKeyguardSecurityContainerController.startDisappearAnimation(finishRunnable)
+ && finishRunnable != null) {
+ finishRunnable.run();
+ }
+ }
+
+ /**
+ * Called when the Keyguard is not actively shown anymore on the screen.
+ */
+ public void onPause() {
+ if (DEBUG) {
+ Log.d(TAG, String.format("screen off, instance %s at %s",
+ Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+ }
+ mKeyguardSecurityContainerController.showPrimarySecurityScreen(true);
+ mKeyguardSecurityContainerController.onPause();
+ mView.clearFocus();
+ }
+
+ /**
+ * Called when the view needs to be shown.
+ */
+ public void showPrimarySecurityScreen() {
+ if (DEBUG) Log.d(TAG, "show()");
+ mKeyguardSecurityContainerController.showPrimarySecurityScreen(false);
+ }
+
+ public void setExpansion(float fraction) {
+ float alpha = MathUtils.map(KeyguardBouncer.ALPHA_EXPANSION_THRESHOLD, 1, 1, 0, fraction);
+ mView.setAlpha(MathUtils.constrain(alpha, 0f, 1f));
+ mView.setTranslationY(fraction * mView.getHeight());
+ }
+
+ /**
+ * When bouncer was visible and is starting to become hidden.
+ */
+ public void onStartingToHide() {
+ mKeyguardSecurityContainerController.onStartingToHide();
+ }
+
+ public boolean hasDismissActions() {
+ return mDismissAction != null || mCancelAction != null;
+ }
+
+ public SecurityMode getCurrentSecurityMode() {
+ return mKeyguardSecurityContainerController.getCurrentSecurityMode();
+ }
+
+ public int getTop() {
+ int top = mView.getTop();
+ // The password view has an extra top padding that should be ignored.
+ if (getCurrentSecurityMode() == SecurityMode.Password) {
+ View messageArea = mView.findViewById(R.id.keyguard_message_area);
+ top += messageArea.getTop();
+ }
+ return top;
+ }
+
+ public boolean handleBackKey() {
+ if (mKeyguardSecurityContainerController.getCurrentSecuritySelection()
+ != SecurityMode.None) {
+ mKeyguardSecurityContainerController.dismiss(
+ false, KeyguardUpdateMonitor.getCurrentUser());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
+ * some cases where we wish to disable it, notably when the menu button placement or technology
+ * is prone to false positives.
+ *
+ * @return true if the menu key should be enabled
+ */
+ public boolean shouldEnableMenuKey() {
+ final Resources res = mView.getResources();
+ final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
+ final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
+ final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
+ return !configDisabled || isTestHarness || fileOverride;
+ }
+
+ /**
+ * Allows the media keys to work when the keyguard is showing.
+ * The media keys should be of no interest to the actual keyguard view(s),
+ * so intercepting them here should not be of any harm.
+ * @param event The key event
+ * @return whether the event was consumed as a media key.
+ */
+ public boolean interceptMediaKey(KeyEvent event) {
+ int keyCode = event.getKeyCode();
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ /* Suppress PLAY/PAUSE toggle when phone is ringing or
+ * in-call to avoid music playback */
+ if (mTelephonyManager != null &&
+ mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
+ return true; // suppress key event
+ }
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_RECORD:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+ case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+ handleMediaKeyEvent(event);
+ return true;
+ }
+
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_MUTE: {
+ if (KEYGUARD_MANAGES_VOLUME) {
+ // Volume buttons should only function for music (local or remote).
+ // TODO: Actually handle MUTE.
+ mAudioManager.adjustSuggestedStreamVolume(
+ keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ ? AudioManager.ADJUST_RAISE
+ : AudioManager.ADJUST_LOWER /* direction */,
+ AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */);
+ // Don't execute default volume behavior
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_RECORD:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+ case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+ handleMediaKeyEvent(event);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private void handleMediaKeyEvent(KeyEvent keyEvent) {
+ mAudioManager.dispatchMediaKeyEvent(keyEvent);
+ }
+
+ public void finish(boolean strongAuth, int currentUser) {
+ mSecurityCallback.finish(strongAuth, currentUser);
+ }
+
+
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
new file mode 100644
index 0000000..f056bdb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 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.keyguard;
+
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+
+/** Controller for a {@link KeyguardMessageAreaController}. */
+public class KeyguardMessageAreaController extends ViewController<KeyguardMessageArea> {
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final ConfigurationController mConfigurationController;
+
+ private KeyguardMessageAreaController(KeyguardMessageArea view,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ ConfigurationController configurationController) {
+ super(view);
+
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mConfigurationController = configurationController;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ //mConfigurationController.addCallback();
+ //mKeyguardUpdateMonitor.registerCallback();
+ }
+
+ @Override
+ protected void onViewDetached() {
+ //mConfigurationController.removeCallback();
+ //mKeyguardUpdateMonitor.removeCallback();
+ }
+
+ /** Factory for createing {@link com.android.keyguard.KeyguardMessageAreaController}. */
+ public static class Factory {
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final ConfigurationController mConfigurationController;
+
+ @Inject
+ public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor,
+ ConfigurationController configurationController) {
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mConfigurationController = configurationController;
+ }
+
+ /** Build a new {@link KeyguardMessageAreaController}. */
+ public KeyguardMessageAreaController create(KeyguardMessageArea view) {
+ return new KeyguardMessageAreaController(
+ view, mKeyguardUpdateMonitor, mConfigurationController);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java
new file mode 100644
index 0000000..5c125fc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardRootViewController.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.keyguard;
+
+import android.view.ViewGroup;
+
+import com.android.keyguard.dagger.KeyguardBouncerScope;
+import com.android.keyguard.dagger.RootView;
+import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+/** Controller for a {@link KeyguardBouncer}'s Root view. */
+@KeyguardBouncerScope
+public class KeyguardRootViewController extends ViewController<ViewGroup> {
+ @Inject
+ public KeyguardRootViewController(@RootView ViewGroup view) {
+ super(view);
+ }
+
+ public ViewGroup getView() {
+ return mView;
+ }
+
+ @Override
+ protected void onViewAttached() {
+
+ }
+
+ @Override
+ protected void onViewDetached() {
+
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
new file mode 100644
index 0000000..17f25bd08ef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 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.keyguard;
+
+import android.content.res.ColorStateList;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+
+/** Controller for {@link KeyguardSecurityContainer} */
+public class KeyguardSecurityContainerController extends ViewController<KeyguardSecurityContainer> {
+
+ private final LockPatternUtils mLockPatternUtils;
+ private final KeyguardSecurityViewController.Factory mKeyguardSecurityViewControllerFactory;
+
+ @Inject
+ KeyguardSecurityContainerController(KeyguardSecurityContainer view,
+ LockPatternUtils lockPatternUtils,
+ KeyguardSecurityViewController.Factory keyguardSecurityViewControllerFactory) {
+ super(view);
+ mLockPatternUtils = lockPatternUtils;
+ view.setLockPatternUtils(mLockPatternUtils);
+ mKeyguardSecurityViewControllerFactory = keyguardSecurityViewControllerFactory;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ }
+
+ @Override
+ protected void onViewDetached() {
+ }
+
+ /** */
+ public void onPause() {
+ mView.onPause();
+ }
+
+ public void showPrimarySecurityScreen(boolean turningOff) {
+ mView.showPrimarySecurityScreen(turningOff);
+ }
+
+ public void showPromptReason(int reason) {
+ mView.showPromptReason(reason);
+ }
+
+ public void showMessage(CharSequence message, ColorStateList colorState) {
+ mView.showMessage(message, colorState);
+ }
+
+ public SecurityMode getCurrentSecuritySelection() {
+ return mView.getCurrentSecuritySelection();
+ }
+
+ public void dismiss(boolean authenticated, int targetUserId) {
+ mView.dismiss(authenticated, targetUserId);
+ }
+
+ public void reset() {
+ mView.reset();
+ }
+
+ public CharSequence getTitle() {
+ return mView.getTitle();
+ }
+
+ public void onResume(int screenOn) {
+ mView.onResume(screenOn);
+ }
+
+ public void startAppearAnimation() {
+ mView.startAppearAnimation();
+ }
+
+ public boolean startDisappearAnimation(Runnable onFinishRunnable) {
+ return mView.startDisappearAnimation(onFinishRunnable);
+ }
+
+ public void onStartingToHide() {
+ mView.onStartingToHide();
+ }
+
+ public void setSecurityCallback(SecurityCallback securityCallback) {
+ mView.setSecurityCallback(securityCallback);
+ }
+
+ public boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId,
+ boolean bypassSecondaryLockScreen) {
+ return mView.showNextSecurityScreenOrFinish(
+ authenticated, targetUserId, bypassSecondaryLockScreen);
+ }
+
+ public boolean needsInput() {
+ return mView.needsInput();
+ }
+
+ public SecurityMode getCurrentSecurityMode() {
+ return mView.getCurrentSecurityMode();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewController.java
new file mode 100644
index 0000000..ef9ba19
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewController.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 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.keyguard;
+
+import android.view.View;
+
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+
+
+/** Controller for a {@link KeyguardSecurityView}. */
+public class KeyguardSecurityViewController extends ViewController<View> {
+
+ private final KeyguardSecurityView mView;
+
+ private KeyguardSecurityViewController(KeyguardSecurityView view) {
+ super((View) view);
+ // KeyguardSecurityView isn't actually a View, so we need to track it ourselves.
+ mView = view;
+ }
+
+ @Override
+ protected void onViewAttached() {
+
+ }
+
+ @Override
+ protected void onViewDetached() {
+
+ }
+
+ /** Factory for a {@link KeyguardSecurityViewController}. */
+ public static class Factory {
+ @Inject
+ public Factory() {
+ }
+
+ /** Create a new {@link KeyguardSecurityViewController}. */
+ public KeyguardSecurityViewController create(KeyguardSecurityView view) {
+ return new KeyguardSecurityViewController(view);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1027329..76090f8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -36,6 +36,7 @@
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.UserSwitchObserver;
@@ -2783,7 +2784,7 @@
@Override
public void onTaskStackChangedBackground() {
try {
- ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
+ RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
if (info == null) {
return;
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java
index 84deaca..5160b7e 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java
@@ -16,27 +16,27 @@
package com.android.keyguard.dagger;
-import android.view.ViewGroup;
-
+import com.android.keyguard.KeyguardHostViewController;
+import com.android.keyguard.KeyguardRootViewController;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import dagger.BindsInstance;
import dagger.Subcomponent;
/**
* Dagger Subcomponent for the {@link KeyguardBouncer}.
*/
-@Subcomponent
+@Subcomponent(modules = {KeyguardBouncerModule.class})
@KeyguardBouncerScope
public interface KeyguardBouncerComponent {
/** Simple factory for {@link KeyguardBouncerComponent}. */
@Subcomponent.Factory
interface Factory {
- KeyguardBouncerComponent build(
- @BindsInstance @ContainerView ViewGroup container,
- @BindsInstance KeyguardBouncer.BouncerExpansionCallback bouncerExpansionCallback);
+ KeyguardBouncerComponent create();
}
- /** */
- KeyguardBouncer createKeyguardBouncer();
+ /** Returns a {@link KeyguardRootViewController}. */
+ KeyguardRootViewController getKeyguardRootViewController();
+
+ /** Returns a {@link KeyguardHostViewController}. */
+ KeyguardHostViewController getKeyguardHostViewController();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
new file mode 100644
index 0000000..b6010c8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 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.keyguard.dagger;
+
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardMessageArea;
+import com.android.keyguard.KeyguardSecurityContainer;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardBouncer;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Module to create and access view related to the {@link KeyguardBouncer}.
+ */
+@Module
+public interface KeyguardBouncerModule {
+ /** */
+ @Provides
+ @KeyguardBouncerScope
+ @RootView
+ static ViewGroup providesRootView(LayoutInflater layoutInflater) {
+ return (ViewGroup) layoutInflater.inflate(R.layout.keyguard_bouncer, null);
+ }
+
+ /** */
+ @Provides
+ @KeyguardBouncerScope
+ static KeyguardMessageArea providesKeyguardMessageArea(@RootView ViewGroup viewGroup) {
+ return viewGroup.findViewById(R.id.keyguard_message_area);
+ }
+
+ /** */
+ @Provides
+ @KeyguardBouncerScope
+ static KeyguardHostView providesKeyguardHostView(@RootView ViewGroup rootView) {
+ return rootView.findViewById(R.id.keyguard_host_view);
+ }
+
+ /** */
+ @Provides
+ @KeyguardBouncerScope
+ static KeyguardSecurityContainer preovidesKeyguardSecurityContainer(KeyguardHostView hostView) {
+ return hostView.findViewById(R.id.keyguard_security_container);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java b/packages/SystemUI/src/com/android/keyguard/dagger/RootView.java
similarity index 96%
rename from packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
rename to packages/SystemUI/src/com/android/keyguard/dagger/RootView.java
index e65f19d..5ebff09 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/RootView.java
@@ -26,5 +26,5 @@
@Qualifier
@Documented
@Retention(RUNTIME)
-public @interface ContainerView {
+public @interface RootView {
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index 128af37..68e404e 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -43,6 +43,7 @@
private static final int DURATION_MS = 5000;
private static final int START_DELAY_MS = 3000;
+ private final Runnable mAnimationTask;
private final Context mContext;
private final WindowManager mWindowManager;
@@ -70,6 +71,14 @@
applyResourcesValues();
mImageView.setImageResource(getIconResId(mMagnificationMode));
mImageView.setOnTouchListener(this::onTouch);
+
+ mAnimationTask = () -> {
+ mImageView.animate()
+ .alpha(0f)
+ .setDuration(DURATION_MS)
+ .withEndAction(() -> removeButton())
+ .start();
+ };
}
private void applyResourcesValues() {
@@ -147,13 +156,8 @@
// Dismiss the magnification switch button after the button is displayed for a period of
// time.
mImageView.animate().cancel();
- mImageView.animate()
- .alpha(0f)
- .setStartDelay(START_DELAY_MS)
- .setDuration(DURATION_MS)
- .withEndAction(
- () -> removeButton())
- .start();
+ mImageView.removeCallbacks(mAnimationTask);
+ mImageView.postDelayed(mAnimationTask, START_DELAY_MS);
}
void onConfigurationChanged(int configDiff) {
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index b9b849b..83de324 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -16,7 +16,6 @@
package com.android.systemui.broadcast
-import android.app.ActivityManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -33,6 +32,7 @@
import com.android.systemui.Dumpable
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
+import com.android.systemui.settings.UserTracker
import java.io.FileDescriptor
import java.io.PrintWriter
import java.util.concurrent.Executor
@@ -47,8 +47,6 @@
private const val MSG_ADD_RECEIVER = 0
private const val MSG_REMOVE_RECEIVER = 1
private const val MSG_REMOVE_RECEIVER_FOR_USER = 2
-private const val MSG_USER_SWITCH = 3
-private const val MSG_SET_STARTING_USER = 99
private const val TAG = "BroadcastDispatcher"
private const val DEBUG = true
@@ -68,23 +66,15 @@
private val bgLooper: Looper,
private val bgExecutor: Executor,
private val dumpManager: DumpManager,
- private val logger: BroadcastDispatcherLogger
-) : Dumpable, BroadcastReceiver() {
+ private val logger: BroadcastDispatcherLogger,
+ private val userTracker: UserTracker
+) : Dumpable {
// Only modify in BG thread
private val receiversByUser = SparseArray<UserBroadcastDispatcher>(20)
fun initialize() {
dumpManager.registerDumpable(javaClass.name, this)
- handler.sendEmptyMessage(MSG_SET_STARTING_USER)
- registerReceiver(this, IntentFilter(Intent.ACTION_USER_SWITCHED), null, UserHandle.ALL)
- }
-
- override fun onReceive(context: Context, intent: Intent) {
- if (intent.action == Intent.ACTION_USER_SWITCHED) {
- val user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL)
- handler.obtainMessage(MSG_USER_SWITCH, user, 0).sendToTarget()
- }
}
/**
@@ -181,7 +171,6 @@
pw.println("Broadcast dispatcher:")
val ipw = IndentingPrintWriter(pw, " ")
ipw.increaseIndent()
- ipw.println("Current user: ${handler.currentUser}")
for (index in 0 until receiversByUser.size()) {
ipw.println("User ${receiversByUser.keyAt(index)}")
receiversByUser.valueAt(index).dump(fd, ipw, args)
@@ -190,7 +179,6 @@
}
private val handler = object : Handler(bgLooper) {
- var currentUser = UserHandle.USER_SYSTEM
override fun handleMessage(msg: Message) {
when (msg.what) {
@@ -199,7 +187,7 @@
// If the receiver asked to be registered under the current user, we register
// under the actual current user.
val userId = if (data.user.identifier == UserHandle.USER_CURRENT) {
- currentUser
+ userTracker.userId
} else {
data.user.identifier
}
@@ -221,14 +209,6 @@
MSG_REMOVE_RECEIVER_FOR_USER -> {
receiversByUser.get(msg.arg1)?.unregisterReceiver(msg.obj as BroadcastReceiver)
}
-
- MSG_USER_SWITCH -> {
- currentUser = msg.arg1
- }
- MSG_SET_STARTING_USER -> {
- currentUser = ActivityManager.getCurrentUser()
- }
-
else -> super.handleMessage(msg)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index a86a469..9f7358b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -17,9 +17,12 @@
import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.PathParser;
import android.widget.ImageView;
@@ -30,6 +33,9 @@
import java.util.EnumSet;
+import static android.graphics.Paint.DITHER_FLAG;
+import static android.graphics.Paint.FILTER_BITMAP_FLAG;
+
/**
* View that displays an adaptive icon with an app-badge and a dot.
*
@@ -43,6 +49,8 @@
public static final float WHITE_SCRIM_ALPHA = 0.54f;
/** Same as value in Launcher3 IconShape */
public static final int DEFAULT_PATH_SIZE = 100;
+ /** Same as value in Launcher3 BaseIconFactory */
+ private static final float ICON_BADGE_SCALE = 0.444f;
/**
* Flags that suppress the visibility of the 'new' dot, for one reason or another. If any of
@@ -69,6 +77,7 @@
private BubbleViewProvider mBubble;
private int mBubbleBitmapSize;
+ private int mBubbleSize;
private DotRenderer mDotRenderer;
private DotRenderer.DrawParams mDrawParams;
private boolean mOnLeft;
@@ -93,6 +102,7 @@
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mBubbleBitmapSize = getResources().getDimensionPixelSize(R.dimen.bubble_bitmap_size);
+ mBubbleSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
mDrawParams = new DotRenderer.DrawParams();
Path iconPath = PathParser.createPathFromPathData(
@@ -108,7 +118,7 @@
*/
public void setRenderedBubble(BubbleViewProvider bubble) {
mBubble = bubble;
- setImageBitmap(bubble.getBadgedImage());
+ showBadge();
mDotColor = bubble.getDotColor();
drawDot(bubble.getDotPath());
}
@@ -161,14 +171,6 @@
}
/**
- * Set whether the dot should appear on left or right side of the view.
- */
- void setDotOnLeft(boolean onLeft) {
- mOnLeft = onLeft;
- invalidate();
- }
-
- /**
* @param iconPath The new icon path to use when calculating dot position.
*/
void drawDot(Path iconPath) {
@@ -219,22 +221,29 @@
return mDotColor;
}
- /** Sets the position of the 'new' dot, animating it out and back in if requested. */
- void setDotPositionOnLeft(boolean onLeft, boolean animate) {
- if (animate && onLeft != getDotOnLeft() && shouldDrawDot()) {
+ /** Sets the position of the dot and badge, animating them out and back in if requested. */
+ void animateDotBadgePositions(boolean onLeft) {
+ mOnLeft = onLeft;
+
+ if (onLeft != getDotOnLeft() && shouldDrawDot()) {
animateDotScale(0f /* showDot */, () -> {
- setDotOnLeft(onLeft);
+ invalidate();
animateDotScale(1.0f, null /* after */);
});
- } else {
- setDotOnLeft(onLeft);
}
+ // TODO animate badge
+ showBadge();
+
}
- boolean getDotPositionOnLeft() {
- return getDotOnLeft();
+ /** Sets the position of the dot and badge. */
+ void setDotBadgeOnLeft(boolean onLeft) {
+ mOnLeft = onLeft;
+ invalidate();
+ showBadge();
}
+
/** Whether to draw the dot in onDraw(). */
private boolean shouldDrawDot() {
// Always render the dot if it's animating, since it could be animating out. Otherwise, show
@@ -276,4 +285,33 @@
}
}).start();
}
+
+ void showBadge() {
+ Drawable badge = mBubble.getAppBadge();
+ if (badge == null) {
+ setImageBitmap(mBubble.getBubbleIcon());
+ return;
+ }
+ Canvas bubbleCanvas = new Canvas();
+ Bitmap noBadgeBubble = mBubble.getBubbleIcon();
+ Bitmap bubble = noBadgeBubble.copy(noBadgeBubble.getConfig(), /* isMutable */ true);
+
+ bubbleCanvas.setDrawFilter(new PaintFlagsDrawFilter(DITHER_FLAG, FILTER_BITMAP_FLAG));
+ bubbleCanvas.setBitmap(bubble);
+
+ final int badgeSize = (int) (ICON_BADGE_SCALE * mBubbleSize);
+ if (mOnLeft) {
+ badge.setBounds(0, mBubbleSize - badgeSize, badgeSize, mBubbleSize);
+ } else {
+ badge.setBounds(mBubbleSize - badgeSize, mBubbleSize - badgeSize,
+ mBubbleSize, mBubbleSize);
+ }
+ badge.draw(bubbleCanvas);
+ bubbleCanvas.setBitmap(null);
+ setImageBitmap(bubble);
+ }
+
+ void hideBadge() {
+ setImageBitmap(mBubble.getBubbleIcon());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 27863ba..e6c1bc3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -41,7 +41,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
-import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import java.io.FileDescriptor;
@@ -92,8 +91,9 @@
}
private FlyoutMessage mFlyoutMessage;
- private Drawable mBadgedAppIcon;
- private Bitmap mBadgedImage;
+ private Drawable mBadgeDrawable;
+ // Bitmap with no badge, no dot
+ private Bitmap mBubbleBitmap;
private int mDotColor;
private Path mDotPath;
private int mFlags;
@@ -199,12 +199,13 @@
}
@Override
- public Bitmap getBadgedImage() {
- return mBadgedImage;
+ public Bitmap getBubbleIcon() {
+ return mBubbleBitmap;
}
- public Drawable getBadgedAppIcon() {
- return mBadgedAppIcon;
+ @Override
+ public Drawable getAppBadge() {
+ return mBadgeDrawable;
}
@Override
@@ -340,8 +341,9 @@
mAppName = info.appName;
mFlyoutMessage = info.flyoutMessage;
- mBadgedAppIcon = info.badgedAppIcon;
- mBadgedImage = info.badgedBubbleImage;
+ mBadgeDrawable = info.badgeDrawable;
+ mBubbleBitmap = info.bubbleBitmap;
+
mDotColor = info.dotColor;
mDotPath = info.dotPath;
@@ -694,6 +696,7 @@
pw.print(" showInShade: "); pw.println(showInShade());
pw.print(" showDot: "); pw.println(showDot());
pw.print(" showFlyout: "); pw.println(showFlyout());
+ pw.print(" lastActivity: "); pw.println(getLastActivity());
pw.print(" desiredHeight: "); pw.println(getDesiredHeightString());
pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification());
pw.print(" autoExpand: "); pw.println(shouldAutoExpand());
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index c81b7ce..4b4e275 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -196,7 +196,7 @@
private INotificationManager mINotificationManager;
// Callback that updates BubbleOverflowActivity on data change.
- @Nullable private Runnable mOverflowCallback = null;
+ @Nullable private BubbleData.Listener mOverflowListener = null;
// Only load overflow data from disk once
private boolean mOverflowDataLoaded = false;
@@ -722,8 +722,8 @@
mInflateSynchronously = inflateSynchronously;
}
- void setOverflowCallback(Runnable updateOverflow) {
- mOverflowCallback = updateOverflow;
+ void setOverflowListener(BubbleData.Listener listener) {
+ mOverflowListener = listener;
}
/**
@@ -1327,9 +1327,10 @@
// Lazy load overflow bubbles from disk
loadOverflowBubblesFromDisk();
+
// Update bubbles in overflow.
- if (mOverflowCallback != null) {
- mOverflowCallback.run();
+ if (mOverflowListener != null) {
+ mOverflowListener.applyUpdate(update);
}
// Collapsing? Do this first before remaining steps.
@@ -1438,21 +1439,6 @@
cb.invalidateNotifications("BubbleData.Listener.applyUpdate");
}
updateStack();
-
- if (DEBUG_BUBBLE_CONTROLLER) {
- Log.d(TAG, "\n[BubbleData] bubbles:");
- Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getBubbles(),
- mBubbleData.getSelectedBubble()));
-
- if (mStackView != null) {
- Log.d(TAG, "\n[BubbleStackView]");
- Log.d(TAG, BubbleDebugConfig.formatBubblesString(mStackView.getBubblesOnScreen(),
- mStackView.getExpandedBubble()));
- }
- Log.d(TAG, "\n[BubbleData] overflow:");
- Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getOverflowBubbles(),
- null) + "\n");
- }
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 5c6d16d..a747db6 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -75,6 +75,8 @@
@Nullable Bubble selectedBubble;
@Nullable Bubble addedBubble;
@Nullable Bubble updatedBubble;
+ @Nullable Bubble addedOverflowBubble;
+ @Nullable Bubble removedOverflowBubble;
// Pair with Bubble and @DismissReason Integer
final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>();
@@ -93,10 +95,12 @@
|| addedBubble != null
|| updatedBubble != null
|| !removedBubbles.isEmpty()
+ || addedOverflowBubble != null
+ || removedOverflowBubble != null
|| orderChanged;
}
- void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) {
+ void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) {
removedBubbles.add(new Pair<>(bubbleToRemove, reason));
}
}
@@ -486,8 +490,9 @@
b.stopInflation();
}
mLogger.logOverflowRemove(b, reason);
- mStateChange.bubbleRemoved(b, reason);
mOverflowBubbles.remove(b);
+ mStateChange.bubbleRemoved(b, reason);
+ mStateChange.removedOverflowBubble = b;
}
return;
}
@@ -532,6 +537,7 @@
}
mLogger.logOverflowAdd(bubble, reason);
mOverflowBubbles.add(0, bubble);
+ mStateChange.addedOverflowBubble = bubble;
bubble.stopInflation();
if (mOverflowBubbles.size() == mMaxOverflowBubbles + 1) {
// Remove oldest bubble.
@@ -542,6 +548,7 @@
mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED);
mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
mOverflowBubbles.remove(oldest);
+ mStateChange.removedOverflowBubble = oldest;
}
}
@@ -821,11 +828,19 @@
: "null");
pw.print("expanded: ");
pw.println(mExpanded);
- pw.print("count: ");
+
+ pw.print("stack bubble count: ");
pw.println(mBubbles.size());
for (Bubble bubble : mBubbles) {
bubble.dump(fd, pw, args);
}
+
+ pw.print("overflow bubble count: ");
+ pw.println(mOverflowBubbles.size());
+ for (Bubble bubble : mOverflowBubbles) {
+ bubble.dump(fd, pw, args);
+ }
+
pw.print("summaryKeys: ");
pw.println(mSuppressedGroupKeys.size());
for (String key : mSuppressedGroupKeys.keySet()) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 80150c9..3331096 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -164,7 +164,7 @@
ActivityOptions options = ActivityOptions.makeCustomAnimation(getContext(),
0 /* enterResId */, 0 /* exitResId */);
options.setTaskAlwaysOnTop(true);
- options.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ // Soptions.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
// Post to keep the lifecycle normal
post(() -> {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
index d017bc0..371e849 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
@@ -156,17 +156,4 @@
canvas.setBitmap(null);
return bitmap;
}
-
- /**
- * Returns a {@link BitmapInfo} for the entire bubble icon including the badge.
- */
- BitmapInfo getBubbleBitmap(Drawable bubble, BitmapInfo badge) {
- BitmapInfo bubbleIconInfo = createBadgedIconBitmap(bubble,
- null /* user */,
- true /* shrinkNonAdaptiveIcons */);
-
- badgeWithDrawable(bubbleIconInfo.icon,
- new BitmapDrawable(mContext.getResources(), badge.icon));
- return bubbleIconInfo;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt
index 155b71b..6d3c2a6 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt
@@ -23,6 +23,7 @@
import android.graphics.Path
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.Drawable
import android.graphics.drawable.InsetDrawable
import android.util.PathParser
import android.util.TypedValue
@@ -36,8 +37,9 @@
private val stack: BubbleStackView
) : BubbleViewProvider {
- private var bitmap: Bitmap? = null
- private var dotPath: Path? = null
+ private lateinit var bitmap : Bitmap
+ private lateinit var dotPath : Path
+
private var bitmapSize = 0
private var iconBitmapSize = 0
private var dotColor = 0
@@ -80,40 +82,41 @@
expandedView.updateDimensions()
}
- fun updateBtnTheme() {
+ private fun updateBtnTheme() {
val res = context.resources
// Set overflow button accent color, dot color
val typedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.colorAccent, typedValue, true)
-
val colorAccent = res.getColor(typedValue.resourceId)
- overflowBtn.getDrawable()?.setTint(colorAccent)
+ overflowBtn.drawable?.setTint(colorAccent)
dotColor = colorAccent
- // Set button and activity background color
- val nightMode = (res.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
- == Configuration.UI_MODE_NIGHT_YES)
- val bg = ColorDrawable(res.getColor(
- if (nightMode) R.color.bubbles_dark else R.color.bubbles_light))
-
- // Set button icon
val iconFactory = BubbleIconFactory(context)
- val fg = InsetDrawable(overflowBtn.getDrawable(),
- bitmapSize - iconBitmapSize /* inset */)
- bitmap = iconFactory.createBadgedIconBitmap(AdaptiveIconDrawable(bg, fg),
- null /* user */, true /* shrinkNonAdaptiveIcons */).icon
- // Set dot path
+ // Update bitmap
+ val nightMode = (res.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+ == Configuration.UI_MODE_NIGHT_YES)
+ val bg = ColorDrawable(res.getColor(
+ if (nightMode) R.color.bubbles_dark else R.color.bubbles_light))
+
+ val fg = InsetDrawable(overflowBtn.drawable,
+ bitmapSize - iconBitmapSize /* inset */)
+ bitmap = iconFactory.createBadgedIconBitmap(AdaptiveIconDrawable(bg, fg),
+ null /* user */, true /* shrinkNonAdaptiveIcons */).icon
+
+ // Update dot path
dotPath = PathParser.createPathFromPathData(
- res.getString(com.android.internal.R.string.config_icon_mask))
+ res.getString(com.android.internal.R.string.config_icon_mask))
val scale = iconFactory.normalizer.getScale(overflowBtn.getDrawable(),
- null /* outBounds */, null /* path */, null /* outMaskShape */)
+ null /* outBounds */, null /* path */, null /* outMaskShape */)
val radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f
val matrix = Matrix()
matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
- radius /* pivot y */)
- dotPath?.transform(matrix)
+ radius /* pivot y */)
+ dotPath.transform(matrix)
+
+ // Attach BubbleOverflow to BadgedImageView
overflowBtn.setRenderedBubble(this)
}
@@ -129,7 +132,11 @@
return dotColor
}
- override fun getBadgedImage(): Bitmap? {
+ override fun getAppBadge(): Drawable? {
+ return null
+ }
+
+ override fun getBubbleIcon(): Bitmap {
return bitmap
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
index 9926f2e..160addc 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
@@ -108,14 +108,10 @@
mEmptyStateSubtitle = findViewById(R.id.bubble_overflow_empty_subtitle);
mEmptyStateImage = findViewById(R.id.bubble_overflow_empty_state_image);
- updateDimensions();
- onDataChanged(mBubbleController.getOverflowBubbles());
- mBubbleController.setOverflowCallback(() -> {
- onDataChanged(mBubbleController.getOverflowBubbles());
- });
+ updateOverflow();
}
- void updateDimensions() {
+ void updateOverflow() {
Resources res = getResources();
final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
mRecyclerView.setLayoutManager(
@@ -137,6 +133,22 @@
mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles,
mBubbleController::promoteBubbleFromOverflow, viewWidth, viewHeight);
mRecyclerView.setAdapter(mAdapter);
+
+ mOverflowBubbles.clear();
+ mOverflowBubbles.addAll(mBubbleController.getOverflowBubbles());
+ mAdapter.notifyDataSetChanged();
+ updateEmptyStateVisibility();
+
+ mBubbleController.setOverflowListener(mDataListener);
+ updateTheme();
+ }
+
+ void updateEmptyStateVisibility() {
+ if (mOverflowBubbles.isEmpty()) {
+ mEmptyState.setVisibility(View.VISIBLE);
+ } else {
+ mEmptyState.setVisibility(View.GONE);
+ }
}
/**
@@ -168,22 +180,40 @@
mEmptyStateSubtitle.setTextColor(textColor);
}
- void onDataChanged(List<Bubble> bubbles) {
- mOverflowBubbles.clear();
- mOverflowBubbles.addAll(bubbles);
- mAdapter.notifyDataSetChanged();
+ private final BubbleData.Listener mDataListener = new BubbleData.Listener() {
- if (mOverflowBubbles.isEmpty()) {
- mEmptyState.setVisibility(View.VISIBLE);
- } else {
- mEmptyState.setVisibility(View.GONE);
- }
+ @Override
+ public void applyUpdate(BubbleData.Update update) {
- if (DEBUG_OVERFLOW) {
- Log.d(TAG, "Updated overflow bubbles:\n" + BubbleDebugConfig.formatBubblesString(
- mOverflowBubbles, /*selected*/ null));
+ Bubble toRemove = update.removedOverflowBubble;
+ if (toRemove != null) {
+ if (DEBUG_OVERFLOW) {
+ Log.d(TAG, "remove: " + toRemove);
+ }
+ toRemove.cleanupViews();
+ final int i = mOverflowBubbles.indexOf(toRemove);
+ mOverflowBubbles.remove(toRemove);
+ mAdapter.notifyItemRemoved(i);
+ }
+
+ Bubble toAdd = update.addedOverflowBubble;
+ if (toAdd != null) {
+ if (DEBUG_OVERFLOW) {
+ Log.d(TAG, "add: " + toAdd);
+ }
+ mOverflowBubbles.add(0, toAdd);
+ mAdapter.notifyItemInserted(0);
+ }
+
+ updateEmptyStateVisibility();
+
+ if (DEBUG_OVERFLOW) {
+ Log.d(TAG, BubbleDebugConfig.formatBubblesString(
+ mBubbleController.getOverflowBubbles(),
+ null));
+ }
}
- }
+ };
@Override
public void onStart() {
@@ -198,8 +228,7 @@
@Override
public void onResume() {
super.onResume();
- updateDimensions();
- updateTheme();
+ updateOverflow();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 64df2b9..55f9631 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -16,13 +16,6 @@
package com.android.systemui.bubbles;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
-import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
-import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -99,6 +92,12 @@
import java.util.List;
import java.util.function.Consumer;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+
/**
* Renders bubbles in a stack and handles animating expanded and collapsed states.
*/
@@ -276,6 +275,10 @@
/** Description of current animation controller state. */
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Stack view state:");
+
+ String bubblesOnScreen = BubbleDebugConfig.formatBubblesString(
+ getBubblesOnScreen(), getExpandedBubble());
+ pw.print(" bubbles on screen: "); pw.println(bubblesOnScreen);
pw.print(" gestureInProgress: "); pw.println(mIsGestureInProgress);
pw.print(" showingDismiss: "); pw.println(mDismissView.isShowing());
pw.print(" isExpansionAnimating: "); pw.println(mIsExpansionAnimating);
@@ -654,13 +657,10 @@
mStackOnLeftOrWillBe =
mStackAnimationController.flingStackThenSpringToEdge(
viewInitialX + dx, velX, velY) <= 0;
-
- updateBubbleZOrdersAndDotPosition(true /* animate */);
-
+ updateBubbleIcons();
logBubbleEvent(null /* no bubble associated with bubble stack move */,
SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED);
}
-
mDismissView.hide();
}
@@ -1464,8 +1464,7 @@
// Set the dot position to the opposite of the side the stack is resting on, since the stack
// resting slightly off-screen would result in the dot also being off-screen.
- bubble.getIconView().setDotPositionOnLeft(
- !mStackOnLeftOrWillBe /* onLeft */, false /* animate */);
+ bubble.getIconView().setDotBadgeOnLeft(!mStackOnLeftOrWillBe /* onLeft */);
bubble.getIconView().setOnClickListener(mBubbleClickListener);
bubble.getIconView().setOnTouchListener(mBubbleTouchListener);
@@ -1516,7 +1515,7 @@
Bubble bubble = bubbles.get(i);
mBubbleContainer.reorderView(bubble.getIconView(), i);
}
- updateBubbleZOrdersAndDotPosition(false /* animate */);
+ updateBubbleIcons();
updatePointerPosition();
}
@@ -2359,7 +2358,7 @@
// name and icon.
if (show && mBubbleData.hasBubbleInStackWithKey(mExpandedBubble.getKey())) {
final Bubble bubble = mBubbleData.getBubbleInStackWithKey(mExpandedBubble.getKey());
- mManageSettingsIcon.setImageDrawable(bubble.getBadgedAppIcon());
+ mManageSettingsIcon.setImageDrawable(bubble.getAppBadge());
mManageSettingsText.setText(getResources().getString(
R.string.bubbles_app_settings, bubble.getAppName()));
}
@@ -2547,28 +2546,31 @@
}
mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
- updateBubbleZOrdersAndDotPosition(false);
+ updateBubbleIcons();
}
- /** Sets the appropriate Z-order and dot position for each bubble in the stack. */
- private void updateBubbleZOrdersAndDotPosition(boolean animate) {
+ /**
+ * Sets the appropriate Z-order, badge, and dot position for each bubble in the stack.
+ * Animate dot and badge changes.
+ */
+ private void updateBubbleIcons() {
int bubbleCount = getBubbleCount();
for (int i = 0; i < bubbleCount; i++) {
BadgedImageView bv = (BadgedImageView) mBubbleContainer.getChildAt(i);
bv.setZ((mMaxBubbles * mBubbleElevation) - i);
- // If the dot is on the left, and so is the stack, we need to change the dot position.
- if (bv.getDotPositionOnLeft() == mStackOnLeftOrWillBe) {
- bv.setDotPositionOnLeft(!mStackOnLeftOrWillBe, animate);
- }
-
- if (!mIsExpanded && i > 0) {
- // If we're collapsed and this bubble is behind other bubbles, suppress its dot.
- bv.addDotSuppressionFlag(
- BadgedImageView.SuppressionFlag.BEHIND_STACK);
- } else {
+ if (mIsExpanded) {
bv.removeDotSuppressionFlag(
BadgedImageView.SuppressionFlag.BEHIND_STACK);
+ bv.animateDotBadgePositions(false /* onLeft */);
+ } else if (i == 0) {
+ bv.removeDotSuppressionFlag(
+ BadgedImageView.SuppressionFlag.BEHIND_STACK);
+ bv.animateDotBadgePositions(!mStackOnLeftOrWillBe);
+ } else {
+ bv.addDotSuppressionFlag(
+ BadgedImageView.SuppressionFlag.BEHIND_STACK);
+ bv.hideBadge();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
index 5749169..28757fa 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
@@ -120,8 +120,8 @@
BubbleExpandedView expandedView;
ShortcutInfo shortcutInfo;
String appName;
- Bitmap badgedBubbleImage;
- Drawable badgedAppIcon;
+ Bitmap bubbleBitmap;
+ Drawable badgeDrawable;
int dotColor;
Path dotPath;
Bubble.FlyoutMessage flyoutMessage;
@@ -179,9 +179,10 @@
BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon,
b.isImportantConversation());
- info.badgedAppIcon = badgedIcon;
- info.badgedBubbleImage = iconFactory.getBubbleBitmap(bubbleDrawable,
- badgeBitmapInfo).icon;
+ info.badgeDrawable = badgedIcon;
+ info.bubbleBitmap = iconFactory.createBadgedIconBitmap(bubbleDrawable,
+ null /* user */,
+ true /* shrinkNonAdaptiveIcons */).icon;
// Dot color & placement
Path iconPath = PathParser.createPathFromPathData(
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
index f1a01be..916ad18 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
@@ -18,6 +18,7 @@
import android.graphics.Bitmap;
import android.graphics.Path;
+import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.annotation.Nullable;
@@ -34,12 +35,17 @@
String getKey();
- Bitmap getBadgedImage();
+ /** Bubble icon bitmap with no badge and no dot. */
+ Bitmap getBubbleIcon();
+
+ /** App badge drawable to draw above bubble icon. */
+ @Nullable Drawable getAppBadge();
+
+ /** Path of normalized bubble icon to draw dot on. */
+ Path getDotPath();
int getDotColor();
- Path getDotPath();
-
boolean showDot();
int getDisplayId();
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index 31830b9..40662536 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -263,6 +263,7 @@
val context = itemView.context
val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme())
+ icon.imageTintList = null
ci.customIcon?.let {
icon.setImageIcon(it)
} ?: run {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 3710310..2b529f9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -104,6 +104,7 @@
private var hidden = true
private lateinit var dismissGlobalActions: Runnable
private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow)
+ private var retainCache = false
private val collator = Collator.getInstance(context.resources.configuration.locales[0])
private val localeComparator = compareBy<SelectionItem, CharSequence>(collator) {
@@ -149,6 +150,7 @@
this.parent = parent
this.dismissGlobalActions = dismissGlobalActions
hidden = false
+ retainCache = false
allStructures = controlsController.get().getFavorites()
selectedStructure = loadPreference(allStructures)
@@ -235,6 +237,8 @@
}
putIntentExtras(i, si)
startActivity(context, i)
+
+ retainCache = true
}
private fun putIntentExtras(intent: Intent, si: StructureInfo) {
@@ -497,7 +501,7 @@
controlsListingController.get().removeCallback(listingCallback)
- RenderInfo.clearCache()
+ if (!retainCache) RenderInfo.clearCache()
}
override fun onRefreshState(componentName: ComponentName, controls: List<Control>) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 0dd9488..38e12a6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -61,11 +61,11 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -78,6 +78,7 @@
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.util.leak.LeakDetector;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -269,10 +270,11 @@
@Background Looper backgroundLooper,
@Background Executor backgroundExecutor,
DumpManager dumpManager,
- BroadcastDispatcherLogger logger
+ BroadcastDispatcherLogger logger,
+ UserTracker userTracker
) {
BroadcastDispatcher bD = new BroadcastDispatcher(context, backgroundLooper,
- backgroundExecutor, dumpManager, logger);
+ backgroundExecutor, dumpManager, logger, userTracker);
bD.initialize();
return bD;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index c331bd3..3a5ce4d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -28,7 +28,6 @@
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
-import com.android.systemui.onehanded.OneHandedUI;
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
@@ -90,12 +89,6 @@
@ClassKey(LatencyTester.class)
public abstract SystemUI bindLatencyTester(LatencyTester sysui);
- /** Inject into OneHandedUI. */
- @Binds
- @IntoMap
- @ClassKey(OneHandedUI.class)
- public abstract SystemUI bindOneHandedUI(OneHandedUI sysui);
-
/** Inject into PowerUI. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 3e64749..9c90510 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -19,6 +19,7 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
@@ -548,7 +549,7 @@
if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
return false;
}
- return true;
+ return action.shouldShow();
}
/**
@@ -961,6 +962,8 @@
@VisibleForTesting
class ScreenshotAction extends SinglePressAction implements LongPressAction {
+ final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
+
public ScreenshotAction() {
super(R.drawable.ic_screenshot, R.string.global_action_screenshot);
}
@@ -993,6 +996,19 @@
}
@Override
+ public boolean shouldShow() {
+ // Include screenshot in power menu for legacy nav because it is not accessible
+ // through Recents in that mode
+ return is2ButtonNavigationEnabled();
+ }
+
+ boolean is2ButtonNavigationEnabled() {
+ return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_navBarInteractionMode);
+ }
+
+
+ @Override
public boolean onLongPress() {
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) {
mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
@@ -1615,6 +1631,10 @@
* @return
*/
CharSequence getMessage();
+
+ default boolean shouldShow() {
+ return true;
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt
index 9dcc3bb..a7d17e1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt
@@ -177,7 +177,7 @@
userDefinedBrightness = systemSettings.getFloat(SCREEN_BRIGHTNESS_FLOAT)
}
})
- userDefinedBrightness = systemSettings.getFloat(SCREEN_BRIGHTNESS_FLOAT)
+ userDefinedBrightness = systemSettings.getFloat(SCREEN_BRIGHTNESS_FLOAT, 1f)
}
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index e5a9ac1..f150381 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -42,7 +42,7 @@
private val mediaHostStatesManager: MediaHostStatesManager,
private val activityStarter: ActivityStarter,
@Main executor: DelayableExecutor,
- mediaManager: MediaDataManager,
+ private val mediaManager: MediaDataManager,
configurationController: ConfigurationController,
falsingManager: FalsingManager
) {
@@ -109,6 +109,7 @@
private val pageIndicator: PageIndicator
private val visualStabilityCallback: VisualStabilityManager.Callback
private var needsReordering: Boolean = false
+ private var keysNeedRemoval = mutableSetOf<String>()
private var isRtl: Boolean = false
set(value) {
if (value != field) {
@@ -161,6 +162,10 @@
needsReordering = false
reorderAllPlayers()
}
+
+ keysNeedRemoval.forEach { removePlayer(it) }
+ keysNeedRemoval.clear()
+
// Let's reset our scroll position
mediaCarouselScrollHandler.scrollToStart()
}
@@ -168,13 +173,19 @@
true /* persistent */)
mediaManager.addListener(object : MediaDataManager.Listener {
override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
- if (!data.active && !Utils.useMediaResumption(context)) {
- // This view is inactive, let's remove this! This happens e.g when dismissing /
- // timing out a view. We still have the data around because resumption could
- // be on, but we should save the resources and release this.
- onMediaDataRemoved(key)
+ addOrUpdatePlayer(key, oldKey, data)
+ val canRemove = data.isPlaying?.let { !it } ?: data.isClearable
+ if (canRemove && !Utils.useMediaResumption(context)) {
+ // This view isn't playing, let's remove this! This happens e.g when
+ // dismissing/timing out a view. We still have the data around because
+ // resumption could be on, but we should save the resources and release this.
+ if (visualStabilityManager.isReorderingAllowed) {
+ onMediaDataRemoved(key)
+ } else {
+ keysNeedRemoval.add(key)
+ }
} else {
- addOrUpdatePlayer(key, oldKey, data)
+ keysNeedRemoval.remove(key)
}
}
@@ -236,12 +247,12 @@
var newPlayer = mediaControlPanelFactory.get()
newPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
- MediaPlayerData.addMediaPlayer(key, data, newPlayer)
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
newPlayer.view?.player?.setLayoutParams(lp)
newPlayer.bind(data)
newPlayer.setListening(currentlyExpanded)
+ MediaPlayerData.addMediaPlayer(key, data, newPlayer)
updatePlayerToState(newPlayer, noAnimation = true)
reorderAllPlayers()
} else {
@@ -271,6 +282,9 @@
removed.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
updatePageIndicator()
+
+ // Inform the media manager of a potentially late dismissal
+ mediaManager.dismissMediaData(key, 0L)
}
}
@@ -478,12 +492,11 @@
internal object MediaPlayerData {
private data class MediaSortKey(
val data: MediaData,
- val updateTime: Long = 0,
- val isPlaying: Boolean = false
+ val updateTime: Long = 0
)
private val comparator =
- compareByDescending<MediaSortKey> { it.isPlaying }
+ compareByDescending<MediaSortKey> { it.data.isPlaying }
.thenByDescending { it.data.isLocalSession }
.thenByDescending { !it.data.resumption }
.thenByDescending { it.updateTime }
@@ -493,7 +506,7 @@
fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) {
removeMediaPlayer(key)
- val sortKey = MediaSortKey(data, System.currentTimeMillis(), player.isPlaying())
+ val sortKey = MediaSortKey(data, System.currentTimeMillis())
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index d6a0268..40a879a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -94,7 +94,17 @@
* Notification key for cancelling a media player after a timeout (when not using resumption.)
*/
val notificationKey: String? = null,
- var hasCheckedForResume: Boolean = false
+ var hasCheckedForResume: Boolean = false,
+
+ /**
+ * If apps do not report PlaybackState, set as null to imply 'undetermined'
+ */
+ val isPlaying: Boolean? = null,
+
+ /**
+ * Set from the notification and used as fallback when PlaybackState cannot be determined
+ */
+ val isClearable: Boolean = true
)
/** State of a media action. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index 0664a41..1f580a9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -136,14 +136,8 @@
/**
* Are there any media entries we should display?
- * If resumption is enabled, this will include inactive players
- * If resumption is disabled, we only want to show active players
*/
- fun hasAnyMedia() = if (mediaResumeListener.isResumptionEnabled()) {
- userEntries.isNotEmpty()
- } else {
- hasActiveMedia()
- }
+ fun hasAnyMedia() = userEntries.isNotEmpty()
/**
* Add a listener for filtered [MediaData] changes
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index b2ad19b..cb6b22c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -47,6 +47,7 @@
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState
import com.android.systemui.statusbar.notification.MediaNotificationProcessor
import com.android.systemui.statusbar.notification.row.HybridGroupManager
import com.android.systemui.util.Assert
@@ -350,6 +351,16 @@
}
fun dismissMediaData(key: String, delay: Long) {
+ backgroundExecutor.execute {
+ mediaEntries[key]?.let { mediaData ->
+ if (mediaData.isLocalSession) {
+ mediaData.token?.let {
+ val mediaController = mediaControllerFactory.create(it)
+ mediaController.transportControls.stop()
+ }
+ }
+ }
+ }
foregroundExecutor.executeDelayed({ removeEntry(key) }, delay)
}
@@ -500,6 +511,7 @@
val isLocalSession = mediaController.playbackInfo?.playbackType ==
MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL ?: true
+ val isPlaying = mediaController.playbackState?.let { isPlayingState(it.state) } ?: null
foregroundExecutor.execute {
val resumeAction: Runnable? = mediaEntries[key]?.resumeAction
@@ -509,7 +521,8 @@
smallIconDrawable, artist, song, artWorkIcon, actionIcons,
actionsToShowCollapsed, sbn.packageName, token, notif.contentIntent, null,
active, resumeAction = resumeAction, isLocalSession = isLocalSession,
- notificationKey = key, hasCheckedForResume = hasCheckedForResume))
+ notificationKey = key, hasCheckedForResume = hasCheckedForResume,
+ isPlaying = isPlaying, isClearable = sbn.isClearable()))
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index c00b5e9..5b59214 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -125,8 +125,6 @@
}, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED)
}
- fun isResumptionEnabled() = useMediaResumption
-
private fun loadSavedComponents() {
// Make sure list is empty (if we switched users)
resumeComponents.clear()
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index c7e7817..4e0df21 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -122,7 +122,6 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -137,6 +136,7 @@
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.PrintWriter;
import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index 9b9dc6d..339e504 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -55,7 +55,6 @@
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -65,6 +64,7 @@
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 8a468f6e..13b9a55 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -87,12 +87,12 @@
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.PrintWriter;
import java.util.function.Consumer;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 92d2f42..dfc82f1 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -38,11 +38,11 @@
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
+import android.view.Choreographer;
import android.view.ISystemGestureExclusionListener;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
-import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -67,6 +67,7 @@
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -169,7 +170,7 @@
private boolean mGestureBlockingActivityRunning;
private InputMonitor mInputMonitor;
- private InputEventReceiver mInputEventReceiver;
+ private InputChannelCompat.InputEventReceiver mInputEventReceiver;
private NavigationEdgeBackPlugin mEdgeBackPlugin;
private int mLeftInset;
@@ -383,8 +384,9 @@
// Register input event receiver
mInputMonitor = InputManager.getInstance().monitorGestureInput(
"edge-swipe", mDisplayId);
- mInputEventReceiver = new SysUiInputEventReceiver(
- mInputMonitor.getInputChannel(), Looper.getMainLooper());
+ mInputEventReceiver = new InputChannelCompat.InputEventReceiver(
+ mInputMonitor.getInputChannel(), Looper.getMainLooper(),
+ Choreographer.getInstance(), this::onInputEvent);
// Add a nav bar panel window
setEdgeBackPlugin(new NavigationBarEdgePanel(mContext));
@@ -520,6 +522,7 @@
if (action == MotionEvent.ACTION_DOWN) {
// Verify if this is in within the touch region and we aren't in immersive mode, and
// either the bouncer is showing or the notification panel is hidden
+ mInputEventReceiver.setBatchingEnabled(false);
mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset;
mLogGesture = false;
mInRejectedExclusion = false;
@@ -571,6 +574,7 @@
mThresholdCrossed = true;
// Capture inputs
mInputMonitor.pilferPointers();
+ mInputEventReceiver.setBatchingEnabled(true);
} else {
logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_FAR_FROM_EDGE);
}
@@ -672,15 +676,4 @@
}
proto.edgeBackGestureHandler.allowGesture = mAllowGesture;
}
-
- class SysUiInputEventReceiver extends InputEventReceiver {
- SysUiInputEventReceiver(InputChannel channel, Looper looper) {
- super(channel, looper);
- }
-
- public void onInputEvent(InputEvent event) {
- EdgeBackGestureHandler.this.onInputEvent(event);
- finishInputEvent(event, true);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedController.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedController.java
deleted file mode 100644
index bb59449..0000000
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedController.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.onehanded;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.SystemProperties;
-import android.view.KeyEvent;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.wm.shell.common.DisplayChangeController;
-import com.android.wm.shell.common.DisplayController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import javax.inject.Inject;
-
-/**
- * Manages and manipulates the one handed states, transitions, and gesture for phones.
- */
-@SysUISingleton
-public class OneHandedController implements Dumpable {
- private static final String TAG = "OneHandedManager";
- private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
- "persist.debug.one_handed_offset_percentage";
-
- private boolean mIsOneHandedEnabled;
- private boolean mIsSwipeToNotificationEnabled;
- private boolean mTaskChangeToExit;
- private float mOffSetFraction;
-
- private final CommandQueue mCommandQueue;
- private final DisplayController mDisplayController;
- private final OneHandedGestureHandler mGestureHandler;
- private final OneHandedTimeoutHandler mTimeoutHandler;
- private final OneHandedTouchHandler mTouchHandler;
- private final OneHandedTutorialHandler mTutorialHandler;
- private final SysUiState mSysUiFlagContainer;
-
- private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
-
- /**
- * Handler for system task stack changes, exit when user lunch new task or bring task to front
- */
- private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
- @Override
- public void onTaskCreated(int taskId, ComponentName componentName) {
- if (!mIsOneHandedEnabled || !mDisplayAreaOrganizer.isInOneHanded()) {
- return;
- }
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_APP_TAPS_OUT);
- stopOneHanded();
- }
-
- @Override
- public void onTaskMovedToFront(int taskId) {
- if (!mIsOneHandedEnabled || !mDisplayAreaOrganizer.isInOneHanded()) {
- return;
- }
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_APP_TAPS_OUT);
- stopOneHanded();
- }
- };
-
- /**
- * Handle rotation based on OnDisplayChangingListener callback
- */
- private final DisplayChangeController.OnDisplayChangingListener mRotationController =
- (display, fromRotation, toRotation, wct) -> {
- if (mDisplayAreaOrganizer != null) {
- mDisplayAreaOrganizer.onRotateDisplay(fromRotation, toRotation);
- }
- };
-
- /**
- * Constructor of OneHandedManager
- */
- @Inject
- public OneHandedController(Context context,
- CommandQueue commandQueue,
- DisplayController displayController,
- NavigationModeController navigationModeController,
- SysUiState sysUiState) {
- mCommandQueue = commandQueue;
- mDisplayController = displayController;
- mDisplayController.addDisplayChangingController(mRotationController);
- mSysUiFlagContainer = sysUiState;
- mOffSetFraction = SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f;
-
- mIsOneHandedEnabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
- context.getContentResolver());
- mIsSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
- context.getContentResolver());
- mTimeoutHandler = OneHandedTimeoutHandler.get();
- mTouchHandler = new OneHandedTouchHandler();
- mTutorialHandler = new OneHandedTutorialHandler(context);
- mDisplayAreaOrganizer = new OneHandedDisplayAreaOrganizer(context, displayController,
- new OneHandedAnimationController(context), mTutorialHandler);
- mGestureHandler = new OneHandedGestureHandler(
- context, displayController, navigationModeController);
- updateOneHandedEnabled();
- setupGestures();
- }
-
- /**
- * Constructor of OneHandedManager for testing
- */
- // TODO(b/161980408): Should remove extra constructor.
- @VisibleForTesting
- OneHandedController(Context context,
- CommandQueue commandQueue,
- DisplayController displayController,
- OneHandedDisplayAreaOrganizer displayAreaOrganizer,
- OneHandedTouchHandler touchHandler,
- OneHandedTutorialHandler tutorialHandler,
- OneHandedGestureHandler gestureHandler,
- SysUiState sysUiState) {
- mCommandQueue = commandQueue;
- mDisplayAreaOrganizer = displayAreaOrganizer;
- mDisplayController = displayController;
- mDisplayController.addDisplayChangingController(mRotationController);
- mSysUiFlagContainer = sysUiState;
- mOffSetFraction = SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f;
-
- mIsOneHandedEnabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
- context.getContentResolver());
- mIsSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
- context.getContentResolver());
- mTimeoutHandler = OneHandedTimeoutHandler.get();
- mTouchHandler = touchHandler;
- mTutorialHandler = tutorialHandler;
- mGestureHandler = gestureHandler;
- updateOneHandedEnabled();
- setupGestures();
- }
-
- /**
- * Set one handed enabled or disabled by OneHanded UI when user update settings
- */
- public void setOneHandedEnabled(boolean enabled) {
- mIsOneHandedEnabled = enabled;
- updateOneHandedEnabled();
- }
-
- /**
- * Set one handed enabled or disabled by OneHanded UI when user update settings
- */
- public void setTaskChangeToExit(boolean enabled) {
- if (mTaskChangeToExit == enabled) {
- return;
- }
- mTaskChangeToExit = enabled;
- updateOneHandedEnabled();
- }
-
- /**
- * Sets whether to enable swipe bottom to notification gesture when user update settings.
- */
- public void setSwipeToNotificationEnabled(boolean enabled) {
- mIsSwipeToNotificationEnabled = enabled;
- updateOneHandedEnabled();
- }
-
- /**
- * Enters one handed mode.
- */
- public void startOneHanded() {
- if (!mDisplayAreaOrganizer.isInOneHanded()) {
- final int yOffSet = Math.round(getDisplaySize().y * mOffSetFraction);
- mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
- mTimeoutHandler.resetTimer();
- }
- }
-
- /**
- * Exits one handed mode.
- */
- public void stopOneHanded() {
- if (mDisplayAreaOrganizer.isInOneHanded()) {
- mDisplayAreaOrganizer.scheduleOffset(0, 0);
- mTimeoutHandler.removeTimer();
- }
- }
-
- private void setupGestures() {
- mTouchHandler.registerTouchEventListener(
- new OneHandedTouchHandler.OneHandedTouchEventCallback() {
- @Override
- public void onStart() {
- if (mIsOneHandedEnabled) {
- startOneHanded();
- }
- }
-
- @Override
- public void onStop() {
- if (mIsOneHandedEnabled) {
- stopOneHanded();
- }
- }
- });
-
- mGestureHandler.setGestureEventListener(
- new OneHandedGestureHandler.OneHandedGestureEventCallback() {
- @Override
- public void onStart() {
- if (mIsOneHandedEnabled) {
- startOneHanded();
- } else if (mIsSwipeToNotificationEnabled) {
- mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN);
- }
- }
-
- @Override
- public void onStop() {
- if (mIsOneHandedEnabled) {
- stopOneHanded();
- } else if (mIsSwipeToNotificationEnabled) {
- mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP);
- }
- }
- });
-
- mDisplayAreaOrganizer.registerTransitionCallback(new OneHandedTransitionCallback() {
- @Override
- public void onStartFinished(Rect bounds) {
- mSysUiFlagContainer.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE,
- true).commitUpdate(DEFAULT_DISPLAY);
- }
-
- @Override
- public void onStopFinished(Rect bounds) {
- mSysUiFlagContainer.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE,
- false).commitUpdate(DEFAULT_DISPLAY);
- }
- });
-
- mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler);
- mDisplayAreaOrganizer.registerTransitionCallback(mGestureHandler);
- mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
- }
-
- /**
- * Query the current display real size from {@link DisplayController}
- *
- * @return {@link DisplayController#getDisplay(int)#getDisplaySize()}
- */
- private Point getDisplaySize() {
- Point displaySize = new Point();
- if (mDisplayController != null && mDisplayController.getDisplay(DEFAULT_DISPLAY) != null) {
- mDisplayController.getDisplay(DEFAULT_DISPLAY).getRealSize(displaySize);
- }
- return displaySize;
- }
-
- private void updateOneHandedEnabled() {
- if (mDisplayAreaOrganizer.isInOneHanded()) {
- stopOneHanded();
- }
- // TODO Be aware to unregisterOrganizer() after animation finished
- mDisplayAreaOrganizer.unregisterOrganizer();
- if (mIsOneHandedEnabled) {
- mDisplayAreaOrganizer.registerOrganizer(
- OneHandedDisplayAreaOrganizer.FEATURE_ONE_HANDED);
- }
- ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
- if (mTaskChangeToExit) {
- ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
- }
- mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
- mGestureHandler.onOneHandedEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);
- }
-
- @Override
- public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
- final String innerPrefix = " ";
- pw.println(TAG + "states: ");
- pw.print(innerPrefix + "mSysUiFlagContainer=");
- pw.println(mSysUiFlagContainer.getFlags());
- pw.print(innerPrefix + "mOffSetFraction=");
- pw.println(mOffSetFraction);
-
- if (mDisplayAreaOrganizer != null) {
- mDisplayAreaOrganizer.dump(fd, pw, args);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java
deleted file mode 100644
index 3348a06..0000000
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.onehanded;
-
-import static android.os.UserHandle.USER_CURRENT;
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import android.content.Context;
-import android.content.om.IOverlayManager;
-import android.content.om.OverlayInfo;
-import android.database.ContentObserver;
-import android.inputmethodservice.InputMethodService;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.Dependency;
-import com.android.systemui.Dumpable;
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.statusbar.CommandQueue;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import javax.inject.Inject;
-
-/**
- * A service that controls UI of the one handed mode function.
- */
-@SysUISingleton
-public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dumpable {
- private static final String TAG = "OneHandedUI";
- private static final String ONE_HANDED_MODE_GESTURAL_OVERLAY =
- "com.android.internal.systemui.onehanded.gestural";
- private static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
-
- private final OneHandedController mOneHandedController;
- private final CommandQueue mCommandQueue;
- private final Handler mMainHandler = new Handler(Looper.getMainLooper());
- private final IOverlayManager mOverlayManager;
- private final OneHandedTimeoutHandler mTimeoutHandler;
- private final ScreenLifecycle mScreenLifecycle;
-
- private final ContentObserver mEnabledObserver = new ContentObserver(mMainHandler) {
- @Override
- public void onChange(boolean selfChange) {
- final boolean enabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
- mContext.getContentResolver());
- OneHandedEvents.writeEvent(enabled
- ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_ON
- : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_OFF);
- if (mOneHandedController != null) {
- mOneHandedController.setOneHandedEnabled(enabled);
- }
-
- // Also checks swipe to notification settings since they all need gesture overlay.
- setEnabledGesturalOverlay(
- enabled || OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
- mContext.getContentResolver()));
- }
- };
-
- private final ContentObserver mTimeoutObserver = new ContentObserver(mMainHandler) {
- @Override
- public void onChange(boolean selfChange) {
- final int newTimeout = OneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
- mContext.getContentResolver());
- int metricsId = OneHandedEvents.OneHandedSettingsTogglesEvent.INVALID.getId();
- switch (newTimeout) {
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER:
- metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_NEVER;
- break;
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS:
- metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_4;
- break;
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS:
- metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_8;
- break;
- case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS:
- metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_12;
- break;
- default:
- // do nothing
- break;
- }
- OneHandedEvents.writeEvent(metricsId);
-
- if (mTimeoutHandler != null) {
- mTimeoutHandler.setTimeout(newTimeout);
- }
- }
- };
-
- private final ContentObserver mTaskChangeExitObserver = new ContentObserver(mMainHandler) {
- @Override
- public void onChange(boolean selfChange) {
- final boolean enabled = OneHandedSettingsUtil.getSettingsTapsAppToExit(
- mContext.getContentResolver());
- OneHandedEvents.writeEvent(enabled
- ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_ON
- : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_OFF);
-
- if (mOneHandedController != null) {
- mOneHandedController.setTaskChangeToExit(enabled);
- }
- }
- };
-
- private final ContentObserver mSwipeToNotificationEnabledObserver =
- new ContentObserver(mMainHandler) {
- @Override
- public void onChange(boolean selfChange) {
- final boolean enabled =
- OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
- mContext.getContentResolver());
- if (mOneHandedController != null) {
- mOneHandedController.setSwipeToNotificationEnabled(enabled);
- }
-
- // Also checks one handed mode settings since they all need gesture overlay.
- setEnabledGesturalOverlay(
- enabled || OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
- mContext.getContentResolver()));
- }
- };
-
- @Inject
- public OneHandedUI(Context context,
- CommandQueue commandQueue,
- OneHandedController oneHandedController,
- ScreenLifecycle screenLifecycle) {
- super(context);
-
- if (!SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
- Log.i(TAG, "Device config SUPPORT_ONE_HANDED_MODE off");
- mCommandQueue = null;
- mOneHandedController = null;
- mOverlayManager = null;
- mTimeoutHandler = null;
- mScreenLifecycle = null;
- return;
- }
-
- mCommandQueue = commandQueue;
- mOneHandedController = oneHandedController;
- mTimeoutHandler = OneHandedTimeoutHandler.get();
- mScreenLifecycle = screenLifecycle;
- mOverlayManager = IOverlayManager.Stub.asInterface(
- ServiceManager.getService(Context.OVERLAY_SERVICE));
- }
-
- @Override
- public void start() {
- if (!SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
- return;
- }
- mCommandQueue.addCallback(this);
- setupKeyguardUpdateMonitor();
- setupScreenObserver();
- setupSettingObservers();
- setupTimeoutListener();
- setupGesturalOverlay();
- updateSettings();
- }
-
- private void setupGesturalOverlay() {
- if (!OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(mContext.getContentResolver())) {
- return;
- }
-
- OverlayInfo info = null;
- try {
- // TODO(b/157958539) migrate new RRO config file after S+
- mOverlayManager.setHighestPriority(ONE_HANDED_MODE_GESTURAL_OVERLAY, USER_CURRENT);
- info = mOverlayManager.getOverlayInfo(ONE_HANDED_MODE_GESTURAL_OVERLAY, USER_CURRENT);
- } catch (RemoteException e) { /* Do nothing */ }
-
- if (info != null && !info.isEnabled()) {
- // Enable the default gestural one handed overlay.
- setEnabledGesturalOverlay(true);
- }
- }
-
- private void setupTimeoutListener() {
- mTimeoutHandler.registerTimeoutListener(timeoutTime -> {
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_TIMEOUT_OUT);
- stopOneHanded();
- });
- }
-
- private void setupKeyguardUpdateMonitor() {
- final KeyguardUpdateMonitorCallback keyguardCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onKeyguardBouncerChanged(boolean bouncer) {
- if (bouncer) {
- stopOneHanded();
- }
- }
-
- @Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- stopOneHanded();
- }
- };
- Dependency.get(KeyguardUpdateMonitor.class).registerCallback(keyguardCallback);
- }
-
- @Override
- public void onCameraLaunchGestureDetected(int source) {
- stopOneHanded();
- }
-
- private void setupScreenObserver() {
- final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
- @Override
- public void onScreenTurningOff() {
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_SCREEN_OFF_OUT);
- stopOneHanded();
- }
- };
- mScreenLifecycle.addObserver(mScreenObserver);
- }
-
- private void setupSettingObservers() {
- OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_ENABLED,
- mContext.getContentResolver(), mEnabledObserver);
- OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
- mContext.getContentResolver(), mTimeoutObserver);
- OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.TAPS_APP_TO_EXIT,
- mContext.getContentResolver(), mTaskChangeExitObserver);
- OneHandedSettingsUtil.registerSettingsKeyObserver(
- Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
- mContext.getContentResolver(), mSwipeToNotificationEnabledObserver);
- }
-
- private void updateSettings() {
- mOneHandedController.setOneHandedEnabled(OneHandedSettingsUtil
- .getSettingsOneHandedModeEnabled(mContext.getContentResolver()));
- mTimeoutHandler.setTimeout(OneHandedSettingsUtil
- .getSettingsOneHandedModeTimeout(mContext.getContentResolver()));
- mOneHandedController.setTaskChangeToExit(OneHandedSettingsUtil
- .getSettingsTapsAppToExit(mContext.getContentResolver()));
- mOneHandedController.setSwipeToNotificationEnabled(OneHandedSettingsUtil
- .getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
- }
-
- @Override
- public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
- boolean showImeSwitcher) {
- if (displayId != DEFAULT_DISPLAY) {
- return;
- }
- if ((vis & InputMethodService.IME_VISIBLE) != 0) {
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_POP_IME_OUT);
- stopOneHanded();
- }
- }
-
- @VisibleForTesting
- private void setEnabledGesturalOverlay(boolean enabled) {
- try {
- mOverlayManager.setEnabled(ONE_HANDED_MODE_GESTURAL_OVERLAY, enabled, USER_CURRENT);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Trigger one handed more
- */
- public void startOneHanded() {
- mOneHandedController.startOneHanded();
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_IN);
- }
-
- /**
- * Dismiss one handed more
- */
- public void stopOneHanded() {
- mOneHandedController.stopOneHanded();
- OneHandedEvents.writeEvent(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
- }
-
- /**
- * Dump all one handed data of states
- */
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- final String innerPrefix = " ";
- pw.println(TAG + "one handed states: ");
-
- if (mOneHandedController != null) {
- mOneHandedController.dump(fd, pw, args);
- }
-
- if (mTimeoutHandler != null) {
- mTimeoutHandler.dump(fd, pw, args);
- }
-
- OneHandedSettingsUtil.dump(pw, innerPrefix, mContext.getContentResolver());
-
- if (mOverlayManager != null) {
- OverlayInfo info = null;
- try {
- info = mOverlayManager.getOverlayInfo(ONE_HANDED_MODE_GESTURAL_OVERLAY,
- USER_CURRENT);
- } catch (RemoteException e) { /* Do nothing */ }
-
- if (info != null && !info.isEnabled()) {
- pw.print(innerPrefix + "OverlayInfo=");
- pw.println(info);
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index b464e8ad..89b5c38 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -22,8 +22,8 @@
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
-import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
@@ -328,14 +328,14 @@
return false;
}
- // Bail early if the pinned stack is staled.
- final ActivityManager.StackInfo pinnedStackInfo;
+ // Bail early if the pinned task is staled.
+ final RootTaskInfo pinnedTaskInfo;
try {
- pinnedStackInfo = ActivityTaskManager.getService()
- .getStackInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
- if (pinnedStackInfo == null) return false;
+ pinnedTaskInfo = ActivityTaskManager.getService()
+ .getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+ if (pinnedTaskInfo == null) return false;
} catch (RemoteException e) {
- Log.e(TAG, "Failed to get StackInfo for pinned stack", e);
+ Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e);
return false;
}
@@ -362,7 +362,7 @@
getInsetBounds(outInsetBounds);
outBounds.set(postChangeStackBounds);
- t.setBounds(pinnedStackInfo.stackToken, outBounds);
+ t.setBounds(pinnedTaskInfo.token, outBounds);
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 6f44090..a5ee3a0 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -57,16 +57,15 @@
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransactionCallback;
-import android.window.WindowOrganizer;
import com.android.internal.os.SomeArgs;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.pip.phone.PipMenuActivityController;
import com.android.systemui.pip.phone.PipUpdateThread;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -100,6 +99,36 @@
private static final int MSG_FINISH_RESIZE = 4;
private static final int MSG_RESIZE_USER = 5;
+ // Not a complete set of states but serves what we want right now.
+ private enum State {
+ UNDEFINED(0),
+ TASK_APPEARED(1),
+ ENTERING_PIP(2),
+ EXITING_PIP(3);
+
+ private final int mStateValue;
+
+ State(int value) {
+ mStateValue = value;
+ }
+
+ private boolean isInPip() {
+ return mStateValue >= TASK_APPEARED.mStateValue
+ && mStateValue != EXITING_PIP.mStateValue;
+ }
+
+ /**
+ * Resize request can be initiated in other component, ignore if we are no longer in PIP,
+ * still waiting for animation or we're exiting from it.
+ *
+ * @return {@code true} if the resize request should be blocked/ignored.
+ */
+ private boolean shouldBlockResizeRequest() {
+ return mStateValue < ENTERING_PIP.mStateValue
+ || mStateValue == EXITING_PIP.mStateValue;
+ }
+ }
+
private final Context mContext;
private final Handler mMainHandler;
private final Handler mUpdateHandler;
@@ -201,8 +230,7 @@
private ActivityManager.RunningTaskInfo mTaskInfo;
private WindowContainerToken mToken;
private SurfaceControl mLeash;
- private boolean mInPip;
- private boolean mExitingPip;
+ private State mState = State.UNDEFINED;
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
@@ -254,11 +282,11 @@
}
public boolean isInPip() {
- return mInPip;
+ return mState.isInPip();
}
public boolean isDeferringEnterPipAnimation() {
- return mInPip && mShouldDeferEnteringPip;
+ return mState.isInPip() && mShouldDeferEnteringPip;
}
/**
@@ -287,9 +315,9 @@
* @param animationDurationMs duration in millisecond for the exiting PiP transition
*/
public void exitPip(int animationDurationMs) {
- if (!mInPip || mExitingPip || mToken == null) {
+ if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) {
Log.wtf(TAG, "Not allowed to exitPip in current state"
- + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken);
+ + " mState=" + mState + " mToken=" + mToken);
return;
}
@@ -304,15 +332,15 @@
? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
: TRANSITION_DIRECTION_LEAVE_PIP;
if (orientationDiffers) {
+ mState = State.EXITING_PIP;
// Send started callback though animation is ignored.
sendOnPipTransitionStarted(direction);
// Don't bother doing an animation if the display rotation differs or if it's in
// a non-supported windowing mode
applyWindowingModeChangeOnExit(wct, direction);
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
// Send finished callback though animation is ignored.
sendOnPipTransitionFinished(direction);
- mInPip = false;
} else {
final SurfaceControl.Transaction tx =
mSurfaceControlTransactionFactory.getTransaction();
@@ -334,11 +362,10 @@
scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
null /* sourceHintRect */, direction, animationDurationMs,
null /* updateBoundsCallback */);
- mInPip = false;
+ mState = State.EXITING_PIP;
}
});
}
- mExitingPip = true;
}
private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) {
@@ -357,9 +384,9 @@
* Removes PiP immediately.
*/
public void removePip() {
- if (!mInPip || mExitingPip || mToken == null) {
+ if (!mState.isInPip() || mToken == null) {
Log.wtf(TAG, "Not allowed to removePip in current state"
- + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken);
+ + " mState=" + mState + " mToken=" + mToken);
return;
}
@@ -371,7 +398,7 @@
.setDuration(mEnterExitAnimationDuration)
.start());
mInitialState.remove(mToken.asBinder());
- mExitingPip = true;
+ mState = State.EXITING_PIP;
}
private void removePipImmediately() {
@@ -379,7 +406,7 @@
// Reset the task bounds first to ensure the activity configuration is reset as well
final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mToken, null);
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
ActivityTaskManager.getService().removeStacksInWindowingModes(
new int[]{ WINDOWING_MODE_PINNED });
@@ -393,8 +420,7 @@
Objects.requireNonNull(info, "Requires RunningTaskInfo");
mTaskInfo = info;
mToken = mTaskInfo.token;
- mInPip = true;
- mExitingPip = false;
+ mState = State.TASK_APPEARED;
mLeash = leash;
mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
@@ -424,6 +450,7 @@
scheduleAnimateResizePip(currentBounds, destinationBounds, sourceHintRect,
TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
null /* updateBoundsCallback */);
+ mState = State.ENTERING_PIP;
} else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration);
mOneShotAnimationType = ANIM_TYPE_BOUNDS;
@@ -469,6 +496,9 @@
.setPipAnimationCallback(mPipAnimationCallback)
.setDuration(durationMs)
.start());
+ // mState is set right after the animation is kicked off to block any resize
+ // requests such as offsetPip that may have been called prior to the transition.
+ mState = State.ENTERING_PIP;
}
});
}
@@ -561,7 +591,7 @@
*/
@Override
public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
- if (!mInPip) {
+ if (!mState.isInPip()) {
return;
}
final WindowContainerToken token = info.token;
@@ -572,8 +602,7 @@
}
mShouldDeferEnteringPip = false;
mPictureInPictureParams = null;
- mInPip = false;
- mExitingPip = false;
+ mState = State.UNDEFINED;
mPipUiEventLoggerLogger.setTaskInfo(null);
}
@@ -601,7 +630,7 @@
@Override
public void onFixedRotationFinished(int displayId) {
- if (mShouldDeferEnteringPip && mInPip) {
+ if (mShouldDeferEnteringPip && mState.isInPip()) {
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
@@ -624,7 +653,7 @@
mPipAnimationController.getCurrentAnimator();
if (animator == null || !animator.isRunning()
|| animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) {
- if (mInPip && fromRotation) {
+ if (mState.isInPip() && fromRotation) {
// If we are rotating while there is a current animation, immediately cancel the
// animation (remove the listeners so we don't trigger the normal finish resize
// call that should only happen on the update thread)
@@ -713,10 +742,10 @@
private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds,
Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction,
int durationMs, Consumer<Rect> updateBoundsCallback) {
- if (!mInPip) {
+ if (!mState.isInPip()) {
// TODO: tend to use shouldBlockResizeRequest here as well but need to consider
// the fact that when in exitPip, scheduleAnimateResizePip is executed in the window
- // container transaction callback and we want to set the mExitingPip immediately.
+ // container transaction callback and we want to set the mState immediately.
return;
}
@@ -773,7 +802,7 @@
private void scheduleFinishResizePip(Rect destinationBounds,
@PipAnimationController.TransitionDirection int direction,
Consumer<Rect> updateBoundsCallback) {
- if (shouldBlockResizeRequest()) {
+ if (mState.shouldBlockResizeRequest()) {
return;
}
@@ -792,7 +821,7 @@
mSurfaceTransactionHelper
.crop(tx, mLeash, destinationBounds)
.resetScale(tx, mLeash, destinationBounds)
- .round(tx, mLeash, mInPip);
+ .round(tx, mLeash, mState.isInPip());
return tx;
}
@@ -801,7 +830,7 @@
*/
public void scheduleOffsetPip(Rect originalBounds, int offset, int duration,
Consumer<Rect> updateBoundsCallback) {
- if (shouldBlockResizeRequest()) {
+ if (mState.shouldBlockResizeRequest()) {
return;
}
if (mShouldDeferEnteringPip) {
@@ -846,7 +875,7 @@
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper
.crop(tx, mLeash, destinationBounds)
- .round(tx, mLeash, mInPip);
+ .round(tx, mLeash, mState.isInPip());
tx.apply();
}
@@ -932,7 +961,7 @@
*/
public void applyFinishBoundsResize(@NonNull WindowContainerTransaction wct,
@PipAnimationController.TransitionDirection int direction) {
- WindowOrganizer.applyTransaction(wct);
+ mTaskOrganizer.applyTransaction(wct);
}
/**
@@ -984,16 +1013,6 @@
}
/**
- * Resize request can be initiated in other component, ignore if we are no longer in PIP
- * or we're exiting from it.
- *
- * @return {@code true} if the resize request should be blocked/ignored.
- */
- private boolean shouldBlockResizeRequest() {
- return !mInPip || mExitingPip;
- }
-
- /**
* Sync with {@link SplitScreen} on destination bounds if PiP is going to split screen.
*
* @param destinationBoundsOut contain the updated destination bounds if applicable
@@ -1027,7 +1046,7 @@
pw.println(innerPrefix + "mToken=" + mToken
+ " binder=" + (mToken != null ? mToken.asBinder() : null));
pw.println(innerPrefix + "mLeash=" + mLeash);
- pw.println(innerPrefix + "mInPip=" + mInPip);
+ pw.println(innerPrefix + "mState=" + mState);
pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java
index 6998e90..4f225e2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java
@@ -25,6 +25,7 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityManager;
import android.app.RemoteAction;
import android.content.ComponentName;
@@ -324,9 +325,9 @@
configController.addCallback(mOverlayChangedListener);
try {
- ActivityManager.StackInfo stackInfo = ActivityTaskManager.getService().getStackInfo(
+ RootTaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
- if (stackInfo != null) {
+ if (taskInfo != null) {
// If SystemUI restart, and it already existed a pinned stack,
// register the pip input consumer to ensure touch can send to it.
mInputConsumerController.registerInputConsumer(true /* withSfVsync */);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 873ba26..d308172 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -19,8 +19,8 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import android.app.ActivityManager.StackInfo;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.RemoteAction;
import android.content.Context;
import android.content.pm.ParceledListSlice;
@@ -312,10 +312,10 @@
// Fetch the pinned stack bounds
Rect stackBounds = null;
try {
- StackInfo pinnedStackInfo = ActivityTaskManager.getService().getStackInfo(
+ RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
- if (pinnedStackInfo != null) {
- stackBounds = pinnedStackInfo.bounds;
+ if (pinnedTaskInfo != null) {
+ stackBounds = pinnedTaskInfo.bounds;
}
} catch (RemoteException e) {
Log.e(TAG, "Error showing PIP menu", e);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java
index 993bfe0..c66f442 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java
@@ -475,12 +475,10 @@
final Pair<ComponentName, Integer> topPipActivityInfo =
PipUtils.getTopPipActivity(mContext, ActivityManager.getService());
if (topPipActivityInfo.first != null) {
- final UserHandle user = UserHandle.of(topPipActivityInfo.second);
final Intent settingsIntent = new Intent(ACTION_PICTURE_IN_PICTURE_SETTINGS,
Uri.fromParts("package", topPipActivityInfo.first.getPackageName(), null));
- settingsIntent.putExtra(Intent.EXTRA_USER_HANDLE, user);
settingsIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
- mContext.startActivity(settingsIntent);
+ mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index 50d20d3..08d9b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -15,7 +15,7 @@
*/
package com.android.systemui.pip.phone;
-import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_USER_RESIZE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_PINCH_RESIZE;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_BOTTOM;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT;
import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
@@ -46,6 +46,7 @@
import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
import android.view.ViewConfiguration;
import com.android.internal.policy.TaskResizingAlgorithm;
@@ -67,6 +68,8 @@
public class PipResizeGestureHandler {
private static final String TAG = "PipResizeGestureHandler";
+ private static final float PINCH_THRESHOLD = 0.05f;
+ private static final float STARTING_SCALE_FACTOR = 1.0f;
private static final int INVALID_SYSUI_STATE_MASK =
SYSUI_STATE_GLOBAL_ACTIONS_SHOWING
@@ -83,6 +86,7 @@
private final int mDisplayId;
private final Executor mMainExecutor;
private final SysUiState mSysUiState;
+ private final ScaleGestureDetector mScaleGestureDetector;
private final Region mTmpRegion = new Region();
private final PointF mDownPoint = new PointF();
@@ -105,8 +109,10 @@
private boolean mAllowGesture;
private boolean mIsAttached;
private boolean mIsEnabled;
- private boolean mEnableUserResize;
+ private boolean mEnablePinchResize;
private boolean mThresholdCrossed;
+ private boolean mUsingPinchToZoom = false;
+ private float mScaleFactor = STARTING_SCALE_FACTOR;
private InputMonitor mInputMonitor;
private InputEventReceiver mInputEventReceiver;
@@ -136,17 +142,73 @@
context.getDisplay().getRealSize(mMaxSize);
reloadResources();
- mEnableUserResize = DeviceConfig.getBoolean(
+ mScaleGestureDetector = new ScaleGestureDetector(context,
+ new ScaleGestureDetector.OnScaleGestureListener() {
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ mScaleFactor *= detector.getScaleFactor();
+
+ if (!mThresholdCrossed
+ && (mScaleFactor > (STARTING_SCALE_FACTOR + PINCH_THRESHOLD)
+ || mScaleFactor < (STARTING_SCALE_FACTOR - PINCH_THRESHOLD))) {
+ mThresholdCrossed = true;
+ mInputMonitor.pilferPointers();
+ }
+ if (mThresholdCrossed) {
+ int height = Math.min(mMaxSize.y, Math.max(mMinSize.y,
+ (int) (mScaleFactor * mLastDownBounds.height())));
+ int width = Math.min(mMaxSize.x, Math.max(mMinSize.x,
+ (int) (mScaleFactor * mLastDownBounds.width())));
+ int top, bottom, left, right;
+
+ if ((mCtrlType & CTRL_TOP) != 0) {
+ top = mLastDownBounds.bottom - height;
+ bottom = mLastDownBounds.bottom;
+ } else {
+ top = mLastDownBounds.top;
+ bottom = mLastDownBounds.top + height;
+ }
+
+ if ((mCtrlType & CTRL_LEFT) != 0) {
+ left = mLastDownBounds.right - width;
+ right = mLastDownBounds.right;
+ } else {
+ left = mLastDownBounds.left;
+ right = mLastDownBounds.left + width;
+ }
+
+ mLastResizeBounds.set(left, top, right, bottom);
+ mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds,
+ mLastResizeBounds,
+ null);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ setCtrlTypeForPinchToZoom();
+ return true;
+ }
+
+ @Override
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ mScaleFactor = STARTING_SCALE_FACTOR;
+ finishResize();
+ }
+ });
+
+ mEnablePinchResize = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SYSTEMUI,
- PIP_USER_RESIZE,
- /* defaultValue = */ true);
+ PIP_PINCH_RESIZE,
+ /* defaultValue = */ false);
deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mMainExecutor,
new DeviceConfig.OnPropertiesChangedListener() {
@Override
public void onPropertiesChanged(DeviceConfig.Properties properties) {
- if (properties.getKeyset().contains(PIP_USER_RESIZE)) {
- mEnableUserResize = properties.getBoolean(
- PIP_USER_RESIZE, /* defaultValue = */ true);
+ if (properties.getKeyset().contains(PIP_PINCH_RESIZE)) {
+ mEnablePinchResize = properties.getBoolean(
+ PIP_PINCH_RESIZE, /* defaultValue = */ false);
}
}
});
@@ -193,7 +255,7 @@
}
private void updateIsEnabled() {
- boolean isEnabled = mIsAttached && mEnableUserResize;
+ boolean isEnabled = mIsAttached;
if (isEnabled == mIsEnabled) {
return;
}
@@ -211,7 +273,11 @@
private void onInputEvent(InputEvent ev) {
if (ev instanceof MotionEvent) {
- onMotionEvent((MotionEvent) ev);
+ if (mUsingPinchToZoom) {
+ mScaleGestureDetector.onTouchEvent((MotionEvent) ev);
+ } else {
+ onDragCornerResize((MotionEvent) ev);
+ }
}
}
@@ -254,8 +320,51 @@
}
public boolean willStartResizeGesture(MotionEvent ev) {
- return mEnableUserResize && isInValidSysUiState()
- && isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY());
+ if (isInValidSysUiState()) {
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ // Always pass the DOWN event to the ScaleGestureDetector
+ mScaleGestureDetector.onTouchEvent(ev);
+ if (isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY())) {
+ return true;
+ }
+ break;
+
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if (mEnablePinchResize && ev.getPointerCount() == 2) {
+ mUsingPinchToZoom = true;
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return false;
+ }
+
+ private void setCtrlTypeForPinchToZoom() {
+ final Rect currentPipBounds = mMotionHelper.getBounds();
+ mLastDownBounds.set(mMotionHelper.getBounds());
+
+ Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds);
+ mDisplayBounds.set(movementBounds.left,
+ movementBounds.top,
+ movementBounds.right + currentPipBounds.width(),
+ movementBounds.bottom + currentPipBounds.height());
+
+ if (currentPipBounds.left == mDisplayBounds.left) {
+ mCtrlType |= CTRL_RIGHT;
+ } else {
+ mCtrlType |= CTRL_LEFT;
+ }
+
+ if (currentPipBounds.top > mDisplayBounds.top + mDisplayBounds.height()) {
+ mCtrlType |= CTRL_TOP;
+ } else {
+ mCtrlType |= CTRL_BOTTOM;
+ }
}
private void setCtrlType(int x, int y) {
@@ -295,7 +404,7 @@
return (mSysUiState.getFlags() & INVALID_SYSUI_STATE_MASK) == 0;
}
- private void onMotionEvent(MotionEvent ev) {
+ private void onDragCornerResize(MotionEvent ev) {
int action = ev.getActionMasked();
float x = ev.getX();
float y = ev.getY();
@@ -345,28 +454,33 @@
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (!mLastResizeBounds.isEmpty()) {
- mUserResizeBounds.set(mLastResizeBounds);
- mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
- (Rect bounds) -> {
- new Handler(Looper.getMainLooper()).post(() -> {
- mMotionHelper.synchronizePinnedStackBounds();
- mUpdateMovementBoundsRunnable.run();
- resetState();
- });
- });
- mPipUiEventLogger.log(
- PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
- } else {
- resetState();
- }
+ finishResize();
break;
}
}
}
+ private void finishResize() {
+ if (!mLastResizeBounds.isEmpty()) {
+ mUserResizeBounds.set(mLastResizeBounds);
+ mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
+ (Rect bounds) -> {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ mMotionHelper.synchronizePinnedStackBounds();
+ mUpdateMovementBoundsRunnable.run();
+ resetState();
+ });
+ });
+ mPipUiEventLogger.log(
+ PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
+ } else {
+ resetState();
+ }
+ }
+
private void resetState() {
mCtrlType = CTRL_NONE;
+ mUsingPinchToZoom = false;
mAllowGesture = false;
mThresholdCrossed = false;
}
@@ -397,7 +511,7 @@
pw.println(innerPrefix + "mAllowGesture=" + mAllowGesture);
pw.println(innerPrefix + "mIsAttached=" + mIsAttached);
pw.println(innerPrefix + "mIsEnabled=" + mIsEnabled);
- pw.println(innerPrefix + "mEnableUserResize=" + mEnableUserResize);
+ pw.println(innerPrefix + "mEnablePinchResize=" + mEnablePinchResize);
pw.println(innerPrefix + "mThresholdCrossed=" + mThresholdCrossed);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 9693f23..97b3484 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -650,8 +650,7 @@
}
MotionEvent ev = (MotionEvent) inputEvent;
- if (ev.getActionMasked() == MotionEvent.ACTION_DOWN
- && mPipResizeGestureHandler.willStartResizeGesture(ev)) {
+ if (mPipResizeGestureHandler.willStartResizeGesture(ev)) {
// Initialize the touch state for the gesture, but immediately reset to invalidate the
// gesture
mTouchState.onTouchEvent(ev);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
index 4cfec01..baa8f11 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
@@ -19,8 +19,8 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import android.app.ActivityManager.StackInfo;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -40,15 +40,15 @@
IActivityManager activityManager) {
try {
final String sysUiPackageName = context.getPackageName();
- final StackInfo pinnedStackInfo = ActivityTaskManager.getService().getStackInfo(
+ final RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
- if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
- pinnedStackInfo.taskIds.length > 0) {
- for (int i = pinnedStackInfo.taskNames.length - 1; i >= 0; i--) {
+ if (pinnedTaskInfo != null && pinnedTaskInfo.childTaskIds != null
+ && pinnedTaskInfo.childTaskIds.length > 0) {
+ for (int i = pinnedTaskInfo.childTaskNames.length - 1; i >= 0; i--) {
ComponentName cn = ComponentName.unflattenFromString(
- pinnedStackInfo.taskNames[i]);
+ pinnedTaskInfo.childTaskNames[i]);
if (cn != null && !cn.getPackageName().equals(sysUiPackageName)) {
- return new Pair<>(cn, pinnedStackInfo.taskUserIds[i]);
+ return new Pair<>(cn, pinnedTaskInfo.childTaskUserIds[i]);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java
index 3b3235f..12a545a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java
@@ -21,8 +21,8 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackInfo;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityTaskManager;
import android.app.RemoteAction;
import android.content.BroadcastReceiver;
@@ -289,7 +289,7 @@
// 1. Configuration changed due to the language change (RTL <-> RTL)
// 2. SystemUI restarts after the crash
mPipBounds = mDefaultPipBounds;
- resizePinnedStack(getPinnedStackInfo() == null ? STATE_NO_PIP : STATE_PIP);
+ resizePinnedStack(getPinnedTaskInfo() == null ? STATE_NO_PIP : STATE_PIP);
}
/**
@@ -505,15 +505,15 @@
return mState != STATE_NO_PIP;
}
- private StackInfo getPinnedStackInfo() {
- StackInfo stackInfo = null;
+ private RootTaskInfo getPinnedTaskInfo() {
+ RootTaskInfo taskInfo = null;
try {
- stackInfo = ActivityTaskManager.getService().getStackInfo(
+ taskInfo = ActivityTaskManager.getService().getRootTaskInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
} catch (RemoteException e) {
- Log.e(TAG, "getStackInfo failed", e);
+ Log.e(TAG, "getRootTaskInfo failed", e);
}
- return stackInfo;
+ return taskInfo;
}
private void handleMediaResourceGranted(String[] packageNames) {
@@ -611,14 +611,14 @@
if (getState() != STATE_NO_PIP) {
boolean hasPip = false;
- StackInfo stackInfo = getPinnedStackInfo();
- if (stackInfo == null || stackInfo.taskIds == null) {
+ RootTaskInfo taskInfo = getPinnedTaskInfo();
+ if (taskInfo == null || taskInfo.childTaskIds == null) {
Log.w(TAG, "There is nothing in pinned stack");
closePipInternal(false);
return;
}
- for (int i = stackInfo.taskIds.length - 1; i >= 0; --i) {
- if (stackInfo.taskIds[i] == mPipTaskId) {
+ for (int i = taskInfo.childTaskIds.length - 1; i >= 0; --i) {
+ if (taskInfo.childTaskIds[i] == mPipTaskId) {
// PIP task is still alive.
hasPip = true;
break;
@@ -642,16 +642,16 @@
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
if (DEBUG) Log.d(TAG, "onActivityPinned()");
- StackInfo stackInfo = getPinnedStackInfo();
- if (stackInfo == null) {
+ RootTaskInfo taskInfo = getPinnedTaskInfo();
+ if (taskInfo == null) {
Log.w(TAG, "Cannot find pinned stack");
return;
}
- if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
- mPinnedStackId = stackInfo.stackId;
- mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
+ if (DEBUG) Log.d(TAG, "PINNED_STACK:" + taskInfo);
+ mPinnedStackId = taskInfo.taskId;
+ mPipTaskId = taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1];
mPipComponentName = ComponentName.unflattenFromString(
- stackInfo.taskNames[stackInfo.taskNames.length - 1]);
+ taskInfo.childTaskNames[taskInfo.childTaskNames.length - 1]);
// Set state to STATE_PIP so we show it when the pinned stack animation ends.
mState = STATE_PIP;
mMediaSessionManager.addOnActiveSessionsChangedListener(
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index e57478e..0fbd73b 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -72,6 +72,8 @@
private const val ALL_INDICATORS =
SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED
private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED
+ private const val DEFAULT_ALL_INDICATORS = false
+ private const val DEFAULT_MIC_CAMERA = true
}
@VisibleForTesting
@@ -81,12 +83,12 @@
private fun isAllIndicatorsEnabled(): Boolean {
return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
- ALL_INDICATORS, false)
+ ALL_INDICATORS, DEFAULT_ALL_INDICATORS)
}
+ // TODO(b/168209929) Remove hardcode
private fun isMicCameraEnabled(): Boolean {
- return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
- MIC_CAMERA, false)
+ return true
}
private var currentUserIds = emptyList<Int>()
@@ -118,14 +120,15 @@
// Running on the ui executor so can iterate on callbacks
if (properties.keyset.contains(ALL_INDICATORS)) {
- allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS, false)
+ allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS,
+ DEFAULT_ALL_INDICATORS)
callbacks.forEach { it.get()?.onFlagAllChanged(allIndicatorsAvailable) }
}
-
- if (properties.keyset.contains(MIC_CAMERA)) {
- micCameraAvailable = properties.getBoolean(MIC_CAMERA, false)
- callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) }
- }
+ // TODO(b/168209929) Uncomment
+// if (properties.keyset.contains(MIC_CAMERA)) {
+// micCameraAvailable = properties.getBoolean(MIC_CAMERA, DEFAULT_MIC_CAMERA)
+// callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) }
+// }
internalUiExecutor.updateListeningState()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 1a7e229..47002683 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -38,8 +38,8 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 56f010d..2a976f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -75,7 +75,6 @@
import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.onehanded.OneHandedUI;
import com.android.systemui.pip.Pip;
import com.android.systemui.pip.PipAnimationController;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
@@ -87,12 +86,14 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
import com.android.systemui.statusbar.policy.CallbackController;
+import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.onehanded.OneHandedEvents;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -135,7 +136,7 @@
private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
private final Intent mQuickStepIntent;
private final ScreenshotHelper mScreenshotHelper;
- private final OneHandedUI mOneHandedUI;
+ private final Optional<OneHanded> mOneHandedOptional;
private final CommandQueue mCommandQueue;
private Region mActiveNavBarRegion;
@@ -464,9 +465,7 @@
}
long token = Binder.clearCallingIdentity();
try {
- if (mOneHandedUI != null) {
- mOneHandedUI.startOneHanded();
- }
+ mOneHandedOptional.ifPresent(oneHanded -> oneHanded.startOneHanded());
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -479,9 +478,8 @@
}
long token = Binder.clearCallingIdentity();
try {
- if (mOneHandedUI != null) {
- mOneHandedUI.stopOneHanded();
- }
+ mOneHandedOptional.ifPresent(oneHanded -> oneHanded.stopOneHanded(
+ OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT));
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -620,7 +618,8 @@
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
Optional<Pip> pipOptional,
Optional<SplitScreen> splitScreenOptional,
- Optional<Lazy<StatusBar>> statusBarOptionalLazy, OneHandedUI oneHandedUI,
+ Optional<Lazy<StatusBar>> statusBarOptionalLazy,
+ Optional<OneHanded> oneHandedOptional,
BroadcastDispatcher broadcastDispatcher) {
super(broadcastDispatcher);
mContext = context;
@@ -640,7 +639,7 @@
.supportsRoundedCornersOnWindows(mContext.getResources());
mSysUiState = sysUiState;
mSysUiState.addCallback(this::notifySystemUiStateFlags);
- mOneHandedUI = oneHandedUI;
+ mOneHandedOptional = oneHandedOptional;
// Assumes device always starts with back button until launcher tells it that it does not
mNavBarButtonAlpha = 1.0f;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7dd4edd..2b4fa2a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -574,7 +574,8 @@
private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect,
Insets screenInsets, boolean showFlash) {
if (mScreenshotLayout.isAttachedToWindow()) {
- if (!mDismissAnimation.isRunning()) { // if we didn't already dismiss for another reason
+ // if we didn't already dismiss for another reason
+ if (mDismissAnimation == null || !mDismissAnimation.isRunning()) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED);
}
dismissScreenshot("new screenshot requested", true);
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 0d92d1e..b9b4f42 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -30,8 +30,8 @@
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.recents.Recents;
-import com.android.systemui.stackdivider.DividerView;
-import com.android.systemui.stackdivider.SplitScreen;
+import com.android.wm.shell.splitscreen.DividerView;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index c01bdc4..8bf134d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -21,6 +21,7 @@
import static com.android.systemui.statusbar.phone.StatusBar.SHOW_LOCKSCREEN_MEDIA_ARTWORK;
import android.annotation.MainThread;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.content.Context;
@@ -57,6 +58,7 @@
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
@@ -233,8 +235,17 @@
NotificationVisibility visibility,
boolean removedByUser,
int reason) {
- onNotificationRemoved(entry.getKey());
- mediaDataManager.onNotificationRemoved(entry.getKey());
+ removeEntry(entry);
+ }
+ });
+
+ // Pending entries are never inflated, and will never generate a call to onEntryRemoved().
+ // This can happen when notifications are added and canceled before inflation. Add this
+ // separate listener for cleanup, since media inflation occurs onPendingEntryAdded().
+ notificationEntryManager.addCollectionListener(new NotifCollectionListener() {
+ @Override
+ public void onEntryCleanUp(@NonNull NotificationEntry entry) {
+ removeEntry(entry);
}
});
@@ -247,6 +258,11 @@
mPropertiesChangedListener);
}
+ private void removeEntry(NotificationEntry entry) {
+ onNotificationRemoved(entry.getKey());
+ mMediaDataManager.onNotificationRemoved(entry.getKey());
+ }
+
/**
* Check if a state should be considered actively playing
* @param state a PlaybackState
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 9586795..a816ecc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -516,6 +516,7 @@
return mLifetimeExtenders;
}
+ @Nullable
public RemoteInputController getController() {
return mRemoteInputController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 8f3033e..7bac007 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -188,7 +188,7 @@
viewState.openedAmount = openedAmount;
viewState.clipTopAmount = 0;
viewState.alpha = 1;
- viewState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0;
+ viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0;
viewState.hideSensitive = false;
viewState.xTranslation = getTranslationX();
if (mNotGoneIndex != -1) {
@@ -352,7 +352,7 @@
}
setBackgroundTop(backgroundTop);
setFirstElementRoundness(firstElementRoundness);
- mShelfIcons.setSpeedBumpIndex(mAmbientState.getSpeedBumpIndex());
+ mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex());
mShelfIcons.calculateIconTranslations();
mShelfIcons.applyIconStates();
for (int i = 0; i < mHostLayoutController.getChildCount(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 8cf8a22..01d3103 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -390,17 +390,21 @@
}
private Drawable getIcon(StatusBarIcon icon) {
- return getIcon(getContext(), icon);
+ Context notifContext = mNotification != null ?
+ mNotification.getPackageContext(getContext()) : getContext();
+ return getIcon(getContext(), notifContext, icon);
}
/**
* Returns the right icon to use for this item
*
- * @param context Context to use to get resources
+ * @param sysuiContext Context to use to get scale factor
+ * @param context Context to use to get resources of notification icon
* @return Drawable for this item, or null if the package or item could not
* be found
*/
- public static Drawable getIcon(Context context, StatusBarIcon statusBarIcon) {
+ public static Drawable getIcon(Context sysuiContext,
+ Context context, StatusBarIcon statusBarIcon) {
int userId = statusBarIcon.user.getIdentifier();
if (userId == UserHandle.USER_ALL) {
userId = UserHandle.USER_SYSTEM;
@@ -409,7 +413,8 @@
Drawable icon = statusBarIcon.icon.loadDrawableAsUser(context, userId);
TypedValue typedValue = new TypedValue();
- context.getResources().getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
+ sysuiContext.getResources().getValue(R.dimen.status_bar_icon_scale_factor,
+ typedValue, true);
float scaleFactor = typedValue.getFloat();
// No need to scale the icon, so return it as is.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 838cf0c..363a085 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -26,6 +26,7 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AppGlobals;
import android.app.Notification;
import android.app.NotificationManager;
@@ -55,10 +56,10 @@
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.UiBackground;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.NotificationChannels;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.List;
import java.util.Optional;
@@ -161,16 +162,16 @@
() -> {
ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs);
try {
- final ActivityManager.StackInfo focusedStack =
- ActivityTaskManager.getService().getFocusedStackInfo();
- if (focusedStack != null) {
+ final RootTaskInfo focusedTask =
+ ActivityTaskManager.getService().getFocusedRootTaskInfo();
+ if (focusedTask != null) {
final int windowingMode =
- focusedStack.configuration.windowConfiguration
+ focusedTask.configuration.windowConfiguration
.getWindowingMode();
if (windowingMode == WINDOWING_MODE_FULLSCREEN
|| windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
|| windowingMode == WINDOWING_MODE_FREEFORM) {
- checkAndPostForStack(focusedStack, notifs, noMan, pm);
+ checkAndPostForStack(focusedTask, notifs, noMan, pm);
}
}
if (mDockedStackExists) {
@@ -205,10 +206,8 @@
@NonNull NotificationManager noMan,
@NonNull IPackageManager pm) {
try {
- final ActivityManager.StackInfo info =
- ActivityTaskManager.getService()
- .getStackInfo(
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
+ final RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo(
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
checkAndPostForStack(info, notifs, noMan, pm);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
@@ -221,7 +220,7 @@
* exists, this method removes it from {@code notifs} in the arguments.
*/
private void checkAndPostForStack(
- @Nullable ActivityManager.StackInfo info,
+ @Nullable RootTaskInfo info,
@NonNull ArraySet<Pair<String, Integer>> notifs,
@NonNull NotificationManager noMan,
@NonNull IPackageManager pm) {
@@ -241,7 +240,7 @@
info.userId,
appInfo,
noMan,
- info.taskIds[info.taskIds.length - 1]);
+ info.childTaskIds[info.childTaskIds.length - 1]);
}
}
} catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
index 82c1f24..fd0476b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
@@ -110,4 +110,11 @@
mPreviousAttachState.clone(mAttachState);
mAttachState.reset();
}
+
+ /**
+ * True if this entry was attached in the last pass, else false.
+ */
+ public boolean wasAttachedInPreviousPass() {
+ return getPreviousAttachState().getParent() != null;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index 90492b5..fdfd724 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -18,6 +18,7 @@
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED;
import static android.service.notification.NotificationListenerService.REASON_CLICK;
@@ -459,8 +460,7 @@
+ ": has not been marked for removal"));
}
- if (isDismissedByUser(entry)) {
- // User-dismissed notifications cannot be lifetime-extended
+ if (cannotBeLifetimeExtended(entry)) {
cancelLifetimeExtension(entry);
} else {
updateLifetimeExtension(entry);
@@ -583,7 +583,7 @@
}
private void cancelLocalDismissal(NotificationEntry entry) {
- if (isDismissedByUser(entry)) {
+ if (entry.getDismissState() != NOT_DISMISSED) {
entry.setDismissState(NOT_DISMISSED);
if (entry.getSbn().getNotification().isGroupSummary()) {
for (NotificationEntry otherEntry : mNotificationSet.values()) {
@@ -669,12 +669,16 @@
* immediately removed from the collection, but can sometimes stick around due to lifetime
* extenders.
*/
- private static boolean isCanceled(NotificationEntry entry) {
+ private boolean isCanceled(NotificationEntry entry) {
return entry.mCancellationReason != REASON_NOT_CANCELED;
}
- private static boolean isDismissedByUser(NotificationEntry entry) {
- return entry.getDismissState() != NOT_DISMISSED;
+ private boolean cannotBeLifetimeExtended(NotificationEntry entry) {
+ final boolean locallyDismissedByUser = entry.getDismissState() != NOT_DISMISSED;
+ final boolean systemServerReportedUserCancel =
+ entry.mCancellationReason == REASON_CLICK
+ || entry.mCancellationReason == REASON_CANCEL;
+ return locallyDismissedByUser || systemServerReportedUserCancel;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 2b545c5..a0ef1b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -513,28 +513,66 @@
}
}
- private void stabilizeGroupingNotifs(List<ListEntry> list) {
+ private void stabilizeGroupingNotifs(List<ListEntry> topLevelList) {
if (mNotifStabilityManager == null) {
return;
}
- for (int i = 0; i < list.size(); i++) {
- final ListEntry tle = list.get(i);
- if (tle.getPreviousAttachState().getParent() == null) {
- continue; // new entries are allowed
- }
-
- final GroupEntry prevParent = tle.getPreviousAttachState().getParent();
- final GroupEntry assignedParent = tle.getParent();
- if (prevParent != assignedParent) {
- if (!mNotifStabilityManager.isGroupChangeAllowed(tle.getRepresentativeEntry())) {
- tle.getAttachState().getSuppressedChanges().setParent(assignedParent);
- tle.setParent(prevParent);
+ for (int i = 0; i < topLevelList.size(); i++) {
+ final ListEntry tle = topLevelList.get(i);
+ if (tle instanceof GroupEntry) {
+ // maybe put children back into their old group (including moving back to top-level)
+ GroupEntry groupEntry = (GroupEntry) tle;
+ List<NotificationEntry> children = groupEntry.getRawChildren();
+ for (int j = 0; j < groupEntry.getChildren().size(); j++) {
+ if (maybeSuppressGroupChange(children.get(j), topLevelList)) {
+ // child was put back into its previous group, so we remove it from this
+ // group
+ children.remove(j);
+ j--;
+ }
+ }
+ } else {
+ // maybe put top-level-entries back into their previous groups
+ if (maybeSuppressGroupChange(tle.getRepresentativeEntry(), topLevelList)) {
+ // entry was put back into its previous group, so we remove it from the list of
+ // top-level-entries
+ topLevelList.remove(i);
+ i--;
}
}
}
}
+ /**
+ * Returns true if the group change was suppressed, else false
+ */
+ private boolean maybeSuppressGroupChange(NotificationEntry entry, List<ListEntry> out) {
+ if (!entry.wasAttachedInPreviousPass()) {
+ return false; // new entries are allowed
+ }
+
+ final GroupEntry prevParent = entry.getPreviousAttachState().getParent();
+ final GroupEntry assignedParent = entry.getParent();
+ if (prevParent != assignedParent
+ && !mNotifStabilityManager.isGroupChangeAllowed(entry.getRepresentativeEntry())) {
+ entry.getAttachState().getSuppressedChanges().setParent(assignedParent);
+ entry.setParent(prevParent);
+ if (prevParent == ROOT_ENTRY) {
+ out.add(entry);
+ } else if (prevParent != null) {
+ prevParent.addChild(entry);
+ if (!mGroups.containsKey(prevParent.getKey())) {
+ mGroups.put(prevParent.getKey(), prevParent);
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
private void promoteNotifs(List<ListEntry> list) {
for (int i = 0; i < list.size(); i++) {
final ListEntry tle = list.get(i);
@@ -577,6 +615,17 @@
} else if (group.getSummary() == null
|| children.size() < MIN_CHILDREN_FOR_GROUP) {
+
+ if (group.getSummary() != null
+ && group.wasAttachedInPreviousPass()
+ && mNotifStabilityManager != null
+ && !mNotifStabilityManager.isGroupChangeAllowed(group.getSummary())) {
+ // if this group was previously attached and group changes aren't
+ // allowed, keep it around until group changes are allowed again
+ group.getAttachState().getSuppressedChanges().setWasPruneSuppressed(true);
+ continue;
+ }
+
// If the group doesn't provide a summary or is too small, ignore it and add
// its children (if any) directly to top-level.
@@ -673,7 +722,6 @@
GroupEntry parent = (GroupEntry) entry;
for (NotificationEntry child : parent.getChildren()) {
child.getAttachState().setSection(section);
- child.getAttachState().setSection(section);
}
parent.sortChildren(sChildComparator);
}
@@ -719,6 +767,12 @@
curr.getParent());
}
+ if (curr.getSuppressedChanges().getWasPruneSuppressed()) {
+ mLogger.logGroupPruningSuppressed(
+ mIterationCount,
+ curr.getParent());
+ }
+
if (curr.getExcludingFilter() != prev.getExcludingFilter()) {
mLogger.logFilterChanged(
mIterationCount,
@@ -868,9 +922,9 @@
NotifSection finalSection = newSection;
- // are we changing sections of this entry?
+ // have we seen this entry before and are we changing its section?
if (mNotifStabilityManager != null
- && prevAttachState.getParent() != null
+ && entry.wasAttachedInPreviousPass()
&& newSection != prevAttachState.getSection()) {
// are section changes allowed?
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
index 3eb2e61..584563b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
@@ -24,28 +24,37 @@
*/
data class SuppressedAttachState private constructor(
/**
- * Null if not attached to the current shade list. If top-level, then the shade list root. If
- * part of a group, then that group's GroupEntry.
+ * The suppressed section assignment for this ListEntry.
+ * Null if no section change was suppressed.
+ */
+ var section: NotifSection?,
+
+ /**
+ * The suppressed parent assignment for this ListEntry.
+ * - Null if no parent change was suppressed.
+ * - Root if suppressing group change to top-level
+ * - GroupEntry if suppressing group change to a different group
*/
var parent: GroupEntry?,
/**
- * The assigned section for this ListEntry. If the child of the group, this will be the
- * parent's section. Null if not attached to the list.
+ * Whether the ListEntry would have been pruned had its group change not been suppressed.
*/
- var section: NotifSection?
+ var wasPruneSuppressed: Boolean
) {
/** Copies the state of another instance. */
fun clone(other: SuppressedAttachState) {
parent = other.parent
section = other.section
+ wasPruneSuppressed = other.wasPruneSuppressed
}
/** Resets back to a "clean" state (the same as created by the factory method) */
fun reset() {
parent = null
section = null
+ wasPruneSuppressed = false
}
companion object {
@@ -53,7 +62,8 @@
fun create(): SuppressedAttachState {
return SuppressedAttachState(
null,
- null)
+ null,
+ false)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
index 3aaa9ac..f0eb084 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
@@ -22,6 +22,8 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.android.systemui.statusbar.notification.dagger.PeopleHeader
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
import javax.inject.Inject
@@ -33,7 +35,8 @@
*/
@SysUISingleton
class ConversationCoordinator @Inject constructor(
- private val peopleNotificationIdentifier: PeopleNotificationIdentifier
+ private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
+ @PeopleHeader peopleHeaderController: NodeController
) : Coordinator {
private val notificationPromoter = object : NotifPromoter(TAG) {
@@ -43,9 +46,9 @@
}
val sectioner = object : NotifSectioner("People") {
- override fun isInSection(entry: ListEntry): Boolean {
- return isConversation(entry.representativeEntry!!)
- }
+ override fun isInSection(entry: ListEntry): Boolean =
+ isConversation(entry.representativeEntry!!)
+ override fun getHeaderNodeController() = peopleHeaderController
}
override fun attach(pipeline: NotifPipeline) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
index 24e912e..be1383f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
@@ -30,6 +30,8 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.notification.collection.render.NodeController;
+import com.android.systemui.statusbar.notification.dagger.IncomingHeader;
import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -61,6 +63,7 @@
private final HeadsUpViewBinder mHeadsUpViewBinder;
private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final NotificationRemoteInputManager mRemoteInputManager;
+ private final NodeController mIncomingHeaderController;
// tracks the current HeadUpNotification reported by HeadsUpManager
private @Nullable NotificationEntry mCurrentHun;
@@ -73,11 +76,13 @@
HeadsUpManager headsUpManager,
HeadsUpViewBinder headsUpViewBinder,
NotificationInterruptStateProvider notificationInterruptStateProvider,
- NotificationRemoteInputManager remoteInputManager) {
+ NotificationRemoteInputManager remoteInputManager,
+ @IncomingHeader NodeController incomingHeaderController) {
mHeadsUpManager = headsUpManager;
mHeadsUpViewBinder = headsUpViewBinder;
mNotificationInterruptStateProvider = notificationInterruptStateProvider;
mRemoteInputManager = remoteInputManager;
+ mIncomingHeaderController = incomingHeaderController;
}
@Override
@@ -196,6 +201,12 @@
public boolean isInSection(ListEntry entry) {
return isCurrentlyShowingHun(entry);
}
+
+ @Nullable
+ @Override
+ public NodeController getHeaderNodeController() {
+ return mIncomingHeaderController;
+ }
};
private final OnHeadsUpChangedListener mOnHeadsUpChangedListener =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
index 0f08e0f..133ddfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.collection.coordinator;
+import android.annotation.Nullable;
+
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.ListEntry;
@@ -24,6 +26,9 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.render.NodeController;
+import com.android.systemui.statusbar.notification.dagger.AlertingHeader;
+import com.android.systemui.statusbar.notification.dagger.SilentHeader;
import javax.inject.Inject;
@@ -40,13 +45,19 @@
private final StatusBarStateController mStatusBarStateController;
private final HighPriorityProvider mHighPriorityProvider;
+ private final NodeController mSilentHeaderController;
+ private final NodeController mAlertingHeaderController;
@Inject
public RankingCoordinator(
StatusBarStateController statusBarStateController,
- HighPriorityProvider highPriorityProvider) {
+ HighPriorityProvider highPriorityProvider,
+ @AlertingHeader NodeController alertingHeaderController,
+ @SilentHeader NodeController silentHeaderController) {
mStatusBarStateController = statusBarStateController;
mHighPriorityProvider = highPriorityProvider;
+ mAlertingHeaderController = alertingHeaderController;
+ mSilentHeaderController = silentHeaderController;
}
@Override
@@ -70,6 +81,12 @@
public boolean isInSection(ListEntry entry) {
return mHighPriorityProvider.isHighPriority(entry);
}
+
+ @Nullable
+ @Override
+ public NodeController getHeaderNodeController() {
+ return mAlertingHeaderController;
+ }
};
private final NotifSectioner mSilentNotifSectioner = new NotifSectioner("Silent") {
@@ -77,6 +94,12 @@
public boolean isInSection(ListEntry entry) {
return !mHighPriorityProvider.isHighPriority(entry);
}
+
+ @Nullable
+ @Override
+ public NodeController getHeaderNodeController() {
+ return mSilentHeaderController;
+ }
};
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index 08030f8..5d6c043 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -110,7 +110,7 @@
public boolean isGroupChangeAllowed(NotificationEntry entry) {
final boolean isGroupChangeAllowedForEntry =
mReorderingAllowed || mHeadsUpManager.isAlerting(entry.getKey());
- mIsSuppressingGroupChange |= isGroupChangeAllowedForEntry;
+ mIsSuppressingGroupChange |= !isGroupChangeAllowedForEntry;
return isGroupChangeAllowedForEntry;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
index cce8cdc..610cd33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
@@ -26,6 +26,7 @@
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -38,17 +39,20 @@
private final HeadsUpManager mHeadsUpManager;
private final StatusBarStateController mStatusBarStateController;
private final VisualStabilityManager mVisualStabilityManager;
+ private final GroupMembershipManager mGroupMembershipManager;
public OnUserInteractionCallbackImplLegacy(
NotificationEntryManager notificationEntryManager,
HeadsUpManager headsUpManager,
StatusBarStateController statusBarStateController,
- VisualStabilityManager visualStabilityManager
+ VisualStabilityManager visualStabilityManager,
+ GroupMembershipManager groupMembershipManager
) {
mNotificationEntryManager = notificationEntryManager;
mHeadsUpManager = headsUpManager;
mStatusBarStateController = statusBarStateController;
mVisualStabilityManager = visualStabilityManager;
+ mGroupMembershipManager = groupMembershipManager;
}
/**
@@ -69,6 +73,13 @@
dismissalSurface = NotificationStats.DISMISSAL_AOD;
}
+ if (mGroupMembershipManager.isOnlyChildInGroup(entry)) {
+ NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry);
+ if (groupSummary.isClearable()) {
+ onDismiss(groupSummary, cancellationReason);
+ }
+ }
+
mNotificationEntryManager.performRemoveNotification(
entry.getSbn(),
new DismissedByUserStats(
@@ -82,6 +93,7 @@
NotificationLogger.getNotificationLocation(entry))),
cancellationReason
);
+
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
index c09122e..c9fc992 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.listbuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.render.NodeController
data class NotifSection(
val sectioner: NotifSectioner,
@@ -24,4 +25,7 @@
) {
val label: String
get() = "Section($index, \"${sectioner.name}\")"
+
+ val headerController: NodeController?
+ get() = sectioner.headerNodeController
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
index 9ee7db7..5a35127 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
@@ -174,8 +174,19 @@
str1 = suppressedParent?.key
str2 = keepingParent?.key
}, {
- "(Build $long1) Change of parent to '$str1' suppressed; " +
- "keeping parent '$str2'"
+ "(Build $long1) Change of parent to '$str1' suppressed; keeping parent '$str2'"
+ })
+ }
+
+ fun logGroupPruningSuppressed(
+ buildId: Int,
+ keepingParent: GroupEntry?
+ ) {
+ buffer.log(TAG, INFO, {
+ int1 = buildId
+ str1 = keepingParent?.key
+ }, {
+ "(Build $long1) Group pruning suppressed; keeping parent '$str1'"
})
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java
index b57f504..c8982d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java
@@ -16,8 +16,12 @@
package com.android.systemui.statusbar.notification.collection.listbuilder.pluggable;
+import android.annotation.Nullable;
+
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
+import com.android.systemui.statusbar.notification.collection.render.NodeController;
+import com.android.systemui.statusbar.notification.collection.render.NodeSpec;
/**
* Pluggable for participating in notif sectioning. See {@link ShadeListBuilder#setSections}.
@@ -34,4 +38,12 @@
* notification. The first section to return true determines the section of the notification.
*/
public abstract boolean isInSection(ListEntry entry);
+
+ /**
+ * Returns an optional {@link NodeSpec} for the section header. If {@code null}, no header will
+ * be used for the section.
+ */
+ public @Nullable NodeController getHeaderNodeController() {
+ return null;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
index c1f468a..e784ec6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
@@ -56,7 +56,7 @@
return false;
}
- return entry.getParent().getChildren().size() == 1;
+ return !isGroupSummary(entry) && entry.getParent().getChildren().size() == 1;
}
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
index 67f7b1c..727ce20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
@@ -39,9 +39,7 @@
throw RuntimeException("Not supported")
}
- fun getChildCount(): Int {
- throw RuntimeException("Not supported")
- }
+ fun getChildCount(): Int = 0
fun addChildAt(child: NodeController, index: Int) {
throw RuntimeException("Not supported")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
new file mode 100644
index 0000000..498b8e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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.systemui.statusbar.notification.collection.render
+
+import android.annotation.StringRes
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.R
+import com.android.systemui.statusbar.notification.dagger.HeaderClick
+import com.android.systemui.statusbar.notification.dagger.HeaderText
+import com.android.systemui.statusbar.notification.dagger.NodeLabel
+import com.android.systemui.statusbar.notification.dagger.SectionHeaderScope
+import com.android.systemui.statusbar.notification.stack.SectionHeaderView
+import javax.inject.Inject
+
+interface SectionHeaderController {
+ fun reinflateView(parent: ViewGroup)
+ val headerView: SectionHeaderView?
+ fun setOnClearAllClickListener(listener: View.OnClickListener)
+}
+
+@SectionHeaderScope
+internal class SectionHeaderNodeControllerImpl @Inject constructor(
+ @NodeLabel override val nodeLabel: String,
+ private val layoutInflater: LayoutInflater,
+ @HeaderText @StringRes private val headerTextResId: Int,
+ @HeaderClick private val onHeaderClickListener: View.OnClickListener
+) : NodeController, SectionHeaderController {
+
+ private var _view: SectionHeaderView? = null
+ private var clearAllClickListener: View.OnClickListener? = null
+
+ override fun reinflateView(parent: ViewGroup) {
+ var oldPos = -1
+ _view?.let { _view ->
+ _view.transientContainer?.removeView(_view)
+ if (_view.parent === parent) {
+ oldPos = parent.indexOfChild(_view)
+ parent.removeView(_view)
+ }
+ }
+ val inflated = layoutInflater.inflate(
+ R.layout.status_bar_notification_section_header,
+ parent,
+ false /* attachToRoot */)
+ as SectionHeaderView
+ inflated.setHeaderText(headerTextResId)
+ inflated.setOnHeaderClickListener(onHeaderClickListener)
+ clearAllClickListener?.let { inflated.setOnClearAllClickListener(it) }
+ if (oldPos != -1) {
+ parent.addView(inflated, oldPos)
+ }
+ _view = inflated
+ }
+
+ override val headerView: SectionHeaderView?
+ get() = _view
+
+ override fun setOnClearAllClickListener(listener: View.OnClickListener) {
+ clearAllClickListener = listener
+ _view?.setOnClearAllClickListener(listener)
+ }
+
+ override val view: View
+ get() = _view!!
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
index 019520f..22ca496 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -65,9 +65,7 @@
*
* For debugging purposes.
*/
- fun getViewLabel(view: View): String {
- return views[view]?.label ?: view.toString()
- }
+ fun getViewLabel(view: View): String = views[view]?.label ?: view.toString()
private fun detachChildren(
parentNode: ShadeNode,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
index 5243854..c1a63e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -42,46 +42,34 @@
private val rootController = RootNodeController(listContainer, View(context))
private val viewDiffer = ShadeViewDiffer(rootController, logger)
- fun attach(listBuilder: ShadeListBuilder) {
- listBuilder.setOnRenderListListener(::onNewNotifTree)
- }
+ fun attach(listBuilder: ShadeListBuilder) =
+ listBuilder.setOnRenderListListener(::onNewNotifTree)
- private fun onNewNotifTree(tree: List<ListEntry>) {
- viewDiffer.applySpec(buildTree(tree))
- }
+ private fun onNewNotifTree(tree: List<ListEntry>) = viewDiffer.applySpec(buildTree(tree))
private fun buildTree(notifList: List<ListEntry>): NodeSpec {
- val root = NodeSpecImpl(null, rootController)
-
- for (entry in notifList) {
- // TODO: Add section header logic here
- root.children.add(buildNotifNode(entry, root))
+ val root = NodeSpecImpl(null, rootController).apply {
+ // Insert first section header, if present
+ notifList.firstOrNull()?.section?.headerController?.let {
+ children.add(NodeSpecImpl(this, it))
+ }
+ notifList.asSequence().zipWithNext().forEach { (prev, entry) ->
+ // Insert new header if the section has changed between two entries
+ entry.section.takeIf { it != prev.section }?.headerController?.let {
+ children.add(NodeSpecImpl(this, it))
+ }
+ children.add(buildNotifNode(entry, this))
+ }
}
-
notificationIconAreaController.updateNotificationIcons(notifList)
return root
}
- private fun buildNotifNode(entry: ListEntry, parent: NodeSpec): NodeSpec {
- return when (entry) {
- is NotificationEntry -> {
- NodeSpecImpl(parent, viewBarn.requireView(entry))
- }
- is GroupEntry -> {
- val groupNode = NodeSpecImpl(
- parent,
- viewBarn.requireView(checkNotNull(entry.summary)))
-
- for (childEntry in entry.children) {
- groupNode.children.add(buildNotifNode(childEntry, groupNode))
- }
-
- groupNode
- }
- else -> {
- throw RuntimeException("Unexpected entry: $entry")
- }
- }
+ private fun buildNotifNode(entry: ListEntry, parent: NodeSpec): NodeSpec = when (entry) {
+ is NotificationEntry -> NodeSpecImpl(parent, viewBarn.requireView(entry))
+ is GroupEntry -> NodeSpecImpl(parent, viewBarn.requireView(checkNotNull(entry.summary)))
+ .apply { entry.children.forEach { children.add(buildNotifNode(it, this)) } }
+ else -> throw RuntimeException("Unexpected entry: $entry")
}
}
@@ -91,12 +79,11 @@
private val viewBarn: NotifViewBarn,
private val notificationIconAreaController: NotificationIconAreaController
) {
- fun create(listContainer: NotificationListContainer): ShadeViewManager {
- return ShadeViewManager(
- context,
- listContainer,
- logger,
- viewBarn,
- notificationIconAreaController)
- }
+ fun create(listContainer: NotificationListContainer) =
+ ShadeViewManager(
+ context,
+ listContainer,
+ logger,
+ viewBarn,
+ notificationIconAreaController)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
new file mode 100644
index 0000000..179d49c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2020 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.systemui.statusbar.notification.dagger
+
+import android.annotation.StringRes
+import android.content.Intent
+import android.provider.Settings
+import android.view.View
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
+import com.android.systemui.statusbar.notification.collection.render.SectionHeaderNodeControllerImpl
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Module
+import dagger.Provides
+import dagger.Subcomponent
+import javax.inject.Provider
+import javax.inject.Qualifier
+import javax.inject.Scope
+
+@Module(subcomponents = [SectionHeaderControllerSubcomponent::class])
+object NotificationSectionHeadersModule {
+
+ @Provides
+ @HeaderClick
+ @JvmStatic fun providesOnHeaderClickListener(
+ activityStarter: ActivityStarter
+ ) = View.OnClickListener {
+ activityStarter.startActivity(
+ Intent(Settings.ACTION_NOTIFICATION_SETTINGS),
+ true /* onlyProvisioned */,
+ true /* dismissShade */,
+ Intent.FLAG_ACTIVITY_SINGLE_TOP)
+ }
+
+ @Provides
+ @IncomingHeader
+ @SysUISingleton
+ @JvmStatic fun providesIncomingHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("incoming header")
+ .headerText(R.string.notification_section_header_incoming)
+ .build()
+
+ @Provides
+ @AlertingHeader
+ @SysUISingleton
+ @JvmStatic fun providesAlertingHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("alerting header")
+ .headerText(R.string.notification_section_header_alerting)
+ .build()
+
+ @Provides
+ @PeopleHeader
+ @SysUISingleton
+ @JvmStatic fun providesPeopleHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("people header")
+ .headerText(R.string.notification_section_header_conversations)
+ .build()
+
+ @Provides
+ @SilentHeader
+ @SysUISingleton
+ @JvmStatic fun providesSilentHeaderSubcomponent(
+ builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+ ) = builder.get()
+ .nodeLabel("silent header")
+ .headerText(R.string.notification_section_header_gentle)
+ .build()
+
+ @Provides
+ @SilentHeader
+ @JvmStatic fun providesSilentHeaderNodeController(
+ @SilentHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @SilentHeader
+ @JvmStatic fun providesSilentHeaderController(
+ @SilentHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+
+ @Provides
+ @AlertingHeader
+ @JvmStatic fun providesAlertingHeaderNodeController(
+ @AlertingHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @AlertingHeader
+ @JvmStatic fun providesAlertingHeaderController(
+ @AlertingHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+
+ @Provides
+ @PeopleHeader
+ @JvmStatic fun providesPeopleHeaderNodeController(
+ @PeopleHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @PeopleHeader
+ @JvmStatic fun providesPeopleHeaderController(
+ @PeopleHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+
+ @Provides
+ @IncomingHeader
+ @JvmStatic fun providesIncomingHeaderNodeController(
+ @IncomingHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.nodeController
+
+ @Provides
+ @IncomingHeader
+ @JvmStatic fun providesIncomingHeaderController(
+ @IncomingHeader subcomponent: SectionHeaderControllerSubcomponent
+ ) = subcomponent.headerController
+}
+
+@Subcomponent(modules = [ SectionHeaderBindingModule::class ])
+@SectionHeaderScope
+interface SectionHeaderControllerSubcomponent {
+
+ val nodeController: NodeController
+ val headerController: SectionHeaderController
+
+ @Subcomponent.Builder
+ interface Builder {
+ fun build(): SectionHeaderControllerSubcomponent
+ @BindsInstance fun nodeLabel(@NodeLabel nodeLabel: String): Builder
+ @BindsInstance fun headerText(@HeaderText @StringRes headerText: Int): Builder
+ }
+}
+
+@Module
+private abstract class SectionHeaderBindingModule {
+ @Binds abstract fun bindsNodeController(impl: SectionHeaderNodeControllerImpl): NodeController
+ @Binds abstract fun bindsSectionHeaderController(
+ impl: SectionHeaderNodeControllerImpl
+ ): SectionHeaderController
+}
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class HeaderText
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class IncomingHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class AlertingHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class SilentHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class PeopleHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class NodeLabel
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class HeaderClick
+
+@Scope
+@Retention(AnnotationRetention.BINARY)
+annotation class SectionHeaderScope
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index e2aae64..2327063 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -88,7 +88,7 @@
/**
* Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
*/
-@Module
+@Module(includes = { NotificationSectionHeadersModule.class })
public interface NotificationsModule {
/** Provides an instance of {@link NotificationEntryManager} */
@SysUISingleton
@@ -205,9 +205,11 @@
Context context,
NotificationGutsManager notificationGutsManager,
NotificationEntryManager notificationEntryManager,
- MetricsLogger metricsLogger) {
+ MetricsLogger metricsLogger,
+ GroupMembershipManager groupMembershipManager) {
return new NotificationBlockingHelperManager(
- context, notificationGutsManager, notificationEntryManager, metricsLogger);
+ context, notificationGutsManager, notificationEntryManager, metricsLogger,
+ groupMembershipManager);
}
/** Provides an instance of {@link GroupMembershipManager} */
@@ -273,7 +275,8 @@
Lazy<NotifCollection> notifCollection,
Lazy<VisualStabilityCoordinator> visualStabilityCoordinator,
NotificationEntryManager entryManager,
- VisualStabilityManager visualStabilityManager) {
+ VisualStabilityManager visualStabilityManager,
+ Lazy<GroupMembershipManager> groupMembershipManagerLazy) {
return featureFlags.isNewNotifPipelineRenderingEnabled()
? new OnUserInteractionCallbackImpl(
pipeline.get(),
@@ -285,7 +288,8 @@
entryManager,
headsUpManager,
statusBarStateController,
- visualStabilityManager);
+ visualStabilityManager,
+ groupMembershipManagerLazy.get());
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 89f7205..adda049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -817,13 +817,6 @@
return mNotificationParent != null;
}
- /**
- * @return whether this notification is the only child in the group summary
- */
- public boolean isOnlyChildInGroup() {
- return mGroupMembershipManager.isOnlyChildInGroup(mEntry);
- }
-
public ExpandableNotificationRow getNotificationParent() {
return mNotificationParent;
}
@@ -1425,14 +1418,6 @@
}
public void performDismiss(boolean fromAccessibility) {
- if (isOnlyChildInGroup()) {
- NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(mEntry);
- if (groupSummary.isClearable()) {
- // If this is the only child in the group, dismiss the group, but don't try to show
- // the blocking helper affordance!
- groupSummary.getRow().performDismiss(fromAccessibility);
- }
- }
dismiss(fromAccessibility);
if (mEntry.isClearable()) {
if (mOnUserInteractionCallback != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
index 9212325..ab78d19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
@@ -28,6 +28,8 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
@@ -48,6 +50,7 @@
private final NotificationGutsManager mNotificationGutsManager;
private final NotificationEntryManager mNotificationEntryManager;
private final MetricsLogger mMetricsLogger;
+ private final GroupMembershipManager mGroupMembershipManager;
/** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */
private ExpandableNotificationRow mBlockingHelperRow;
private Set<String> mNonBlockablePkgs;
@@ -65,7 +68,8 @@
Context context,
NotificationGutsManager notificationGutsManager,
NotificationEntryManager notificationEntryManager,
- MetricsLogger metricsLogger) {
+ MetricsLogger metricsLogger,
+ GroupMembershipManager groupMembershipManager) {
mContext = context;
mNotificationGutsManager = notificationGutsManager;
mNotificationEntryManager = notificationEntryManager;
@@ -73,6 +77,7 @@
mNonBlockablePkgs = new HashSet<>();
Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
com.android.internal.R.array.config_nonBlockableNotificationPackages));
+ mGroupMembershipManager = groupMembershipManager;
}
/**
@@ -92,11 +97,12 @@
// - The row is blockable (i.e. not non-blockable)
// - The dismissed row is a valid group (>1 or 0 children from the same channel)
// or the only child in the group
- if ((row.getEntry().getUserSentiment() == USER_SENTIMENT_NEGATIVE || DEBUG)
+ final NotificationEntry entry = row.getEntry();
+ if ((entry.getUserSentiment() == USER_SENTIMENT_NEGATIVE || DEBUG)
&& mIsShadeExpanded
&& !row.getIsNonblockable()
- && ((!row.isChildInGroup() || row.isOnlyChildInGroup())
- && row.getNumUniqueChannels() <= 1)) {
+ && ((!row.isChildInGroup() || mGroupMembershipManager.isOnlyChildInGroup(entry))
+ && row.getNumUniqueChannels() <= 1)) {
// Dismiss any current blocking helper before continuing forward (only one can be shown
// at a given time).
dismissCurrentBlockingHelper();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 0302b2b..8050fea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -30,7 +30,6 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.ArrayList;
@@ -50,7 +49,6 @@
private ActivatableNotificationView mActivatedChild;
private float mOverScrollTopAmount;
private float mOverScrollBottomAmount;
- private int mSpeedBumpIndex = -1;
private boolean mDozing;
private boolean mHideSensitive;
private float mStackTranslation;
@@ -245,14 +243,6 @@
return top ? mOverScrollTopAmount : mOverScrollBottomAmount;
}
- public int getSpeedBumpIndex() {
- return mSpeedBumpIndex;
- }
-
- public void setSpeedBumpIndex(int shelfIndex) {
- mSpeedBumpIndex = shelfIndex;
- }
-
public SectionProvider getSectionProvider() {
return mSectionProvider;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index ff7793d..4f7e14b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -18,23 +18,21 @@
import android.annotation.ColorInt
import android.annotation.IntDef
import android.annotation.LayoutRes
-import android.content.Intent
-import android.provider.Settings
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.media.KeyguardMediaController
-import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.people.DataListener
-import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter
-import com.android.systemui.statusbar.notification.people.PeopleHubViewBoundary
-import com.android.systemui.statusbar.notification.people.PersonViewModel
-import com.android.systemui.statusbar.notification.people.Subscription
+import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
+import com.android.systemui.statusbar.notification.collection.render.ShadeViewManager
+import com.android.systemui.statusbar.notification.dagger.AlertingHeader
+import com.android.systemui.statusbar.notification.dagger.IncomingHeader
+import com.android.systemui.statusbar.notification.dagger.PeopleHeader
+import com.android.systemui.statusbar.notification.dagger.SilentHeader
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView
@@ -46,19 +44,25 @@
import javax.inject.Inject
/**
- * Manages the boundaries of the two notification sections (high priority and low priority). Also
- * shows/hides the headers for those sections where appropriate.
+ * Manages the boundaries of the notification sections (incoming, conversations, high priority, and
+ * low priority).
+ *
+ * In the legacy notification pipeline, this is responsible for correctly positioning all section
+ * headers after the [NotificationStackScrollLayout] has had notifications added/removed/changed. In
+ * the new pipeline, this is handled as part of the [ShadeViewManager].
*
* TODO: Move remaining sections logic from NSSL into this class.
*/
class NotificationSectionsManager @Inject internal constructor(
- private val activityStarter: ActivityStarter,
private val statusBarStateController: StatusBarStateController,
private val configurationController: ConfigurationController,
- private val peopleHubViewAdapter: PeopleHubViewAdapter,
private val keyguardMediaController: KeyguardMediaController,
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
- private val logger: NotificationSectionsLogger
+ private val logger: NotificationSectionsLogger,
+ @IncomingHeader private val incomingHeaderController: SectionHeaderController,
+ @PeopleHeader private val peopleHeaderController: SectionHeaderController,
+ @AlertingHeader private val alertingHeaderController: SectionHeaderController,
+ @SilentHeader private val silentHeaderController: SectionHeaderController
) : SectionProvider {
private val configurationListener = object : ConfigurationController.ConfigurationListener {
@@ -67,46 +71,25 @@
}
}
- private val peopleHubViewBoundary: PeopleHubViewBoundary = object : PeopleHubViewBoundary {
- override fun setVisible(isVisible: Boolean) {
- if (peopleHubVisible != isVisible) {
- peopleHubVisible = isVisible
- if (initialized) {
- updateSectionBoundaries("PeopleHub visibility changed")
- }
- }
- }
-
- override val associatedViewForClickAnimation: View
- get() = peopleHeaderView!!
-
- override val personViewAdapters: Sequence<DataListener<PersonViewModel?>>
- get() = peopleHeaderView!!.personViewAdapters
- }
-
private lateinit var parent: NotificationStackScrollLayout
private var initialized = false
private var onClearSilentNotifsClickListener: View.OnClickListener? = null
- @get:VisibleForTesting
- var silentHeaderView: SectionHeaderView? = null
- private set
+ @VisibleForTesting
+ val silentHeaderView: SectionHeaderView?
+ get() = silentHeaderController.headerView
- @get:VisibleForTesting
- var alertingHeaderView: SectionHeaderView? = null
- private set
+ @VisibleForTesting
+ val alertingHeaderView: SectionHeaderView?
+ get() = alertingHeaderController.headerView
- @get:VisibleForTesting
- var incomingHeaderView: SectionHeaderView? = null
- private set
+ @VisibleForTesting
+ val incomingHeaderView: SectionHeaderView?
+ get() = incomingHeaderController.headerView
- @get:VisibleForTesting
- var peopleHeaderView: PeopleHubView? = null
- private set
-
- @set:VisibleForTesting
- var peopleHubVisible = false
- private var peopleHubSubscription: Subscription? = null
+ @VisibleForTesting
+ val peopleHeaderView: SectionHeaderView?
+ get() = peopleHeaderController.headerView
@get:VisibleForTesting
var mediaControlsView: MediaHeaderView? = null
@@ -150,34 +133,10 @@
* Reinflates the entire notification header, including all decoration views.
*/
fun reinflateViews(layoutInflater: LayoutInflater) {
- silentHeaderView = reinflateView(
- silentHeaderView, layoutInflater, R.layout.status_bar_notification_section_header
- ).apply {
- setHeaderText(R.string.notification_section_header_gentle)
- setOnHeaderClickListener { onGentleHeaderClick() }
- setOnClearAllClickListener { onClearGentleNotifsClick(it) }
- }
- alertingHeaderView = reinflateView(
- alertingHeaderView, layoutInflater, R.layout.status_bar_notification_section_header
- ).apply {
- setHeaderText(R.string.notification_section_header_alerting)
- setOnHeaderClickListener { onGentleHeaderClick() }
- }
- peopleHubSubscription?.unsubscribe()
- peopleHubSubscription = null
- peopleHeaderView = reinflateView(peopleHeaderView, layoutInflater, R.layout.people_strip)
- .apply {
- setOnHeaderClickListener(View.OnClickListener { onGentleHeaderClick() })
- }
- if (ENABLE_SNOOZED_CONVERSATION_HUB) {
- peopleHubSubscription = peopleHubViewAdapter.bindView(peopleHubViewBoundary)
- }
- incomingHeaderView = reinflateView(
- incomingHeaderView, layoutInflater, R.layout.status_bar_notification_section_header
- ).apply {
- setHeaderText(R.string.notification_section_header_incoming)
- setOnHeaderClickListener { onGentleHeaderClick() }
- }
+ silentHeaderController.reinflateView(parent)
+ alertingHeaderController.reinflateView(parent)
+ peopleHeaderController.reinflateView(parent)
+ incomingHeaderController.reinflateView(parent)
mediaControlsView =
reinflateView(mediaControlsView, layoutInflater, R.layout.keyguard_media_header)
.also(keyguardMediaController::attach)
@@ -296,7 +255,6 @@
// target, but won't be once they are moved / removed after the pass has completed.
val showHeaders = statusBarStateController.state != StatusBarState.KEYGUARD
- val usingPeopleFiltering = sectionsFeatureManager.isFilteringEnabled()
val usingMediaControls = sectionsFeatureManager.isMediaControlsEnabled()
val mediaState = mediaControlsView?.let(::expandableViewHeaderState)
@@ -319,7 +277,6 @@
).filterNotNull()
var peopleNotifsPresent = false
- var lastNotifIndex = 0
var nextBucket: Int? = null
var inIncomingSection = false
@@ -373,30 +330,9 @@
// Check if there are any people notifications
peopleNotifsPresent = peopleNotifsPresent || row.entry.bucket == BUCKET_PEOPLE
-
- if (nextBucket == null) {
- lastNotifIndex = i
- }
nextBucket = row.entry.bucket
}
- if (showHeaders && usingPeopleFiltering && peopleHubVisible) {
- peopleState?.targetPosition = peopleState?.targetPosition
- // Insert the people header even if there are no people visible, in order to
- // show the hub. Put it directly above the next header.
- ?: alertingState?.targetPosition
- ?: gentleState?.targetPosition
- // Put it at the end of the list.
- ?: lastNotifIndex
-
- // Offset the target to account for the current position of the people header.
- peopleState?.targetPosition = peopleState?.currentPosition?.let { current ->
- peopleState.targetPosition?.let { target ->
- if (current < target) target - 1 else target
- }
- }
- }
-
mediaState?.targetPosition = if (usingMediaControls) 0 else null
logger.logStr("New header target positions:")
@@ -420,14 +356,6 @@
.hasActiveClearableNotifications(NotificationStackScrollLayout.ROWS_GENTLE)
setAreThereDismissableGentleNotifs(hasActiveClearableNotifications)
}
- peopleHeaderView?.run {
- canSwipe = showHeaders && peopleHubVisible && !peopleNotifsPresent
- peopleState?.targetPosition?.let { targetPosition ->
- if (targetPosition != peopleState.currentPosition) {
- resetTranslation()
- }
- }
- }
}
private sealed class SectionBounds {
@@ -513,31 +441,13 @@
}
}
- private fun onGentleHeaderClick() {
- val intent = Intent(Settings.ACTION_NOTIFICATION_SETTINGS)
- activityStarter.startActivity(
- intent,
- true,
- true,
- Intent.FLAG_ACTIVITY_SINGLE_TOP)
- }
-
- private fun onClearGentleNotifsClick(v: View) {
- onClearSilentNotifsClickListener?.onClick(v)
- }
-
/** Listener for when the "clear all" button is clicked on the gentle notification header. */
fun setOnClearSilentNotifsClickListener(listener: View.OnClickListener) {
onClearSilentNotifsClickListener = listener
}
- fun hidePeopleRow() {
- peopleHubVisible = false
- updateSectionBoundaries("PeopleHub dismissed")
- }
-
fun setHeaderForegroundColor(@ColorInt color: Int) {
- peopleHeaderView?.setTextColor(color)
+ peopleHeaderView?.setForegroundColor(color)
silentHeaderView?.setForegroundColor(color)
alertingHeaderView?.setForegroundColor(color)
}
@@ -545,7 +455,6 @@
companion object {
private const val TAG = "NotifSectionsManager"
private const val DEBUG = false
- private const val ENABLE_SNOOZED_CONVERSATION_HUB = false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index c24d3fc..e0e3013 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -16,14 +16,10 @@
package com.android.systemui.statusbar.notification.stack;
-import static android.service.notification.NotificationStats.DISMISSAL_SHADE;
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
-import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -49,10 +45,8 @@
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Bundle;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.notification.NotificationListenerService;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -83,8 +77,6 @@
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
import com.android.keyguard.KeyguardSliceView;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
@@ -96,27 +88,20 @@
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
import com.android.systemui.statusbar.EmptyShadeView;
-import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
+import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
-import com.android.systemui.statusbar.notification.collection.NotifCollection;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
-import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -136,7 +121,6 @@
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.ScrollAdapter;
-import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.Assert;
import java.io.FileDescriptor;
@@ -173,7 +157,6 @@
*/
private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1;
private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider;
- private final DynamicPrivacyController mDynamicPrivacyController;
private final SysuiStatusBarStateController mStatusbarStateController;
private ExpandHelper mExpandHelper;
@@ -225,7 +208,6 @@
private int mBottomMargin;
private int mBottomInset = 0;
private float mQsExpansionFraction;
- private int mCurrentUserId;
/**
* The algorithm which calculates the properties for our children
@@ -248,6 +230,9 @@
private boolean mChangePositionInProgress;
private boolean mChildTransferInProgress;
+ private int mSpeedBumpIndex = -1;
+ private boolean mSpeedBumpIndexDirty = true;
+
/**
* The raw amount of the overScroll on the top, which is not rubber-banded.
*/
@@ -444,7 +429,6 @@
private int mMaxDisplayedNotifications = -1;
private int mStatusBarHeight;
private int mMinInteractionHeight;
- private boolean mNoAmbient;
private final Rect mClipRect = new Rect();
private boolean mIsClipped;
private Rect mRequestedClipBounds;
@@ -466,12 +450,7 @@
private int mHeadsUpInset;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private final Rect mTmpRect = new Rect();
- private final FeatureFlags mFeatureFlags;
- private final NotifPipeline mNotifPipeline;
- private final NotifCollection mNotifCollection;
- private final NotificationEntryManager mEntryManager;
- private final IStatusBarService mBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+ private DismissAllAnimationListener mDismissAllAnimationListener;
@VisibleForTesting
protected final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
protected final UiEventLogger mUiEventLogger;
@@ -551,18 +530,13 @@
@Named(VIEW_CONTEXT) Context context,
AttributeSet attrs,
NotificationRoundnessManager notificationRoundnessManager,
- DynamicPrivacyController dynamicPrivacyController,
SysuiStatusBarStateController statusbarStateController,
NotificationSectionsManager notificationSectionsManager,
ForegroundServiceSectionController fgsSectionController,
ForegroundServiceDismissalFeatureController fgsFeatureController,
- FeatureFlags featureFlags,
- NotifPipeline notifPipeline,
- NotificationEntryManager entryManager,
- NotifCollection notifCollection,
- UiEventLogger uiEventLogger,
GroupMembershipManager groupMembershipManager,
- GroupExpansionManager groupExpansionManager
+ GroupExpansionManager groupExpansionManager,
+ UiEventLogger uiEventLogger
) {
super(context, attrs, 0, 0);
Resources res = getResources();
@@ -574,7 +548,8 @@
mSectionsManager.initialize(this, LayoutInflater.from(context));
mSectionsManager.setOnClearSilentNotifsClickListener(v -> {
// Leave the shade open if there will be other notifs left over to clear
- final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
+ final boolean closeShade =
+ !mController.hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
clearNotifications(ROWS_GENTLE, closeShade);
});
mSections = mSectionsManager.createSectionsForBuckets();
@@ -611,37 +586,8 @@
mDebugPaint.setTextSize(25f);
}
mClearAllEnabled = res.getBoolean(R.bool.config_enableNotificationsClearAll);
-
- TunerService tunerService = Dependency.get(TunerService.class);
- tunerService.addTunable((key, newValue) -> {
- if (key.equals(HIGH_PRIORITY)) {
- mHighPriorityBeforeSpeedBump = "1".equals(newValue);
- }
- }, HIGH_PRIORITY);
-
- mFeatureFlags = featureFlags;
- mNotifPipeline = notifPipeline;
- mEntryManager = entryManager;
- mNotifCollection = notifCollection;
- if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
- @Override
- public void onEntryUpdated(NotificationEntry entry) {
- NotificationStackScrollLayout.this.onEntryUpdated(entry);
- }
- });
- } else {
- mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
- @Override
- public void onPreEntryUpdated(NotificationEntry entry) {
- NotificationStackScrollLayout.this.onEntryUpdated(entry);
- }
- });
- }
mGroupMembershipManager = groupMembershipManager;
mGroupExpansionManager = groupExpansionManager;
-
- mDynamicPrivacyController = dynamicPrivacyController;
mStatusbarStateController = statusbarStateController;
initializeForegroundServiceSection(fgsFeatureController);
mUiEventLogger = uiEventLogger;
@@ -705,10 +651,13 @@
if (mFooterView == null) {
return;
}
- boolean showDismissView = mClearAllEnabled && hasActiveClearableNotifications(ROWS_ALL);
- boolean showFooterView = (showDismissView || hasActiveNotifications())
+ // TODO: move this logic to controller, which will invoke updateFooterView directly
+ boolean showDismissView = mClearAllEnabled &&
+ mController.hasActiveClearableNotifications(ROWS_ALL);
+ RemoteInputController remoteInputController = mRemoteInputManager.getController();
+ boolean showFooterView = (showDismissView || mController.hasActiveNotifications())
&& mStatusBarState != StatusBarState.KEYGUARD
- && !mRemoteInputManager.getController().isRemoteInputActive();
+ && (remoteInputController == null || !remoteInputController.isRemoteInputActive());
boolean showHistory = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
@@ -719,22 +668,8 @@
* Return whether there are any clearable notifications
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public boolean hasActiveClearableNotifications(@SelectedRows int selection) {
- if (mDynamicPrivacyController.isInLockedDownShade()) {
- return false;
- }
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (!(child instanceof ExpandableNotificationRow)) {
- continue;
- }
- final ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if (row.canViewBeDismissed() && matchesSelection(row, selection)) {
- return true;
- }
- }
- return false;
+ boolean hasActiveClearableNotifications(@SelectedRows int selection) {
+ return mController.hasActiveClearableNotifications(selection);
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -1010,7 +945,33 @@
}
public int getSpeedBumpIndex() {
- return mAmbientState.getSpeedBumpIndex();
+ if (mSpeedBumpIndexDirty) {
+ mSpeedBumpIndexDirty = false;
+ int speedBumpIndex = 0;
+ int currentIndex = 0;
+ final int n = getChildCount();
+ for (int i = 0; i < n; i++) {
+ View view = getChildAt(i);
+ if (view.getVisibility() == View.GONE
+ || !(view instanceof ExpandableNotificationRow)) {
+ continue;
+ }
+ ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+ currentIndex++;
+ boolean beforeSpeedBump;
+ if (mHighPriorityBeforeSpeedBump) {
+ beforeSpeedBump = row.getEntry().getBucket() < BUCKET_SILENT;
+ } else {
+ beforeSpeedBump = !row.getEntry().isAmbient();
+ }
+ if (beforeSpeedBump) {
+ speedBumpIndex = currentIndex;
+ }
+ }
+
+ mSpeedBumpIndex = speedBumpIndex;
+ }
+ return mSpeedBumpIndex;
}
@Override
@@ -1066,12 +1027,6 @@
}
}
- @ShadeViewRefactor(RefactorComponent.ADAPTER)
- private void setSpeedBumpIndex(int newIndex, boolean noAmbient) {
- mAmbientState.setSpeedBumpIndex(newIndex);
- mNoAmbient = noAmbient;
- }
-
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void setChildLocationsChangedListener(
NotificationLogger.OnChildLocationsChangedListener listener) {
@@ -1135,7 +1090,7 @@
} else {
mAmbientState.setScrollY(mOwnScrollY);
}
- mStackScrollAlgorithm.resetViewStates(mAmbientState);
+ mStackScrollAlgorithm.resetViewStates(mAmbientState, getSpeedBumpIndex());
if (!isCurrentlyAnimating() && !mNeedsAnimation) {
applyCurrentState();
} else {
@@ -5270,8 +5225,6 @@
updateFooter();
requestChildrenUpdate();
onUpdateRowStates();
-
- mEntryManager.updateNotifications("StatusBar state changed");
updateVisibility();
}
@@ -5675,10 +5628,6 @@
return mController;
}
- void setCurrentUserid(int userId) {
- mCurrentUserId = userId;
- }
-
void addSwipedOutView(View v) {
mSwipedOutViews.add(v);
}
@@ -5752,6 +5701,14 @@
return mCheckForLeavebehind;
}
+ void setDismissAllAnimationListener(DismissAllAnimationListener dismissAllAnimationListener) {
+ mDismissAllAnimationListener = dismissAllAnimationListener;
+ }
+
+ public void setHighPriorityBeforeSpeedBump(boolean highPriorityBeforeSpeedBump) {
+ mHighPriorityBeforeSpeedBump = highPriorityBeforeSpeedBump;
+ }
+
/**
* A listener that is notified when the empty space below the notifications is clicked on
*/
@@ -5785,32 +5742,11 @@
* @param open Should the fling open or close the overscroll view.
*/
void flingTopOverscroll(float velocity, boolean open);
- }
+ }
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateSpeedBumpIndex() {
- int speedBumpIndex = 0;
- int currentIndex = 0;
- final int N = getChildCount();
- for (int i = 0; i < N; i++) {
- View view = getChildAt(i);
- if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) {
- continue;
- }
- ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- currentIndex++;
- boolean beforeSpeedBump;
- if (mHighPriorityBeforeSpeedBump) {
- beforeSpeedBump = row.getEntry().getBucket() < BUCKET_SILENT;
- } else {
- beforeSpeedBump = !row.getEntry().isAmbient();
- }
- if (beforeSpeedBump) {
- speedBumpIndex = currentIndex;
- }
- }
- boolean noAmbient = speedBumpIndex == N;
- setSpeedBumpIndex(speedBumpIndex, noAmbient);
+ mSpeedBumpIndexDirty = true;
}
/** Updates the indices of the boundaries between sections. */
@@ -5851,7 +5787,7 @@
mSwipeHelper.resetExposedMenuView(animate, force);
}
- private static boolean matchesSelection(
+ static boolean matchesSelection(
ExpandableNotificationRow row,
@SelectedRows int selection) {
switch (selection) {
@@ -6126,7 +6062,7 @@
// --------------------- NotificationEntryManager/NotifPipeline methods ------------------------
- private void onEntryUpdated(NotificationEntry entry) {
+ void onEntryUpdated(NotificationEntry entry) {
// If the row already exists, the user may have performed a dismiss action on the
// notification. Since it's not clearable we should snap it back.
if (entry.rowExists() && !entry.getSbn().isClearable()) {
@@ -6134,73 +6070,17 @@
}
}
- private boolean hasActiveNotifications() {
- if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- return !mNotifPipeline.getShadeList().isEmpty();
- } else {
- return mEntryManager.hasActiveNotifications();
- }
- }
-
/**
* Called after the animations for a "clear all notifications" action has ended.
*/
private void onDismissAllAnimationsEnd(
List<ExpandableNotificationRow> viewsToRemove,
@SelectedRows int selectedRows) {
- if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- if (selectedRows == ROWS_ALL) {
- mNotifCollection.dismissAllNotifications(mCurrentUserId);
- } else {
- final List<Pair<NotificationEntry, DismissedByUserStats>>
- entriesWithRowsDismissedFromShade = new ArrayList<>();
- final int numVisibleEntries = mNotifPipeline.getShadeListCount();
- for (int i = 0; i < viewsToRemove.size(); i++) {
- final NotificationEntry entry = viewsToRemove.get(i).getEntry();
- entriesWithRowsDismissedFromShade.add(
- new Pair<NotificationEntry, DismissedByUserStats>(
- entry,
- getDismissedByUserStats(entry, numVisibleEntries)));
- }
- mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
- }
- } else {
- for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
- if (canChildBeDismissed(rowToRemove)) {
- mEntryManager.performRemoveNotification(
- rowToRemove.getEntry().getSbn(),
- getDismissedByUserStats(
- rowToRemove.getEntry(),
- mEntryManager.getActiveNotificationsCount()),
- NotificationListenerService.REASON_CANCEL_ALL);
- } else {
- rowToRemove.resetTranslation();
- }
- }
- if (selectedRows == ROWS_ALL) {
- try {
- mBarService.onClearAllNotifications(mCurrentUserId);
- } catch (Exception ex) {
- }
- }
+ if (mDismissAllAnimationListener != null) {
+ mDismissAllAnimationListener.onAnimationEnd(viewsToRemove, selectedRows);
}
}
- private DismissedByUserStats getDismissedByUserStats(
- NotificationEntry entry,
- int numVisibleEntries
- ) {
- return new DismissedByUserStats(
- DISMISSAL_SHADE,
- DISMISS_SENTIMENT_NEUTRAL,
- NotificationVisibility.obtain(
- entry.getKey(),
- entry.getRanking().getRank(),
- numVisibleEntries,
- true,
- NotificationLogger.getNotificationLocation(entry)));
- }
-
public void setKeyguardMediaControllorVisible(boolean keyguardMediaControllorVisible) {
mKeyguardMediaControllorVisible = keyguardMediaControllorVisible;
}
@@ -6217,7 +6097,8 @@
/* Only ever called as a consequence of a lockscreen expansion gesture. */
@Override
public boolean onDraggedDown(View startingChild, int dragLengthY) {
- boolean canDragDown = hasActiveNotifications() || mKeyguardMediaControllorVisible;
+ boolean canDragDown =
+ mController.hasActiveNotifications() || mKeyguardMediaControllorVisible;
if (mStatusBarState == StatusBarState.KEYGUARD && canDragDown) {
mLockscreenGestureLogger.write(
MetricsEvent.ACTION_LS_SHADE,
@@ -6235,7 +6116,7 @@
}
return true;
- } else if (mDynamicPrivacyController.isInLockedDownShade()) {
+ } else if (mController.isInLockedDownShade()) {
mStatusbarStateController.setLeaveOpenOnKeyguardHide(true);
mStatusBar.dismissKeyguardThenExecute(() -> false /* dismissAction */,
null /* cancelRunnable */, false /* afterKeyguardGone */);
@@ -6279,7 +6160,7 @@
if (isDragDownAnywhereEnabled()) {
return true;
}
- if (mDynamicPrivacyController.isInLockedDownShade()) {
+ if (mController.isInLockedDownShade()) {
if (view == null) {
// Dragging down is allowed in general
return true;
@@ -6423,7 +6304,7 @@
/** Enum for selecting some or all notification rows (does not included non-notif views). */
@Retention(SOURCE)
@IntDef({ROWS_ALL, ROWS_HIGH_PRIORITY, ROWS_GENTLE})
- public @interface SelectedRows {}
+ @interface SelectedRows {}
/** All rows representing notifs. */
public static final int ROWS_ALL = 0;
/** Only rows where entry.isHighPriority() is true. */
@@ -6465,4 +6346,9 @@
interface KeyguardBypassEnabledProvider {
boolean getBypassEnabled();
}
+
+ interface DismissAllAnimationListener {
+ void onAnimationEnd(
+ List<ExpandableNotificationRow> viewsToRemove, @SelectedRows int selectedRows);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 8d792ab..88b7fab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -16,15 +16,28 @@
package com.android.systemui.statusbar.notification.stack;
+import static android.service.notification.NotificationStats.DISMISSAL_SHADE;
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
+
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnOverscrollTopChangedListener;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.canChildBeDismissed;
+import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.provider.Settings;
+import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
+import android.util.Pair;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
@@ -35,6 +48,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.ExpandHelper;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
@@ -47,6 +62,7 @@
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
import com.android.systemui.statusbar.NotificationShelfController;
@@ -56,11 +72,20 @@
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.ShadeViewRefactor;
+import com.android.systemui.statusbar.notification.collection.NotifCollection;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.NotificationGroup;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.OnGroupChangeListener;
+import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
+import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
+import com.android.systemui.statusbar.notification.dagger.SilentHeader;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -82,6 +107,8 @@
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.BiConsumer;
import javax.inject.Inject;
@@ -110,6 +137,11 @@
private final Resources mResources;
private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
private final ScrimController mScrimController;
+ private final FeatureFlags mFeatureFlags;
+ private final NotifPipeline mNotifPipeline;
+ private final NotifCollection mNotifCollection;
+ private final NotificationEntryManager mNotificationEntryManager;
+ private final IStatusBarService mIStatusBarService;
private final KeyguardMediaController mKeyguardMediaController;
private final SysuiStatusBarStateController mStatusBarStateController;
private final KeyguardBypassController mKeyguardBypassController;
@@ -117,6 +149,7 @@
private final NotificationLockscreenUserManager mLockscreenUserManager;
// TODO: StatusBar should be encapsulated behind a Controller
private final StatusBar mStatusBar;
+ private final SectionHeaderController mSilentHeaderController;
private NotificationStackScrollLayout mView;
private boolean mFadeNotificationsOnDismiss;
@@ -206,13 +239,13 @@
mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(),
mLockscreenUserManager.isAnyProfilePublicMode());
mView.onStatePostChange(mStatusBarStateController.fromShadeLocked());
+ mNotificationEntryManager.updateNotifications("StatusBar state changed");
}
};
private final UserChangedListener mLockscreenUserChangeListener = new UserChangedListener() {
@Override
public void onUserChanged(int userId) {
- mView.setCurrentUserid(userId);
mView.updateSensitiveness(false, mLockscreenUserManager.isAnyProfilePublicMode());
}
};
@@ -359,10 +392,6 @@
row.performDismissWithBlockingHelper(false /* fromAccessibility */);
}
- if (view instanceof PeopleHubView) {
- mNotificationSectionsManager.hidePeopleRow();
- }
-
if (!isBlockingHelperShown) {
mView.addSwipedOutView(view);
}
@@ -523,7 +552,13 @@
StatusBar statusBar,
ScrimController scrimController,
NotificationGroupManagerLegacy legacyGroupManager,
- GroupExpansionManager groupManager) {
+ GroupExpansionManager groupManager,
+ @SilentHeader SectionHeaderController silentHeaderController,
+ FeatureFlags featureFlags,
+ NotifPipeline notifPipeline,
+ NotifCollection notifCollection,
+ NotificationEntryManager notificationEntryManager,
+ IStatusBarService iStatusBarService) {
mAllowLongPress = allowLongPress;
mNotificationGutsManager = notificationGutsManager;
mHeadsUpManager = headsUpManager;
@@ -547,7 +582,6 @@
groupManager.registerGroupExpansionChangeListener((changedRow, expanded) -> {
mView.onGroupExpandChanged(changedRow, expanded);
});
-
legacyGroupManager.registerGroupChangeListener(new OnGroupChangeListener() {
@Override
public void onGroupCreatedFromChildren(NotificationGroup group) {
@@ -559,6 +593,12 @@
mStatusBar.requestNotificationUpdate("onGroupsChanged");
}
});
+ mSilentHeaderController = silentHeaderController;
+ mFeatureFlags = featureFlags;
+ mNotifPipeline = notifPipeline;
+ mNotifCollection = notifCollection;
+ mNotificationEntryManager = notificationEntryManager;
+ mIStatusBarService = iStatusBarService;
}
public void attach(NotificationStackScrollLayout view) {
@@ -566,6 +606,7 @@
mView.setController(this);
mView.setTouchHandler(new TouchHandler());
mView.setStatusBar(mStatusBar);
+ mView.setDismissAllAnimationListener(this::onAnimationEnd);
mSwipeHelper = mNotificationSwipeHelperBuilder
.setSwipeDirection(SwipeHelper.X)
@@ -573,6 +614,22 @@
.setOnMenuEventListener(mMenuEventListener)
.build();
+ if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
+ mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
+ @Override
+ public void onEntryUpdated(NotificationEntry entry) {
+ mView.onEntryUpdated(entry);
+ }
+ });
+ } else {
+ mNotificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
+ @Override
+ public void onPreEntryUpdated(NotificationEntry entry) {
+ mView.onEntryUpdated(entry);
+ }
+ });
+ }
+
mView.initView(mView.getContext(), mKeyguardBypassController::getBypassEnabled,
mSwipeHelper);
@@ -584,7 +641,6 @@
mScrimController.setScrimBehindChangeRunnable(mView::updateBackgroundDimming);
mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
- mView.setCurrentUserid(mLockscreenUserManager.getCurrentUserId());
mFadeNotificationsOnDismiss = // TODO: this should probably be injected directly
mResources.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
@@ -594,12 +650,19 @@
mTunerService.addTunable(
(key, newValue) -> {
- if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
- mView.updateDismissRtlSetting("1".equals(newValue));
- } else if (key.equals(Settings.Secure.NOTIFICATION_HISTORY_ENABLED)) {
- updateFooter();
+ switch (key) {
+ case Settings.Secure.NOTIFICATION_DISMISS_RTL:
+ mView.updateDismissRtlSetting("1".equals(newValue));
+ break;
+ case Settings.Secure.NOTIFICATION_HISTORY_ENABLED:
+ updateFooter();
+ break;
+ case HIGH_PRIORITY:
+ mView.setHighPriorityBeforeSpeedBump("1".equals(newValue));
+ break;
}
},
+ HIGH_PRIORITY,
Settings.Secure.NOTIFICATION_DISMISS_RTL,
Settings.Secure.NOTIFICATION_HISTORY_ENABLED);
@@ -624,6 +687,7 @@
mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
}
mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+ mSilentHeaderController.setOnClearAllClickListener(v -> clearSilentNotifications());
}
public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
@@ -680,12 +744,12 @@
}
public void setOverscrollTopChangedListener(
- NotificationStackScrollLayout.OnOverscrollTopChangedListener listener) {
+ OnOverscrollTopChangedListener listener) {
mView.setOverscrollTopChangedListener(listener);
}
public void setOnEmptySpaceClickListener(
- NotificationStackScrollLayout.OnEmptySpaceClickListener listener) {
+ OnEmptySpaceClickListener listener) {
mView.setOnEmptySpaceClickListener(listener);
}
@@ -713,6 +777,10 @@
return mView.getWakeUpHeight();
}
+ public int getSpeedBumpIndex() {
+ return mView.getSpeedBumpIndex();
+ }
+
public void setHideAmount(float linearAmount, float amount) {
mView.setHideAmount(linearAmount, amount);
}
@@ -999,9 +1067,26 @@
mView.setPulsing(pulsing, animatePulse);
}
- public boolean hasActiveClearableNotifications(
- @NotificationStackScrollLayout.SelectedRows int selection) {
- return mView.hasActiveClearableNotifications(selection);
+ /**
+ * Return whether there are any clearable notifications
+ */
+ public boolean hasActiveClearableNotifications(@SelectedRows int selection) {
+ if (mDynamicPrivacyController.isInLockedDownShade()) {
+ return false;
+ }
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (!(child instanceof ExpandableNotificationRow)) {
+ continue;
+ }
+ final ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ if (row.canViewBeDismissed() &&
+ NotificationStackScrollLayout.matchesSelection(row, selection)) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -1112,6 +1197,29 @@
mView.resetCheckSnoozeLeavebehind();
}
+ private DismissedByUserStats getDismissedByUserStats(
+ NotificationEntry entry,
+ int numVisibleEntries
+ ) {
+ return new DismissedByUserStats(
+ DISMISSAL_SHADE,
+ DISMISS_SENTIMENT_NEUTRAL,
+ NotificationVisibility.obtain(
+ entry.getKey(),
+ entry.getRanking().getRank(),
+ numVisibleEntries,
+ true,
+ NotificationLogger.getNotificationLocation(entry)));
+ }
+
+ boolean hasActiveNotifications() {
+ if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
+ return !mNotifPipeline.getShadeList().isEmpty();
+ } else {
+ return mNotificationEntryManager.hasActiveNotifications();
+ }
+ }
+
public void closeControlsIfOutsideTouch(MotionEvent ev) {
NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
@@ -1134,6 +1242,57 @@
}
}
+ public void clearSilentNotifications() {
+ // Leave the shade open if there will be other notifs left over to clear
+ final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
+ mView.clearNotifications(ROWS_GENTLE, closeShade);
+ }
+
+ private void onAnimationEnd(List<ExpandableNotificationRow> viewsToRemove, int selectedRows) {
+ if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
+ if (selectedRows == ROWS_ALL) {
+ mNotifCollection.dismissAllNotifications(
+ mLockscreenUserManager.getCurrentUserId());
+ } else {
+ final List<Pair<NotificationEntry, DismissedByUserStats>>
+ entriesWithRowsDismissedFromShade = new ArrayList<>();
+ final int numVisibleEntries = mNotifPipeline.getShadeListCount();
+ for (ExpandableNotificationRow row : viewsToRemove) {
+ final NotificationEntry entry = row.getEntry();
+ entriesWithRowsDismissedFromShade.add(
+ new Pair<>(
+ entry,
+ getDismissedByUserStats(entry, numVisibleEntries)));
+ }
+ mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
+ }
+ } else {
+ for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
+ if (canChildBeDismissed(rowToRemove)) {
+ mNotificationEntryManager.performRemoveNotification(
+ rowToRemove.getEntry().getSbn(),
+ getDismissedByUserStats(
+ rowToRemove.getEntry(),
+ mNotificationEntryManager.getActiveNotificationsCount()),
+ NotificationListenerService.REASON_CANCEL_ALL);
+ } else {
+ rowToRemove.resetTranslation();
+ }
+ }
+ if (selectedRows == ROWS_ALL) {
+ try {
+ mIStatusBarService.onClearAllNotifications(
+ mLockscreenUserManager.getCurrentUserId());
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ }
+
+ public boolean isInLockedDownShade() {
+ return mDynamicPrivacyController.isInLockedDownShade();
+ }
+
private class NotificationListContainerImpl implements NotificationListContainer {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
index 5777ba1..99ec7548 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
@@ -97,7 +97,7 @@
/**
* Fired whenever the user clicks on the body of the header (e.g. no sub-buttons or anything).
*/
- void setOnHeaderClickListener(View.OnClickListener listener) {
+ public void setOnHeaderClickListener(View.OnClickListener listener) {
mLabelClickListener = listener;
mLabelView.setOnClickListener(listener);
}
@@ -112,7 +112,7 @@
}
/** Fired when the user clicks on the "X" button on the far right of the header. */
- void setOnClearAllClickListener(View.OnClickListener listener) {
+ public void setOnClearAllClickListener(View.OnClickListener listener) {
mOnClearClickListener = listener;
mClearAllButton.setOnClickListener(listener);
}
@@ -122,7 +122,8 @@
return true;
}
- void setHeaderText(@StringRes int resId) {
+ /** Sets text to be displayed in the header */
+ public void setHeaderText(@StringRes int resId) {
mLabelTextId = resId;
mLabelView.setText(resId);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 541c784..95edfe3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -91,7 +91,7 @@
/**
* Updates the state of all children in the hostview based on this algorithm.
*/
- public void resetViewStates(AmbientState ambientState) {
+ public void resetViewStates(AmbientState ambientState, int speedBumpIndex) {
// The state of the local variables are saved in an algorithmState to easily subdivide it
// into multiple phases.
StackScrollAlgorithmState algorithmState = mTempAlgorithmState;
@@ -110,7 +110,7 @@
updateDimmedActivatedHideSensitive(ambientState, algorithmState);
updateClipping(algorithmState, ambientState);
- updateSpeedBumpState(algorithmState, ambientState);
+ updateSpeedBumpState(algorithmState, speedBumpIndex);
updateShelfState(ambientState);
getNotificationChildrenStates(algorithmState, ambientState);
}
@@ -136,9 +136,9 @@
}
private void updateSpeedBumpState(StackScrollAlgorithmState algorithmState,
- AmbientState ambientState) {
+ int speedBumpIndex) {
int childCount = algorithmState.visibleChildren.size();
- int belowSpeedBump = ambientState.getSpeedBumpIndex();
+ int belowSpeedBump = speedBumpIndex;
for (int i = 0; i < childCount; i++) {
ExpandableView child = algorithmState.visibleChildren.get(i);
ExpandableViewState childViewState = child.getViewState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 09034c0..3665c39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -25,26 +25,21 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
-import android.util.MathUtils;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.view.WindowInsets;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardHostViewController;
+import com.android.keyguard.KeyguardRootViewController;
import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardSecurityView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.keyguard.dagger.ContainerView;
-import com.android.keyguard.dagger.KeyguardBouncerScope;
+import com.android.keyguard.dagger.KeyguardBouncerComponent;
+import com.android.keyguard.dagger.RootView;
import com.android.systemui.DejankUtils;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.system.SysUiStatsLog;
@@ -57,18 +52,16 @@
/**
* A class which manages the bouncer on the lockscreen.
*/
-@KeyguardBouncerScope
public class KeyguardBouncer {
private static final String TAG = "KeyguardBouncer";
static final long BOUNCER_FACE_DELAY = 1200;
- static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
+ public static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
static final float EXPANSION_HIDDEN = 1f;
static final float EXPANSION_VISIBLE = 0f;
protected final Context mContext;
protected final ViewMediatorCallback mCallback;
- protected final LockPatternUtils mLockPatternUtils;
protected final ViewGroup mContainer;
private final FalsingManager mFalsingManager;
private final DismissCallbackRegistry mDismissCallbackRegistry;
@@ -76,6 +69,8 @@
private final BouncerExpansionCallback mExpansionCallback;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final KeyguardStateController mKeyguardStateController;
+ private final KeyguardSecurityModel mKeyguardSecurityModel;
+ private final KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -85,32 +80,33 @@
};
private final Runnable mRemoveViewRunnable = this::removeView;
private final KeyguardBypassController mKeyguardBypassController;
- protected KeyguardHostView mKeyguardView;
+ private KeyguardHostViewController mKeyguardViewController;
private final Runnable mResetRunnable = ()-> {
- if (mKeyguardView != null) {
- mKeyguardView.resetSecurityContainer();
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.resetSecurityContainer();
}
};
private int mStatusBarHeight;
private float mExpansion = EXPANSION_HIDDEN;
protected ViewGroup mRoot;
+ private KeyguardRootViewController mRootViewController;
private boolean mShowingSoon;
private int mBouncerPromptReason;
private boolean mIsAnimatingAway;
private boolean mIsScrimmed;
- @Inject
- public KeyguardBouncer(Context context, ViewMediatorCallback callback,
- LockPatternUtils lockPatternUtils, @ContainerView ViewGroup container,
+ private KeyguardBouncer(Context context, ViewMediatorCallback callback,
+ ViewGroup container,
DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager,
BouncerExpansionCallback expansionCallback,
KeyguardStateController keyguardStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- KeyguardBypassController keyguardBypassController, Handler handler) {
+ KeyguardBypassController keyguardBypassController, Handler handler,
+ KeyguardSecurityModel keyguardSecurityModel,
+ KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory) {
mContext = context;
mCallback = callback;
- mLockPatternUtils = lockPatternUtils;
mContainer = container;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mFalsingManager = falsingManager;
@@ -118,6 +114,8 @@
mExpansionCallback = expansionCallback;
mHandler = handler;
mKeyguardStateController = keyguardStateController;
+ mKeyguardSecurityModel = keyguardSecurityModel;
+ mKeyguardBouncerComponentFactory = keyguardBouncerComponentFactory;
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
mKeyguardBypassController = keyguardBypassController;
}
@@ -168,7 +166,7 @@
// If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern) is
// set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.
- if (allowDismissKeyguard && mKeyguardView.dismiss(activeUserId)) {
+ if (allowDismissKeyguard && mKeyguardViewController.dismiss(activeUserId)) {
return;
}
@@ -204,12 +202,13 @@
*/
private void onFullyShown() {
mFalsingManager.onBouncerShown();
- if (mKeyguardView == null) {
+ if (mKeyguardViewController == null) {
Log.wtf(TAG, "onFullyShown when view was null");
} else {
- mKeyguardView.onResume();
+ mKeyguardViewController.onResume();
if (mRoot != null) {
- mRoot.announceForAccessibility(mKeyguardView.getAccessibilityTitleForCurrentMode());
+ mRoot.announceForAccessibility(
+ mKeyguardViewController.getAccessibilityTitleForCurrentMode());
}
}
}
@@ -233,28 +232,13 @@
showPromptReason(mBouncerPromptReason);
final CharSequence customMessage = mCallback.consumeCustomMessage();
if (customMessage != null) {
- mKeyguardView.showErrorMessage(customMessage);
+ mKeyguardViewController.showErrorMessage(customMessage);
}
- // We might still be collapsed and the view didn't have time to layout yet or still
- // be small, let's wait on the predraw to do the animation in that case.
- if (mKeyguardView.getHeight() != 0 && mKeyguardView.getHeight() != mStatusBarHeight) {
- mKeyguardView.startAppearAnimation();
- } else {
- mKeyguardView.getViewTreeObserver().addOnPreDrawListener(
- new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- mKeyguardView.getViewTreeObserver().removeOnPreDrawListener(this);
- mKeyguardView.startAppearAnimation();
- return true;
- }
- });
- mKeyguardView.requestLayout();
- }
+ mKeyguardViewController.appear(mStatusBarHeight);
mShowingSoon = false;
if (mExpansion == EXPANSION_VISIBLE) {
- mKeyguardView.onResume();
- mKeyguardView.resetSecurityContainer();
+ mKeyguardViewController.onResume();
+ mKeyguardViewController.resetSecurityContainer();
showPromptReason(mBouncerPromptReason);
}
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,
@@ -270,16 +254,16 @@
* and {@link KeyguardSecurityView#PROMPT_REASON_RESTART}
*/
public void showPromptReason(int reason) {
- if (mKeyguardView != null) {
- mKeyguardView.showPromptReason(reason);
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.showPromptReason(reason);
} else {
Log.w(TAG, "Trying to show prompt reason on empty bouncer");
}
}
public void showMessage(String message, ColorStateList colorState) {
- if (mKeyguardView != null) {
- mKeyguardView.showMessage(message, colorState);
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.showMessage(message, colorState);
} else {
Log.w(TAG, "Trying to show message on empty bouncer");
}
@@ -293,7 +277,7 @@
public void showWithDismissAction(OnDismissAction r, Runnable cancelAction) {
ensureView();
- mKeyguardView.setOnDismissAction(r, cancelAction);
+ mKeyguardViewController.setOnDismissAction(r, cancelAction);
show(false /* resetSecuritySelection */);
}
@@ -307,9 +291,9 @@
mFalsingManager.onBouncerHidden();
mCallback.onBouncerVisiblityChanged(false /* shown */);
cancelShowRunnable();
- if (mKeyguardView != null) {
- mKeyguardView.cancelDismissAction();
- mKeyguardView.cleanUp();
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.cancelDismissAction();
+ mKeyguardViewController.cleanUp();
}
mIsAnimatingAway = false;
if (mRoot != null) {
@@ -328,8 +312,8 @@
*/
public void startPreHideAnimation(Runnable runnable) {
mIsAnimatingAway = true;
- if (mKeyguardView != null) {
- mKeyguardView.startDisappearAnimation(runnable);
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.startDisappearAnimation(runnable);
} else if (runnable != null) {
runnable.run();
}
@@ -345,8 +329,9 @@
}
public void onScreenTurnedOff() {
- if (mKeyguardView != null && mRoot != null && mRoot.getVisibility() == View.VISIBLE) {
- mKeyguardView.onPause();
+ if (mKeyguardViewController != null
+ && mRoot != null && mRoot.getVisibility() == View.VISIBLE) {
+ mKeyguardViewController.onPause();
}
}
@@ -380,7 +365,7 @@
}
private void showPrimarySecurityScreen() {
- mKeyguardView.showPrimarySecurityScreen();
+ mKeyguardViewController.showPrimarySecurityScreen();
}
/**
@@ -391,10 +376,8 @@
public void setExpansion(float fraction) {
float oldExpansion = mExpansion;
mExpansion = fraction;
- if (mKeyguardView != null && !mIsAnimatingAway) {
- float alpha = MathUtils.map(ALPHA_EXPANSION_THRESHOLD, 1, 1, 0, fraction);
- mKeyguardView.setAlpha(MathUtils.constrain(alpha, 0f, 1f));
- mKeyguardView.setTranslationY(fraction * mKeyguardView.getHeight());
+ if (mKeyguardViewController != null && !mIsAnimatingAway) {
+ mKeyguardViewController.setExpansion(fraction);
}
if (fraction == EXPANSION_VISIBLE && oldExpansion != EXPANSION_VISIBLE) {
@@ -405,28 +388,22 @@
mExpansionCallback.onFullyHidden();
} else if (fraction != EXPANSION_VISIBLE && oldExpansion == EXPANSION_VISIBLE) {
mExpansionCallback.onStartingToHide();
- if (mKeyguardView != null) {
- mKeyguardView.onStartingToHide();
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.onStartingToHide();
}
}
}
public boolean willDismissWithAction() {
- return mKeyguardView != null && mKeyguardView.hasDismissActions();
+ return mKeyguardViewController != null && mKeyguardViewController.hasDismissActions();
}
public int getTop() {
- if (mKeyguardView == null) {
+ if (mKeyguardViewController == null) {
return 0;
}
- int top = mKeyguardView.getTop();
- // The password view has an extra top padding that should be ignored.
- if (mKeyguardView.getCurrentSecurityMode() == SecurityMode.Password) {
- View messageArea = mKeyguardView.findViewById(R.id.keyguard_message_area);
- top += messageArea.getTop();
- }
- return top;
+ return mKeyguardViewController.getTop();
}
protected void ensureView() {
@@ -442,10 +419,13 @@
protected void inflateView() {
removeView();
mHandler.removeCallbacks(mRemoveViewRunnable);
- mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
- mKeyguardView = mRoot.findViewById(R.id.keyguard_host_view);
- mKeyguardView.setLockPatternUtils(mLockPatternUtils);
- mKeyguardView.setViewMediatorCallback(mCallback);
+ KeyguardBouncerComponent component = mKeyguardBouncerComponentFactory.create();
+ mRootViewController = component.getKeyguardRootViewController();
+ mRootViewController.init();
+ mRoot = mRootViewController.getView(); // TODO(b/166448040): Don't access root view here.
+ mKeyguardViewController = component.getKeyguardHostViewController();
+ mKeyguardViewController.init();
+
mContainer.addView(mRoot, mContainer.getChildCount());
mStatusBarHeight = mRoot.getResources().getDimensionPixelOffset(
com.android.systemui.R.dimen.status_bar_height);
@@ -465,7 +445,7 @@
}
public boolean onBackPressed() {
- return mKeyguardView != null && mKeyguardView.handleBackKey();
+ return mKeyguardViewController != null && mKeyguardViewController.handleBackKey();
}
/**
@@ -473,7 +453,7 @@
* notifications on Keyguard, like SIM PIN/PUK.
*/
public boolean needsFullscreenBouncer() {
- SecurityMode mode = Dependency.get(KeyguardSecurityModel.class).getSecurityMode(
+ SecurityMode mode = mKeyguardSecurityModel.getSecurityMode(
KeyguardUpdateMonitor.getCurrentUser());
return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
}
@@ -483,8 +463,8 @@
* makes this method much faster.
*/
public boolean isFullscreenBouncer() {
- if (mKeyguardView != null) {
- SecurityMode mode = mKeyguardView.getCurrentSecurityMode();
+ if (mKeyguardViewController != null) {
+ SecurityMode mode = mKeyguardViewController.getCurrentSecurityMode();
return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
}
return false;
@@ -494,21 +474,22 @@
* WARNING: This method might cause Binder calls.
*/
public boolean isSecure() {
- return mKeyguardView == null || mKeyguardView.getSecurityMode() != SecurityMode.None;
+ return mKeyguardSecurityModel.getSecurityMode(
+ KeyguardUpdateMonitor.getCurrentUser()) != SecurityMode.None;
}
public boolean shouldDismissOnMenuPressed() {
- return mKeyguardView.shouldEnableMenuKey();
+ return mKeyguardViewController.shouldEnableMenuKey();
}
public boolean interceptMediaKey(KeyEvent event) {
ensureView();
- return mKeyguardView.interceptMediaKey(event);
+ return mKeyguardViewController.interceptMediaKey(event);
}
public void notifyKeyguardAuthenticated(boolean strongAuth) {
ensureView();
- mKeyguardView.finish(strongAuth, KeyguardUpdateMonitor.getCurrentUser());
+ mKeyguardViewController.finish(strongAuth, KeyguardUpdateMonitor.getCurrentUser());
}
public void dump(PrintWriter pw) {
@@ -516,8 +497,8 @@
pw.println(" isShowing(): " + isShowing());
pw.println(" mStatusBarHeight: " + mStatusBarHeight);
pw.println(" mExpansion: " + mExpansion);
- pw.println(" mKeyguardView; " + mKeyguardView);
- pw.println(" mShowingSoon: " + mKeyguardView);
+ pw.println(" mKeyguardViewController; " + mKeyguardViewController);
+ pw.println(" mShowingSoon: " + mShowingSoon);
pw.println(" mBouncerPromptReason: " + mBouncerPromptReason);
pw.println(" mIsAnimatingAway: " + mIsAnimatingAway);
}
@@ -528,4 +509,46 @@
void onStartingToShow();
void onFullyHidden();
}
+
+ /** Create a {@link KeyguardBouncer} once a container and bouncer callback are available. */
+ public static class Factory {
+ private final Context mContext;
+ private final ViewMediatorCallback mCallback;
+ private final DismissCallbackRegistry mDismissCallbackRegistry;
+ private final FalsingManager mFalsingManager;
+ private final KeyguardStateController mKeyguardStateController;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final KeyguardBypassController mKeyguardBypassController;
+ private final Handler mHandler;
+ private final KeyguardSecurityModel mKeyguardSecurityModel;
+ private final KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+
+ @Inject
+ public Factory(Context context, ViewMediatorCallback callback,
+ DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager,
+ KeyguardStateController keyguardStateController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ KeyguardBypassController keyguardBypassController, Handler handler,
+ KeyguardSecurityModel keyguardSecurityModel,
+ KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory) {
+ mContext = context;
+ mCallback = callback;
+ mDismissCallbackRegistry = dismissCallbackRegistry;
+ mFalsingManager = falsingManager;
+ mKeyguardStateController = keyguardStateController;
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mKeyguardBypassController = keyguardBypassController;
+ mHandler = handler;
+ mKeyguardSecurityModel = keyguardSecurityModel;
+ mKeyguardBouncerComponentFactory = keyguardBouncerComponentFactory;
+ }
+
+ public KeyguardBouncer create(@RootView ViewGroup container,
+ BouncerExpansionCallback expansionCallback) {
+ return new KeyguardBouncer(mContext, mCallback, container,
+ mDismissCallbackRegistry, mFalsingManager, expansionCallback,
+ mKeyguardStateController, mKeyguardUpdateMonitor, mKeyguardBypassController,
+ mHandler, mKeyguardSecurityModel, mKeyguardBouncerComponentFactory);
+ }
+ }
}
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 2986727..31c1a5e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -177,7 +177,6 @@
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.CommandQueue;
@@ -231,6 +230,7 @@
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.volume.VolumeComponent;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.FileDescriptor;
import java.io.PrintWriter;
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 b56993b..51209d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -44,7 +44,6 @@
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.systemui.DejankUtils;
import com.android.systemui.dagger.SysUISingleton;
@@ -104,7 +103,7 @@
private final NavigationModeController mNavigationModeController;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final Optional<FaceAuthScreenBrightnessController> mFaceAuthScreenBrightnessController;
- private final KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+ private final KeyguardBouncer.Factory mKeyguardBouncerFactory;
private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() {
@Override
public void onFullyShown() {
@@ -216,7 +215,7 @@
KeyguardStateController keyguardStateController,
Optional<FaceAuthScreenBrightnessController> faceAuthScreenBrightnessController,
NotificationMediaManager notificationMediaManager,
- KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory) {
+ KeyguardBouncer.Factory keyguardBouncerFactory) {
mContext = context;
mViewMediatorCallback = callback;
mLockPatternUtils = lockPatternUtils;
@@ -229,7 +228,7 @@
mStatusBarStateController = sysuiStatusBarStateController;
mDockManager = dockManager;
mFaceAuthScreenBrightnessController = faceAuthScreenBrightnessController;
- mKeyguardBouncerComponentFactory = keyguardBouncerComponentFactory;
+ mKeyguardBouncerFactory = keyguardBouncerFactory;
}
@Override
@@ -246,9 +245,7 @@
mLastLockVisible = mLockIconContainer.getVisibility() == View.VISIBLE;
}
mBiometricUnlockController = biometricUnlockController;
- mBouncer = mKeyguardBouncerComponentFactory
- .build(container, mExpansionCallback)
- .createKeyguardBouncer();
+ mBouncer = mKeyguardBouncerFactory.create(container, mExpansionCallback);
mNotificationPanelViewController = notificationPanelViewController;
notificationPanelViewController.addExpansionListener(this);
mBypassController = bypassController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index f806567..737cdeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -281,17 +281,10 @@
// TODO: Some of this code may be able to move to NotificationEntryManager.
removeHUN(row);
- NotificationEntry parentToCancel = null;
- if (shouldAutoCancel(entry.getSbn()) && mGroupMembershipManager.isOnlyChildInGroup(entry)) {
- NotificationEntry summarySbn = mGroupMembershipManager.getLogicalGroupSummary(entry);
- if (shouldAutoCancel(summarySbn.getSbn())) {
- parentToCancel = summarySbn;
- }
- }
- final NotificationEntry parentToCancelFinal = parentToCancel;
+
final Runnable runnable = () -> handleNotificationClickAfterPanelCollapsed(
entry, row, controller, intent,
- isActivityIntent, wasOccluded, parentToCancelFinal);
+ isActivityIntent, wasOccluded);
if (showOverLockscreen) {
mShadeController.addPostCollapseAction(runnable);
@@ -312,8 +305,7 @@
RemoteInputController controller,
PendingIntent intent,
boolean isActivityIntent,
- boolean wasOccluded,
- NotificationEntry parentToCancelFinal) {
+ boolean wasOccluded) {
String notificationKey = entry.getKey();
mLogger.logHandleClickAfterPanelCollapsed(notificationKey);
@@ -373,22 +365,23 @@
NotificationLogger.getNotificationLocation(entry);
final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
rank, count, true, location);
+
+ // NMS will officially remove notification if the notification has FLAG_AUTO_CANCEL:
mClickNotifier.onNotificationClick(notificationKey, nv);
- if (!canBubble) {
- if (parentToCancelFinal != null) {
- // TODO: (b/145659174) remove - this cancels the parent if the notification clicked
- // on will auto-cancel and is the only child in the group. This won't be
- // necessary in the new pipeline due to group pruning in ShadeListBuilder.
- removeNotification(parentToCancelFinal);
- }
+ // TODO (b/162832756): delete these notification removals when migrating to the new
+ // pipeline; this is taken care of in {@link NotifCollection#tryRemoveNotification}
+ // which cancels lifetime extenders if the notification was dismissed by the user (ie:
+ // clicked or manually dismissed)
+ if (!canBubble && !mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
if (shouldAutoCancel(entry.getSbn())
|| mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
notificationKey)) {
- // Automatically remove all notifications that we may have kept around longer
+ // manually call notification removal in order to cancel any lifetime extenders
removeNotification(row.getEntry());
}
}
+
mIsCollapsingToShowActivityOverLockscreen = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 16c3dc4..b7f8314 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -46,7 +46,6 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -99,6 +98,7 @@
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.volume.VolumeComponent;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
import java.util.concurrent.Executor;
diff --git a/packages/SystemUI/src/com/android/systemui/util/ViewController.java b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
new file mode 100644
index 0000000..64f8dbb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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.systemui.util;
+
+import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
+
+/**
+ * Utility class that handles view lifecycle events for View Controllers.
+ *
+ * Implementations should handle setup and teardown related activities inside of
+ * {@link #onViewAttached()} and {@link #onViewDetached()}.
+ *
+ * @param <T> View class that this ViewController is for.
+ */
+public abstract class ViewController<T extends View> {
+ protected final T mView;
+ private boolean mInited;
+
+ private OnAttachStateChangeListener mOnAttachStateListener = new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ ViewController.this.onViewAttached();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ ViewController.this.onViewDetached();
+ }
+ };
+
+ protected ViewController(T view) {
+ mView = view;
+ }
+
+ /** Call immediately after constructing Controller in order to handle view lifecycle events. */
+ public void init() {
+ if (mInited) {
+ return;
+ }
+ mInited = true;
+
+ if (mView.isAttachedToWindow()) {
+ mOnAttachStateListener.onViewAttachedToWindow(mView);
+ }
+ mView.addOnAttachStateChangeListener(mOnAttachStateListener);
+ }
+
+ /**
+ * Called when the view is attached and a call to {@link #init()} has been made in either order.
+ */
+ protected abstract void onViewAttached();
+
+ /**
+ * Called when the view is detached.
+ */
+ protected abstract void onViewDetached();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
index d8cb280..0869cf7 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
@@ -31,13 +31,13 @@
import com.android.systemui.pip.tv.PipController;
import com.android.systemui.pip.tv.PipNotification;
import com.android.systemui.pip.tv.dagger.TvPipComponent;
-import com.android.systemui.stackdivider.SplitScreen;
-import com.android.systemui.stackdivider.SplitScreenController;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.splitscreen.SplitScreen;
+import com.android.wm.shell.splitscreen.SplitScreenController;
import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 27af5f9..6f681e8 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -16,27 +16,44 @@
package com.android.systemui.wmshell;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import android.app.ActivityManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.graphics.Rect;
+import android.inputmethodservice.InputMethodService;
+import android.os.IBinder;
+import android.view.KeyEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.pip.Pip;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.tracing.ProtoTraceable;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.nano.WmShellTraceProto;
+import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.onehanded.OneHandedEvents;
+import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
+import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.protolog.ShellProtoLogImpl;
+import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -54,8 +71,15 @@
private final DisplayImeController mDisplayImeController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ActivityManagerWrapper mActivityManagerWrapper;
+ private final NavigationModeController mNavigationModeController;
+ private final ScreenLifecycle mScreenLifecycle;
+ private final SysUiState mSysUiState;
private final Optional<Pip> mPipOptional;
private final Optional<SplitScreen> mSplitScreenOptional;
+ private final Optional<OneHanded> mOneHandedOptional;
+ // Inject the organizer directly in case the optionals aren't loaded to depend on it. There
+ // are non-optional windowing features like FULLSCREEN.
+ private final ShellTaskOrganizer mShellTaskOrganizer;
private final ProtoTracer mProtoTracer;
@Inject
@@ -63,16 +87,26 @@
KeyguardUpdateMonitor keyguardUpdateMonitor,
ActivityManagerWrapper activityManagerWrapper,
DisplayImeController displayImeController,
+ NavigationModeController navigationModeController,
+ ScreenLifecycle screenLifecycle,
+ SysUiState sysUiState,
Optional<Pip> pipOptional,
Optional<SplitScreen> splitScreenOptional,
+ Optional<OneHanded> oneHandedOptional,
+ ShellTaskOrganizer shellTaskOrganizer,
ProtoTracer protoTracer) {
super(context);
mCommandQueue = commandQueue;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mActivityManagerWrapper = activityManagerWrapper;
mDisplayImeController = displayImeController;
+ mNavigationModeController = navigationModeController;
+ mScreenLifecycle = screenLifecycle;
+ mSysUiState = sysUiState;
mPipOptional = pipOptional;
mSplitScreenOptional = splitScreenOptional;
+ mOneHandedOptional = oneHandedOptional;
+ mShellTaskOrganizer = shellTaskOrganizer;
mProtoTracer = protoTracer;
mProtoTracer.add(this);
}
@@ -83,9 +117,9 @@
// constructor. And make sure the initialization of DisplayImeController won't depend on
// specific feature anymore.
mDisplayImeController.startMonitorDisplays();
-
mPipOptional.ifPresent(this::initPip);
mSplitScreenOptional.ifPresent(this::initSplitScreen);
+ mOneHandedOptional.ifPresent(this::initOneHanded);
}
@VisibleForTesting
@@ -145,6 +179,103 @@
});
}
+ @VisibleForTesting
+ void initOneHanded(OneHanded oneHanded) {
+ if (!oneHanded.hasOneHandedFeature()) {
+ return;
+ }
+
+ int currentMode = mNavigationModeController.addListener(mode ->
+ oneHanded.setThreeButtonModeEnabled(mode == NAV_BAR_MODE_3BUTTON));
+ oneHanded.setThreeButtonModeEnabled(currentMode == NAV_BAR_MODE_3BUTTON);
+
+ oneHanded.registerTransitionCallback(new OneHandedTransitionCallback() {
+ @Override
+ public void onStartFinished(Rect bounds) {
+ mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE,
+ true).commitUpdate(DEFAULT_DISPLAY);
+ }
+
+ @Override
+ public void onStopFinished(Rect bounds) {
+ mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE,
+ false).commitUpdate(DEFAULT_DISPLAY);
+ }
+ });
+
+ oneHanded.registerGestureCallback(new OneHandedGestureEventCallback() {
+ @Override
+ public void onStart() {
+ if (oneHanded.isOneHandedEnabled()) {
+ oneHanded.startOneHanded();
+ } else if (oneHanded.isSwipeToNotificationEnabled()) {
+ mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN);
+ }
+ }
+
+ @Override
+ public void onStop() {
+ if (oneHanded.isOneHandedEnabled()) {
+ oneHanded.stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
+ } else if (oneHanded.isSwipeToNotificationEnabled()) {
+ mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP);
+ }
+ }
+ });
+
+ mKeyguardUpdateMonitor.registerCallback(new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onKeyguardBouncerChanged(boolean bouncer) {
+ if (bouncer) {
+ oneHanded.stopOneHanded();
+ }
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ oneHanded.stopOneHanded();
+ }
+ });
+
+ mScreenLifecycle.addObserver(new ScreenLifecycle.Observer() {
+ @Override
+ public void onScreenTurningOff() {
+ oneHanded.stopOneHanded(
+ OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_SCREEN_OFF_OUT);
+ }
+ });
+
+ mCommandQueue.addCallback(new CommandQueue.Callbacks() {
+ @Override
+ public void onCameraLaunchGestureDetected(int source) {
+ oneHanded.stopOneHanded();
+ }
+
+ @Override
+ public void setImeWindowStatus(int displayId, IBinder token, int vis,
+ int backDisposition, boolean showImeSwitcher) {
+ if (displayId == DEFAULT_DISPLAY && (vis & InputMethodService.IME_VISIBLE) != 0) {
+ oneHanded.stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_POP_IME_OUT);
+ }
+ }
+ });
+
+ mActivityManagerWrapper.registerTaskStackListener(
+ new TaskStackChangeListener() {
+ @Override
+ public void onTaskCreated(int taskId, ComponentName componentName) {
+ oneHanded.stopOneHanded(
+ OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_APP_TAPS_OUT);
+ }
+
+ @Override
+ public void onTaskMovedToFront(int taskId) {
+ oneHanded.stopOneHanded(
+ OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_APP_TAPS_OUT);
+ }
+ });
+ }
+
@Override
public void writeToProto(SystemUiTraceProto proto) {
if (proto.wmShell == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index e63c6c3..3faa8a7 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -27,7 +27,6 @@
import com.android.systemui.pip.Pip;
import com.android.systemui.pip.PipSurfaceTransactionHelper;
import com.android.systemui.pip.PipUiEventLogger;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
@@ -36,6 +35,8 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.splitscreen.SplitScreen;
import dagger.BindsOptionalOf;
import dagger.Module;
@@ -95,22 +96,25 @@
@SysUISingleton
@Provides
- static ShellTaskOrganizer provideShellTaskOrganizer() {
- ShellTaskOrganizer organizer = new ShellTaskOrganizer();
+ static ShellTaskOrganizer provideShellTaskOrganizer(TransactionPool transactionPool) {
+ ShellTaskOrganizer organizer = new ShellTaskOrganizer(transactionPool);
organizer.registerOrganizer();
return organizer;
}
+ @SysUISingleton
+ @Provides
+ static FlingAnimationUtils.Builder provideFlingAnimationUtilsBuilder(
+ DisplayMetrics displayMetrics) {
+ return new FlingAnimationUtils.Builder(displayMetrics);
+ }
+
@BindsOptionalOf
abstract Pip optionalPip();
@BindsOptionalOf
abstract SplitScreen optionalSplitScreen();
- @SysUISingleton
- @Provides
- static FlingAnimationUtils.Builder provideFlingAnimationUtilsBuilder(
- DisplayMetrics displayMetrics) {
- return new FlingAnimationUtils.Builder(displayMetrics);
- }
+ @BindsOptionalOf
+ abstract OneHanded optionalOneHanded();
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 1870b76..16fb2ca 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -30,8 +30,6 @@
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.pip.PipUiEventLogger;
import com.android.systemui.pip.phone.PipController;
-import com.android.systemui.stackdivider.SplitScreen;
-import com.android.systemui.stackdivider.SplitScreenController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
@@ -40,6 +38,10 @@
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.onehanded.OneHandedController;
+import com.android.wm.shell.splitscreen.SplitScreen;
+import com.android.wm.shell.splitscreen.SplitScreenController;
import java.util.Optional;
@@ -109,4 +111,10 @@
pipUiEventLogger, shellTaskOrganizer);
}
+ @SysUISingleton
+ @Provides
+ static OneHanded provideOneHandedController(Context context,
+ DisplayController displayController) {
+ return OneHandedController.create(context, displayController);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
similarity index 61%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java
rename to packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
index dd5c833..54e879e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
@@ -11,7 +11,7 @@
* 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
+ * limitations under the License.
*/
package com.android.keyguard;
@@ -19,11 +19,12 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import android.media.AudioManager;
+import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -39,41 +40,44 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class KeyguardHostViewTest extends SysuiTestCase {
+public class KeyguardHostViewControllerTest extends SysuiTestCase {
@Mock
- private KeyguardSecurityContainer mSecurityContainer;
+ private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
- private LockPatternUtils mLockPatternUtils;
+ private KeyguardHostView mKeyguardHostView;
+ @Mock
+ private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
+ @Mock
+ private AudioManager mAudioManager;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private ViewMediatorCallback mViewMediatorCallback;
+
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
- private KeyguardHostView mKeyguardHostView;
+ private KeyguardHostViewController mKeyguardHostViewController;
@Before
public void setup() {
- mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
- mKeyguardHostView = new KeyguardHostView(getContext()) {
- @Override
- protected void onFinishInflate() {
- mSecurityContainer = KeyguardHostViewTest.this.mSecurityContainer;
- mLockPatternUtils = KeyguardHostViewTest.this.mLockPatternUtils;
- }
- };
- mKeyguardHostView.onFinishInflate();
+ mKeyguardHostViewController = new KeyguardHostViewController(
+ mKeyguardHostView, mKeyguardUpdateMonitor, mKeyguardSecurityContainerController,
+ mAudioManager, mTelephonyManager, mViewMediatorCallback);
}
@Test
public void testHasDismissActions() {
- Assert.assertFalse("Action not set yet", mKeyguardHostView.hasDismissActions());
- mKeyguardHostView.setOnDismissAction(mock(OnDismissAction.class),
+ Assert.assertFalse("Action not set yet", mKeyguardHostViewController.hasDismissActions());
+ mKeyguardHostViewController.setOnDismissAction(mock(OnDismissAction.class),
null /* cancelAction */);
- Assert.assertTrue("Action should exist", mKeyguardHostView.hasDismissActions());
+ Assert.assertTrue("Action should exist", mKeyguardHostViewController.hasDismissActions());
}
@Test
public void testOnStartingToHide() {
- mKeyguardHostView.onStartingToHide();
- verify(mSecurityContainer).onStartingToHide();
+ mKeyguardHostViewController.onStartingToHide();
+ verify(mKeyguardSecurityContainerController).onStartingToHide();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index b7175ea..0fe3817 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -39,6 +39,7 @@
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
@@ -78,7 +79,7 @@
Dependency.setInstance(mDependency);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
mock(Executor.class), mock(DumpManager.class),
- mock(BroadcastDispatcherLogger.class));
+ mock(BroadcastDispatcherLogger.class), mock(UserTracker.class));
mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
Instrumentation inst = spy(mRealInstrumentation);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index cdbc647..64e0673 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -231,7 +231,6 @@
private void assertShowButtonAnimation() {
verify(mViewPropertyAnimator).cancel();
verify(mViewPropertyAnimator).setDuration(anyLong());
- verify(mViewPropertyAnimator).setStartDelay(anyLong());
verify(mViewPropertyAnimator).alpha(anyFloat());
verify(mViewPropertyAnimator).start();
}
@@ -239,11 +238,15 @@
private void initMockImageViewAndAnimator() {
when(mViewPropertyAnimator.setDuration(anyLong())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.alpha(anyFloat())).thenReturn(mViewPropertyAnimator);
- when(mViewPropertyAnimator.setStartDelay(anyLong())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.withEndAction(any(Runnable.class))).thenReturn(
mViewPropertyAnimator);
when(mSpyImageView.animate()).thenReturn(mViewPropertyAnimator);
+ doAnswer(invocation -> {
+ Runnable run = invocation.getArgument(0);
+ run.run();
+ return null;
+ }).when(mSpyImageView).postDelayed(any(), anyLong());
}
private void resetMockImageViewAndAnimator() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 22e9594..65301fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -18,7 +18,6 @@
import android.content.BroadcastReceiver
import android.content.Context
-import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
@@ -30,6 +29,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
+import com.android.systemui.settings.UserTracker
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import junit.framework.Assert.assertSame
@@ -80,6 +80,8 @@
private lateinit var mockHandler: Handler
@Mock
private lateinit var logger: BroadcastDispatcherLogger
+ @Mock
+ private lateinit var userTracker: UserTracker
private lateinit var executor: Executor
@@ -101,6 +103,7 @@
mock(Executor::class.java),
mock(DumpManager::class.java),
logger,
+ userTracker,
mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
// These should be valid filters
@@ -178,11 +181,7 @@
@Test
fun testRegisterCurrentAsActualUser() {
- val intent = Intent(Intent.ACTION_USER_SWITCHED).apply {
- putExtra(Intent.EXTRA_USER_HANDLE, user1.identifier)
- }
- broadcastDispatcher.onReceive(mockContext, intent)
- testableLooper.processAllMessages()
+ `when`(userTracker.userId).thenReturn(user1.identifier)
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, UserHandle.CURRENT)
@@ -250,8 +249,9 @@
executor: Executor,
dumpManager: DumpManager,
logger: BroadcastDispatcherLogger,
+ userTracker: UserTracker,
var mockUBRMap: Map<Int, UserBroadcastDispatcher>
- ) : BroadcastDispatcher(context, bgLooper, executor, dumpManager, logger) {
+ ) : BroadcastDispatcher(context, bgLooper, executor, dumpManager, logger, userTracker) {
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
index 949932d..da00e7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
@@ -26,6 +26,7 @@
import com.android.systemui.SysuiTestableContext
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
+import com.android.systemui.settings.UserTracker
import java.util.concurrent.Executor
class FakeBroadcastDispatcher(
@@ -33,8 +34,9 @@
looper: Looper,
executor: Executor,
dumpManager: DumpManager,
- logger: BroadcastDispatcherLogger
-) : BroadcastDispatcher(context, looper, executor, dumpManager, logger) {
+ logger: BroadcastDispatcherLogger,
+ userTracker: UserTracker
+) : BroadcastDispatcher(context, looper, executor, dumpManager, logger, userTracker) {
private val registeredReceivers = ArraySet<BroadcastReceiver>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index 909acea..b4af786 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -49,6 +49,7 @@
import android.util.FeatureFlagUtils;
import android.view.IWindowManager;
import android.view.View;
+import android.view.WindowManagerPolicyConstants;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
@@ -241,6 +242,28 @@
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
}
+ @Test
+ public void testShouldShowScreenshot() {
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.integer.config_navBarInteractionMode,
+ WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON);
+
+ GlobalActionsDialog.ScreenshotAction screenshotAction =
+ mGlobalActionsDialog.makeScreenshotActionForTesting();
+ assertThat(screenshotAction.shouldShow()).isTrue();
+ }
+
+ @Test
+ public void testShouldNotShowScreenshot() {
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.integer.config_navBarInteractionMode,
+ WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON);
+
+ GlobalActionsDialog.ScreenshotAction screenshotAction =
+ mGlobalActionsDialog.makeScreenshotActionForTesting();
+ assertThat(screenshotAction.shouldShow()).isFalse();
+ }
+
private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) {
mTestableLooper.processAllMessages();
verify(mUiEventLogger, times(1))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt
index 58cb032..73a7ca9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt
@@ -87,6 +87,8 @@
override fun createAnimator(start: Float, end: Float) = animator
}
`when`(systemSettings.getFloat(eq(SCREEN_BRIGHTNESS_FLOAT))).thenReturn(INITIAL_BRIGHTNESS)
+ `when`(systemSettings.getFloat(eq(SCREEN_BRIGHTNESS_FLOAT), eq(1f)))
+ .thenReturn(INITIAL_BRIGHTNESS)
faceAuthScreenBrightnessController.attach(whiteOverlay)
verify(keyguardUpdateMonitor).registerCallback(capture(keyguardUpdateCallback))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index 89538ac..609b847 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -74,7 +74,7 @@
mMediaData = new MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null,
new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, true,
- false, KEY, false);
+ false, KEY, false, false, false);
mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
index da1ec98..ef8d322 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
@@ -25,7 +25,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -34,6 +33,8 @@
companion object {
val LOCAL = true
val RESUMPTION = true
+ val PLAYING = true
+ val UNDETERMINED = null
}
@Before
@@ -44,15 +45,13 @@
@Test
fun addPlayingThenRemote() {
val playerIsPlaying = mock(MediaControlPanel::class.java)
- whenever(playerIsPlaying.isPlaying).thenReturn(true)
- val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION)
+ val dataIsPlaying = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION)
val playerIsRemote = mock(MediaControlPanel::class.java)
- whenever(playerIsRemote.isPlaying).thenReturn(false)
- val dataIsRemote = createMediaData("app2", !LOCAL, !RESUMPTION)
+ val dataIsRemote = createMediaData("app2", PLAYING, !LOCAL, !RESUMPTION)
- MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
val players = MediaPlayerData.players()
assertThat(players).hasSize(2)
@@ -63,18 +62,16 @@
@Ignore("Flaky")
fun switchPlayersPlaying() {
val playerIsPlaying1 = mock(MediaControlPanel::class.java)
- whenever(playerIsPlaying1.isPlaying).thenReturn(true)
- val dataIsPlaying1 = createMediaData("app1", LOCAL, !RESUMPTION)
+ var dataIsPlaying1 = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION)
val playerIsPlaying2 = mock(MediaControlPanel::class.java)
- whenever(playerIsPlaying2.isPlaying).thenReturn(false)
- val dataIsPlaying2 = createMediaData("app2", LOCAL, !RESUMPTION)
+ var dataIsPlaying2 = createMediaData("app2", !PLAYING, LOCAL, !RESUMPTION)
MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
- whenever(playerIsPlaying1.isPlaying).thenReturn(false)
- whenever(playerIsPlaying2.isPlaying).thenReturn(true)
+ dataIsPlaying1 = createMediaData("app1", !PLAYING, LOCAL, !RESUMPTION)
+ dataIsPlaying2 = createMediaData("app2", PLAYING, LOCAL, !RESUMPTION)
MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
@@ -87,38 +84,43 @@
@Test
fun fullOrderTest() {
val playerIsPlaying = mock(MediaControlPanel::class.java)
- whenever(playerIsPlaying.isPlaying).thenReturn(true)
- val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION)
+ val dataIsPlaying = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION)
val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java)
- whenever(playerIsPlayingAndRemote.isPlaying).thenReturn(true)
- val dataIsPlayingAndRemote = createMediaData("app2", !LOCAL, !RESUMPTION)
+ val dataIsPlayingAndRemote = createMediaData("app2", PLAYING, !LOCAL, !RESUMPTION)
val playerIsStoppedAndLocal = mock(MediaControlPanel::class.java)
- whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
- val dataIsStoppedAndLocal = createMediaData("app3", LOCAL, !RESUMPTION)
+ val dataIsStoppedAndLocal = createMediaData("app3", !PLAYING, LOCAL, !RESUMPTION)
val playerIsStoppedAndRemote = mock(MediaControlPanel::class.java)
- whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
- val dataIsStoppedAndRemote = createMediaData("app4", !LOCAL, !RESUMPTION)
+ val dataIsStoppedAndRemote = createMediaData("app4", !PLAYING, !LOCAL, !RESUMPTION)
val playerCanResume = mock(MediaControlPanel::class.java)
- whenever(playerCanResume.isPlaying).thenReturn(false)
- val dataCanResume = createMediaData("app5", LOCAL, RESUMPTION)
+ val dataCanResume = createMediaData("app5", !PLAYING, LOCAL, RESUMPTION)
+
+ val playerUndetermined = mock(MediaControlPanel::class.java)
+ val dataUndetermined = createMediaData("app6", UNDETERMINED, LOCAL, RESUMPTION)
MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal)
MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote)
MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume)
MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
MediaPlayerData.addMediaPlayer("2", dataIsPlayingAndRemote, playerIsPlayingAndRemote)
+ MediaPlayerData.addMediaPlayer("6", dataUndetermined, playerUndetermined)
val players = MediaPlayerData.players()
- assertThat(players).hasSize(5)
+ assertThat(players).hasSize(6)
assertThat(players).containsExactly(playerIsPlaying, playerIsPlayingAndRemote,
- playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote).inOrder()
+ playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote,
+ playerUndetermined).inOrder()
}
- private fun createMediaData(app: String, isLocalSession: Boolean, resumption: Boolean) =
+ private fun createMediaData(
+ app: String,
+ isPlaying: Boolean?,
+ isLocalSession: Boolean,
+ resumption: Boolean
+ ) =
MediaData(0, false, 0, app, null, null, null, null, emptyList(), emptyList<Int>(), "",
- null, null, null, true, null, isLocalSession, resumption, null, false)
+ null, null, null, true, null, isLocalSession, resumption, null, false, isPlaying)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
index 57dbac5..ad5f987 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
@@ -52,7 +52,6 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -60,6 +59,7 @@
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.wm.shell.splitscreen.SplitScreen;
import org.junit.After;
import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 389c5a0..f308e9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -68,7 +68,6 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -77,6 +76,7 @@
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
+import com.android.wm.shell.splitscreen.SplitScreen;
import org.junit.Before;
import org.junit.Rule;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
deleted file mode 100644
index 756382a6..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.onehanded;
-
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.wm.shell.common.DisplayController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class OneHandedGestureHandlerTest extends OneHandedTestCase {
- OneHandedTouchHandler mTouchHandler;
- OneHandedTutorialHandler mTutorialHandler;
- OneHandedGestureHandler mGestureHandler;
- OneHandedController mOneHandedController;
- @Mock
- CommandQueue mCommandQueue;
- @Mock
- DisplayController mMockDisplayController;
- @Mock
- OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
- @Mock
- SysUiState mMockSysUiState;
- @Mock
- NavigationModeController mMockNavigationModeController;
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mTouchHandler = new OneHandedTouchHandler();
- mTutorialHandler = new OneHandedTutorialHandler(mContext);
- mGestureHandler = Mockito.spy(new OneHandedGestureHandler(
- mContext, mMockDisplayController, mMockNavigationModeController));
- mOneHandedController = new OneHandedController(
- getContext(),
- mCommandQueue,
- mMockDisplayController,
- mMockDisplayAreaOrganizer,
- mTouchHandler,
- mTutorialHandler,
- mGestureHandler,
- mMockSysUiState);
- }
-
- @Test
- public void testOneHandedManager_registerForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mGestureHandler);
- }
-
- @Test
- public void testOneHandedManager_setGestureEventListener() {
- verify(mGestureHandler).setGestureEventListener(any());
-
- assertThat(mGestureHandler.mGestureEventCallback).isNotNull();
- }
-
- @Test
- public void testReceiveNewConfig_whenSetOneHandedEnabled() {
- // 1st called at init
- verify(mGestureHandler).onOneHandedEnabled(true);
- mOneHandedController.setOneHandedEnabled(true);
- // 2nd called by setOneHandedEnabled()
- verify(mGestureHandler, times(2)).onOneHandedEnabled(true);
- }
-
- @Test
- public void testOneHandedDisabled_shouldDisposeInputChannel() {
- mOneHandedController.setOneHandedEnabled(false);
- mOneHandedController.setSwipeToNotificationEnabled(false);
-
- assertThat(mGestureHandler.mInputMonitor).isNull();
- assertThat(mGestureHandler.mInputEventReceiver).isNull();
- }
-
- @Test
- public void testChangeNavBarTo2Button_shouldDisposeInputChannel() {
- // 1st called at init
- verify(mGestureHandler).onOneHandedEnabled(true);
- mOneHandedController.setOneHandedEnabled(true);
- // 2nd called by setOneHandedEnabled()
- verify(mGestureHandler, times(2)).onOneHandedEnabled(true);
-
- mGestureHandler.onNavigationModeChanged(NAV_BAR_MODE_2BUTTON);
-
- assertThat(mGestureHandler.mInputMonitor).isNull();
- assertThat(mGestureHandler.mInputEventReceiver).isNull();
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
deleted file mode 100644
index 3c3ace0..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.onehanded;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.wm.shell.common.DisplayController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class OneHandedTouchHandlerTest extends OneHandedTestCase {
- OneHandedTouchHandler mTouchHandler;
- OneHandedTutorialHandler mTutorialHandler;
- OneHandedGestureHandler mGestureHandler;
- OneHandedController mOneHandedController;
- @Mock
- CommandQueue mCommandQueue;
- @Mock
- DisplayController mMockDisplayController;
- @Mock
- NavigationModeController mMockNavigationModeController;
- @Mock
- OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
- @Mock
- SysUiState mMockSysUiState;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mTouchHandler = Mockito.spy(new OneHandedTouchHandler());
- mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController,
- mMockNavigationModeController);
- mOneHandedController = new OneHandedController(
- getContext(),
- mCommandQueue,
- mMockDisplayController,
- mMockDisplayAreaOrganizer,
- mTouchHandler,
- mTutorialHandler,
- mGestureHandler,
- mMockSysUiState);
- }
-
- @Test
- public void testOneHandedManager_registerForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mTouchHandler);
- }
-
- @Test
- public void testOneHandedManager_registerTouchEventListener() {
- verify(mTouchHandler).registerTouchEventListener(any());
- assertThat(mTouchHandler.mTouchEventCallback).isNotNull();
- }
-
- @Test
- public void testOneHandedDisabled_shouldDisposeInputChannel() {
- mOneHandedController.setOneHandedEnabled(false);
- assertThat(mTouchHandler.mInputMonitor).isNull();
- assertThat(mTouchHandler.mInputEventReceiver).isNull();
- }
-
- @Test
- public void testOneHandedEnabled_monitorInputChannel() {
- mOneHandedController.setOneHandedEnabled(true);
- assertThat(mTouchHandler.mInputMonitor).isNotNull();
- assertThat(mTouchHandler.mInputEventReceiver).isNotNull();
- }
-
- @Test
- public void testReceiveNewConfig_whenSetOneHandedEnabled() {
- // 1st called at init
- verify(mTouchHandler).onOneHandedEnabled(true);
- mOneHandedController.setOneHandedEnabled(true);
- // 2nd called by setOneHandedEnabled()
- verify(mTouchHandler, times(2)).onOneHandedEnabled(true);
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java
deleted file mode 100644
index ae3df5d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.onehanded;
-
-import static org.junit.Assume.assumeTrue;
-import static org.mockito.Mockito.verify;
-
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.statusbar.CommandQueue;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class OneHandedUITest extends OneHandedTestCase {
- private static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
-
- CommandQueue mCommandQueue;
- KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- OneHandedUI mOneHandedUI;
- ScreenLifecycle mScreenLifecycle;
- @Mock
- OneHandedController mOneHandedController;
- @Mock
- OneHandedTimeoutHandler mMockTimeoutHandler;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mCommandQueue = new CommandQueue(mContext);
- mScreenLifecycle = new ScreenLifecycle();
- mOneHandedUI = new OneHandedUI(mContext,
- mCommandQueue,
- mOneHandedController,
- mScreenLifecycle);
- mOneHandedUI.start();
- mKeyguardUpdateMonitor = mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
- }
-
- @Before
- public void assumeOneHandedModeSupported() {
- assumeTrue(SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false));
- }
-
- @Test
- public void testStartOneHanded() {
- mOneHandedUI.startOneHanded();
-
- verify(mOneHandedController).startOneHanded();
- }
-
- @Test
- public void testStopOneHanded() {
- mOneHandedUI.stopOneHanded();
-
- verify(mOneHandedController).stopOneHanded();
- }
-
- @Test
- public void tesSettingsObserver_updateTapAppToExit() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TAPS_APP_TO_EXIT, 1);
-
- verify(mOneHandedController).setTaskChangeToExit(true);
- }
-
- @Test
- public void tesSettingsObserver_updateEnabled() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ONE_HANDED_MODE_ENABLED, 1);
-
- verify(mOneHandedController).setOneHandedEnabled(true);
- }
-
- @Test
- public void tesSettingsObserver_updateTimeout() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
- OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
-
- verify(mMockTimeoutHandler).setTimeout(
- OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
- }
-
- @Test
- public void tesSettingsObserver_updateSwipeToNotification() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 1);
-
- verify(mOneHandedController).setSwipeToNotificationEnabled(true);
- }
-
- @Ignore("Clarifying do not receive callback")
- @Test
- public void testKeyguardBouncerShowing_shouldStopOneHanded() {
- mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
-
- verify(mOneHandedController).stopOneHanded();
- }
-
- @Test
- public void testScreenTurningOff_shouldStopOneHanded() {
- mScreenLifecycle.dispatchScreenTurningOff();
-
- verify(mOneHandedController).stopOneHanded();
- }
-
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt
index 4ba29e6..1f10d01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt
@@ -32,6 +32,7 @@
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
@@ -96,22 +97,25 @@
}
@Test
- fun testNotListeningByDefault() {
+ fun testNotListeningAllByDefault() {
assertFalse(privacyItemController.allIndicatorsAvailable)
- assertFalse(privacyItemController.micCameraAvailable)
-
- verify(appOpsController, never()).addCallback(any(), any())
}
@Test
+ fun testMicCameraListeningByDefault() {
+ assertTrue(privacyItemController.micCameraAvailable)
+ }
+
+ @Test
+ @Ignore // TODO(b/168209929)
fun testMicCameraChanged() {
- changeMicCamera(true)
+ changeMicCamera(false) // default is true
executor.runAllReady()
- verify(callback).onFlagMicCameraChanged(true)
+ verify(callback).onFlagMicCameraChanged(false)
verify(callback, never()).onFlagAllChanged(anyBoolean())
- assertTrue(privacyItemController.micCameraAvailable)
+ assertFalse(privacyItemController.micCameraAvailable)
assertFalse(privacyItemController.allIndicatorsAvailable)
}
@@ -124,20 +128,20 @@
verify(callback, never()).onFlagMicCameraChanged(anyBoolean())
assertTrue(privacyItemController.allIndicatorsAvailable)
- assertFalse(privacyItemController.micCameraAvailable)
}
@Test
+ @Ignore // TODO(b/168209929)
fun testBothChanged() {
changeAll(true)
- changeMicCamera(true)
+ changeMicCamera(false)
executor.runAllReady()
verify(callback, atLeastOnce()).onFlagAllChanged(true)
- verify(callback, atLeastOnce()).onFlagMicCameraChanged(true)
+ verify(callback, atLeastOnce()).onFlagMicCameraChanged(false)
assertTrue(privacyItemController.allIndicatorsAvailable)
- assertTrue(privacyItemController.micCameraAvailable)
+ assertFalse(privacyItemController.micCameraAvailable)
}
@Test
@@ -149,6 +153,7 @@
}
@Test
+ @Ignore // TODO(b/168209929)
fun testMicCamera_listening() {
changeMicCamera(true)
executor.runAllReady()
@@ -157,27 +162,22 @@
}
@Test
- fun testAll_listening() {
- changeAll(true)
- executor.runAllReady()
-
- verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any())
- }
-
- @Test
+ @Ignore // TODO(b/168209929)
fun testAllFalse_notListening() {
changeAll(true)
executor.runAllReady()
changeAll(false)
+ changeMicCamera(false)
executor.runAllReady()
verify(appOpsController).removeCallback(any(), any())
}
@Test
+ @Ignore // TODO(b/168209929)
fun testSomeListening_stillListening() {
+ // Mic and camera are true by default
changeAll(true)
- changeMicCamera(true)
executor.runAllReady()
changeAll(false)
executor.runAllReady()
@@ -186,7 +186,9 @@
}
@Test
- fun testAllDeleted_stopListening() {
+ @Ignore // TODO(b/168209929)
+ fun testAllDeleted_micCameraFalse_stopListening() {
+ changeMicCamera(false)
changeAll(true)
executor.runAllReady()
changeAll(null)
@@ -196,13 +198,14 @@
}
@Test
- fun testMicDeleted_stopListening() {
+ @Ignore // TODO(b/168209929)
+ fun testMicDeleted_stillListening() {
changeMicCamera(true)
executor.runAllReady()
changeMicCamera(null)
executor.runAllReady()
- verify(appOpsController).removeCallback(any(), any())
+ verify(appOpsController, never()).removeCallback(any(), any())
}
private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
index fb42baa..0a079b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -43,6 +43,7 @@
import org.junit.Assert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
@@ -271,8 +272,10 @@
}
@Test
+ @Ignore // TODO(b/168209929)
fun testNotListeningWhenIndicatorsDisabled() {
changeAll(false)
+ changeMicCamera(false)
privacyItemController.addCallback(callback)
executor.runAllReady()
verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 359faba..ce0f122 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -442,7 +442,7 @@
}
@Test
- public void testDismissingLifetimeExtendedSummaryDoesNotDismissChildren() {
+ public void testRetractingLifetimeExtendedSummaryDoesNotDismissChildren() {
// GIVEN A notif group with one summary and two children
mCollection.addNotificationLifetimeExtender(mExtender1);
CollectionEvent notif1 = postNotif(
@@ -460,15 +460,16 @@
NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key);
NotificationEntry entry3 = mCollectionListener.getEntry(notif3.key);
- // GIVEN that the summary and one child are retracted, but both are lifetime-extended
+ // GIVEN that the summary and one child are retracted by the app, but both are
+ // lifetime-extended
mExtender1.shouldExtendLifetime = true;
- mNoMan.retractNotif(notif1.sbn, REASON_CANCEL);
- mNoMan.retractNotif(notif2.sbn, REASON_CANCEL);
+ mNoMan.retractNotif(notif1.sbn, REASON_APP_CANCEL);
+ mNoMan.retractNotif(notif2.sbn, REASON_APP_CANCEL);
assertEquals(
new ArraySet<>(List.of(entry1, entry2, entry3)),
new ArraySet<>(mCollection.getAllNotifs()));
- // WHEN the summary is dismissed by the user
+ // WHEN the summary is retracted by the app
mCollection.dismissNotification(entry1, defaultStats(entry1));
// THEN the summary is removed, but both children stick around
@@ -480,6 +481,28 @@
}
@Test
+ public void testNMSReportsUserDismissalAlwaysRemovesNotif() throws RemoteException {
+ // GIVEN notifications are lifetime extended
+ mExtender1.shouldExtendLifetime = true;
+ CollectionEvent notif = postNotif(buildNotif(TEST_PACKAGE, 1, "myTag"));
+ CollectionEvent notif2 = postNotif(buildNotif(TEST_PACKAGE, 2, "myTag"));
+ NotificationEntry entry = mCollectionListener.getEntry(notif.key);
+ NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key);
+ assertEquals(
+ new ArraySet<>(List.of(entry, entry2)),
+ new ArraySet<>(mCollection.getAllNotifs()));
+
+ // WHEN the notifications are reported to be dismissed by the user by NMS
+ mNoMan.retractNotif(notif.sbn, REASON_CANCEL);
+ mNoMan.retractNotif(notif2.sbn, REASON_CLICK);
+
+ // THEN the notifications are removed b/c they were dismissed by the user
+ assertEquals(
+ new ArraySet<>(List.of()),
+ new ArraySet<>(mCollection.getAllNotifs()));
+ }
+
+ @Test
public void testDismissNotificationCallsDismissInterceptors() throws RemoteException {
// GIVEN a collection with notifications with multiple dismiss interceptors
mInterceptor1.shouldInterceptDismissal = true;
@@ -833,13 +856,13 @@
NotifEvent notif2 = mNoMan.postNotif(buildNotif(TEST_PACKAGE2, 88));
NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key);
- // WHEN a notification is removed
- mNoMan.retractNotif(notif2.sbn, REASON_CLICK);
+ // WHEN a notification is removed by the app
+ mNoMan.retractNotif(notif2.sbn, REASON_APP_CANCEL);
// THEN each extender is asked whether to extend, even if earlier ones return true
- verify(mExtender1).shouldExtendLifetime(entry2, REASON_CLICK);
- verify(mExtender2).shouldExtendLifetime(entry2, REASON_CLICK);
- verify(mExtender3).shouldExtendLifetime(entry2, REASON_CLICK);
+ verify(mExtender1).shouldExtendLifetime(entry2, REASON_APP_CANCEL);
+ verify(mExtender2).shouldExtendLifetime(entry2, REASON_APP_CANCEL);
+ verify(mExtender3).shouldExtendLifetime(entry2, REASON_APP_CANCEL);
// THEN the entry is not removed
assertTrue(mCollection.getAllNotifs().contains(entry2));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index 8acb705..2ce22a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -58,6 +58,7 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener;
import com.android.systemui.util.time.FakeSystemClock;
@@ -964,6 +965,198 @@
}
@Test
+ public void testStabilizeGroupsDoesNotAllowGrouping() {
+ // GIVEN one group child without a summary yet
+ addGroupChild(0, PACKAGE_1, GROUP_1);
+
+ dispatchBuild();
+
+ // GIVEN visual stability manager doesn't allow any group changes
+ mListBuilder.setNotifStabilityManager(
+ new TestableStabilityManager().setAllowGroupChanges(false));
+
+ // WHEN we run the pipeline with the addition of a group summary & child
+ addGroupSummary(1, PACKAGE_1, GROUP_1);
+ addGroupChild(2, PACKAGE_1, GROUP_1);
+
+ dispatchBuild();
+
+ // THEN all notifications are top-level and the summary doesn't show yet
+ // because group changes aren't allowed by the stability manager
+ verifyBuiltList(
+ notif(0),
+ notif(2)
+ );
+ }
+
+ @Test
+ public void testStabilizeGroupsAllowsGroupingAllNewNotifications() {
+ // GIVEN visual stability manager doesn't allow any group changes
+ mListBuilder.setNotifStabilityManager(
+ new TestableStabilityManager().setAllowGroupChanges(false));
+
+ // WHEN we run the pipeline with all new notification groups
+ addGroupChild(0, PACKAGE_1, GROUP_1);
+ addGroupSummary(1, PACKAGE_1, GROUP_1);
+ addGroupChild(2, PACKAGE_1, GROUP_1);
+ addGroupSummary(3, PACKAGE_2, GROUP_2);
+ addGroupChild(4, PACKAGE_2, GROUP_2);
+ addGroupChild(5, PACKAGE_2, GROUP_2);
+
+ dispatchBuild();
+
+ // THEN all notifications are grouped since they're all new
+ verifyBuiltList(
+ group(
+ summary(1),
+ child(0),
+ child(2)
+ ),
+ group(
+ summary(3),
+ child(4),
+ child(5)
+ )
+ );
+ }
+
+
+ @Test
+ public void testStabilizeGroupsAllowsGroupingOnlyNewNotifications() {
+ // GIVEN one group child without a summary yet
+ addGroupChild(0, PACKAGE_1, GROUP_1);
+
+ dispatchBuild();
+
+ // GIVEN visual stability manager doesn't allow any group changes
+ mListBuilder.setNotifStabilityManager(
+ new TestableStabilityManager().setAllowGroupChanges(false));
+
+ // WHEN we run the pipeline with the addition of a group summary & child
+ addGroupSummary(1, PACKAGE_1, GROUP_1);
+ addGroupChild(2, PACKAGE_1, GROUP_1);
+ addGroupSummary(3, PACKAGE_2, GROUP_2);
+ addGroupChild(4, PACKAGE_2, GROUP_2);
+ addGroupChild(5, PACKAGE_2, GROUP_2);
+
+ dispatchBuild();
+
+ // THEN all notifications are top-level and the summary doesn't show yet
+ // because group changes aren't allowed by the stability manager
+ verifyBuiltList(
+ notif(0),
+ group(
+ summary(3),
+ child(4),
+ child(5)
+ ),
+ notif(2)
+ );
+ }
+
+ @Test
+ public void testStabilizeGroupsHidesGroupSummary() {
+ // GIVEN one group child with a summary
+ addGroupChild(0, PACKAGE_1, GROUP_1);
+ addGroupSummary(1, PACKAGE_1, GROUP_1);
+
+ dispatchBuild(); // group summary is hidden because it needs at least 2 children to group
+
+ // GIVEN visual stability manager doesn't allow any group changes
+ mListBuilder.setNotifStabilityManager(
+ new TestableStabilityManager().setAllowGroupChanges(false));
+
+ // WHEN we run the pipeline with the addition of a child
+ addGroupChild(2, PACKAGE_1, GROUP_1);
+
+ dispatchBuild();
+
+ // THEN the children notifications are top-level and the summary still doesn't show yet
+ // because group changes aren't allowed by the stability manager
+ verifyBuiltList(
+ notif(0),
+ notif(2)
+ );
+ }
+
+ @Test
+ public void testStabilizeGroupsDelayedSummaryRendersAllNotifsTopLevel() {
+ // GIVEN group children posted without a summary
+ addGroupChild(0, PACKAGE_1, GROUP_1);
+ addGroupChild(1, PACKAGE_1, GROUP_1);
+ addGroupChild(2, PACKAGE_1, GROUP_1);
+ addGroupChild(3, PACKAGE_1, GROUP_1);
+
+ dispatchBuild();
+
+ // GIVEN visual stability manager doesn't allow any group changes
+ final TestableStabilityManager stabilityManager =
+ new TestableStabilityManager().setAllowGroupChanges(false);
+ mListBuilder.setNotifStabilityManager(stabilityManager);
+
+ // WHEN the delayed summary is posted
+ addGroupSummary(4, PACKAGE_1, GROUP_1);
+
+ dispatchBuild();
+
+ // THEN all entries are top-level since group changes aren't allowed
+ verifyBuiltList(
+ notif(0),
+ notif(1),
+ notif(2),
+ notif(3),
+ notif(4)
+ );
+
+ // WHEN visual stability manager allows group changes again
+ stabilityManager.setAllowGroupChanges(true);
+ stabilityManager.invalidateList();
+
+ // THEN entries are grouped
+ verifyBuiltList(
+ group(
+ summary(4),
+ child(0),
+ child(1),
+ child(2),
+ child(3)
+ )
+ );
+ }
+
+ @Test
+ public void testStabilizeSectionDisallowsNewSection() {
+ // GIVEN one non-default sections
+ final NotifSectioner originalSectioner = new PackageSectioner(PACKAGE_1);
+ mListBuilder.setSectioners(List.of(originalSectioner));
+
+ // GIVEN notifications that's sectioned by sectioner1
+ addNotif(0, PACKAGE_1);
+ dispatchBuild();
+ assertEquals(originalSectioner, mEntrySet.get(0).getSection().getSectioner());
+
+ // WHEN section changes aren't allowed
+ final TestableStabilityManager stabilityManager =
+ new TestableStabilityManager().setAllowSectionChanges(false);
+ mListBuilder.setNotifStabilityManager(stabilityManager);
+
+ // WHEN we try to change the section
+ final NotifSectioner newSectioner = new PackageSectioner(PACKAGE_1);
+ mListBuilder.setSectioners(List.of(newSectioner, originalSectioner));
+ dispatchBuild();
+
+ // THEN the section remains the same since section changes aren't allowed
+ assertEquals(originalSectioner, mEntrySet.get(0).getSection().getSectioner());
+
+ // WHEN section changes are allowed again
+ stabilityManager.setAllowSectionChanges(true);
+ stabilityManager.invalidateList();
+
+ // THEN the section updates
+ assertEquals(newSectioner, mEntrySet.get(0).getSection().getSectioner());
+ }
+
+ @Test
public void testDispatchListOnBeforeSort() {
// GIVEN a registered OnBeforeSortListener
RecordingOnBeforeSortListener listener =
@@ -999,8 +1192,8 @@
@Test
public void testDispatchListOnBeforeRender() {
// GIVEN a registered OnBeforeRenderList
- RecordingOnBeforeRenderistener listener =
- new RecordingOnBeforeRenderistener();
+ RecordingOnBeforeRenderListener listener =
+ new RecordingOnBeforeRenderListener();
mListBuilder.addOnBeforeRenderListListener(listener);
// GIVEN some new notifs out of order
@@ -1450,7 +1643,7 @@
}
}
- private static class RecordingOnBeforeRenderistener
+ private static class RecordingOnBeforeRenderListener
implements OnBeforeRenderListListener {
List<ListEntry> mEntriesReceived;
@@ -1460,6 +1653,39 @@
}
}
+ private static class TestableStabilityManager extends NotifStabilityManager {
+ boolean mAllowGroupChanges = true;
+ boolean mAllowSectionChanges = true;
+
+ TestableStabilityManager() {
+ super("Test");
+ }
+
+ TestableStabilityManager setAllowGroupChanges(boolean allowGroupChanges) {
+ mAllowGroupChanges = allowGroupChanges;
+ return this;
+ }
+
+ TestableStabilityManager setAllowSectionChanges(boolean allowSectionChanges) {
+ mAllowSectionChanges = allowSectionChanges;
+ return this;
+ }
+
+ @Override
+ public void onBeginRun() {
+ }
+
+ @Override
+ public boolean isGroupChangeAllowed(NotificationEntry entry) {
+ return mAllowGroupChanges;
+ }
+
+ @Override
+ public boolean isSectionChangeAllowed(NotificationEntry entry) {
+ return mAllowSectionChanges;
+ }
+ }
+
private static final String PACKAGE_1 = "com.test1";
private static final String PACKAGE_2 = "com.test2";
private static final String PACKAGE_3 = "org.test3";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
index 09c9bcd..711f0ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
@@ -26,6 +26,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.render.NodeController
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
import org.junit.Assert.assertFalse
@@ -47,12 +48,10 @@
private lateinit var promoter: NotifPromoter
private lateinit var peopleSectioner: NotifSectioner
- @Mock
- private lateinit var pipeline: NotifPipeline
- @Mock
- private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
- @Mock
- private lateinit var channel: NotificationChannel
+ @Mock private lateinit var pipeline: NotifPipeline
+ @Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
+ @Mock private lateinit var channel: NotificationChannel
+ @Mock private lateinit var headerController: NodeController
private lateinit var entry: NotificationEntry
private lateinit var coordinator: ConversationCoordinator
@@ -60,7 +59,7 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- coordinator = ConversationCoordinator(peopleNotificationIdentifier)
+ coordinator = ConversationCoordinator(peopleNotificationIdentifier, headerController)
whenever(channel.isImportantConversation).thenReturn(true)
coordinator.attach(pipeline)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
index fa992a5..7e771ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
@@ -39,6 +39,7 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.notification.collection.render.NodeController;
import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback;
@@ -73,6 +74,7 @@
@Mock private NotificationRemoteInputManager mRemoteInputManager;
@Mock private RemoteInputController mRemoteInputController;
@Mock private NotifLifetimeExtender.OnEndLifetimeExtensionCallback mEndLifetimeExtension;
+ @Mock private NodeController mHeaderController;
private NotificationEntry mEntry;
@@ -85,8 +87,8 @@
mHeadsUpManager,
mHeadsUpViewBinder,
mNotificationInterruptStateProvider,
- mRemoteInputManager
- );
+ mRemoteInputManager,
+ mHeaderController);
mCoordinator.attach(mNotifPipeline);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
index 3a7d28a..1031d6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
@@ -38,6 +38,7 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.render.NodeController;
import org.junit.Before;
import org.junit.Test;
@@ -54,6 +55,8 @@
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private HighPriorityProvider mHighPriorityProvider;
@Mock private NotifPipeline mNotifPipeline;
+ @Mock private NodeController mAlertingHeaderController;
+ @Mock private NodeController mSilentHeaderController;
@Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor;
@@ -67,8 +70,9 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- RankingCoordinator rankingCoordinator =
- new RankingCoordinator(mStatusBarStateController, mHighPriorityProvider);
+ RankingCoordinator rankingCoordinator = new RankingCoordinator(
+ mStatusBarStateController, mHighPriorityProvider, mAlertingHeaderController,
+ mSilentHeaderController);
mEntry = new NotificationEntryBuilder().build();
rankingCoordinator.attach(mNotifPipeline);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index 605b4d1..4edca7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -296,6 +296,22 @@
}
@Test
+ public void testNotSuppressingGroupChangesAnymore_invalidationCalled() {
+ // GIVEN visual stability is being maintained b/c panel is expanded
+ setPulsing(false);
+ setScreenOn(true);
+ setPanelExpanded(true);
+
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // WHEN the panel isn't expanded anymore
+ setPanelExpanded(false);
+
+ // invalidate is called because we were previously suppressing a group change
+ verifyInvalidateCalled(true);
+ }
+
+ @Test
public void testHeadsUp_allowedToChangeGroupAndSection() {
// GIVEN group + section changes disallowed
setScreenOn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
index 5aeb43f..edb8776 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
@@ -49,6 +49,7 @@
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import org.junit.Before;
import org.junit.Test;
@@ -71,6 +72,7 @@
@Mock private NotificationEntryManager mEntryManager;
@Mock private NotificationMenuRow mMenuRow;
@Mock private NotificationMenuRowPlugin.MenuItem mMenuItem;
+ @Mock private GroupMembershipManager mGroupMembershipManager;
@Before
public void setUp() {
@@ -89,7 +91,8 @@
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
mBlockingHelperManager = new NotificationBlockingHelperManager(
- mContext, mGutsManager, mEntryManager, mock(MetricsLogger.class));
+ mContext, mGutsManager, mEntryManager, mock(MetricsLogger.class),
+ mGroupMembershipManager);
// By default, have the shade visible/expanded.
mBlockingHelperManager.setNotificationShadeExpanded(1f);
}
@@ -185,6 +188,7 @@
.build();
assertFalse(childRow.getIsNonblockable());
+ when(mGroupMembershipManager.isOnlyChildInGroup(childRow.getEntry())).thenReturn(true);
assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(childRow, mMenuRow));
verify(mGutsManager).openGuts(childRow, 0, 0, mMenuItem);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 7ca2478..8cd7103 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -53,6 +53,7 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -63,6 +64,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -87,6 +89,10 @@
@Mock private NotificationRowComponent mNotificationRowComponent;
@Mock private ActivatableNotificationViewController mActivatableNotificationViewController;
@Mock private NotificationSectionsLogger mLogger;
+ @Mock private SectionHeaderController mIncomingHeaderController;
+ @Mock private SectionHeaderController mPeopleHeaderController;
+ @Mock private SectionHeaderController mAlertingHeaderController;
+ @Mock private SectionHeaderController mSilentHeaderController;
private NotificationSectionsManager mSectionsManager;
@@ -109,15 +115,21 @@
});
when(mNotificationRowComponent.getActivatableNotificationViewController())
.thenReturn(mActivatableNotificationViewController);
+ when(mIncomingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
+ when(mPeopleHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
+ when(mAlertingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
+ when(mSilentHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
mSectionsManager =
new NotificationSectionsManager(
- mActivityStarterDelegate,
mStatusBarStateController,
mConfigurationController,
- mPeopleHubAdapter,
mKeyguardMediaController,
mSectionsFeatureManager,
- mLogger
+ mLogger,
+ mIncomingHeaderController,
+ mPeopleHeaderController,
+ mAlertingHeaderController,
+ mSilentHeaderController
);
// Required in order for the header inflation to work properly
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
@@ -241,8 +253,9 @@
mSectionsManager.updateSectionBoundaries();
clearInvocations(mNssl);
+ SectionHeaderView silentHeaderView = mSectionsManager.getSilentHeaderView();
ViewGroup transientParent = mock(ViewGroup.class);
- mSectionsManager.getSilentHeaderView().setTransientContainer(transientParent);
+ when(silentHeaderView.getTransientContainer()).thenReturn(transientParent);
// WHEN the LO section reappears
setStackState(
@@ -252,8 +265,8 @@
// THEN the header is first removed from the transient parent before being added to the
// NSSL.
- verify(transientParent).removeTransientView(mSectionsManager.getSilentHeaderView());
- verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 1);
+ verify(transientParent).removeTransientView(silentHeaderView);
+ verify(mNssl).addView(silentHeaderView, 1);
}
@Test
@@ -358,23 +371,6 @@
}
@Test
- public void testPeopleFiltering_keepPeopleHeaderWhenSectionEmpty() {
- mSectionsManager.setPeopleHubVisible(true);
- enablePeopleFiltering();
-
- setStackState(
- PEOPLE_HEADER,
- ALERTING_HEADER,
- ALERTING,
- GENTLE_HEADER,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- verify(mNssl, never()).removeView(mSectionsManager.getPeopleHeaderView());
- verify(mNssl).changeViewPosition(mSectionsManager.getPeopleHeaderView(), 0);
- }
-
- @Test
public void testPeopleFiltering_AlertingHunWhilePeopleVisible() {
enablePeopleFiltering();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index f48e6ea79..81cbef7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -16,6 +16,8 @@
import static android.provider.Settings.Secure.NOTIFICATION_HISTORY_ENABLED;
import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -43,44 +45,26 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.EmptyShadeView;
-import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
-import com.android.systemui.statusbar.notification.NotificationFilter;
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
-import com.android.systemui.statusbar.notification.collection.NotifCollection;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
-import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.KeyguardBypassEnabledProvider;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.util.leak.LeakDetector;
import org.junit.After;
import org.junit.Before;
@@ -92,9 +76,6 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Tests for {@link NotificationStackScrollLayout}.
*/
@@ -109,7 +90,6 @@
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Mock private StatusBar mBar;
@Mock private SysuiStatusBarStateController mBarState;
- @Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private NotificationBlockingHelperManager mBlockingHelperManager;
@Mock private NotificationGroupManagerLegacy mGroupMembershipManger;
@Mock private NotificationGroupManagerLegacy mGroupExpansionManager;
@@ -122,11 +102,9 @@
@Mock private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider;
@Mock private NotificationSectionsManager mNotificationSectionsManager;
@Mock private NotificationSection mNotificationSection;
- @Mock private FeatureFlags mFeatureFlags;
@Mock private SysuiStatusBarStateController mStatusBarStateController;
@Mock private NotificationSwipeHelper mNotificationSwipeHelper;
- @Mock NotificationStackScrollLayoutController mStackScrollLayoutController;
- private NotificationEntryManager mEntryManager;
+ @Mock private NotificationStackScrollLayoutController mStackScrollLayoutController;
private int mOriginalInterruptionModelSetting;
private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
@@ -154,31 +132,6 @@
mRemoteInputManager);
mDependency.injectMockDependency(ShadeController.class);
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
-
- mEntryManager = new NotificationEntryManager(
- mock(NotificationEntryManagerLogger.class),
- mock(NotificationGroupManagerLegacy.class),
- new NotificationRankingManager(
- () -> mock(NotificationMediaManager.class),
- mGroupMembershipManger,
- mHeadsUpManager,
- mock(NotificationFilter.class),
- mock(NotificationEntryManagerLogger.class),
- mock(NotificationSectionsFeatureManager.class),
- mock(PeopleNotificationIdentifier.class),
- mock(HighPriorityProvider.class)
- ),
- mock(NotificationEntryManager.KeyguardEnvironment.class),
- mock(FeatureFlags.class),
- () -> mock(NotificationRowBinder.class),
- () -> mRemoteInputManager,
- mock(LeakDetector.class),
- mock(ForegroundServiceDismissalFeatureController.class),
- mock(IStatusBarService.class)
- );
- mEntryManager.setUpWithPresenter(mock(NotificationPresenter.class));
- when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
-
NotificationShelfController notificationShelfController =
mock(NotificationShelfController.class);
NotificationShelf notificationShelf = mock(NotificationShelf.class);
@@ -196,18 +149,13 @@
getContext(),
null,
mNotificationRoundnessManager,
- mock(DynamicPrivacyController.class),
mStatusBarStateController,
mNotificationSectionsManager,
mock(ForegroundServiceSectionController.class),
mock(ForegroundServiceDismissalFeatureController.class),
- mFeatureFlags,
- mock(NotifPipeline.class),
- mEntryManager,
- mock(NotifCollection.class),
- mUiEventLoggerFake,
mGroupMembershipManger,
- mGroupExpansionManager
+ mGroupExpansionManager,
+ mUiEventLoggerFake
);
mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider,
mNotificationSwipeHelper);
@@ -216,9 +164,9 @@
mStackScroller.setStatusBar(mBar);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
when(mStackScrollLayoutController.getNoticationRoundessManager())
- .thenReturn(mock(NotificationRoundnessManager.class));
+ .thenReturn(mNotificationRoundnessManager);
mStackScroller.setController(mStackScrollLayoutController);
-
+
// Stub out functionality that isn't necessary to test.
doNothing().when(mBar)
.executeRunnableDismissingKeyguard(any(Runnable.class),
@@ -323,8 +271,6 @@
@Test
public void testUpdateFooter_noNotifications() {
setBarStateForTest(StatusBarState.SHADE);
- assertEquals(0, mEntryManager.getActiveNotificationsCount());
-
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
mStackScroller.updateFooter();
@@ -334,15 +280,15 @@
@Test
public void testUpdateFooter_remoteInput() {
setBarStateForTest(StatusBarState.SHADE);
- ArrayList<NotificationEntry> entries = new ArrayList<>();
- entries.add(new NotificationEntryBuilder().build());
- addEntriesToEntryManager(entries);
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
when(row.canViewBeDismissed()).thenReturn(true);
when(mStackScroller.getChildCount()).thenReturn(1);
when(mStackScroller.getChildAt(anyInt())).thenReturn(row);
when(mRemoteInputController.isRemoteInputActive()).thenReturn(true);
+ when(mStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL))
+ .thenReturn(true);
+ when(mStackScrollLayoutController.hasActiveNotifications()).thenReturn(true);
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
@@ -354,14 +300,9 @@
public void testUpdateFooter_oneClearableNotification() {
setBarStateForTest(StatusBarState.SHADE);
- ArrayList<NotificationEntry> entries = new ArrayList<>();
- entries.add(new NotificationEntryBuilder().build());
- addEntriesToEntryManager(entries);
-
- ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
- when(row.canViewBeDismissed()).thenReturn(true);
- when(mStackScroller.getChildCount()).thenReturn(1);
- when(mStackScroller.getChildAt(anyInt())).thenReturn(row);
+ when(mStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL))
+ .thenReturn(true);
+ when(mStackScrollLayoutController.hasActiveNotifications()).thenReturn(true);
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
@@ -373,9 +314,13 @@
public void testUpdateFooter_oneNonClearableNotification() {
setBarStateForTest(StatusBarState.SHADE);
- ArrayList<NotificationEntry> entries = new ArrayList<>();
- entries.add(new NotificationEntryBuilder().build());
- addEntriesToEntryManager(entries);
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+ when(row.canViewBeDismissed()).thenReturn(false);
+ when(mStackScroller.getChildCount()).thenReturn(1);
+ when(mStackScroller.getChildAt(anyInt())).thenReturn(row);
+ when(mStackScrollLayoutController.hasActiveNotifications()).thenReturn(true);
+ when(mStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL))
+ .thenReturn(false);
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
@@ -435,7 +380,7 @@
@Test
public void testClearNotifications_All() {
- mStackScroller.clearNotifications(NotificationStackScrollLayout.ROWS_ALL, true);
+ mStackScroller.clearNotifications(ROWS_ALL, true);
assertEquals(1, mUiEventLoggerFake.numLogs());
assertEquals(NotificationStackScrollLayout.NotificationPanelEvent
.DISMISS_ALL_NOTIFICATIONS_PANEL.getId(), mUiEventLoggerFake.eventId(0));
@@ -451,8 +396,8 @@
@Test
public void testAddNotificationUpdatesSpeedBumpIndex() {
- // initial state == -1
- assertEquals(-1, mStackScroller.getSpeedBumpIndex());
+ // initial state calculated == 0
+ assertEquals(0, mStackScroller.getSpeedBumpIndex());
// add notification that's before the speed bump
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
@@ -467,8 +412,8 @@
@Test
public void testAddAmbientNotificationNoSpeedBumpUpdate() {
- // initial state == -1
- assertEquals(-1, mStackScroller.getSpeedBumpIndex());
+ // initial state calculated == 0
+ assertEquals(0, mStackScroller.getSpeedBumpIndex());
// add notification that's after the speed bump
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
@@ -483,8 +428,8 @@
@Test
public void testRemoveNotificationUpdatesSpeedBump() {
- // initial state == -1
- assertEquals(-1, mStackScroller.getSpeedBumpIndex());
+ // initial state calculated == 0
+ assertEquals(0, mStackScroller.getSpeedBumpIndex());
// add 3 notification that are after the speed bump
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
@@ -508,10 +453,4 @@
// rather than the mock because the spy just coppied the anonymous inner /shruggie.
mStackScroller.setStatusBarState(state);
}
-
- private void addEntriesToEntryManager(List<NotificationEntry> entries) {
- for (NotificationEntry e : entries) {
- mEntryManager.addActiveNotificationForTest(e);
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
index 32c6828..60d6c53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
@@ -37,6 +37,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.media.KeyguardMediaController;
@@ -44,11 +45,16 @@
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotifCollection;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
+import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
@@ -76,53 +82,38 @@
@RunWith(AndroidTestingRunner.class)
public class NotificationStackScrollerControllerTest extends SysuiTestCase {
- @Mock
- private NotificationGutsManager mNotificationGutsManager;
- @Mock
- private HeadsUpManagerPhone mHeadsUpManager;
- @Mock
- private NotificationRoundnessManager mNotificationRoundnessManager;
- @Mock
- private TunerService mTunerService;
- @Mock
- private DynamicPrivacyController mDynamicPrivacyController;
- @Mock
- private ConfigurationController mConfigurationController;
- @Mock
- private NotificationStackScrollLayout mNotificationStackScrollLayout;
- @Mock
- private ZenModeController mZenModeController;
- @Mock
- private KeyguardMediaController mKeyguardMediaController;
- @Mock
- private SysuiStatusBarStateController mSysuiStatusBarStateController;
- @Mock
- private KeyguardBypassController mKeyguardBypassController;
- @Mock
- private SysuiColorExtractor mColorExtractor;
- @Mock
- private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
- @Mock
- private MetricsLogger mMetricsLogger;
- @Mock
- private FalsingManager mFalsingManager;
- @Mock
- private NotificationSectionsManager mNotificationSectionsManager;
- @Mock
- private Resources mResources;
+ @Mock private NotificationGutsManager mNotificationGutsManager;
+ @Mock private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
+ @Mock private TunerService mTunerService;
+ @Mock private DynamicPrivacyController mDynamicPrivacyController;
+ @Mock private ConfigurationController mConfigurationController;
+ @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
+ @Mock private ZenModeController mZenModeController;
+ @Mock private KeyguardMediaController mKeyguardMediaController;
+ @Mock private SysuiStatusBarStateController mSysuiStatusBarStateController;
+ @Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private SysuiColorExtractor mColorExtractor;
+ @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
+ @Mock private MetricsLogger mMetricsLogger;
+ @Mock private FalsingManager mFalsingManager;
+ @Mock private NotificationSectionsManager mNotificationSectionsManager;
+ @Mock private Resources mResources;
@Mock(answer = Answers.RETURNS_SELF)
private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
- @Mock
- private NotificationSwipeHelper mNotificationSwipeHelper;
- @Mock
- private StatusBar mStatusBar;
- @Mock
- private ScrimController mScrimController;
- @Mock
- private NotificationGroupManagerLegacy mLegacyGroupManager;
+ @Mock private NotificationSwipeHelper mNotificationSwipeHelper;
+ @Mock private StatusBar mStatusBar;
+ @Mock private ScrimController mScrimController;
+ @Mock private NotificationGroupManagerLegacy mLegacyGroupManager;
+ @Mock private SectionHeaderController mSilentHeaderController;
+ @Mock private FeatureFlags mFeatureFlags;
+ @Mock private NotifPipeline mNotifPipeline;
+ @Mock private NotifCollection mNotifCollection;
+ @Mock private NotificationEntryManager mEntryManager;
+ @Mock private IStatusBarService mIStatusBarService;
@Captor
- ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
+ private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
private NotificationStackScrollLayoutController mController;
@@ -131,6 +122,7 @@
MockitoAnnotations.initMocks(this);
when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper);
+ when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
mController = new NotificationStackScrollLayoutController(
true,
@@ -154,7 +146,13 @@
mStatusBar,
mScrimController,
mLegacyGroupManager,
- mLegacyGroupManager
+ mLegacyGroupManager,
+ mSilentHeaderController,
+ mFeatureFlags,
+ mNotifPipeline,
+ mNotifCollection,
+ mEntryManager,
+ mIStatusBarService
);
when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true);
@@ -254,7 +252,6 @@
UserChangedListener changedListener = userChangedCaptor.getValue();
changedListener.onUserChanged(0);
- verify(mNotificationStackScrollLayout).setCurrentUserid(0);
verify(mNotificationStackScrollLayout).updateSensitiveness(false, true);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 0a041e4..1b05ad7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -38,16 +38,16 @@
import android.testing.TestableLooper;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardHostViewController;
+import com.android.keyguard.KeyguardRootViewController;
import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.DismissCallbackRegistry;
@@ -76,13 +76,9 @@
@Mock
private ViewMediatorCallback mViewMediatorCallback;
@Mock
- private LockPatternUtils mLockPatternUtils;
- @Mock
private DismissCallbackRegistry mDismissCallbackRegistry;
@Mock
- private KeyguardHostView mKeyguardHostView;
- @Mock
- private ViewTreeObserver mViewTreeObserver;
+ private KeyguardHostViewController mKeyguardHostViewController;
@Mock
private KeyguardBouncer.BouncerExpansionCallback mExpansionCallback;
@Mock
@@ -96,7 +92,13 @@
@Mock
private KeyguardSecurityModel mKeyguardSecurityModel;
@Mock
+ private KeyguardRootViewController mRootViewController;
+ @Mock
private ViewGroup mRootView;
+ @Mock
+ private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+ @Mock
+ private KeyguardBouncerComponent mKeyguardBouncerComponent;
@Rule
public MockitoRule mRule = MockitoJUnit.rule();
private Integer mRootVisibility = View.INVISIBLE;
@@ -106,7 +108,6 @@
public void setup() {
allowTestableLooperAsMainThread();
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
- mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
mDependency.injectMockDependency(KeyguardStateController.class);
when(mRootView.getVisibility()).thenAnswer((Answer<Integer>) invocation -> mRootVisibility);
doAnswer(invocation -> {
@@ -116,19 +117,22 @@
when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
.thenReturn(KeyguardSecurityModel.SecurityMode.None);
DejankUtils.setImmediate(true);
+ when(mKeyguardBouncerComponentFactory.create()).thenReturn(mKeyguardBouncerComponent);
+ when(mKeyguardBouncerComponent.getKeyguardHostViewController())
+ .thenReturn(mKeyguardHostViewController);
+ when(mKeyguardBouncerComponent.getKeyguardRootViewController())
+ .thenReturn(mRootViewController);
+
+ when(mRootViewController.getView()).thenReturn(mRootView);
+ when(mRootView.getResources()).thenReturn(mContext.getResources());
+
final ViewGroup container = new FrameLayout(getContext());
- when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
- when(mKeyguardHostView.getHeight()).thenReturn(500);
- mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
- mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
- mExpansionCallback, mKeyguardStateController, mKeyguardUpdateMonitor,
- mKeyguardBypassController, mHandler) {
- @Override
- protected void inflateView() {
- mKeyguardView = mKeyguardHostView;
- mRoot = mRootView;
- }
- };
+ mBouncer = new KeyguardBouncer.Factory(getContext(), mViewMediatorCallback,
+ mDismissCallbackRegistry, mFalsingManager,
+ mKeyguardStateController, mKeyguardUpdateMonitor,
+ mKeyguardBypassController, mHandler, mKeyguardSecurityModel,
+ mKeyguardBouncerComponentFactory)
+ .create(container, mExpansionCallback);
}
@Test
@@ -154,12 +158,10 @@
mBouncer.ensureView();
mBouncer.setExpansion(1);
- reset(mKeyguardHostView);
- when(mKeyguardHostView.getHeight()).thenReturn(500);
+ reset(mKeyguardHostViewController);
mBouncer.show(true);
- verify(mKeyguardHostView).setAlpha(eq(1f));
- verify(mKeyguardHostView).setTranslationY(eq(0f));
+ verify(mKeyguardHostViewController).setExpansion(0);
}
@Test
@@ -177,23 +179,23 @@
@Test
public void testShow_triesToDismissKeyguard() {
mBouncer.show(true);
- verify(mKeyguardHostView).dismiss(anyInt());
+ verify(mKeyguardHostViewController).dismiss(anyInt());
}
@Test
public void testShow_resetsSecuritySelection() {
mBouncer.show(false);
- verify(mKeyguardHostView, never()).showPrimarySecurityScreen();
+ verify(mKeyguardHostViewController, never()).showPrimarySecurityScreen();
mBouncer.hide(false);
mBouncer.show(true);
- verify(mKeyguardHostView).showPrimarySecurityScreen();
+ verify(mKeyguardHostViewController).showPrimarySecurityScreen();
}
@Test
public void testShow_animatesKeyguardView() {
mBouncer.show(true);
- verify(mKeyguardHostView).startAppearAnimation();
+ verify(mKeyguardHostViewController).appear(anyInt());
}
@Test
@@ -201,7 +203,7 @@
final String errorMessage = "an error message";
when(mViewMediatorCallback.consumeCustomMessage()).thenReturn(errorMessage);
mBouncer.show(true);
- verify(mKeyguardHostView).showErrorMessage(eq(errorMessage));
+ verify(mKeyguardHostViewController).showErrorMessage(eq(errorMessage));
}
@Test
@@ -218,10 +220,10 @@
verify(mExpansionCallback).onFullyShown();
verify(mExpansionCallback, never()).onStartingToHide();
- verify(mKeyguardHostView, never()).onStartingToHide();
+ verify(mKeyguardHostViewController, never()).onStartingToHide();
mBouncer.setExpansion(0.9f);
verify(mExpansionCallback).onStartingToHide();
- verify(mKeyguardHostView).onStartingToHide();
+ verify(mKeyguardHostViewController).onStartingToHide();
}
@Test
@@ -230,7 +232,7 @@
mBouncer.setExpansion(0.1f);
mBouncer.setExpansion(0);
- verify(mKeyguardHostView).onResume();
+ verify(mKeyguardHostViewController).onResume();
verify(mRootView).announceForAccessibility(any());
}
@@ -267,7 +269,7 @@
public void testShowPromptReason_propagates() {
mBouncer.ensureView();
mBouncer.showPromptReason(1);
- verify(mKeyguardHostView).showPromptReason(eq(1));
+ verify(mKeyguardHostViewController).showPromptReason(eq(1));
}
@Test
@@ -275,7 +277,8 @@
final String message = "a message";
mBouncer.ensureView();
mBouncer.showMessage(message, ColorStateList.valueOf(Color.GREEN));
- verify(mKeyguardHostView).showMessage(eq(message), eq(ColorStateList.valueOf(Color.GREEN)));
+ verify(mKeyguardHostViewController).showMessage(
+ eq(message), eq(ColorStateList.valueOf(Color.GREEN)));
}
@Test
@@ -283,7 +286,7 @@
final OnDismissAction dismissAction = () -> false;
final Runnable cancelAction = () -> {};
mBouncer.showWithDismissAction(dismissAction, cancelAction);
- verify(mKeyguardHostView).setOnDismissAction(dismissAction, cancelAction);
+ verify(mKeyguardHostViewController).setOnDismissAction(dismissAction, cancelAction);
Assert.assertTrue("Should be showing", mBouncer.isShowing());
}
@@ -297,7 +300,7 @@
ran[0] = false;
mBouncer.ensureView();
mBouncer.startPreHideAnimation(r);
- verify(mKeyguardHostView).startDisappearAnimation(r);
+ verify(mKeyguardHostViewController).startDisappearAnimation(r);
Assert.assertFalse("Callback should have been deferred", ran[0]);
}
@@ -322,16 +325,14 @@
public void testSetExpansion() {
mBouncer.ensureView();
mBouncer.setExpansion(0.5f);
- verify(mKeyguardHostView).setAlpha(anyFloat());
- verify(mKeyguardHostView).setTranslationY(anyFloat());
+ verify(mKeyguardHostViewController).setExpansion(0.5f);
}
@Test
public void testIsFullscreenBouncer_asksKeyguardView() {
mBouncer.ensureView();
mBouncer.isFullscreenBouncer();
- verify(mKeyguardHostView).getCurrentSecurityMode();
- verify(mKeyguardHostView, never()).getSecurityMode();
+ verify(mKeyguardHostViewController).getCurrentSecurityMode();
}
@Test
@@ -346,21 +347,18 @@
@Test
public void testIsHiding_skipsTranslation() {
mBouncer.show(false /* reset */);
- reset(mKeyguardHostView);
+ reset(mKeyguardHostViewController);
mBouncer.startPreHideAnimation(null /* runnable */);
mBouncer.setExpansion(0.5f);
- verify(mKeyguardHostView, never()).setTranslationY(anyFloat());
- verify(mKeyguardHostView, never()).setAlpha(anyFloat());
+ verify(mKeyguardHostViewController, never()).setExpansion(anyFloat());
}
@Test
public void testIsSecure() {
- Assert.assertTrue("Bouncer is secure before inflating views", mBouncer.isSecure());
-
mBouncer.ensureView();
for (KeyguardSecurityModel.SecurityMode mode : KeyguardSecurityModel.SecurityMode.values()){
- reset(mKeyguardHostView);
- when(mKeyguardHostView.getSecurityMode()).thenReturn(mode);
+ reset(mKeyguardSecurityModel);
+ when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(mode);
Assert.assertEquals("Security doesn't match for mode: " + mode,
mBouncer.isSecure(), mode != KeyguardSecurityModel.SecurityMode.None);
}
@@ -392,7 +390,7 @@
public void testWillDismissWithAction() {
mBouncer.ensureView();
Assert.assertFalse("Action not set yet", mBouncer.willDismissWithAction());
- when(mKeyguardHostView.hasDismissActions()).thenReturn(true);
+ when(mKeyguardHostViewController.hasDismissActions()).thenReturn(true);
Assert.assertTrue("Action should exist", mBouncer.willDismissWithAction());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 1083273..9832d31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -39,7 +39,6 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
@@ -92,9 +91,7 @@
@Mock
private FaceAuthScreenBrightnessController mFaceAuthScreenBrightnessController;
@Mock
- private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
- @Mock
- private KeyguardBouncerComponent mKeyguardBouncerComponent;
+ private KeyguardBouncer.Factory mKeyguardBouncerFactory;
@Mock
private KeyguardBouncer mBouncer;
@@ -107,11 +104,10 @@
when(mLockIconContainer.animate()).thenReturn(mock(ViewPropertyAnimator.class,
RETURNS_DEEP_STUBS));
- when(mKeyguardBouncerComponentFactory.build(
+ when(mKeyguardBouncerFactory.create(
any(ViewGroup.class),
any(KeyguardBouncer.BouncerExpansionCallback.class)))
- .thenReturn(mKeyguardBouncerComponent);
- when(mKeyguardBouncerComponent.createKeyguardBouncer()).thenReturn(mBouncer);
+ .thenReturn(mBouncer);
mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(
getContext(),
@@ -126,7 +122,7 @@
mKeyguardStateController,
Optional.of(mFaceAuthScreenBrightnessController),
mock(NotificationMediaManager.class),
- mKeyguardBouncerComponentFactory);
+ mKeyguardBouncerFactory);
mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
mNotificationPanelView, mBiometrucUnlockController,
mLockIconContainer, mNotificationContainer, mBypassController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 5143596..7d8a626 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -96,7 +96,6 @@
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationListener;
@@ -143,6 +142,7 @@
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.volume.VolumeComponent;
+import com.android.wm.shell.splitscreen.SplitScreen;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index ac9346f..94d5458 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.test.suitebuilder.annotation.SmallTest;
@@ -26,13 +27,20 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.pip.Pip;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.stackdivider.SplitScreen;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.tracing.ProtoTracer;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.onehanded.OneHandedGestureHandler;
+import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
+import com.android.wm.shell.splitscreen.SplitScreen;
import org.junit.Before;
import org.junit.Test;
@@ -51,16 +59,22 @@
@Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock ActivityManagerWrapper mActivityManagerWrapper;
@Mock DisplayImeController mDisplayImeController;
+ @Mock NavigationModeController mNavigationModeController;
+ @Mock ScreenLifecycle mScreenLifecycle;
+ @Mock SysUiState mSysUiState;
@Mock Pip mPip;
@Mock SplitScreen mSplitScreen;
+ @Mock OneHanded mOneHanded;
+ @Mock ShellTaskOrganizer mTaskOrganizer;
@Mock ProtoTracer mProtoTracer;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mWMShell = new WMShell(mContext, mCommandQueue, mKeyguardUpdateMonitor,
- mActivityManagerWrapper, mDisplayImeController, Optional.of(mPip),
- Optional.of(mSplitScreen), mProtoTracer);
+ mActivityManagerWrapper, mDisplayImeController, mNavigationModeController,
+ mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mSplitScreen),
+ Optional.of(mOneHanded), mTaskOrganizer, mProtoTracer);
}
@Test
@@ -85,4 +99,22 @@
verify(mActivityManagerWrapper).registerTaskStackListener(
any(TaskStackChangeListener.class));
}
+
+ @Test
+ public void initOneHanded_registersCallbacks() {
+ when(mOneHanded.hasOneHandedFeature()).thenReturn(true);
+ mWMShell.initOneHanded(mOneHanded);
+
+ verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
+ verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
+ verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
+ verify(mNavigationModeController).addListener(
+ any(NavigationModeController.ModeChangedListener.class));
+ verify(mActivityManagerWrapper).registerTaskStackListener(
+ any(TaskStackChangeListener.class));
+
+ verify(mOneHanded).registerGestureCallback(any(
+ OneHandedGestureHandler.OneHandedGestureEventCallback.class));
+ verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
+ }
}
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index c8becce..bf643cd 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -16,19 +16,9 @@
java_sdk_library {
name: "framework-tethering",
defaults: ["framework-module-defaults"],
+ impl_library_visibility: ["//frameworks/base/packages/Tethering:__subpackages__"],
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
- // Restrict access to implementation library.
- impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
- "//frameworks/base/packages/Tethering:__subpackages__",
- ],
-
- srcs: [
- ":framework-tethering-srcs",
- ],
+ srcs: [":framework-tethering-srcs"],
jarjar_rules: "jarjar-rules.txt",
installable: true,
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..e66d920
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M21.5,10.25c0-2.79-1.22-5.43-3.35-7.24c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06 C18.97,5.68,20,7.9,20,10.25c0,0.41,0.34,0.75,0.75,0.75S21.5,10.66,21.5,10.25z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2.5c-0.83,0-1.5,0.67-1.5,1.5v0.7C7.91,5.36,6,7.71,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h16v-2 c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4C13.5,3.17,12.83,2.5,12,2.5z M16.5,10.5V15 c0,1.21,0.86,2.22,2,2.45v0.05h-13v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5C7.5,8.02,9.52,6,12,6S16.5,8.02,16.5,10.5z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..2f5bdb0e
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.12,9.67C4.42,7.73,5.38,6,6.77,4.73C7.19,4.35,7.2,3.7,6.8,3.3c-0.39-0.39-1-0.39-1.4-0.03 C3.7,4.84,2.52,6.96,2.15,9.34c-0.1,0.61,0.37,1.16,0.99,1.16C3.63,10.5,4.04,10.15,4.12,9.67z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18.6,3.28c-0.4-0.37-1.02-0.36-1.4,0.02c-0.4,0.4-0.38,1.04,0.03,1.42c1.38,1.27,2.35,3,2.65,4.94 c0.08,0.49,0.5,0.84,0.98,0.84c0.61,0,1.09-0.55,0.99-1.16C21.47,6.96,20.29,4.84,18.6,3.28z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18,16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h15.6c0.45,0,0.67-0.54,0.35-0.85L18,16z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..c92bdf6
--- /dev/null
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M6.81,3.81L5.75,2.75C3.45,4.76,2,7.71,2,11h1.5C3.5,8.13,4.79,5.55,6.81,3.81z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M18.25,2.75l-1.06,1.06C19.21,5.55,20.5,8.13,20.5,11H22C22,7.71,20.55,4.76,18.25,2.75z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M18,10.5c0-4.38-2.72-5.57-4.5-5.89V4c0-1.59-1.43-1.5-1.5-1.5c-0.05,0-1.5-0.09-1.5,1.5v0.62C8.72,4.94,6,6.14,6,10.5v7 H4V19h16v-1.5h-2V10.5z M16.5,17.5h-9v-7C7.5,7.57,8.94,5.95,12,6c3.07-0.05,4.5,1.55,4.5,4.5V17.5z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M12,22c0.07,0,2,0.12,2-2h-4C10,22.12,11.91,22,12,22z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..8f854e7
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2.5c-0.69,0-1.25,0.56-1.25,1.25v0.77C8.04,5.11,6,7.51,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75 h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,17,19.25,17H18v-6.6c0-2.88-2.04-5.29-4.75-5.87V3.75C13.25,3.06,12.69,2.5,12,2.5z M16.5,10.4V17h-9v-6.6c0-2.48,2.02-4.5,4.5-4.5S16.5,7.91,16.5,10.4z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18.15,3.01c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06C18.97,5.68,20,7.9,20,10.25 c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75C21.5,7.46,20.28,4.82,18.15,3.01z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..e022c63
--- /dev/null
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M6.47,4.81c0.37-0.38,0.35-0.99-0.03-1.37c-0.4-0.4-1.05-0.39-1.44,0.02c-1.62,1.72-2.7,3.95-2.95,6.43 C2,10.48,2.46,11,3.05,11h0.01c0.51,0,0.93-0.38,0.98-0.88C4.24,8.07,5.13,6.22,6.47,4.81z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M18.99,3.47c-0.39-0.41-1.04-0.42-1.44-0.02c-0.38,0.38-0.39,0.98-0.03,1.37c1.34,1.41,2.23,3.26,2.43,5.3 c0.05,0.5,0.48,0.88,0.98,0.88h0.01c0.59,0,1.05-0.52,0.99-1.11C21.69,7.42,20.61,5.19,18.99,3.47z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M19,17h-1v-6c0-3.07-1.63-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5c-0.83,0-1.5,0.67-1.5,1.5v0.68C7.64,5.36,6,7.92,6,11 v6H5c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1C20,17.45,19.55,17,19,17z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..1e25d27
--- /dev/null
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright (C) 2020 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.
+-->
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M18,6.5L16.5,5H13V3h-2v2H7.5L6,6.5v11H4V19h16v-1.5h-2V6.5z M7.5,17.5v-11h9v11H7.5z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M6.81,3.81L5.75,2.75C3.45,4.76,2,7.71,2,11h1.5C3.5,8.13,4.79,5.55,6.81,3.81z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M18.25,2.75l-1.06,1.06C19.21,5.55,20.5,8.13,20.5,11H22C22,7.71,20.55,4.76,18.25,2.75z"/>
+</vector>
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index 3d6a128..4473754 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -72,7 +72,8 @@
};
/**
- * Register a UiAutomation. Only one may be registered at a time.
+ * Register a UiAutomation if it uses the accessibility subsystem. Only one may be registered
+ * at a time.
*
* @param owner A binder object owned by the process that owns the UiAutomation to be
* registered.
@@ -80,6 +81,7 @@
* @param accessibilityServiceInfo The UiAutomation's service info
* @param flags The UiAutomation's flags
* @param id The id for the service connection
+ * @see UiAutomation#FLAG_DONT_USE_ACCESSIBILITY
*/
void registerUiTestAutomationServiceLocked(IBinder owner,
IAccessibilityServiceClient serviceClient,
@@ -88,14 +90,15 @@
AccessibilitySecurityPolicy securityPolicy,
AbstractAccessibilityServiceConnection.SystemSupport systemSupport,
WindowManagerInternal windowManagerInternal,
- SystemActionPerformer systemActionPerfomer,
+ SystemActionPerformer systemActionPerformer,
AccessibilityWindowManager awm, int flags) {
synchronized (mLock) {
accessibilityServiceInfo.setComponentName(COMPONENT_NAME);
if (mUiAutomationService != null) {
- throw new IllegalStateException("UiAutomationService " + serviceClient
- + "already registered!");
+ throw new IllegalStateException(
+ "UiAutomationService " + mUiAutomationService.mServiceInterface
+ + "already registered!");
}
try {
@@ -106,12 +109,17 @@
return;
}
+ mUiAutomationFlags = flags;
mSystemSupport = systemSupport;
+ // Ignore registering UiAutomation if it is not allowed to use the accessibility
+ // subsystem.
+ if (!useAccessibility()) {
+ return;
+ }
mUiAutomationService = new UiAutomationService(context, accessibilityServiceInfo, id,
mainHandler, mLock, securityPolicy, systemSupport, windowManagerInternal,
- systemActionPerfomer, awm);
+ systemActionPerformer, awm);
mUiAutomationServiceOwner = owner;
- mUiAutomationFlags = flags;
mUiAutomationServiceInfo = accessibilityServiceInfo;
mUiAutomationService.mServiceInterface = serviceClient;
mUiAutomationService.onAdded();
@@ -130,15 +138,15 @@
void unregisterUiTestAutomationServiceLocked(IAccessibilityServiceClient serviceClient) {
synchronized (mLock) {
- if ((mUiAutomationService == null)
+ if (useAccessibility()
+ && ((mUiAutomationService == null)
|| (serviceClient == null)
|| (mUiAutomationService.mServiceInterface == null)
|| (serviceClient.asBinder()
- != mUiAutomationService.mServiceInterface.asBinder())) {
+ != mUiAutomationService.mServiceInterface.asBinder()))) {
throw new IllegalStateException("UiAutomationService " + serviceClient
+ " not registered!");
}
-
destroyUiAutomationService();
}
}
@@ -150,14 +158,19 @@
}
boolean isUiAutomationRunningLocked() {
- return (mUiAutomationService != null);
+ return (mUiAutomationService != null || !useAccessibility());
}
boolean suppressingAccessibilityServicesLocked() {
- return (mUiAutomationService != null) && ((mUiAutomationFlags
+ return (mUiAutomationService != null || !useAccessibility())
+ && ((mUiAutomationFlags
& UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0);
}
+ boolean useAccessibility() {
+ return ((mUiAutomationFlags & UiAutomation.FLAG_DONT_USE_ACCESSIBILITY) == 0);
+ }
+
boolean isTouchExplorationEnabledLocked() {
return (mUiAutomationService != null)
&& mUiAutomationService.mRequestTouchExplorationMode;
@@ -209,14 +222,14 @@
mUiAutomationService.onRemoved();
mUiAutomationService.resetLocked();
mUiAutomationService = null;
- mUiAutomationFlags = 0;
if (mUiAutomationServiceOwner != null) {
mUiAutomationServiceOwner.unlinkToDeath(
mUiAutomationServiceOwnerDeathRecipient, 0);
mUiAutomationServiceOwner = null;
}
- mSystemSupport.onClientChangeLocked(false);
}
+ mUiAutomationFlags = 0;
+ mSystemSupport.onClientChangeLocked(false);
}
}
@@ -227,9 +240,9 @@
int id, Handler mainHandler, Object lock,
AccessibilitySecurityPolicy securityPolicy,
SystemSupport systemSupport, WindowManagerInternal windowManagerInternal,
- SystemActionPerformer systemActionPerfomer, AccessibilityWindowManager awm) {
+ SystemActionPerformer systemActionPerformer, AccessibilityWindowManager awm) {
super(context, COMPONENT_NAME, accessibilityServiceInfo, id, mainHandler, lock,
- securityPolicy, systemSupport, windowManagerInternal, systemActionPerfomer,
+ securityPolicy, systemSupport, windowManagerInternal, systemActionPerformer,
awm);
mMainHandler = mainHandler;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index b6f2a47..c583dcc 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -37,6 +37,7 @@
import android.view.Display;
import android.view.MagnificationSpec;
import android.view.View;
+import android.view.accessibility.MagnificationAnimationCallback;
import android.view.animation.DecelerateInterpolator;
import com.android.internal.R;
@@ -63,7 +64,7 @@
private static final boolean DEBUG = false;
private static final String LOG_TAG = "FullScreenMagnificationController";
- private static final Runnable STUB_RUNNABLE = () -> {
+ private static final MagnificationAnimationCallback STUB_ANIMATION_CALLBACK = success -> {
};
public static final float MIN_SCALE = 1.0f;
public static final float MAX_SCALE = 8.0f;
@@ -304,18 +305,19 @@
}
}
- void sendSpecToAnimation(MagnificationSpec spec, Runnable endCallback) {
+ void sendSpecToAnimation(MagnificationSpec spec,
+ MagnificationAnimationCallback animationCallback) {
if (DEBUG) {
Slog.i(LOG_TAG,
- "sendSpecToAnimation(spec = " + spec + ", endCallback = " + endCallback
- + ")");
+ "sendSpecToAnimation(spec = " + spec + ", animationCallback = "
+ + animationCallback + ")");
}
if (Thread.currentThread().getId() == mMainThreadId) {
- mSpecAnimationBridge.updateSentSpecMainThread(spec, endCallback);
+ mSpecAnimationBridge.updateSentSpecMainThread(spec, animationCallback);
} else {
final Message m = PooledLambda.obtainMessage(
SpecAnimationBridge::updateSentSpecMainThread,
- mSpecAnimationBridge, spec, endCallback);
+ mSpecAnimationBridge, spec, animationCallback);
mControllerCtx.getHandler().sendMessage(m);
}
}
@@ -415,11 +417,11 @@
@GuardedBy("mLock")
boolean reset(boolean animate) {
- return reset(transformToStubRunnable(animate));
+ return reset(transformToStubCallback(animate));
}
@GuardedBy("mLock")
- boolean reset(Runnable endCallback) {
+ boolean reset(MagnificationAnimationCallback animationCallback) {
if (!mRegistered) {
return false;
}
@@ -430,7 +432,7 @@
onMagnificationChangedLocked();
}
mIdOfLastServiceToMagnify = INVALID_ID;
- sendSpecToAnimation(spec, endCallback);
+ sendSpecToAnimation(spec, animationCallback);
return changed;
}
@@ -458,24 +460,23 @@
final float centerX = normPivotX + offsetX;
final float centerY = normPivotY + offsetY;
mIdOfLastServiceToMagnify = id;
- return setScaleAndCenter(scale, centerX, centerY, transformToStubRunnable(animate), id);
+ return setScaleAndCenter(scale, centerX, centerY, transformToStubCallback(animate), id);
}
@GuardedBy("mLock")
boolean setScaleAndCenter(float scale, float centerX, float centerY,
- Runnable endCallback, int id) {
+ MagnificationAnimationCallback animationCallback, int id) {
if (!mRegistered) {
return false;
}
if (DEBUG) {
Slog.i(LOG_TAG,
"setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
- + ", centerY = " + centerY + ", endCallback = " + endCallback
- + ", id = " + id
- + ")");
+ + ", centerY = " + centerY + ", endCallback = "
+ + animationCallback + ", id = " + id + ")");
}
final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
- sendSpecToAnimation(mCurrentMagnificationSpec, endCallback);
+ sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback);
if (isMagnifying() && (id != INVALID_ID)) {
mIdOfLastServiceToMagnify = id;
}
@@ -875,7 +876,7 @@
* the spec did not change
*/
public boolean reset(int displayId, boolean animate) {
- return reset(displayId, animate ? STUB_RUNNABLE : null);
+ return reset(displayId, animate ? STUB_ANIMATION_CALLBACK : null);
}
/**
@@ -883,18 +884,19 @@
* transition.
*
* @param displayId The logical display id.
- * @param endCallback Called when the animation is ended or the spec did not change.
+ * @param animationCallback Called when the animation result is valid.
* {@code null} to transition immediately
* @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change
*/
- public boolean reset(int displayId, Runnable endCallback) {
+ public boolean reset(int displayId,
+ MagnificationAnimationCallback animationCallback) {
synchronized (mLock) {
final DisplayMagnification display = mDisplays.get(displayId);
if (display == null) {
return false;
}
- return display.reset(endCallback);
+ return display.reset(animationCallback);
}
}
@@ -946,7 +948,7 @@
return false;
}
return display.setScaleAndCenter(Float.NaN, centerX, centerY,
- animate ? STUB_RUNNABLE : null, id);
+ animate ? STUB_ANIMATION_CALLBACK : null, id);
}
}
@@ -970,7 +972,7 @@
public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY,
boolean animate, int id) {
return setScaleAndCenter(displayId, scale, centerX, centerY,
- transformToStubRunnable(animate), id);
+ transformToStubCallback(animate), id);
}
/**
@@ -984,20 +986,20 @@
* center and scale, or {@link Float#NaN} to leave unchanged
* @param centerY the screen-relative Y coordinate around which to
* center and scale, or {@link Float#NaN} to leave unchanged
- * @param endCallback called when the transition is finished successfully or the spec did not
- * change. {@code null} to transition immediately.
+ * @param animationCallback Called when the animation result is valid.
+ * {@code null} to transition immediately
* @param id the ID of the service requesting the change
* @return {@code true} if the magnification spec changed, {@code false} if
* the spec did not change
*/
public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY,
- Runnable endCallback, int id) {
+ MagnificationAnimationCallback animationCallback, int id) {
synchronized (mLock) {
final DisplayMagnification display = mDisplays.get(displayId);
if (display == null) {
return false;
}
- return display.setScaleAndCenter(scale, centerX, centerY, endCallback, id);
+ return display.setScaleAndCenter(scale, centerX, centerY, animationCallback, id);
}
}
@@ -1230,7 +1232,7 @@
private final ValueAnimator mValueAnimator;
// Called when the callee wants animating and the sent spec matches the target spec.
- private Runnable mEndCallback;
+ private MagnificationAnimationCallback mAnimationCallback;
private final Object mLock;
private final int mDisplayId;
@@ -1268,33 +1270,35 @@
}
}
- void updateSentSpecMainThread(MagnificationSpec spec, Runnable endCallback) {
+ void updateSentSpecMainThread(MagnificationSpec spec,
+ MagnificationAnimationCallback animationCallback) {
if (mValueAnimator.isRunning()) {
- // Avoid AnimationEnd Callback.
- mEndCallback = null;
mValueAnimator.cancel();
}
- mEndCallback = endCallback;
+ mAnimationCallback = animationCallback;
// If the current and sent specs don't match, update the sent spec.
synchronized (mLock) {
final boolean changed = !mSentMagnificationSpec.equals(spec);
if (changed) {
- if (mEndCallback != null) {
+ if (mAnimationCallback != null) {
animateMagnificationSpecLocked(spec);
} else {
setMagnificationSpecLocked(spec);
}
} else {
- sendEndCallbackMainThread();
+ sendEndCallbackMainThread(true);
}
}
}
- private void sendEndCallbackMainThread() {
- if (mEndCallback != null) {
- mEndCallback.run();
- mEndCallback = null;
+ private void sendEndCallbackMainThread(boolean success) {
+ if (mAnimationCallback != null) {
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "sendEndCallbackMainThread: " + success);
+ }
+ mAnimationCallback.onResult(success);
+ mAnimationCallback = null;
}
}
@@ -1337,17 +1341,16 @@
@Override
public void onAnimationStart(Animator animation) {
-
}
@Override
public void onAnimationEnd(Animator animation) {
- sendEndCallbackMainThread();
+ sendEndCallbackMainThread(true);
}
@Override
public void onAnimationCancel(Animator animation) {
-
+ sendEndCallbackMainThread(false);
}
@Override
@@ -1481,7 +1484,7 @@
}
@Nullable
- private static Runnable transformToStubRunnable(boolean animate) {
- return animate ? STUB_RUNNABLE : null;
+ private static MagnificationAnimationCallback transformToStubCallback(boolean animate) {
+ return animate ? STUB_ANIMATION_CALLBACK : null;
}
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerConstants.java b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
index d8c5f6f..4bd987a 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerConstants.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
@@ -112,7 +112,7 @@
}
public String getSettingValue(ContentResolver resolver) {
- return Settings.Secure.getString(resolver, SETTING);
+ return Settings.Secure.getStringForUser(resolver, SETTING, resolver.getUserId());
}
public synchronized void update(KeyValueListParser parser) {
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index b962539..16077cb 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -228,7 +228,7 @@
PackageManagerInternal.class);
RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
mBackupManagerService.getPackageManager(), allowApks, info, signatures,
- pmi, mUserId);
+ pmi, mUserId, mBackupEligibilityRules);
mManifestSignatures.put(info.packageName, signatures);
mPackagePolicies.put(pkg, restorePolicy);
mPackageInstallers.put(pkg, info.installerPackageName);
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 3789fa1..6963248 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -389,13 +389,29 @@
public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
boolean allowApks, FileMetadata info, Signature[] signatures,
PackageManagerInternal pmi, int userId) {
+ return chooseRestorePolicy(packageManager, allowApks, info, signatures, pmi, userId,
+ BackupEligibilityRules.forBackup(packageManager, pmi, userId));
+ }
+
+ /**
+ * Chooses restore policy.
+ *
+ * @param packageManager - PackageManager instance.
+ * @param allowApks - allow restore set to include apks.
+ * @param info - file metadata.
+ * @param signatures - array of signatures parsed from backup file.
+ * @param userId - ID of the user for which restore is performed.
+ * @param eligibilityRules - {@link BackupEligibilityRules} for this operation.
+ * @return a restore policy constant.
+ */
+ public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
+ boolean allowApks, FileMetadata info, Signature[] signatures,
+ PackageManagerInternal pmi, int userId, BackupEligibilityRules eligibilityRules) {
if (signatures == null) {
return RestorePolicy.IGNORE;
}
RestorePolicy policy = RestorePolicy.IGNORE;
- BackupEligibilityRules eligibilityRules = BackupEligibilityRules.forBackup(packageManager,
- pmi, userId);
// Okay, got the manifest info we need...
try {
PackageInfo pkgInfo = packageManager.getPackageInfoAsUser(
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 65ac784..d92706d 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -39,6 +39,7 @@
import android.os.BatteryProperty;
import android.os.BatteryStats;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.FileUtils;
@@ -59,6 +60,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.service.battery.BatteryServiceDumpProto;
+import android.sysprop.PowerProperties;
import android.util.EventLog;
import android.util.MutableInt;
import android.util.Slog;
@@ -182,6 +184,7 @@
private int mChargeStartLevel;
private boolean mUpdatesStopped;
+ private boolean mBatteryInputSuspended;
private Led mLed;
@@ -234,6 +237,8 @@
invalidChargerObserver.startObserving(
"DEVPATH=/devices/virtual/switch/invalid_charger");
}
+
+ mBatteryInputSuspended = PowerProperties.battery_input_suspended().orElse(false);
}
@Override
@@ -876,6 +881,10 @@
pw.println(" reset [-f]");
pw.println(" Unfreeze battery state, returning to current hardware values.");
pw.println(" -f: force a battery change broadcast be sent, prints new sequence.");
+ if (Build.IS_DEBUGGABLE) {
+ pw.println(" disable_charge");
+ pw.println(" Suspend charging even if plugged in. ");
+ }
}
static final int OPTION_FORCE_UPDATE = 1<<0;
@@ -997,6 +1006,20 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
+ if (mBatteryInputSuspended) {
+ PowerProperties.battery_input_suspended(false);
+ mBatteryInputSuspended = false;
+ }
+ } break;
+ case "suspend_input": {
+ if (!Build.IS_DEBUGGABLE) {
+ throw new SecurityException(
+ "battery suspend_input is only supported on debuggable builds");
+ }
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
+ PowerProperties.battery_input_suspended(true);
+ mBatteryInputSuspended = true;
} break;
default:
return shell.handleDefaultCommands(cmd);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index f372c6f..0d79240 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -166,6 +166,7 @@
private String mAddress;
private String mName;
private final ContentResolver mContentResolver;
+ private final int mUserId;
private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
private IBinder mBluetoothBinder;
@@ -481,6 +482,7 @@
mName = null;
mErrorRecoveryRetryCounter = 0;
mContentResolver = context.getContentResolver();
+ mUserId = mContentResolver.getUserId();
// Observe BLE scan only mode settings change.
registerForBleScanModeChange();
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
@@ -625,7 +627,8 @@
}
if (mContext.getResources()
.getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
- && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
+ && Settings.Secure.getIntForUser(mContentResolver,
+ SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0, mUserId)
== 0) {
// if the valid flag is not set, don't load the address and name
if (DBG) {
@@ -633,8 +636,10 @@
}
return;
}
- mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
- mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
+ mName = Settings.Secure.getStringForUser(
+ mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mUserId);
+ mAddress = Settings.Secure.getStringForUser(
+ mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mUserId);
if (DBG) {
Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
}
@@ -648,26 +653,31 @@
*/
private void storeNameAndAddress(String name, String address) {
if (name != null) {
- Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
+ Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name,
+ mUserId);
mName = name;
if (DBG) {
- Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
- SECURE_SETTINGS_BLUETOOTH_NAME));
+ Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getStringForUser(
+ mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME,
+ mUserId));
}
}
if (address != null) {
- Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
+ Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS,
+ address, mUserId);
mAddress = address;
if (DBG) {
Slog.d(TAG,
- "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
- SECURE_SETTINGS_BLUETOOTH_ADDRESS));
+ "Stored Bluetoothaddress: " + Settings.Secure.getStringForUser(
+ mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS,
+ mUserId));
}
}
if ((name != null) && (address != null)) {
- Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
+ Settings.Secure.putIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1,
+ mUserId);
}
}
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index b09b260..500e768 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -126,6 +126,16 @@
}
@Override
+ public boolean closePartition() throws RemoteException {
+ IGsiService service = getGsiService();
+ if (service.closePartition() != 0) {
+ Slog.i(TAG, "Partition installation completes with error");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
public boolean finishInstallation() throws RemoteException {
IGsiService service = getGsiService();
if (service.closeInstall() != 0) {
diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java
index 3bcb36f..4de4075 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -19,6 +19,7 @@
import android.Manifest.permission;
import android.annotation.Nullable;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.PermissionChecker;
@@ -404,7 +405,8 @@
}
public int getSecureInt(Context context, String name, int defaultValue) {
- return Settings.Secure.getInt(context.getContentResolver(), name, defaultValue);
+ final ContentResolver cr = context.getContentResolver();
+ return Settings.Secure.getIntForUser(cr, name, defaultValue, cr.getUserId());
}
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 27c5d4a..eb18da2 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4687,14 +4687,19 @@
}
}
- public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) {
+ public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode,
+ int previousMode) {
final long token = Binder.clearCallingIdentity();
try {
// When using FUSE, we may need to kill the app if the op changes
switch(code) {
case OP_REQUEST_INSTALL_PACKAGES:
- // Always kill regardless of op change, to remount apps /storage
- killAppForOpChange(code, uid);
+ if (previousMode == MODE_ALLOWED || mode == MODE_ALLOWED) {
+ // If we transition to/from MODE_ALLOWED, kill the app to make
+ // sure it has the correct view of /storage. Changing between
+ // MODE_DEFAULT / MODE_ERRORED is a no-op
+ killAppForOpChange(code, uid);
+ }
return;
case OP_MANAGE_EXTERNAL_STORAGE:
if (mode != MODE_ALLOWED) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index eb8308b..e433fbd 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -64,6 +64,7 @@
import android.telephony.LocationAccessPolicy;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
+import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
import android.telephony.PreciseDisconnectCause;
@@ -142,13 +143,13 @@
int callerUid;
int callerPid;
- int events;
+ long events;
int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
- boolean matchPhoneStateListenerEvent(int events) {
+ boolean matchPhoneStateListenerEvent(long events) {
return (callback != null) && ((events & this.events) != 0);
}
@@ -177,7 +178,7 @@
+ onSubscriptionsChangedListenerCallback
+ " onOpportunisticSubscriptionsChangedListenererCallback="
+ onOpportunisticSubscriptionsChangedListenerCallback + " subId=" + subId
- + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}";
+ + " phoneId=" + phoneId + " events=" + Long.toHexString(events) + "}";
}
}
@@ -306,6 +307,8 @@
private final LocalLog mListenLog = new LocalLog(00);
+ private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+
/**
* Per-phone map of precise data connection state. The key of the map is the pair of transport
* type and APN setting. This is the cache to prevent redundant callbacks to the listeners.
@@ -318,19 +321,19 @@
// Starting in Q, almost all cellular location requires FINE location enforcement.
// Prior to Q, cellular was available with COARSE location enforcement. Bits in this
// list will be checked for COARSE on apps targeting P or earlier and FINE on Q or later.
- static final int ENFORCE_LOCATION_PERMISSION_MASK =
+ static final long ENFORCE_LOCATION_PERMISSION_MASK =
PhoneStateListener.LISTEN_CELL_LOCATION
| PhoneStateListener.LISTEN_CELL_INFO
| PhoneStateListener.LISTEN_REGISTRATION_FAILURE
| PhoneStateListener.LISTEN_BARRING_INFO;
- static final int ENFORCE_PHONE_STATE_PERMISSION_MASK =
+ static final long ENFORCE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
| PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
| PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
| PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED;
- static final int ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK =
+ static final long ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE
| PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE
| PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES
@@ -339,11 +342,11 @@
| PhoneStateListener.LISTEN_REGISTRATION_FAILURE
| PhoneStateListener.LISTEN_BARRING_INFO;
- static final int READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
+ static final long READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
| PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS;
- static final int READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK =
+ static final long READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT
| PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED
| PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED
@@ -495,6 +498,7 @@
cutListToSize(mImsReasonInfo, mNumPhones);
cutListToSize(mPreciseDataConnectionStates, mNumPhones);
cutListToSize(mBarringInfo, mNumPhones);
+ cutListToSize(mPhysicalChannelConfigs, mNumPhones);
return;
}
@@ -528,6 +532,8 @@
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mTelephonyDisplayInfos[i] = null;
+ mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig(
+ PhysicalChannelConfig.CONNECTION_UNKNOWN,0));
}
}
@@ -588,6 +594,7 @@
mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones];
mBarringInfo = new ArrayList<>();
mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones];
+ mPhysicalChannelConfigs = new ArrayList<>();
for (int i = 0; i < numPhones; i++) {
mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -617,6 +624,8 @@
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mTelephonyDisplayInfos[i] = null;
+ mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig(
+ PhysicalChannelConfig.CONNECTION_UNKNOWN,0));
}
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -795,23 +804,23 @@
@Override
public void listenWithFeature(String callingPackage, String callingFeatureId,
- IPhoneStateListener callback, int events, boolean notifyNow) {
+ IPhoneStateListener callback, long events, boolean notifyNow) {
listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, callingPackage,
callingFeatureId, callback, events, notifyNow);
}
@Override
public void listenForSubscriber(int subId, String callingPackage, String callingFeatureId,
- IPhoneStateListener callback, int events, boolean notifyNow) {
+ IPhoneStateListener callback, long events, boolean notifyNow) {
listen(callingPackage, callingFeatureId, callback, events, notifyNow, subId);
}
private void listen(String callingPackage, @Nullable String callingFeatureId,
- IPhoneStateListener callback, int events, boolean notifyNow, int subId) {
+ IPhoneStateListener callback, long events, boolean notifyNow, int subId) {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
- + " events=0x" + Integer.toHexString(events) + " notifyNow=" + notifyNow + " subId="
+ + " events=0x" + Long.toHexString(events) + " notifyNow=" + notifyNow + " subId="
+ subId + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId;
mListenLog.log(str);
if (VDBG) {
@@ -1098,6 +1107,14 @@
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION) != 0) {
+ try {
+ r.callback.onPhysicalChannelConfigurationChanged(
+ mPhysicalChannelConfigs);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -2258,6 +2275,47 @@
}
}
+ /**
+ * Send a notification to registrants that the configs of physical channel has changed for
+ * a particular subscription.
+ *
+ * @param subId the subId
+ * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
+ */
+ public void notifyPhysicalChannelConfigurationForSubscriber(
+ int subId, List<PhysicalChannelConfig> configs) {
+ if (!checkNotifyPermission("notifyPhysicalChannelConfiguration()")) {
+ return;
+ }
+
+ if (VDBG) {
+ log("notifyPhysicalChannelConfiguration: subId=" + subId + " configs=" + configs);
+ }
+
+ synchronized (mRecords) {
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mPhysicalChannelConfigs.set(phoneId, configs.get(phoneId));
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION)
+ && idMatch(r.subId, subId, phoneId)) {
+ try {
+ if (DBG_LOC) {
+ log("notifyPhysicalChannelConfiguration: "
+ + "mPhysicalChannelConfigs="
+ + configs + " r=" + r);
+ }
+ r.callback.onPhysicalChannelConfigurationChanged(configs);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ }
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -2310,6 +2368,7 @@
pw.println("mEmergencyNumberList=" + mEmergencyNumberList);
pw.println("mDefaultPhoneId=" + mDefaultPhoneId);
pw.println("mDefaultSubId=" + mDefaultSubId);
+ pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs);
pw.decreaseIndent();
@@ -2536,7 +2595,7 @@
== PackageManager.PERMISSION_GRANTED;
}
- private boolean checkListenerPermission(int events, int subId, String callingPackage,
+ private boolean checkListenerPermission(long events, int subId, String callingPackage,
@Nullable String callingFeatureId, String message) {
LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder =
new LocationAccessPolicy.LocationPermissionQuery.Builder()
@@ -2742,7 +2801,7 @@
}
private void checkPossibleMissNotify(Record r, int phoneId) {
- int events = r.events;
+ long events = r.events;
if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
try {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 343e05d..20f3231 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -37,6 +37,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -116,6 +117,8 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -135,9 +138,31 @@
private static final boolean SHOW_DUNGEON_NOTIFICATION = false;
- //TODO: remove this when development is done.
- private static final int DEBUG_FGS_ALLOW_WHILE_IN_USE = 0;
- private static final int DEBUG_FGS_ENFORCE_TYPE = 1;
+ public static final int FGS_FEATURE_DENIED = 0;
+ public static final int FGS_FEATURE_ALLOWED_BY_PROC_STATE = 1;
+ public static final int FGS_FEATURE_ALLOWED_BY_UID_VISIBLE = 2;
+ public static final int FGS_FEATURE_ALLOWED_BY_FLAG = 3;
+ public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_UID = 4;
+ public static final int FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION = 5;
+ public static final int FGS_FEATURE_ALLOWED_BY_TOKEN = 6;
+ public static final int FGS_FEATURE_ALLOWED_BY_PERMISSION = 7;
+ public static final int FGS_FEATURE_ALLOWED_BY_WHITELIST = 8;
+ public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER = 9;
+
+ @IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = {
+ FGS_FEATURE_DENIED,
+ FGS_FEATURE_ALLOWED_BY_PROC_STATE,
+ FGS_FEATURE_ALLOWED_BY_UID_VISIBLE,
+ FGS_FEATURE_ALLOWED_BY_FLAG,
+ FGS_FEATURE_ALLOWED_BY_SYSTEM_UID,
+ FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION,
+ FGS_FEATURE_ALLOWED_BY_TOKEN,
+ FGS_FEATURE_ALLOWED_BY_PERMISSION,
+ FGS_FEATURE_ALLOWED_BY_WHITELIST,
+ FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FgsFeatureRetCode {}
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20*1000;
@@ -519,12 +544,13 @@
}
if (fgRequired) {
- if (!r.mAllowStartForeground) {
+ if (isFgsBgStart(r.mAllowStartForeground)) {
if (!r.mLoggedInfoAllowStartForeground) {
Slog.wtf(TAG, "Background started FGS " + r.mInfoAllowStartForeground);
r.mLoggedInfoAllowStartForeground = true;
}
- if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
+ if (r.mAllowStartForeground == FGS_FEATURE_DENIED
+ && mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
Slog.w(TAG, "startForegroundService() not allowed due to "
+ " mAllowStartForeground false: service "
+ r.shortInstanceName);
@@ -768,9 +794,7 @@
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid,
r.name.getPackageName(), r.name.getClassName(),
FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START);
- synchronized (r.stats.getBatteryStats()) {
- r.stats.startRunningLocked();
- }
+ mAm.mBatteryStatsService.noteServiceStartRunning(r.stats);
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
@@ -809,9 +833,7 @@
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, service.appInfo.uid,
service.name.getPackageName(), service.name.getClassName(),
FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
- synchronized (service.stats.getBatteryStats()) {
- service.stats.stopRunningLocked();
- }
+ mAm.mBatteryStatsService.noteServiceStopRunning(service.stats);
service.startRequested = false;
if (service.tracker != null) {
service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
@@ -970,9 +992,7 @@
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid,
r.name.getPackageName(), r.name.getClassName(),
FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP);
- synchronized (r.stats.getBatteryStats()) {
- r.stats.stopRunningLocked();
- }
+ mAm.mBatteryStatsService.noteServiceStopRunning(r.stats);
r.startRequested = false;
if (r.tracker != null) {
r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
@@ -1427,13 +1447,14 @@
}
if (!ignoreForeground) {
- if (!r.mAllowStartForeground) {
+ if (isFgsBgStart(r.mAllowStartForeground)) {
if (!r.mLoggedInfoAllowStartForeground) {
Slog.wtf(TAG, "Background started FGS "
+ r.mInfoAllowStartForeground);
r.mLoggedInfoAllowStartForeground = true;
}
- if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
+ if (r.mAllowStartForeground == FGS_FEATURE_DENIED
+ && mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
Slog.w(TAG,
"Service.startForeground() not allowed due to "
+ "mAllowStartForeground false: service "
@@ -2518,7 +2539,8 @@
synchronized (stats) {
ss = stats.getServiceStatsLocked(
sInfo.applicationInfo.uid, name.getPackageName(),
- name.getClassName());
+ name.getClassName(), SystemClock.elapsedRealtime(),
+ SystemClock.uptimeMillis());
}
r = new ServiceRecord(mAm, ss, className, name, definingPackageName,
definingUid, filter, sInfo, callingFromFg, res);
@@ -3056,9 +3078,7 @@
}
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_LAUNCH_REPORTED, r.appInfo.uid,
r.name.getPackageName(), r.name.getClassName());
- synchronized (r.stats.getBatteryStats()) {
- r.stats.startLaunchedLocked();
- }
+ mAm.mBatteryStatsService.noteServiceStartLaunch(r.stats);
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
@@ -3402,9 +3422,7 @@
smap.mDelayedStartList.remove(r);
if (r.app != null) {
- synchronized (r.stats.getBatteryStats()) {
- r.stats.stopLaunchedLocked();
- }
+ mAm.mBatteryStatsService.noteServiceStopLaunch(r.stats);
r.app.stopService(r);
r.app.updateBoundClientUids();
if (r.whitelistManager) {
@@ -3940,9 +3958,7 @@
// Clear app state from services.
for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) {
ServiceRecord sr = app.getRunningServiceAt(i);
- synchronized (sr.stats.getBatteryStats()) {
- sr.stats.stopLaunchedLocked();
- }
+ mAm.mBatteryStatsService.noteServiceStopLaunch(sr.stats);
if (sr.app != app && sr.app != null && !sr.app.isPersistent()) {
sr.app.stopService(sr);
sr.app.updateBoundClientUids();
@@ -4885,13 +4901,13 @@
r.mAllowWhileInUsePermissionInFgs = true;
}
- if (!r.mAllowWhileInUsePermissionInFgs || !r.mAllowStartForeground) {
- final boolean temp = shouldAllowFgsFeatureLocked(callingPackage, callingPid,
- callingUid, intent, r, allowBackgroundActivityStarts);
+ if (!r.mAllowWhileInUsePermissionInFgs || (r.mAllowStartForeground == FGS_FEATURE_DENIED)) {
+ final @FgsFeatureRetCode int temp = shouldAllowFgsFeatureLocked(callingPackage,
+ callingPid, callingUid, intent, r, allowBackgroundActivityStarts);
if (!r.mAllowWhileInUsePermissionInFgs) {
- r.mAllowWhileInUsePermissionInFgs = temp;
+ r.mAllowWhileInUsePermissionInFgs = (temp != FGS_FEATURE_DENIED);
}
- if (!r.mAllowStartForeground) {
+ if (r.mAllowStartForeground == FGS_FEATURE_DENIED) {
r.mAllowStartForeground = temp;
}
}
@@ -4903,85 +4919,141 @@
* @param callingUid caller app's uid.
* @param intent intent to start/bind service.
* @param r the service to start.
- * @return true if allow, false otherwise.
+ * @return {@link FgsFeatureRetCode}
*/
- private boolean shouldAllowFgsFeatureLocked(String callingPackage,
+ private @FgsFeatureRetCode int shouldAllowFgsFeatureLocked(String callingPackage,
int callingPid, int callingUid, Intent intent, ServiceRecord r,
boolean allowBackgroundActivityStarts) {
- // Is the allow activity background start flag on?
- if (allowBackgroundActivityStarts) {
- return true;
- }
+ int ret = FGS_FEATURE_DENIED;
- boolean isCallerSystem = false;
- final int callingAppId = UserHandle.getAppId(callingUid);
- switch (callingAppId) {
- case ROOT_UID:
- case SYSTEM_UID:
- case NFC_UID:
- case SHELL_UID:
- isCallerSystem = true;
- break;
- default:
- isCallerSystem = false;
- break;
- }
-
- if (isCallerSystem) {
- return true;
- }
-
- if (r.app != null) {
- ActiveInstrumentation instr = r.app.getActiveInstrumentation();
- if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
- return true;
- }
- if (r.app.areBackgroundActivityStartsAllowedByToken()) {
- return true;
- }
- }
-
- if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
- == PERMISSION_GRANTED) {
- return true;
- }
-
- // Is the calling UID at PROCESS_STATE_TOP or above?
+ final StringBuilder sb = new StringBuilder(64);
final int uidState = mAm.getUidState(callingUid);
- if (uidState <= ActivityManager.PROCESS_STATE_TOP) {
- return true;
+ if (ret == FGS_FEATURE_DENIED) {
+ // Is the calling UID at PROCESS_STATE_TOP or above?
+ if (uidState <= ActivityManager.PROCESS_STATE_TOP) {
+ sb.append("uidState=").append(uidState);
+ ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE;
+ }
}
- // Does the calling UID have any visible activity?
- final boolean isCallingUidVisible = mAm.mAtmInternal.isUidForeground(callingUid);
- if (isCallingUidVisible) {
- return true;
+ if (ret == FGS_FEATURE_DENIED) {
+ // Does the calling UID have any visible activity?
+ final boolean isCallingUidVisible = mAm.mAtmInternal.isUidForeground(callingUid);
+ if (isCallingUidVisible) {
+ ret = FGS_FEATURE_ALLOWED_BY_UID_VISIBLE;
+ }
}
- final boolean isWhiteListedPackage =
- mWhiteListAllowWhileInUsePermissionInFgs.contains(callingPackage);
- if (isWhiteListedPackage) {
- return true;
+ if (ret == FGS_FEATURE_DENIED) {
+ // Is the allow activity background start flag on?
+ if (allowBackgroundActivityStarts) {
+ ret = FGS_FEATURE_ALLOWED_BY_FLAG;
+ }
}
- // Is the calling UID a device owner app?
- final boolean isDeviceOwner = mAm.mInternal.isDeviceOwner(callingUid);
- if (isDeviceOwner) {
- return true;
+ if (ret == FGS_FEATURE_DENIED) {
+ boolean isCallerSystem = false;
+ final int callingAppId = UserHandle.getAppId(callingUid);
+ switch (callingAppId) {
+ case ROOT_UID:
+ case SYSTEM_UID:
+ case NFC_UID:
+ case SHELL_UID:
+ isCallerSystem = true;
+ break;
+ default:
+ isCallerSystem = false;
+ break;
+ }
+
+ if (isCallerSystem) {
+ sb.append("callingUid=").append(callingAppId);
+ ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_UID;
+ }
}
- final String info =
+ if (ret == FGS_FEATURE_DENIED) {
+ if (r.app != null) {
+ ActiveInstrumentation instr = r.app.getActiveInstrumentation();
+ if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
+ ret = FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION;
+ }
+ if (r.app.areBackgroundActivityStartsAllowedByToken()) {
+ ret = FGS_FEATURE_ALLOWED_BY_TOKEN;
+ }
+ }
+ }
+
+ if (ret == FGS_FEATURE_DENIED) {
+ if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
+ == PERMISSION_GRANTED) {
+ ret = FGS_FEATURE_ALLOWED_BY_PERMISSION;
+ }
+ }
+
+ if (ret == FGS_FEATURE_DENIED) {
+ final boolean isWhiteListedPackage =
+ mWhiteListAllowWhileInUsePermissionInFgs.contains(callingPackage);
+ if (isWhiteListedPackage) {
+ ret = FGS_FEATURE_ALLOWED_BY_WHITELIST;
+ }
+ }
+
+ if (ret == FGS_FEATURE_DENIED) {
+ // Is the calling UID a device owner app?
+ final boolean isDeviceOwner = mAm.mInternal.isDeviceOwner(callingUid);
+ if (isDeviceOwner) {
+ ret = FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER;
+ }
+ }
+
+ final String debugInfo =
"[callingPackage: " + callingPackage
+ "; callingUid: " + callingUid
+ "; uidState: " + ProcessList.makeProcStateString(uidState)
+ "; intent: " + intent
+ + "; code:" + fgsCodeToString(ret)
+ + "; extra:" + sb.toString()
+ "; targetSdkVersion:" + r.appInfo.targetSdkVersion
+ "]";
- if (!info.equals(r.mInfoAllowStartForeground)) {
+ if (!debugInfo.equals(r.mInfoAllowStartForeground)) {
r.mLoggedInfoAllowStartForeground = false;
- r.mInfoAllowStartForeground = info;
+ r.mInfoAllowStartForeground = debugInfo;
}
- return false;
+ return ret;
}
+
+ private static String fgsCodeToString(@FgsFeatureRetCode int code) {
+ switch (code) {
+ case FGS_FEATURE_DENIED:
+ return "DENIED";
+ case FGS_FEATURE_ALLOWED_BY_PROC_STATE:
+ return "ALLOWED_BY_PROC_STATE";
+ case FGS_FEATURE_ALLOWED_BY_UID_VISIBLE:
+ return "ALLOWED_BY_UID_VISIBLE";
+ case FGS_FEATURE_ALLOWED_BY_FLAG:
+ return "ALLOWED_BY_FLAG";
+ case FGS_FEATURE_ALLOWED_BY_SYSTEM_UID:
+ return "ALLOWED_BY_SYSTEM_UID";
+ case FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION:
+ return "ALLOWED_BY_INSTR_PERMISSION";
+ case FGS_FEATURE_ALLOWED_BY_TOKEN:
+ return "ALLOWED_BY_TOKEN";
+ case FGS_FEATURE_ALLOWED_BY_PERMISSION:
+ return "ALLOWED_BY_PERMISSION";
+ case FGS_FEATURE_ALLOWED_BY_WHITELIST:
+ return "ALLOWED_BY_WHITELIST";
+ case FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER:
+ return "ALLOWED_BY_DEVICE_OWNER";
+ default:
+ return "";
+ }
+ }
+
+ private static boolean isFgsBgStart(@FgsFeatureRetCode int code) {
+ return code != FGS_FEATURE_ALLOWED_BY_PROC_STATE
+ && code != FGS_FEATURE_ALLOWED_BY_UID_VISIBLE;
+ }
+
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a5d2011..7e664966 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -133,7 +133,6 @@
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.ActivityTaskManagerService.relaunchReasonToString;
-
import android.Manifest;
import android.Manifest.permission;
import android.annotation.BroadcastBehavior;
@@ -143,8 +142,8 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackInfo;
import android.app.ActivityManagerInternal;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.AppOpsManager;
@@ -342,7 +341,6 @@
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
import com.android.server.SystemServiceManager;
import com.android.server.ThreadPriorityBooster;
import com.android.server.UserspaceRebootLogger;
@@ -2835,14 +2833,16 @@
}
final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
- synchronized(bstats) {
- synchronized(mPidsSelfLocked) {
- if (haveNewCpuStats) {
- if (bstats.startAddingCpuLocked()) {
- int totalUTime = 0;
- int totalSTime = 0;
- final int N = mProcessCpuTracker.countStats();
- for (int i=0; i<N; i++) {
+ synchronized (bstats) {
+ if (haveNewCpuStats) {
+ if (bstats.startAddingCpuLocked()) {
+ int totalUTime = 0;
+ int totalSTime = 0;
+ final int statsCount = mProcessCpuTracker.countStats();
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ synchronized (mPidsSelfLocked) {
+ for (int i = 0; i < statsCount; i++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
if (!st.working) {
continue;
@@ -2854,7 +2854,8 @@
BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
if (ps == null || !ps.isActive()) {
pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
- pr.info.uid, pr.processName);
+ pr.info.uid, pr.processName,
+ elapsedRealtime, uptime);
}
ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
pr.curCpuTime += st.rel_utime + st.rel_stime;
@@ -2865,20 +2866,22 @@
BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
if (ps == null || !ps.isActive()) {
st.batteryStats = ps = bstats.getProcessStatsLocked(
- bstats.mapUid(st.uid), st.name);
+ bstats.mapUid(st.uid), st.name,
+ elapsedRealtime, uptime);
}
ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
}
}
- final int userTime = mProcessCpuTracker.getLastUserTime();
- final int systemTime = mProcessCpuTracker.getLastSystemTime();
- final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
- final int irqTime = mProcessCpuTracker.getLastIrqTime();
- final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
- final int idleTime = mProcessCpuTracker.getLastIdleTime();
- bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
- systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
}
+
+ final int userTime = mProcessCpuTracker.getLastUserTime();
+ final int systemTime = mProcessCpuTracker.getLastSystemTime();
+ final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
+ final int irqTime = mProcessCpuTracker.getLastIrqTime();
+ final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
+ final int idleTime = mProcessCpuTracker.getLastIdleTime();
+ bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
+ systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
}
}
@@ -3076,18 +3079,8 @@
Slog.d(TAG_SWITCH,
"updateBatteryStats: comp=" + activity + "res=" + resumed);
}
- final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
- FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
- uid, activity.getPackageName(), activity.getShortClassName(),
- resumed ? FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
- FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
- synchronized (stats) {
- if (resumed) {
- stats.noteActivityResumedLocked(uid);
- } else {
- stats.noteActivityPausedLocked(uid);
- }
- }
+ mBatteryStatsService.updateBatteryStatsOnActivityUsage(activity.getPackageName(),
+ activity.getShortClassName(), uid, userId, resumed);
}
/**
@@ -3626,10 +3619,7 @@
}
}
- BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
- synchronized (stats) {
- stats.noteProcessDiedLocked(app.info.uid, pid);
- }
+ mBatteryStatsService.noteProcessDied(app.info.uid, pid);
if (!app.killed) {
if (!fromBinderDied) {
@@ -6418,8 +6408,8 @@
}
@Override
- public List<StackInfo> getAllStackInfos() {
- return mActivityTaskManager.getAllStackInfos();
+ public List<RootTaskInfo> getAllRootTaskInfos() {
+ return mActivityTaskManager.getAllRootTaskInfos();
}
@Override
@@ -7300,53 +7290,6 @@
return uidRecord != null && !uidRecord.setIdle;
}
- /**
- * Change the sched policy cgroup of a thread.
- *
- * <p>It is intended to be used in jni call of {@link Process#setThreadPriority(int, int)}.
- * When a process is changing the priority of its threads, the sched policy of that
- * thread may need to be changed accordingly - if the priority is changed to below
- * or equal to {@link android.os.Process#THREAD_PRIORITY_BACKGROUND} or raising from it.
- * However, because of the limitation of sepolicy, the thread priority change will
- * fail for some processes. To solve it, we add this binder call in Activity Manager,
- * so that the jni call of {@link Process#setThreadPriority(int, int)} could use it.
- *
- * @param tid tid of the thread to be changed.
- * @param group The sched policy group to be changed to.
- *
- * @throws IllegalArgumentException if group is invalid.
- * @throws SecurityException if no permission.
- *
- * @return Returns {@code true} if the sched policy is changed successfully;
- * {@code false} otherwise.
- */
- @Override
- public boolean setSchedPolicyCgroup(final int tid, final int group) {
- final int pid = Binder.getCallingPid();
- final int tgid = Process.getThreadGroupLeader(tid);
- final int pgroup = Process.getProcessGroup(pid);
-
- // tid is not in the thread group of caller
- if (pid != tgid) {
- return false;
- }
-
- // sched group is higher than its main process
- if (group > pgroup) {
- return false;
- }
-
- try {
- Process.setThreadGroup(tid, group);
- return true;
- } catch (IllegalArgumentException e) {
- Slog.w(TAG, "Failed to set thread group, argument invalid:\n" + e);
- } catch (SecurityException e) {
- Slog.w(TAG, "Failed to set thread group, no permission:\n" + e);
- }
- return false;
- }
-
@Override
public void setPersistentVrThread(int tid) {
mActivityTaskManager.setPersistentVrThread(tid);
@@ -14582,10 +14525,7 @@
timeFormatPreferenceMsgValue, 0);
mHandler.sendMessage(updateTimePreferenceMsg);
}
- BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
- synchronized (stats) {
- stats.noteCurrentTimeChangedLocked();
- }
+ mBatteryStatsService.noteCurrentTimeChanged();
break;
case Intent.ACTION_CLEAR_DNS_CACHE:
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
@@ -15385,8 +15325,8 @@
}
@Override
- public StackInfo getFocusedStackInfo() throws RemoteException {
- return mActivityTaskManager.getFocusedStackInfo();
+ public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException {
+ return mActivityTaskManager.getFocusedRootTaskInfo();
}
@Override
@@ -15957,7 +15897,6 @@
updateCpuStatsNow();
synchronized (this) {
- BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
boolean doCpuKills = true;
if (mLastPowerCheckUptime == 0) {
doCpuKills = false;
@@ -16004,10 +15943,8 @@
cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
}
if (((cputimeUsed * 100) / uptimeSince) >= cpuLimit) {
- synchronized (stats) {
- stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
+ mBatteryStatsService.reportExcessiveCpu(app.info.uid, app.processName,
uptimeSince, cputimeUsed);
- }
app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
+ " dur=" + checkDur + " limit=" + cpuLimit,
ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
@@ -17513,19 +17450,7 @@
@Override
public void updateForegroundTimeIfOnBattery(
String packageName, int uid, long cpuTimeDiff) {
- synchronized (ActivityManagerService.this) {
- if (!mBatteryStatsService.isOnBattery()) {
- return;
- }
- final BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
- synchronized (bsi) {
- final BatteryStatsImpl.Uid.Proc ps =
- bsi.getProcessStatsLocked(uid, packageName);
- if (ps != null) {
- ps.addForegroundTimeLocked(cpuTimeDiff);
- }
- }
- }
+ mBatteryStatsService.updateForegroundTimeIfOnBattery(packageName, uid, cpuTimeDiff);
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index a512cca..9ce8b11 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -28,6 +28,7 @@
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AppGlobals;
import android.app.BroadcastOptions;
import android.app.IActivityController;
@@ -2586,7 +2587,7 @@
case "list":
return runStackList(pw);
case "info":
- return runStackInfo(pw);
+ return runRootTaskInfo(pw);
case "move-top-activity-to-pinned-stack":
return runMoveTopActivityToPinnedStack(pw);
case "remove":
@@ -2668,17 +2669,17 @@
}
int runStackList(PrintWriter pw) throws RemoteException {
- List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
- for (ActivityManager.StackInfo info : stacks) {
+ List<RootTaskInfo> tasks = mTaskInterface.getAllRootTaskInfos();
+ for (RootTaskInfo info : tasks) {
pw.println(info);
}
return 0;
}
- int runStackInfo(PrintWriter pw) throws RemoteException {
+ int runRootTaskInfo(PrintWriter pw) throws RemoteException {
int windowingMode = Integer.parseInt(getNextArgRequired());
int activityType = Integer.parseInt(getNextArgRequired());
- ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
+ RootTaskInfo info = mTaskInterface.getRootTaskInfo(windowingMode, activityType);
pw.println(info);
return 0;
}
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 39f79ca..692b3f1 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -376,7 +376,8 @@
for (int uid : uidsToRemove) {
FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, -1, uid,
FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
- mStats.removeIsolatedUidLocked(uid);
+ mStats.removeIsolatedUidLocked(uid, SystemClock.elapsedRealtime(),
+ SystemClock.uptimeMillis());
}
mStats.clearPendingRemovedUids();
}
@@ -473,11 +474,15 @@
final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver);
final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ final long elapsedRealtimeUs = elapsedRealtime * 1000;
+ final long uptimeUs = uptime * 1000;
synchronized (mStats) {
mStats.addHistoryEventLocked(
- SystemClock.elapsedRealtime(),
- SystemClock.uptimeMillis(),
+ elapsedRealtime,
+ uptime,
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS,
reason, 0);
@@ -490,17 +495,17 @@
}
if ((updateFlags & UPDATE_ALL) != 0) {
- mStats.updateKernelWakelocksLocked();
- mStats.updateKernelMemoryBandwidthLocked();
+ mStats.updateKernelWakelocksLocked(elapsedRealtimeUs);
+ mStats.updateKernelMemoryBandwidthLocked(elapsedRealtimeUs);
}
if ((updateFlags & UPDATE_RPM) != 0) {
- mStats.updateRpmStatsLocked();
+ mStats.updateRpmStatsLocked(elapsedRealtimeUs);
}
if (bluetoothInfo != null) {
if (bluetoothInfo.isValid()) {
- mStats.updateBluetoothStateLocked(bluetoothInfo);
+ mStats.updateBluetoothStateLocked(bluetoothInfo, elapsedRealtime, uptime);
} else {
Slog.w(TAG, "bluetooth info is invalid: " + bluetoothInfo);
}
@@ -512,7 +517,7 @@
if (wifiInfo != null) {
if (wifiInfo.isValid()) {
- mStats.updateWifiState(extractDeltaLocked(wifiInfo));
+ mStats.updateWifiState(extractDeltaLocked(wifiInfo), elapsedRealtime, uptime);
} else {
Slog.w(TAG, "wifi info is invalid: " + wifiInfo);
}
@@ -520,7 +525,7 @@
if (modemInfo != null) {
if (modemInfo.isValid()) {
- mStats.updateMobileRadioState(modemInfo);
+ mStats.updateMobileRadioState(modemInfo, elapsedRealtime, uptime);
} else {
Slog.w(TAG, "modem info is invalid: " + modemInfo);
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d72998b..f427532 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -25,6 +25,7 @@
import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
@@ -62,7 +63,9 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.ParseUtils;
+import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
+import com.android.server.Watchdog;
import java.io.File;
import java.io.FileDescriptor;
@@ -76,6 +79,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -86,7 +90,8 @@
public final class BatteryStatsService extends IBatteryStats.Stub
implements PowerManagerInternal.LowPowerModeListener,
BatteryStatsImpl.PlatformIdleStateCallback,
- BatteryStatsImpl.RailEnergyDataCallback {
+ BatteryStatsImpl.RailEnergyDataCallback,
+ Watchdog.Monitor {
static final String TAG = "BatteryStatsService";
static final boolean DBG = false;
@@ -110,6 +115,10 @@
private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
private static final int MAX_LOW_POWER_STATS_SIZE = 4096;
+ private final HandlerThread mHandlerThread;
+ private final Handler mHandler;
+ private final Object mLock = new Object();
+
/**
* Replaces the information in the given rpmStats with up-to-date information.
*/
@@ -190,6 +199,9 @@
return (umi != null) ? umi.getUserIds() : null;
}
};
+ mHandlerThread = new HandlerThread("batterystats-handler");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
mStats = new BatteryStatsImpl(systemDir, handler, this,
this, mUserManagerUserInfoProvider);
mWorker = new BatteryExternalStatsWorker(context, mStats);
@@ -206,6 +218,7 @@
public void systemServicesReady() {
mStats.systemServicesReady(mContext);
+ Watchdog.getInstance().addMonitor(this);
}
private final class LocalService extends BatteryStatsInternal {
@@ -228,8 +241,20 @@
@Override
public void noteBinderCallStats(int workSourceUid, long incrementatCallCount,
Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids) {
- mStats.noteBinderCallStats(workSourceUid, incrementatCallCount, callStats,
- binderThreadNativeTids);
+ synchronized (BatteryStatsService.this.mLock) {
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ mStats::noteBinderCallStats, workSourceUid, incrementatCallCount,
+ callStats, binderThreadNativeTids,
+ SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()));
+ }
+ }
+ }
+
+ @Override
+ public void monitor() {
+ synchronized (mLock) {
+ }
+ synchronized (mStats) {
}
}
@@ -250,6 +275,19 @@
awaitUninterruptibly(mWorker.scheduleSync(reason, flags));
}
+ private void awaitCompletion() {
+ synchronized (mLock) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ mHandler.post(() -> {
+ latch.countDown();
+ });
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
/**
* At the time when the constructor runs, the power manager has not yet been
* initialized. So we initialize the low power observer later.
@@ -259,8 +297,8 @@
powerMgr.registerLowPowerModeObserver(this);
synchronized (mStats) {
mStats.notePowerSaveModeLocked(
- powerMgr.getLowPowerState(ServiceType.BATTERY_STATS)
- .batterySaverEnabled);
+ powerMgr.getLowPowerState(ServiceType.BATTERY_STATS).batterySaverEnabled,
+ SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
}
(new WakeupReasonThread()).start();
}
@@ -268,6 +306,9 @@
public void shutdown() {
Slog.w("BatteryStats", "Writing battery stats before shutdown...");
+ // Drain the handler queue to make sure we've handled all pending works.
+ awaitCompletion();
+
syncStats("shutdown", BatteryExternalStatsWorker.UPDATE_ALL);
synchronized (mStats) {
@@ -293,9 +334,16 @@
}
@Override
- public void onLowPowerModeChanged(PowerSaveState result) {
- synchronized (mStats) {
- mStats.notePowerSaveModeLocked(result.batterySaverEnabled);
+ public void onLowPowerModeChanged(final PowerSaveState result) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePowerSaveModeLocked(result.batterySaverEnabled,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
@@ -313,7 +361,12 @@
* object to update with the latest info, then write to disk.
*/
public void scheduleWriteToDisk() {
- mWorker.scheduleWrite();
+ synchronized (mLock) {
+ // We still schedule it on the handler so we'll have all existing pending works done.
+ mHandler.post(() -> {
+ mWorker.scheduleWrite();
+ });
+ }
}
// These are for direct use by the activity manager...
@@ -321,70 +374,124 @@
/**
* Remove a UID from the BatteryStats and BatteryStats' external dependencies.
*/
- void removeUid(int uid) {
- synchronized (mStats) {
- mStats.removeUidStatsLocked(uid);
+ void removeUid(final int uid) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.removeUidStatsLocked(uid, elapsedRealtime);
+ }
+ });
}
}
- void onCleanupUser(int userId) {
- synchronized (mStats) {
- mStats.onCleanupUserLocked(userId);
+ void onCleanupUser(final int userId) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.onCleanupUserLocked(userId, elapsedRealtime);
+ }
+ });
}
}
- void onUserRemoved(int userId) {
- synchronized (mStats) {
- mStats.onUserRemovedLocked(userId);
+ void onUserRemoved(final int userId) {
+ synchronized (mLock) {
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.onUserRemovedLocked(userId);
+ }
+ });
}
}
- void addIsolatedUid(int isolatedUid, int appUid) {
- synchronized (mStats) {
- mStats.addIsolatedUidLocked(isolatedUid, appUid);
+ void addIsolatedUid(final int isolatedUid, final int appUid) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.addIsolatedUidLocked(isolatedUid, appUid, elapsedRealtime, uptime);
+ }
+ });
}
}
- void removeIsolatedUid(int isolatedUid, int appUid) {
- synchronized (mStats) {
- mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
+ void removeIsolatedUid(final int isolatedUid, final int appUid) {
+ synchronized (mLock) {
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
+ }
+ });
}
}
- void noteProcessStart(String name, int uid) {
- synchronized (mStats) {
- mStats.noteProcessStartLocked(name, uid);
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
- FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED);
+ void noteProcessStart(final String name, final int uid) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteProcessStartLocked(name, uid, elapsedRealtime, uptime);
+ }
+ });
}
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED);
}
void noteProcessCrash(String name, int uid) {
- synchronized (mStats) {
- mStats.noteProcessCrashLocked(name, uid);
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
- FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteProcessCrashLocked(name, uid, elapsedRealtime, uptime);
+ }
+ });
}
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED);
}
void noteProcessAnr(String name, int uid) {
- synchronized (mStats) {
- mStats.noteProcessAnrLocked(name, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteProcessAnrLocked(name, uid, elapsedRealtime, uptime);
+ }
+ });
}
}
void noteProcessFinish(String name, int uid) {
- synchronized (mStats) {
- mStats.noteProcessFinishLocked(name, uid);
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
- FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteProcessFinishLocked(name, uid, elapsedRealtime, uptime);
+ }
+ });
}
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED);
}
/** @param state Process state from ActivityManager.java. */
void noteUidProcessState(int uid, int state) {
- synchronized (mStats) {
- mStats.noteUidProcessStateLocked(uid, state);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteUidProcessStateLocked(uid, state, elapsedRealtime, uptime);
+ }
+ });
}
}
@@ -396,6 +503,9 @@
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
+ // Drain the handler queue to make sure we've handled all pending works, so we'll get
+ // an accurate stats.
+ awaitCompletion();
syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
@@ -411,6 +521,9 @@
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
+ // Drain the handler queue to make sure we've handled all pending works, so we'll get
+ // an accurate stats.
+ awaitCompletion();
syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
@@ -446,579 +559,1015 @@
}
}
- public void noteEvent(int code, String name, int uid) {
+ public void noteEvent(final int code, final String name, final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteEventLocked(code, name, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteEventLocked(code, name, uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteSyncStart(String name, int uid) {
+ public void noteSyncStart(final String name, final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteSyncStartLocked(name, uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null,
- name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__ON);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteSyncStartLocked(name, uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null,
+ name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__ON);
+ });
}
}
- public void noteSyncFinish(String name, int uid) {
+ public void noteSyncFinish(final String name, final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteSyncFinishLocked(name, uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null,
- name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__OFF);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteSyncFinishLocked(name, uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null,
+ name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__OFF);
+ });
}
}
/** A scheduled job was started. */
- public void noteJobStart(String name, int uid) {
+ public void noteJobStart(final String name, final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteJobStartLocked(name, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteJobStartLocked(name, uid, elapsedRealtime, uptime);
+ }
+ });
}
}
/** A scheduled job was finished. */
- public void noteJobFinish(String name, int uid, int stopReason) {
+ public void noteJobFinish(final String name, final int uid, final int stopReason) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteJobFinishLocked(name, uid, stopReason);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteJobFinishLocked(name, uid, stopReason, elapsedRealtime, uptime);
+ }
+ });
}
}
- void noteJobsDeferred(int uid, int numDeferred, long sinceLast) {
+ void noteJobsDeferred(final int uid, final int numDeferred, final long sinceLast) {
// No need to enforce calling permission, as it is called from an internal interface
- synchronized (mStats) {
- mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWakupAlarm(String name, int uid, WorkSource workSource, String tag) {
+ public void noteWakupAlarm(final String name, final int uid, final WorkSource workSource,
+ final String tag) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWakupAlarmLocked(name, uid, workSource, tag);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWakupAlarmLocked(name, uid, workSource, tag,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteAlarmStart(String name, WorkSource workSource, int uid) {
+ public void noteAlarmStart(final String name, final WorkSource workSource, final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteAlarmStartLocked(name, workSource, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteAlarmStartLocked(name, workSource, uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteAlarmFinish(String name, WorkSource workSource, int uid) {
+ public void noteAlarmFinish(final String name, final WorkSource workSource, final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteAlarmFinishLocked(name, workSource, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteAlarmFinishLocked(name, workSource, uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
- boolean unimportantForLogging) {
+ public void noteStartWakelock(final int uid, final int pid, final String name,
+ final String historyName, final int type, final boolean unimportantForLogging) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type,
- unimportantForLogging, SystemClock.elapsedRealtime(),
- SystemClock.uptimeMillis());
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type,
+ unimportantForLogging, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
+ public void noteStopWakelock(final int uid, final int pid, final String name,
+ final String historyName, final int type) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type,
- SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
- String historyName, int type, boolean unimportantForLogging) {
+ public void noteStartWakelockFromSource(final WorkSource ws, final int pid, final String name,
+ final String historyName, final int type, final boolean unimportantForLogging) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
- type, unimportantForLogging);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
+ type, unimportantForLogging, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
- String historyName, int type, WorkSource newWs, int newPid, String newName,
- String newHistoryName, int newType, boolean newUnimportantForLogging) {
+ public void noteChangeWakelockFromSource(final WorkSource ws, final int pid, final String name,
+ final String historyName, final int type, final WorkSource newWs, final int newPid,
+ final String newName, final String newHistoryName, final int newType,
+ final boolean newUnimportantForLogging) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
- newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
+ newWs, newPid, newName, newHistoryName, newType,
+ newUnimportantForLogging, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
- int type) {
+ public void noteStopWakelockFromSource(final WorkSource ws, final int pid, final String name,
+ final String historyName, final int type) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
+ public void noteLongPartialWakelockStart(final String name, final String historyName,
+ final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteLongPartialWakelockStart(name, historyName, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteLongPartialWakelockStart(name, historyName, uid,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteLongPartialWakelockStartFromSource(String name, String historyName,
- WorkSource workSource) {
+ public void noteLongPartialWakelockStartFromSource(final String name, final String historyName,
+ final WorkSource workSource) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
+ public void noteLongPartialWakelockFinish(final String name, final String historyName,
+ final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteLongPartialWakelockFinish(name, historyName, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteLongPartialWakelockFinish(name, historyName, uid,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
- WorkSource workSource) {
+ public void noteLongPartialWakelockFinishFromSource(final String name, final String historyName,
+ final WorkSource workSource) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteStartSensor(int uid, int sensor) {
+ public void noteStartSensor(final int uid, final int sensor) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteStartSensorLocked(uid, sensor);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid, null,
- sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__ON);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteStartSensorLocked(uid, sensor, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid,
+ null, sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__ON);
+ });
}
}
- public void noteStopSensor(int uid, int sensor) {
+ public void noteStopSensor(final int uid, final int sensor) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteStopSensorLocked(uid, sensor);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid, null,
- sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteStopSensorLocked(uid, sensor, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid,
+ null, sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
+ });
}
}
- public void noteVibratorOn(int uid, long durationMillis) {
+ public void noteVibratorOn(final int uid, final long durationMillis) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteVibratorOnLocked(uid, durationMillis);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteVibratorOnLocked(uid, durationMillis, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteVibratorOff(int uid) {
+ public void noteVibratorOff(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteVibratorOffLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteVibratorOffLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteGpsChanged(WorkSource oldWs, WorkSource newWs) {
+ public void noteGpsChanged(final WorkSource oldWs, final WorkSource newWs) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteGpsChangedLocked(oldWs, newWs);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteGpsChangedLocked(oldWs, newWs, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteGpsSignalQuality(int signalLevel) {
- synchronized (mStats) {
- mStats.noteGpsSignalQualityLocked(signalLevel);
+ public void noteGpsSignalQuality(final int signalLevel) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteGpsSignalQualityLocked(signalLevel, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteScreenState(int state) {
+ public void noteScreenState(final int state) {
enforceCallingPermission();
- if (DBG) Slog.d(TAG, "begin noteScreenState");
- synchronized (mStats) {
- FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED, state);
-
- mStats.noteScreenStateLocked(state);
- }
- if (DBG) Slog.d(TAG, "end noteScreenState");
- }
-
- public void noteScreenBrightness(int brightness) {
- enforceCallingPermission();
- synchronized (mStats) {
- FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness);
- mStats.noteScreenBrightnessLocked(brightness);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ final long currentTime = System.currentTimeMillis();
+ mHandler.post(() -> {
+ if (DBG) Slog.d(TAG, "begin noteScreenState");
+ synchronized (mStats) {
+ mStats.noteScreenStateLocked(state, elapsedRealtime, uptime, currentTime);
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED, state);
+ if (DBG) Slog.d(TAG, "end noteScreenState");
+ });
}
}
- public void noteUserActivity(int uid, int event) {
+ public void noteScreenBrightness(final int brightness) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteUserActivityLocked(uid, event);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteScreenBrightnessLocked(brightness, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness);
+ });
}
}
- public void noteWakeUp(String reason, int reasonUid) {
+ public void noteUserActivity(final int uid, final int event) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWakeUpLocked(reason, reasonUid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteUserActivityLocked(uid, event, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteInteractive(boolean interactive) {
+ public void noteWakeUp(final String reason, final int reasonUid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteInteractiveLocked(interactive);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWakeUpLocked(reason, reasonUid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteConnectivityChanged(int type, String extra) {
+ public void noteInteractive(final boolean interactive) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteConnectivityChangedLocked(type, extra);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteInteractiveLocked(interactive, elapsedRealtime);
+ }
+ });
}
}
- public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) {
+ public void noteConnectivityChanged(final int type, final String extra) {
enforceCallingPermission();
- final boolean update;
- synchronized (mStats) {
- update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteConnectivityChangedLocked(type, extra, elapsedRealtime, uptime);
+ }
+ });
}
+ }
- if (update) {
- mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO);
+ public void noteMobileRadioPowerState(final int powerState, final long timestampNs,
+ final int uid) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ final boolean update;
+ synchronized (mStats) {
+ update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid,
+ elapsedRealtime, uptime);
+ }
+
+ if (update) {
+ mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO);
+ }
+ });
}
}
public void notePhoneOn() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.notePhoneOnLocked();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePhoneOnLocked(elapsedRealtime, uptime);
+ }
+ });
}
}
public void notePhoneOff() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.notePhoneOffLocked();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePhoneOffLocked(elapsedRealtime, uptime);
+ }
+ });
}
}
- public void notePhoneSignalStrength(SignalStrength signalStrength) {
+ public void notePhoneSignalStrength(final SignalStrength signalStrength) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.notePhoneSignalStrengthLocked(signalStrength);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePhoneSignalStrengthLocked(signalStrength, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType) {
+ public void notePhoneDataConnectionState(final int dataType, final boolean hasData,
+ final int serviceType) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void notePhoneState(int state) {
+ public void notePhoneState(final int state) {
enforceCallingPermission();
- int simState = mContext.getSystemService(TelephonyManager.class).getSimState();
- synchronized (mStats) {
- mStats.notePhoneStateLocked(state, simState);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ int simState = mContext.getSystemService(TelephonyManager.class).getSimState();
+ synchronized (mStats) {
+ mStats.notePhoneStateLocked(state, simState, elapsedRealtime, uptime);
+ }
+ });
}
}
public void noteWifiOn() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiOnLocked();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiOnLocked(elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED,
+ FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON);
+ });
}
- FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED,
- FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON);
}
public void noteWifiOff() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiOffLocked();
- }
- FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED,
- FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF);
- }
-
- public void noteStartAudio(int uid) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteAudioOnLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid, null,
- FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__ON);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiOffLocked(elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED,
+ FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF);
+ });
}
}
- public void noteStopAudio(int uid) {
+ public void noteStartAudio(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteAudioOffLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid, null,
- FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteAudioOnLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid,
+ null, FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__ON);
+ });
}
}
- public void noteStartVideo(int uid) {
+ public void noteStopAudio(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteVideoOnLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, uid,
- null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteAudioOffLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid,
+ null, FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
+ });
}
}
- public void noteStopVideo(int uid) {
+ public void noteStartVideo(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteVideoOffLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, uid,
- null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteVideoOnLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED,
+ uid, null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON);
+ });
+ }
+ }
+
+ public void noteStopVideo(final int uid) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteVideoOffLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED,
+ uid, null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF);
+ });
}
}
public void noteResetAudio() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteResetAudioLocked();
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, -1, null,
- FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__RESET);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteResetAudioLocked(elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, -1, null,
+ FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__RESET);
+ });
}
}
public void noteResetVideo() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteResetVideoLocked();
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, -1,
- null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteResetVideoLocked(elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, -1,
+ null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET);
+ });
}
}
- public void noteFlashlightOn(int uid) {
+ public void noteFlashlightOn(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteFlashlightOnLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid,
- null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteFlashlightOnLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid,
+ null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
+ });
}
}
- public void noteFlashlightOff(int uid) {
+ public void noteFlashlightOff(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteFlashlightOffLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid,
- null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteFlashlightOffLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid,
+ null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
+ });
}
}
- public void noteStartCamera(int uid) {
+ public void noteStartCamera(final int uid) {
enforceCallingPermission();
if (DBG) Slog.d(TAG, "begin noteStartCamera");
- synchronized (mStats) {
- mStats.noteCameraOnLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid, null,
- FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__ON);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteCameraOnLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid,
+ null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__ON);
+ });
}
if (DBG) Slog.d(TAG, "end noteStartCamera");
}
- public void noteStopCamera(int uid) {
+ public void noteStopCamera(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteCameraOffLocked(uid);
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid, null,
- FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteCameraOffLocked(uid, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid,
+ null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
+ });
}
}
public void noteResetCamera() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteResetCameraLocked();
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, -1, null,
- FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__RESET);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteResetCameraLocked(elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, -1,
+ null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__RESET);
+ });
}
}
public void noteResetFlashlight() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteResetFlashlightLocked();
- FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, -1,
- null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteResetFlashlightLocked(elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, -1,
+ null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET);
+ });
}
}
@Override
- public void noteWifiRadioPowerState(int powerState, long tsNanos, int uid) {
+ public void noteWifiRadioPowerState(final int powerState, final long tsNanos, final int uid) {
enforceCallingPermission();
-
- // There was a change in WiFi power state.
- // Collect data now for the past activity.
- synchronized (mStats) {
- if (mStats.isOnBattery()) {
- final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH ||
- powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"
- : "inactive";
- mWorker.scheduleSync("wifi-data: " + type, BatteryExternalStatsWorker.UPDATE_WIFI);
- }
- mStats.noteWifiRadioPowerState(powerState, tsNanos, uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ // There was a change in WiFi power state.
+ // Collect data now for the past activity.
+ synchronized (mStats) {
+ if (mStats.isOnBattery()) {
+ final String type =
+ (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
+ || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM)
+ ? "active" : "inactive";
+ mWorker.scheduleSync("wifi-data: " + type,
+ BatteryExternalStatsWorker.UPDATE_WIFI);
+ }
+ mStats.noteWifiRadioPowerState(powerState, tsNanos, uid,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiRunning(WorkSource ws) {
+ public void noteWifiRunning(final WorkSource ws) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiRunningLocked(ws);
- }
- // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too.
- FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
- ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
- }
-
- public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiRunningChangedLocked(oldWs, newWs);
- }
- FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
- newWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
- FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
- oldWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
- }
-
- public void noteWifiStopped(WorkSource ws) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiStoppedLocked(ws);
- }
- FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
- ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
- }
-
- public void noteWifiState(int wifiState, String accessPoint) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiStateLocked(wifiState, accessPoint);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiRunningLocked(ws, elapsedRealtime, uptime);
+ }
+ // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too.
+ FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
+ ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
+ });
}
}
- public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
+ public void noteWifiRunningChanged(final WorkSource oldWs, final WorkSource newWs) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiRunningChangedLocked(oldWs, newWs, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
+ newWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
+ FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
+ oldWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
+ });
}
}
- public void noteWifiRssiChanged(int newRssi) {
+ public void noteWifiStopped(final WorkSource ws) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiRssiChangedLocked(newRssi);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiStoppedLocked(ws, elapsedRealtime, uptime);
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED,
+ ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
+ });
}
}
- public void noteFullWifiLockAcquired(int uid) {
+ public void noteWifiState(final int wifiState, final String accessPoint) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteFullWifiLockAcquiredLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiStateLocked(wifiState, accessPoint, elapsedRealtime);
+ }
+ });
}
}
- public void noteFullWifiLockReleased(int uid) {
+ public void noteWifiSupplicantStateChanged(final int supplState, final boolean failedAuth) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteFullWifiLockReleasedLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiScanStarted(int uid) {
+ public void noteWifiRssiChanged(final int newRssi) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiScanStartedLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiRssiChangedLocked(newRssi, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiScanStopped(int uid) {
+ public void noteFullWifiLockAcquired(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiScanStoppedLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteFullWifiLockAcquiredLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiMulticastEnabled(int uid) {
+ public void noteFullWifiLockReleased(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiMulticastEnabledLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteFullWifiLockReleasedLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiMulticastDisabled(int uid) {
+ public void noteWifiScanStarted(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiMulticastDisabledLocked(uid);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiScanStartedLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
+ public void noteWifiScanStopped(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiScanStoppedLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
+ public void noteWifiMulticastEnabled(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiMulticastEnabledLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiScanStartedFromSource(WorkSource ws) {
+ public void noteWifiMulticastDisabled(final int uid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiScanStartedFromSourceLocked(ws);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiMulticastDisabledLocked(uid, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiScanStoppedFromSource(WorkSource ws) {
+ public void noteFullWifiLockAcquiredFromSource(final WorkSource ws) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiScanStoppedFromSourceLocked(ws);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteFullWifiLockAcquiredFromSourceLocked(ws, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
+ public void noteFullWifiLockReleasedFromSource(final WorkSource ws) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteFullWifiLockReleasedFromSourceLocked(ws, elapsedRealtime, uptime);
+ }
+ });
}
}
- public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
+ public void noteWifiScanStartedFromSource(final WorkSource ws) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiScanStartedFromSourceLocked(ws, elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ public void noteWifiScanStoppedFromSource(final WorkSource ws) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiScanStoppedFromSourceLocked(ws, elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ public void noteWifiBatchedScanStartedFromSource(final WorkSource ws, final int csph) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph,
+ elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ public void noteWifiBatchedScanStoppedFromSource(final WorkSource ws) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws, elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteNetworkInterfaceType(String iface, int networkType) {
+ public void noteNetworkInterfaceType(final String iface, final int networkType) {
enforceCallingPermission();
- mStats.noteNetworkInterfaceType(iface, networkType);
+ synchronized (mLock) {
+ mHandler.post(() -> {
+ mStats.noteNetworkInterfaceType(iface, networkType);
+ });
+ }
}
@Override
@@ -1027,66 +1576,119 @@
// During device boot, qtaguid isn't enabled until after the inital
// loading of battery stats. Now that they're enabled, take our initial
// snapshot for future delta calculation.
- mWorker.scheduleSync("network-stats-enabled",
- BatteryExternalStatsWorker.UPDATE_RADIO | BatteryExternalStatsWorker.UPDATE_WIFI);
- }
-
- @Override
- public void noteDeviceIdleMode(int mode, String activeReason, int activeUid) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid);
- }
- }
-
- public void notePackageInstalled(String pkgName, long versionCode) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.notePackageInstalledLocked(pkgName, versionCode);
- }
- }
-
- public void notePackageUninstalled(String pkgName) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.notePackageUninstalledLocked(pkgName);
+ synchronized (mLock) {
+ // Still schedule it on the handler to make sure we have existing pending works done
+ mHandler.post(() -> {
+ mWorker.scheduleSync("network-stats-enabled",
+ BatteryExternalStatsWorker.UPDATE_RADIO
+ | BatteryExternalStatsWorker.UPDATE_WIFI);
+ });
}
}
@Override
- public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) {
+ public void noteDeviceIdleMode(final int mode, final String activeReason, final int activeUid) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid,
+ elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ public void notePackageInstalled(final String pkgName, final long versionCode) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePackageInstalledLocked(pkgName, versionCode,
+ elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ public void notePackageUninstalled(final String pkgName) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.notePackageUninstalledLocked(pkgName, elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) {
+ public void noteBleScanStarted(final WorkSource ws, final boolean isUnoptimized) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized,
+ elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void noteBleScanStopped(final WorkSource ws, final boolean isUnoptimized) {
+ enforceCallingPermission();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized,
+ uptime, elapsedRealtime);
+ }
+ });
}
}
@Override
public void noteResetBleScan() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteResetBluetoothScanLocked();
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteResetBluetoothScanLocked(elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteBleScanResults(WorkSource ws, int numNewResults) {
+ public void noteBleScanResults(final WorkSource ws, final int numNewResults) {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults,
+ elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteWifiControllerActivity(WifiActivityEnergyInfo info) {
+ public void noteWifiControllerActivity(final WifiActivityEnergyInfo info) {
enforceCallingPermission();
if (info == null || !info.isValid()) {
@@ -1094,24 +1696,36 @@
return;
}
- mStats.updateWifiState(info);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ mStats.updateWifiState(info, elapsedRealtime, uptime);
+ });
+ }
}
@Override
- public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) {
+ public void noteBluetoothControllerActivity(final BluetoothActivityEnergyInfo info) {
enforceCallingPermission();
if (info == null || !info.isValid()) {
Slog.e(TAG, "invalid bluetooth data given: " + info);
return;
}
- synchronized (mStats) {
- mStats.updateBluetoothStateLocked(info);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.updateBluetoothStateLocked(info, elapsedRealtime, uptime);
+ }
+ });
}
}
@Override
- public void noteModemControllerActivity(ModemActivityInfo info) {
+ public void noteModemControllerActivity(final ModemActivityInfo info) {
enforceCallingPermission();
if (info == null || !info.isValid()) {
@@ -1119,7 +1733,13 @@
return;
}
- mStats.updateMobileRadioState(info);
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ mStats.updateMobileRadioState(info, elapsedRealtime, uptime);
+ });
+ }
}
public boolean isOnBattery() {
@@ -1132,32 +1752,43 @@
final int chargeFullUAh, final long chargeTimeToFullSeconds) {
enforceCallingPermission();
- // BatteryService calls us here and we may update external state. It would be wrong
- // to block such a low level service like BatteryService on external stats like WiFi.
- mWorker.scheduleRunnable(() -> {
- synchronized (mStats) {
- final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status);
- if (mStats.isOnBattery() == onBattery) {
- // The battery state has not changed, so we don't need to sync external
- // stats immediately.
- mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
- chargeUAh, chargeFullUAh, chargeTimeToFullSeconds);
- return;
- }
- }
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ final long currentTime = System.currentTimeMillis();
+ // We still schedule this task over the handler thread to make sure we've had
+ // all existing pending work handled before setting the battery state
+ mHandler.post(() -> {
+ // BatteryService calls us here and we may update external state. It would be wrong
+ // to block such a low level service like BatteryService on external stats like WiFi
+ mWorker.scheduleRunnable(() -> {
+ synchronized (mStats) {
+ final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status);
+ if (mStats.isOnBattery() == onBattery) {
+ // The battery state has not changed, so we don't need to sync external
+ // stats immediately.
+ mStats.setBatteryStateLocked(status, health, plugType, level, temp,
+ volt, chargeUAh, chargeFullUAh, chargeTimeToFullSeconds,
+ elapsedRealtime, uptime, currentTime);
+ return;
+ }
+ }
- // Sync external stats first as the battery has changed states. If we don't sync
- // before changing the state, we may not collect the relevant data later.
- // Order here is guaranteed since we're scheduling from the same thread and we are
- // using a single threaded executor.
- mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL);
- mWorker.scheduleRunnable(() -> {
- synchronized (mStats) {
- mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
- chargeUAh, chargeFullUAh, chargeTimeToFullSeconds);
- }
+ // Sync external stats first as the battery has changed states. If we don't sync
+ // before changing the state, we may not collect the relevant data later.
+ // Order here is guaranteed since we're scheduling from the same thread and we
+ // are using a single threaded executor.
+ mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL);
+ mWorker.scheduleRunnable(() -> {
+ synchronized (mStats) {
+ mStats.setBatteryStateLocked(status, health, plugType, level, temp,
+ volt, chargeUAh, chargeFullUAh, chargeTimeToFullSeconds,
+ elapsedRealtime, uptime, currentTime);
+ }
+ });
+ });
});
- });
+ }
}
public long getAwakeTimeBattery() {
@@ -1205,8 +1836,12 @@
try {
String reason;
while ((reason = waitWakeup()) != null) {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
+
synchronized (mStats) {
- mStats.noteWakeupReasonLocked(reason);
+ mStats.noteWakeupReasonLocked(reason,
+ SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
}
}
} catch (RuntimeException e) {
@@ -1273,12 +1908,16 @@
}
private void dumpSettings(PrintWriter pw) {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
mStats.dumpConstantsLocked(pw);
}
}
private void dumpCpuStats(PrintWriter pw) {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
mStats.dumpCpuStatsLocked(pw);
}
@@ -1292,14 +1931,20 @@
return -1;
}
if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
mStats.setRecordAllHistoryLocked(enable);
}
} else if ("no-auto-reset".equals(args[i])) {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
mStats.setNoAutoReset(enable);
}
} else if ("pretend-screen-off".equals(args[i])) {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
mStats.setPretendScreenOff(enable);
}
@@ -1350,6 +1995,7 @@
return;
}
final long events = ParseUtils.parseLong(args[i], 0);
+ awaitCompletion();
synchronized (mStats) {
mStats.createFakeHistoryEvents(events);
pw.println("Battery history create events started.");
@@ -1365,6 +2011,7 @@
} else if ("--daily".equals(arg)) {
flags |= BatteryStats.DUMP_DAILY_ONLY;
} else if ("--reset".equals(arg)) {
+ awaitCompletion();
synchronized (mStats) {
mStats.resetAllStatsCmdLocked();
pw.println("Battery stats reset.");
@@ -1372,6 +2019,7 @@
}
mWorker.scheduleSync("dump", BatteryExternalStatsWorker.UPDATE_ALL);
} else if ("--write".equals(arg)) {
+ awaitCompletion();
syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
synchronized (mStats) {
mStats.writeSyncLocked();
@@ -1379,12 +2027,14 @@
noOutput = true;
}
} else if ("--new-daily".equals(arg)) {
+ awaitCompletion();
synchronized (mStats) {
mStats.recordDailyStatsLocked();
pw.println("New daily stats written.");
noOutput = true;
}
} else if ("--read-daily".equals(arg)) {
+ awaitCompletion();
synchronized (mStats) {
mStats.readDailyStatsLocked();
pw.println("Last daily stats read.");
@@ -1441,6 +2091,7 @@
if (BatteryStatsHelper.checkWifiOnly(mContext)) {
flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
}
+ awaitCompletion();
// Fetch data from external sources and update the BatteryStatsImpl object with them.
syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
} finally {
@@ -1489,6 +2140,7 @@
}
}
if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid());
+ awaitCompletion();
synchronized (mStats) {
mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart);
if (writeData) {
@@ -1528,6 +2180,7 @@
}
}
if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
+ awaitCompletion();
synchronized (mStats) {
mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
if (writeData) {
@@ -1537,6 +2190,7 @@
if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
} else {
if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
+ awaitCompletion();
synchronized (mStats) {
mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
if (writeData) {
@@ -1552,6 +2206,8 @@
* @hide
*/
public CellularBatteryStats getCellularBatteryStats() {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
return mStats.getCellularBatteryStats();
}
@@ -1562,6 +2218,8 @@
* @hide
*/
public WifiBatteryStats getWifiBatteryStats() {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
return mStats.getWifiBatteryStats();
}
@@ -1572,6 +2230,8 @@
* @hide
*/
public GpsBatteryStats getGpsBatteryStats() {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
synchronized (mStats) {
return mStats.getGpsBatteryStats();
}
@@ -1588,6 +2248,8 @@
}
long ident = Binder.clearCallingIdentity();
try {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
if (shouldCollectExternalStats()) {
syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
}
@@ -1614,6 +2276,8 @@
long ident = Binder.clearCallingIdentity();
int i=-1;
try {
+ // Wait for the completion of pending works if there is any
+ awaitCompletion();
if (shouldCollectExternalStats()) {
syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
}
@@ -1685,4 +2349,124 @@
Binder.restoreCallingIdentity(ident);
}
}
+
+ void updateForegroundTimeIfOnBattery(final String packageName, final int uid,
+ final long cpuTimeDiff) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ if (!isOnBattery()) {
+ return;
+ }
+ synchronized (mStats) {
+ final BatteryStatsImpl.Uid.Proc ps =
+ mStats.getProcessStatsLocked(uid, packageName, elapsedRealtime, uptime);
+ if (ps != null) {
+ ps.addForegroundTimeLocked(cpuTimeDiff);
+ }
+ }
+ });
+ }
+ }
+
+ void noteCurrentTimeChanged() {
+ synchronized (mLock) {
+ final long currentTime = System.currentTimeMillis();
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime);
+ }
+ });
+ }
+ }
+
+ void updateBatteryStatsOnActivityUsage(final String packageName, final String className,
+ final int uid, final int userId, final boolean resumed) {
+ synchronized (mLock) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
+ uid, packageName, className,
+ resumed
+ ? FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND
+ : FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
+ synchronized (mStats) {
+ if (resumed) {
+ mStats.noteActivityResumedLocked(uid, elapsedRealtime, uptime);
+ } else {
+ mStats.noteActivityPausedLocked(uid, elapsedRealtime, uptime);
+ }
+ }
+ });
+ }
+ }
+
+ void noteProcessDied(final int uid, final int pid) {
+ synchronized (mLock) {
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.noteProcessDiedLocked(uid, pid);
+ }
+ });
+ }
+ }
+
+ void reportExcessiveCpu(final int uid, final String processName, final long uptimeSince,
+ long cputimeUsed) {
+ synchronized (mLock) {
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ mStats.reportExcessiveCpuLocked(uid, processName, uptimeSince, cputimeUsed);
+ }
+ });
+ }
+ }
+
+ void noteServiceStartRunning(final BatteryStatsImpl.Uid.Pkg.Serv stats) {
+ synchronized (mLock) {
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ stats.startRunningLocked(uptime);
+ }
+ });
+ }
+ }
+
+ void noteServiceStopRunning(final BatteryStatsImpl.Uid.Pkg.Serv stats) {
+ synchronized (mLock) {
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ stats.stopRunningLocked(uptime);
+ }
+ });
+ }
+ }
+
+ void noteServiceStartLaunch(final BatteryStatsImpl.Uid.Pkg.Serv stats) {
+ synchronized (mLock) {
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ stats.startLaunchedLocked(uptime);
+ }
+ });
+ }
+ }
+
+ void noteServiceStopLaunch(final BatteryStatsImpl.Uid.Pkg.Serv stats) {
+ synchronized (mLock) {
+ final long uptime = SystemClock.uptimeMillis();
+ mHandler.post(() -> {
+ synchronized (mStats) {
+ stats.stopLaunchedLocked(uptime);
+ }
+ });
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index c5047e5..9660389 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -479,6 +479,21 @@
private static native void enableFreezerInternal(boolean enable);
/**
+ * Informs binder that a process is about to be frozen. If freezer is enabled on a process via
+ * this method, this method will synchronously dispatch all pending transactions to the
+ * specified pid. This method will not add significant latencies when unfreezing.
+ * After freezing binder calls, binder will block all transaction to the frozen pid, and return
+ * an error to the sending process.
+ *
+ * @param pid the target pid for which binder transactions are to be frozen
+ * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze
+ * binder for the specificed pid.
+ *
+ * @throws RuntimeException in case a flush/freeze operation could not complete successfully.
+ */
+ private static native void freezeBinder(int pid, boolean freeze);
+
+ /**
* Determines whether the freezer is supported by this system
*/
public static boolean isFreezerSupported() {
@@ -727,6 +742,13 @@
}
if (!app.frozen) {
+ try {
+ freezeBinder(app.pid, false);
+ } catch (RuntimeException e) {
+ // TODO: it might be preferable to kill the target pid in this case
+ Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName);
+ }
+
if (DEBUG_FREEZER) {
Slog.d(TAG_AM, "sync unfroze " + app.pid + " " + app.processName);
}
@@ -1039,6 +1061,14 @@
return;
}
+ try {
+ freezeBinder(pid, true);
+ } catch (RuntimeException e) {
+ // TODO: it might be preferable to kill the target pid in this case
+ Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
+ return;
+ }
+
if (pid == 0 || proc.frozen) {
// Already frozen or not a real process, either one being
// launched or one being killed
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index cd3e210..87898d8 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1528,15 +1528,18 @@
&& proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
&& proc.lastCachedPss >= 4000) {
// Turn this condition on to cause killing to happen regularly, for testing.
- if (proc.baseProcessTracker != null) {
- proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
- for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
- ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
- FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED,
- proc.info.uid,
- holder.state.getName(),
- holder.state.getPackage(),
- proc.lastCachedPss, holder.appVersion);
+ synchronized (mService.mProcessStats.mLock) {
+ if (proc.baseProcessTracker != null) {
+ proc.baseProcessTracker.reportCachedKill(
+ proc.pkgList.mPkgList, proc.lastCachedPss);
+ for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
+ FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED,
+ proc.info.uid,
+ holder.state.getName(),
+ holder.state.getPackage(),
+ proc.lastCachedPss, holder.appVersion);
+ }
}
}
proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
@@ -1549,16 +1552,18 @@
if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
.lastCachedPss);
if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
- if (proc.baseProcessTracker != null) {
- proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
- proc.lastCachedPss);
- for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
- ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
- FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED,
- proc.info.uid,
- holder.state.getName(),
- holder.state.getPackage(),
- proc.lastCachedPss, holder.appVersion);
+ synchronized (mService.mProcessStats.mLock) {
+ if (proc.baseProcessTracker != null) {
+ proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
+ proc.lastCachedPss);
+ for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
+ FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED,
+ proc.info.uid,
+ holder.state.getName(),
+ holder.state.getPackage(),
+ proc.lastCachedPss, holder.appVersion);
+ }
}
}
proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 5b12c8c..55e0f2e 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -149,7 +149,7 @@
// allow the service becomes foreground service? Service started from background may not be
// allowed to become a foreground service.
- boolean mAllowStartForeground;
+ @ActiveServices.FgsFeatureRetCode int mAllowStartForeground;
String mInfoAllowStartForeground;
boolean mLoggedInfoAllowStartForeground;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index dfe8af1..b56b09d 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2206,6 +2206,7 @@
updatePermissionRevokedCompat(uid, code, mode);
}
+ int previousMode;
synchronized (this) {
final int defaultMode = AppOpsManager.opToDefaultMode(code);
@@ -2214,12 +2215,14 @@
if (mode == defaultMode) {
return;
}
+ previousMode = AppOpsManager.MODE_DEFAULT;
uidState = new UidState(uid);
uidState.opModes = new SparseIntArray();
uidState.opModes.put(code, mode);
mUidStates.put(uid, uidState);
scheduleWriteLocked();
} else if (uidState.opModes == null) {
+ previousMode = AppOpsManager.MODE_DEFAULT;
if (mode != defaultMode) {
uidState.opModes = new SparseIntArray();
uidState.opModes.put(code, mode);
@@ -2229,6 +2232,7 @@
if (uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == mode) {
return;
}
+ previousMode = uidState.opModes.get(code);
if (mode == defaultMode) {
uidState.opModes.delete(code);
if (uidState.opModes.size() <= 0) {
@@ -2243,7 +2247,7 @@
}
notifyOpChangedForAllPkgsInUid(code, uid, false, permissionPolicyCallback);
- notifyOpChangedSync(code, uid, null, mode);
+ notifyOpChangedSync(code, uid, null, mode, previousMode);
}
/**
@@ -2420,11 +2424,12 @@
}
}
- private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) {
+ private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode,
+ int previousMode) {
final StorageManagerInternal storageManagerInternal =
LocalServices.getService(StorageManagerInternal.class);
if (storageManagerInternal != null) {
- storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode);
+ storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode, previousMode);
}
}
@@ -2458,11 +2463,13 @@
return;
}
+ int previousMode = AppOpsManager.MODE_DEFAULT;
synchronized (this) {
UidState uidState = getUidStateLocked(uid, false);
Op op = getOpLocked(code, uid, packageName, null, bypass, true);
if (op != null) {
if (op.mode != mode) {
+ previousMode = op.mode;
op.mode = mode;
if (uidState != null) {
uidState.evalForegroundOps(mOpModeWatchers);
@@ -2499,7 +2506,7 @@
this, repCbs, code, uid, packageName));
}
- notifyOpChangedSync(code, uid, packageName, mode);
+ notifyOpChangedSync(code, uid, packageName, mode, previousMode);
}
private void notifyOpChanged(ArraySet<ModeCallback> callbacks, int code,
@@ -2542,7 +2549,7 @@
}
private static ArrayList<ChangeRec> addChange(ArrayList<ChangeRec> reports,
- int op, int uid, String packageName) {
+ int op, int uid, String packageName, int previousMode) {
boolean duplicate = false;
if (reports == null) {
reports = new ArrayList<>();
@@ -2557,7 +2564,7 @@
}
}
if (!duplicate) {
- reports.add(new ChangeRec(op, uid, packageName));
+ reports.add(new ChangeRec(op, uid, packageName, previousMode));
}
return reports;
@@ -2565,7 +2572,7 @@
private static HashMap<ModeCallback, ArrayList<ChangeRec>> addCallbacks(
HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks,
- int op, int uid, String packageName, ArraySet<ModeCallback> cbs) {
+ int op, int uid, String packageName, int previousMode, ArraySet<ModeCallback> cbs) {
if (cbs == null) {
return callbacks;
}
@@ -2576,7 +2583,7 @@
for (int i=0; i<N; i++) {
ModeCallback cb = cbs.valueAt(i);
ArrayList<ChangeRec> reports = callbacks.get(cb);
- ArrayList<ChangeRec> changed = addChange(reports, op, uid, packageName);
+ ArrayList<ChangeRec> changed = addChange(reports, op, uid, packageName, previousMode);
if (changed != reports) {
callbacks.put(cb, changed);
}
@@ -2588,11 +2595,13 @@
final int op;
final int uid;
final String pkg;
+ final int previous_mode;
- ChangeRec(int _op, int _uid, String _pkg) {
+ ChangeRec(int _op, int _uid, String _pkg, int _previous_mode) {
op = _op;
uid = _uid;
pkg = _pkg;
+ previous_mode = _previous_mode;
}
}
@@ -2628,18 +2637,19 @@
for (int j = uidOpCount - 1; j >= 0; j--) {
final int code = opModes.keyAt(j);
if (AppOpsManager.opAllowsReset(code)) {
+ int previousMode = opModes.valueAt(j);
opModes.removeAt(j);
if (opModes.size() <= 0) {
uidState.opModes = null;
}
for (String packageName : getPackagesForUid(uidState.uid)) {
callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
- mOpModeWatchers.get(code));
+ previousMode, mOpModeWatchers.get(code));
callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
- mPackageModeWatchers.get(packageName));
+ previousMode, mPackageModeWatchers.get(packageName));
allChanges = addChange(allChanges, code, uidState.uid,
- packageName);
+ packageName, previousMode);
}
}
}
@@ -2670,16 +2680,18 @@
Op curOp = pkgOps.valueAt(j);
if (AppOpsManager.opAllowsReset(curOp.op)
&& curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) {
+ int previousMode = curOp.mode;
curOp.mode = AppOpsManager.opToDefaultMode(curOp.op);
changed = true;
uidChanged = true;
final int uid = curOp.uidState.uid;
callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
- mOpModeWatchers.get(curOp.op));
+ previousMode, mOpModeWatchers.get(curOp.op));
callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
- mPackageModeWatchers.get(packageName));
+ previousMode, mPackageModeWatchers.get(packageName));
- allChanges = addChange(allChanges, curOp.op, uid, packageName);
+ allChanges = addChange(allChanges, curOp.op, uid, packageName,
+ previousMode);
curOp.removeAttributionsWithNoTime();
if (curOp.mAttributions.isEmpty()) {
pkgOps.removeAt(j);
@@ -2720,7 +2732,7 @@
for (int i = 0; i < numChanges; i++) {
ChangeRec change = allChanges.get(i);
notifyOpChangedSync(change.op, change.uid, change.pkg,
- AppOpsManager.opToDefaultMode(change.op));
+ AppOpsManager.opToDefaultMode(change.op), change.previous_mode);
}
}
}
@@ -3926,7 +3938,7 @@
if (!isAttributionTagValid) {
String msg = "attributionTag " + attributionTag + " not declared in"
- + "manifest of " + packageName;
+ + " manifest of " + packageName;
try {
if (mPlatformCompat.isChangeEnabledByPackageName(
SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, packageName,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 5447605..1615998 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -28,6 +28,7 @@
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
+import android.media.ICapturePresetDevicesRoleDispatcher;
import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.MediaMetrics;
import android.os.Binder;
@@ -546,6 +547,25 @@
mDeviceInventory.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
}
+ /*package*/ int setPreferredDevicesForCapturePresetSync(int capturePreset,
+ @NonNull List<AudioDeviceAttributes> devices) {
+ return mDeviceInventory.setPreferredDevicesForCapturePresetSync(capturePreset, devices);
+ }
+
+ /*package*/ int clearPreferredDevicesForCapturePresetSync(int capturePreset) {
+ return mDeviceInventory.clearPreferredDevicesForCapturePresetSync(capturePreset);
+ }
+
+ /*package*/ void registerCapturePresetDevicesRoleDispatcher(
+ @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+ mDeviceInventory.registerCapturePresetDevicesRoleDispatcher(dispatcher);
+ }
+
+ /*package*/ void unregisterCapturePresetDevicesRoleDispatcher(
+ @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+ mDeviceInventory.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
+ }
+
//---------------------------------------------------------------------
// Communication with (to) AudioService
//TODO check whether the AudioService methods are candidates to move here
@@ -694,6 +714,17 @@
sendIMsgNoDelay(MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_QUEUE, strategy);
}
+ /*package*/ void postSaveSetPreferredDevicesForCapturePreset(
+ int capturePreset, List<AudioDeviceAttributes> devices) {
+ sendILMsgNoDelay(
+ MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset, devices);
+ }
+
+ /*package*/ void postSaveClearPreferredDevicesForCapturePreset(int capturePreset) {
+ sendIMsgNoDelay(
+ MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset);
+ }
+
//---------------------------------------------------------------------
// Method forwarding between the helper classes (BtHelper, AudioDeviceInventory)
// only call from a "handle"* method or "on"* method
@@ -1098,6 +1129,17 @@
case MSG_CHECK_MUTE_MUSIC:
checkMessagesMuteMusic(0);
break;
+ case MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET: {
+ final int capturePreset = msg.arg1;
+ final List<AudioDeviceAttributes> devices =
+ (List<AudioDeviceAttributes>) msg.obj;
+ mDeviceInventory.onSaveSetPreferredDevicesForCapturePreset(
+ capturePreset, devices);
+ } break;
+ case MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET: {
+ final int capturePreset = msg.arg1;
+ mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset);
+ } break;
default:
Log.wtf(TAG, "Invalid message " + msg.what);
}
@@ -1174,6 +1216,9 @@
private static final int MSG_CHECK_MUTE_MUSIC = 36;
private static final int MSG_REPORT_NEW_ROUTES_A2DP = 37;
+ private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET = 38;
+ private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 39;
+
private static boolean isMessageHandledUnderWakelock(int msgId) {
switch(msgId) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index fbf07cc..33a8a30 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -31,6 +31,7 @@
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
+import android.media.ICapturePresetDevicesRoleDispatcher;
import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.MediaMetrics;
import android.os.Binder;
@@ -140,6 +141,10 @@
private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevices =
new ArrayMap<>();
+ // List of preferred devices of capture preset
+ private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevicesForCapturePreset =
+ new ArrayMap<>();
+
// the wrapper for AudioSystem static methods, allows us to spy AudioSystem
private final @NonNull AudioSystemAdapter mAudioSystem;
@@ -154,6 +159,10 @@
final RemoteCallbackList<IStrategyPreferredDevicesDispatcher> mPrefDevDispatchers =
new RemoteCallbackList<IStrategyPreferredDevicesDispatcher>();
+ // Monitoring of devices for role and capture preset
+ final RemoteCallbackList<ICapturePresetDevicesRoleDispatcher> mDevRoleCapturePresetDispatchers =
+ new RemoteCallbackList<ICapturePresetDevicesRoleDispatcher>();
+
/*package*/ AudioDeviceInventory(@NonNull AudioDeviceBroker broker) {
mDeviceBroker = broker;
mAudioSystem = AudioSystemAdapter.getDefaultAdapter();
@@ -243,6 +252,9 @@
pw.println(" " + prefix + " type:0x" + Integer.toHexString(keyType)
+ " (" + AudioSystem.getDeviceName(keyType)
+ ") addr:" + valueAddress); });
+ mPreferredDevicesForCapturePreset.forEach((capturePreset, devices) -> {
+ pw.println(" " + prefix + "capturePreset:" + capturePreset
+ + " devices:" + devices); });
}
//------------------------------------------------------------
@@ -270,6 +282,9 @@
mAudioSystem.setDevicesRoleForStrategy(
strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); });
}
+ synchronized (mPreferredDevicesForCapturePreset) {
+ // TODO: call audiosystem to restore
+ }
}
// only public for mocking/spying
@@ -613,6 +628,20 @@
dispatchPreferredDevice(strategy, new ArrayList<AudioDeviceAttributes>());
}
+ /*package*/ void onSaveSetPreferredDevicesForCapturePreset(
+ int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
+ mPreferredDevicesForCapturePreset.put(capturePreset, devices);
+ dispatchDevicesRoleForCapturePreset(
+ capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+ }
+
+ /*package*/ void onSaveClearPreferredDevicesForCapturePreset(int capturePreset) {
+ mPreferredDevicesForCapturePreset.remove(capturePreset);
+ dispatchDevicesRoleForCapturePreset(
+ capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED,
+ new ArrayList<AudioDeviceAttributes>());
+ }
+
//------------------------------------------------------------
//
@@ -651,6 +680,41 @@
mPrefDevDispatchers.unregister(dispatcher);
}
+ /*package*/ int setPreferredDevicesForCapturePresetSync(
+ int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
+ final long identity = Binder.clearCallingIdentity();
+ final int status = mAudioSystem.setDevicesRoleForCapturePreset(
+ capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+ Binder.restoreCallingIdentity(identity);
+
+ if (status == AudioSystem.SUCCESS) {
+ mDeviceBroker.postSaveSetPreferredDevicesForCapturePreset(capturePreset, devices);
+ }
+ return status;
+ }
+
+ /*package*/ int clearPreferredDevicesForCapturePresetSync(int capturePreset) {
+ final long identity = Binder.clearCallingIdentity();
+ final int status = mAudioSystem.clearDevicesRoleForCapturePreset(
+ capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED);
+ Binder.restoreCallingIdentity(identity);
+
+ if (status == AudioSystem.SUCCESS) {
+ mDeviceBroker.postSaveClearPreferredDevicesForCapturePreset(capturePreset);
+ }
+ return status;
+ }
+
+ /*package*/ void registerCapturePresetDevicesRoleDispatcher(
+ @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+ mDevRoleCapturePresetDispatchers.register(dispatcher);
+ }
+
+ /*package*/ void unregisterCapturePresetDevicesRoleDispatcher(
+ @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) {
+ mDevRoleCapturePresetDispatchers.unregister(dispatcher);
+ }
+
/**
* Implements the communication with AudioSystem to (dis)connect a device in the native layers
* @param connect true if connection
@@ -1306,6 +1370,19 @@
mPrefDevDispatchers.finishBroadcast();
}
+ private void dispatchDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+ final int nbDispatchers = mDevRoleCapturePresetDispatchers.beginBroadcast();
+ for (int i = 0; i < nbDispatchers; ++i) {
+ try {
+ mDevRoleCapturePresetDispatchers.getBroadcastItem(i).dispatchDevicesRoleChanged(
+ capturePreset, role, devices);
+ } catch (RemoteException e) {
+ }
+ }
+ mDevRoleCapturePresetDispatchers.finishBroadcast();
+ }
+
//----------------------------------------------------------
// For tests only
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
old mode 100755
new mode 100644
index 4378490..f63c2ee
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -84,6 +84,7 @@
import android.media.IAudioRoutesObserver;
import android.media.IAudioServerStateDispatcher;
import android.media.IAudioService;
+import android.media.ICapturePresetDevicesRoleDispatcher;
import android.media.IPlaybackConfigDispatcher;
import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
@@ -1987,6 +1988,94 @@
mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
}
+ /**
+ * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
+ */
+ public int setPreferredDevicesForCapturePreset(
+ int capturePreset, List<AudioDeviceAttributes> devices) {
+ if (devices == null) {
+ return AudioSystem.ERROR;
+ }
+ enforceModifyAudioRoutingPermission();
+ final String logString = String.format(
+ "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
+ Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
+ devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
+ sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
+ if (devices.stream().anyMatch(device ->
+ device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
+ Log.e(TAG, "Unsupported output routing in " + logString);
+ return AudioSystem.ERROR;
+ }
+
+ final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
+ capturePreset, devices);
+ if (status != AudioSystem.SUCCESS) {
+ Log.e(TAG, String.format("Error %d in %s)", status, logString));
+ }
+
+ return status;
+ }
+
+ /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
+ public int clearPreferredDevicesForCapturePreset(int capturePreset) {
+ enforceModifyAudioRoutingPermission();
+ final String logString = String.format(
+ "removePreferredDeviceForCapturePreset source:%d", capturePreset);
+ sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
+
+ final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
+ if (status != AudioSystem.SUCCESS) {
+ Log.e(TAG, String.format("Error %d in %s", status, logString));
+ }
+ return status;
+ }
+
+ /**
+ * @see AudioManager#getPreferredDevicesForCapturePreset(int)
+ */
+ public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
+ enforceModifyAudioRoutingPermission();
+ List<AudioDeviceAttributes> devices = new ArrayList<>();
+ final long identity = Binder.clearCallingIdentity();
+ final int status = AudioSystem.getDevicesForRoleAndCapturePreset(
+ capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+ Binder.restoreCallingIdentity(identity);
+ if (status != AudioSystem.SUCCESS) {
+ Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
+ status, capturePreset));
+ return new ArrayList<AudioDeviceAttributes>();
+ } else {
+ return devices;
+ }
+ }
+
+ /**
+ * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
+ * Executor, OnPreferredDevicesForCapturePresetChangedListener)
+ */
+ public void registerCapturePresetDevicesRoleDispatcher(
+ @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
+ if (dispatcher == null) {
+ return;
+ }
+ enforceModifyAudioRoutingPermission();
+ mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher);
+ }
+
+ /**
+ * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
+ * AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
+ */
+ public void unregisterCapturePresetDevicesRoleDispatcher(
+ @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
+ if (dispatcher == null) {
+ return;
+ }
+ enforceModifyAudioRoutingPermission();
+ mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
+ }
+
/** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
@NonNull AudioAttributes attributes) {
@@ -4097,6 +4186,62 @@
}
}
+ /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
+ @Override
+ public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
+ @NonNull String packageName, int uid, int pid, UserHandle userHandle,
+ int targetSdkVersion) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Should only be called from system process");
+ }
+
+ final boolean hasModifyAudioSettings =
+ mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ // direction and stream type swap here because the public
+ // adjustSuggested has a different order than the other methods.
+ adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, uid,
+ hasModifyAudioSettings, VOL_ADJUST_NORMAL);
+ }
+
+ /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
+ @Override
+ public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
+ @NonNull String packageName, int uid, int pid, UserHandle userHandle,
+ int targetSdkVersion) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Should only be called from system process");
+ }
+
+ if (direction != AudioManager.ADJUST_SAME) {
+ sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
+ direction/*val1*/, flags/*val2*/,
+ new StringBuilder(packageName).append(" uid:").append(uid)
+ .toString()));
+ }
+ final boolean hasModifyAudioSettings =
+ mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid,
+ hasModifyAudioSettings, VOL_ADJUST_NORMAL);
+ }
+
+ /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
+ @Override
+ public void setStreamVolumeForUid(int streamType, int index, int flags,
+ @NonNull String packageName, int uid, int pid, UserHandle userHandle,
+ int targetSdkVersion) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Should only be called from system process");
+ }
+
+ final boolean hasModifyAudioSettings =
+ mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ setStreamVolume(streamType, index, flags, packageName, packageName, uid,
+ hasModifyAudioSettings);
+ }
+
//==========================================================================================
// Sound Effects
//==========================================================================================
@@ -7982,43 +8127,6 @@
}
@Override
- public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid, int pid) {
- final boolean hasModifyAudioSettings =
- mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
- == PackageManager.PERMISSION_GRANTED;
- // direction and stream type swap here because the public
- // adjustSuggested has a different order than the other methods.
- adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage,
- callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL);
- }
-
- @Override
- public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid, int pid) {
- if (direction != AudioManager.ADJUST_SAME) {
- sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
- direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
- .append(" uid:").append(uid).toString()));
- }
- final boolean hasModifyAudioSettings =
- mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
- == PackageManager.PERMISSION_GRANTED;
- adjustStreamVolume(streamType, direction, flags, callingPackage,
- callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL);
- }
-
- @Override
- public void setStreamVolumeForUid(int streamType, int direction, int flags,
- String callingPackage, int uid, int pid) {
- final boolean hasModifyAudioSettings =
- mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
- == PackageManager.PERMISSION_GRANTED;
- setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid,
- hasModifyAudioSettings);
- }
-
- @Override
public int getRingerModeInternal() {
return AudioService.this.getRingerModeInternal();
}
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index a0e1ca7..ae64990 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -101,6 +101,40 @@
}
/**
+ * Same as (@link AudioSystem#setDevicesRoleForCapturePreset(int, List))
+ * @param capturePreset
+ * @param role
+ * @param devices
+ * @return
+ */
+ public int setDevicesRoleForCapturePreset(int capturePreset, int role,
+ @NonNull List<AudioDeviceAttributes> devices) {
+ return AudioSystem.setDevicesRoleForCapturePreset(capturePreset, role, devices);
+ }
+
+ /**
+ * Same as {@link AudioSystem#removeDevicesRoleForCapturePreset(int, int)}
+ * @param capturePreset
+ * @param role
+ * @param devicesToRemove
+ * @return
+ */
+ public int removeDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devicesToRemove) {
+ return AudioSystem.removeDevicesRoleForCapturePreset(capturePreset, role, devicesToRemove);
+ }
+
+ /**
+ * Same as {@link AudioSystem#}
+ * @param capturePreset
+ * @param role
+ * @return
+ */
+ public int clearDevicesRoleForCapturePreset(int capturePreset, int role) {
+ return AudioSystem.clearDevicesRoleForCapturePreset(capturePreset, role);
+ }
+
+ /**
* Same as {@link AudioSystem#setParameters(String)}
* @param keyValuePairs
* @return
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
old mode 100755
new mode 100644
index bbc29b0..f02bb8f
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioFocusInfo;
@@ -94,8 +95,9 @@
mContext = cntxt;
mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
mFocusEnforcer = pfe;
- mMultiAudioFocusEnabled = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.MULTI_AUDIO_FOCUS_ENABLED, 0) != 0;
+ final ContentResolver cr = mContext.getContentResolver();
+ mMultiAudioFocusEnabled = Settings.System.getIntForUser(cr,
+ Settings.System.MULTI_AUDIO_FOCUS_ENABLED, 0, cr.getUserId()) != 0;
}
protected void dump(PrintWriter pw) {
@@ -1081,8 +1083,9 @@
public void updateMultiAudioFocus(boolean enabled) {
Log.d(TAG, "updateMultiAudioFocus( " + enabled + " )");
mMultiAudioFocusEnabled = enabled;
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.MULTI_AUDIO_FOCUS_ENABLED, enabled ? 1 : 0);
+ final ContentResolver cr = mContext.getContentResolver();
+ Settings.System.putIntForUser(cr,
+ Settings.System.MULTI_AUDIO_FOCUS_ENABLED, enabled ? 1 : 0, cr.getUserId());
if (!mFocusStack.isEmpty()) {
final FocusRequester fr = mFocusStack.peek();
fr.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS, null, false);
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index 73fc17a..9898d76 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -98,7 +98,11 @@
}
if (finish) {
- mCallback.onClientFinished(this, false /* success */);
+ if (mCallback == null) {
+ Slog.e(TAG, "Callback is null, perhaps the client hasn't been started yet?");
+ } else {
+ mCallback.onClientFinished(this, false /* success */);
+ }
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
index e585b48..3c9dddd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
@@ -176,6 +176,9 @@
// TODO(b/157790417): Move this to the scheduler
void binderDiedInternal(boolean clearListener) {
+ Slog.e(TAG, "Binder died, owner: " + getOwnerString()
+ + ", operation: " + this.getClass().getName());
+
if (isAlreadyDone()) {
Slog.w(TAG, "Binder died but client is finished, ignoring");
return;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
index d9c62df..d2c35fe 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
@@ -25,12 +25,14 @@
import android.content.Context;
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
import android.hardware.face.Face;
import android.hardware.face.FaceSensorProperties;
import android.hardware.face.IFaceServiceReceiver;
+import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -109,6 +111,9 @@
@Override
public void onUserSwitching(int newUserId) {
scheduleInternalCleanup(newUserId);
+ scheduleGetFeature(new Binder(), newUserId,
+ BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION,
+ null, mContext.getOpPackageName());
}
};
@@ -360,6 +365,9 @@
if (halId != 0) {
scheduleLoadAuthenticatorIds();
scheduleInternalCleanup(ActivityManager.getCurrentUser());
+ scheduleGetFeature(new Binder(), ActivityManager.getCurrentUser(),
+ BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION,
+ null, mContext.getOpPackageName());
} else {
Slog.e(TAG, "Unable to set callback");
mDaemon = null;
@@ -450,7 +458,7 @@
}
void scheduleGetFeature(@NonNull IBinder token, int userId, int feature,
- @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+ @Nullable ClientMonitorCallbackConverter listener, @NonNull String opPackageName) {
mHandler.post(() -> {
final List<Face> faces = getEnrolledFaces(userId);
if (faces.isEmpty()) {
@@ -461,10 +469,22 @@
scheduleUpdateActiveUserWithoutHandler(userId);
final int faceId = faces.get(0).getBiometricId();
- final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext,
- mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
- opPackageName, mSensorId, feature, faceId);
- mScheduler.scheduleClientMonitor(client);
+ final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext, mLazyDaemon,
+ token, listener, userId, opPackageName, mSensorId, feature, faceId);
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientFinished(
+ @NonNull ClientMonitor<?> clientMonitor, boolean success) {
+ if (success && feature == BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION) {
+ final int settingsValue = client.getValue() ? 1 : 0;
+ Slog.d(TAG, "Updating attention value for user: " + userId
+ + " to value: " + settingsValue);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
+ settingsValue, userId);
+ }
+ }
+ });
});
}
@@ -490,8 +510,15 @@
if (mCurrentChallengeOwner != null) {
Slog.w(TAG, "Current challenge owner: " + mCurrentChallengeOwner
+ ", interrupted by: " + opPackageName);
+ final ClientMonitorCallbackConverter listener =
+ mCurrentChallengeOwner.getListener();
+ if (listener == null) {
+ Slog.w(TAG, "Null listener, skip sending interruption callback");
+ return;
+ }
+
try {
- mCurrentChallengeOwner.getListener().onChallengeInterrupted(mSensorId);
+ listener.onChallengeInterrupted(mSensorId);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify challenge interrupted", e);
}
@@ -504,7 +531,7 @@
@Override
public void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) {
if (client != clientMonitor) {
- Slog.e(TAG, "scheduleGenerateChallenge, mismatched client."
+ Slog.e(TAG, "scheduleGenerateChallenge onClientStarted, mismatched client."
+ " Expecting: " + client + ", received: " + clientMonitor);
return;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
index 8c7b99d..33b2b6a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
@@ -17,6 +17,7 @@
package com.android.server.biometrics.sensors.face;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
@@ -39,9 +40,10 @@
private final int mFeature;
private final int mFaceId;
+ private boolean mValue;
FaceGetFeatureClient(@NonNull Context context, @NonNull LazyDaemon<IBiometricsFace> lazyDaemon,
- @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
+ @NonNull IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
@NonNull String owner, int sensorId, int feature, int faceId) {
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
BiometricsProtoEnums.MODALITY_UNKNOWN, BiometricsProtoEnums.ACTION_UNKNOWN,
@@ -54,7 +56,9 @@
@Override
public void unableToStart() {
try {
- getListener().onFeatureGet(false /* success */, mFeature, false /* value */);
+ if (getListener() != null) {
+ getListener().onFeatureGet(false /* success */, mFeature, false /* value */);
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Unable to send error", e);
}
@@ -70,11 +74,18 @@
protected void startHalOperation() {
try {
final OptionalBool result = getFreshDaemon().getFeature(mFeature, mFaceId);
- getListener().onFeatureGet(result.status == Status.OK, mFeature, result.value);
+ mValue = result.value;
+ if (getListener() != null) {
+ getListener().onFeatureGet(result.status == Status.OK, mFeature, mValue);
+ }
mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to getFeature", e);
mCallback.onClientFinished(this, false /* success */);
}
}
+
+ boolean getValue() {
+ return mValue;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index b689106..c6664f4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -25,9 +25,9 @@
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.face.Face;
+import android.hardware.face.FaceSensorProperties;
import android.hardware.face.IFaceService;
import android.hardware.face.IFaceServiceReceiver;
-import android.hardware.face.FaceSensorProperties;
import android.os.Binder;
import android.os.IBinder;
import android.os.NativeHandle;
@@ -303,7 +303,8 @@
public void getFeature(final IBinder token, int userId, int feature,
IFaceServiceReceiver receiver, final String opPackageName) {
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
- mFace10.scheduleGetFeature(token, userId, feature, receiver, opPackageName);
+ mFace10.scheduleGetFeature(token, userId, feature,
+ new ClientMonitorCallbackConverter(receiver), opPackageName);
}
@Override // Binder call
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index a0bc7d8..5d2f512 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -57,10 +57,12 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.autofill.AutofillManagerInternal;
+import android.widget.Toast;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
+import com.android.server.UiThread;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wm.WindowManagerInternal;
@@ -391,7 +393,9 @@
return null;
}
addActiveOwnerLocked(intendingUid, pkg);
- return getClipboard(intendingUserId).primaryClip;
+ PerUserClipboard clipboard = getClipboard(intendingUserId);
+ maybeNotify(pkg, intendingUid, intendingUserId, clipboard);
+ return clipboard.primaryClip;
}
}
@@ -821,4 +825,65 @@
return appOpsResult == AppOpsManager.MODE_ALLOWED;
}
+
+ /**
+ * Potentially notifies the user (via a toast) about an app accessing the clipboard.
+ * TODO(b/167676460): STOPSHIP as we don't want this code as-is to launch. Just an experiment.
+ */
+ private void maybeNotify(String callingPackage, int uid, @UserIdInt int userId,
+ PerUserClipboard clipboard) {
+ if (clipboard.primaryClip == null) {
+ return;
+ }
+ if (Settings.Global.getInt(getContext().getContentResolver(),
+ "clipboard_access_toast_enabled", 0) == 0) {
+ return;
+ }
+ // Don't notify if the app accessing the clipboard is the same as the current owner.
+ if (UserHandle.isSameApp(uid, clipboard.primaryClipUid)) {
+ return;
+ }
+ // Exclude some special cases. It's a bit wasteful to check these again here, but for now
+ // beneficial to have all the logic contained in this single (probably temporary) method.
+ String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, userId);
+ if (!TextUtils.isEmpty(defaultIme)) {
+ final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
+ if (imePkg.equals(callingPackage)) {
+ return;
+ }
+ }
+ if (mContentCaptureInternal != null
+ && mContentCaptureInternal.isContentCaptureServiceForUser(uid, userId)) {
+ return;
+ }
+ if (mAutofillInternal != null
+ && mAutofillInternal.isAugmentedAutofillServiceForUser(uid, userId)) {
+ return;
+ }
+ // Load the labels for the calling app and the app that set the clipboard content.
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final IPackageManager pm = AppGlobals.getPackageManager();
+ String message;
+ final CharSequence callingLabel = mPm.getApplicationLabel(
+ pm.getApplicationInfo(callingPackage, 0, userId));
+ final String[] packagesForUid = pm.getPackagesForUid(clipboard.primaryClipUid);
+ if (packagesForUid != null && packagesForUid.length > 0) {
+ final CharSequence clipLabel = mPm.getApplicationLabel(
+ pm.getApplicationInfo(packagesForUid[0], 0,
+ UserHandle.getUserId(clipboard.primaryClipUid)));
+ message = callingLabel + " pasted from " + clipLabel;
+ } else {
+ message = callingLabel + " pasted from clipboard";
+ }
+ Slog.i(TAG, message);
+ Toast.makeText(getContext(), UiThread.get().getLooper(), message, Toast.LENGTH_SHORT)
+ .show();
+ } catch (RemoteException e) {
+ /* ignore */
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 92fce8a..c7de8d3 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -107,17 +107,23 @@
}
/**
- * Internal version of the above method. Does not perform costly permission check.
+ * Internal version of the above method, without logging. Does not perform costly permission
+ * check.
+ * TODO(b/167551701): Remove this method and add 'loggability' as a changeid property.
+ */
+ public boolean isChangeEnabledInternalNoLogging(long changeId, ApplicationInfo appInfo) {
+ return mCompatConfig.isChangeEnabled(changeId, appInfo);
+ }
+
+ /**
+ * Internal version of {@link #isChangeEnabled(long, ApplicationInfo)}. Does not perform costly
+ * permission check.
*/
public boolean isChangeEnabledInternal(long changeId, ApplicationInfo appInfo) {
- if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
- reportChange(changeId, appInfo.uid,
- ChangeReporter.STATE_ENABLED);
- return true;
- }
+ boolean value = isChangeEnabledInternalNoLogging(changeId, appInfo);
reportChange(changeId, appInfo.uid,
- ChangeReporter.STATE_DISABLED);
- return false;
+ value ? ChangeReporter.STATE_ENABLED : ChangeReporter.STATE_DISABLED);
+ return value;
}
@Override
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 36d69c9..f42e18a 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -17,8 +17,8 @@
package com.android.server.display;
import android.annotation.Nullable;
-import android.app.ActivityManager.StackInfo;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityTaskManager;
import android.app.TaskStackListener;
import android.content.Context;
@@ -846,7 +846,7 @@
public void run() {
try {
// The foreground app is the top activity of the focused tasks stack.
- final StackInfo info = mActivityTaskManager.getFocusedStackInfo();
+ final RootTaskInfo info = mActivityTaskManager.getFocusedRootTaskInfo();
if (info == null || info.topActivity == null) {
return;
}
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index eea1980..9e82d4f 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -20,6 +20,7 @@
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -377,14 +378,14 @@
}
try {
- final ActivityManager.StackInfo focusedStack = mInjector.getFocusedStack();
- if (focusedStack != null && focusedStack.topActivity != null) {
- builder.setUserId(focusedStack.userId);
- builder.setPackageName(focusedStack.topActivity.getPackageName());
+ final RootTaskInfo focusedTask = mInjector.getFocusedStack();
+ if (focusedTask != null && focusedTask.topActivity != null) {
+ builder.setUserId(focusedTask.userId);
+ builder.setPackageName(focusedTask.topActivity.getPackageName());
} else {
// Ignore the event because we can't determine user / package.
if (DEBUG) {
- Slog.d(TAG, "Ignoring event due to null focusedStack.");
+ Slog.d(TAG, "Ignoring event due to null focusedTask.");
}
return;
}
@@ -1104,8 +1105,8 @@
}
}
- public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
- return ActivityTaskManager.getService().getFocusedStackInfo();
+ public RootTaskInfo getFocusedStack() throws RemoteException {
+ return ActivityTaskManager.getService().getFocusedRootTaskInfo();
}
public void scheduleIdleJob(Context context) {
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index ad3cd67..73f7889 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -493,6 +493,10 @@
== Display.COLOR_MODE_DISPLAY_P3;
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
mDisplayManagerInternal.systemScreenshot(mDisplayId);
+ if (screenshotBuffer == null) {
+ Slog.e(TAG, "Failed to take screenshot. Buffer is null");
+ return false;
+ }
s.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(),
screenshotBuffer.getColorSpace());
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 2b13bcd..4a12ee7 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -284,6 +284,7 @@
// Temporary display info, used for comparing display configurations.
private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
+ private final DisplayInfo mTempNonOverrideDisplayInfo = new DisplayInfo();
// Temporary viewports, used when sending new viewport information to the
// input system. May be used outside of the lock but only on the handler thread.
@@ -508,7 +509,8 @@
mDisplayTransactionListeners.remove(listener);
}
- private void setDisplayInfoOverrideFromWindowManagerInternal(
+ @VisibleForTesting
+ void setDisplayInfoOverrideFromWindowManagerInternal(
int displayId, DisplayInfo info) {
synchronized (mSyncRoot) {
LogicalDisplay display = mLogicalDisplays.get(displayId);
@@ -936,7 +938,8 @@
adapter.registerLocked();
}
- private void handleDisplayDeviceAdded(DisplayDevice device) {
+ @VisibleForTesting
+ void handleDisplayDeviceAdded(DisplayDevice device) {
synchronized (mSyncRoot) {
handleDisplayDeviceAddedLocked(device);
}
@@ -948,7 +951,6 @@
Slog.w(TAG, "Attempted to add already added display device: " + info);
return;
}
-
Slog.i(TAG, "Display device added: " + info);
device.mDebugLastLoggedDeviceInfo = info;
@@ -961,7 +963,8 @@
scheduleTraversalLocked(false);
}
- private void handleDisplayDeviceChanged(DisplayDevice device) {
+ @VisibleForTesting
+ void handleDisplayDeviceChanged(DisplayDevice device) {
synchronized (mSyncRoot) {
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if (!mDisplayDevices.contains(device)) {
@@ -1235,6 +1238,7 @@
LogicalDisplay display = mLogicalDisplays.valueAt(i);
mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
+ display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
display.updateLocked(mDisplayDevices);
if (!display.isValidLocked()) {
mLogicalDisplays.removeAt(i);
@@ -1243,6 +1247,15 @@
} else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
handleLogicalDisplayChanged(displayId, display);
changed = true;
+ } else {
+ // While applications shouldn't know nor care about the non-overridden info, we
+ // still need to let WindowManager know so it can update its own internal state for
+ // things like display cutouts.
+ display.getNonOverrideDisplayInfoLocked(mTempDisplayInfo);
+ if (!mTempNonOverrideDisplayInfo.equals(mTempDisplayInfo)) {
+ handleLogicalDisplayChanged(displayId, display);
+ changed = true;
+ }
}
}
return changed;
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 3c05080..cc6687f 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -869,10 +869,11 @@
}
private void updateRefreshRateSettingLocked() {
- float minRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
- Settings.System.MIN_REFRESH_RATE, 0f);
- float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
- Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
+ final ContentResolver cr = mContext.getContentResolver();
+ float minRefreshRate = Settings.System.getFloatForUser(cr,
+ Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId());
+ float peakRefreshRate = Settings.System.getFloatForUser(cr,
+ Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, cr.getUserId());
updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
}
@@ -1301,8 +1302,9 @@
}
// TODO: brightnessfloat: make it use float not int
private void onBrightnessChangedLocked() {
- int brightness = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS, -1);
+ final ContentResolver cr = mContext.getContentResolver();
+ int brightness = Settings.System.getIntForUser(cr,
+ Settings.System.SCREEN_BRIGHTNESS, -1, cr.getUserId());
Vote vote = null;
boolean insideZone = isInsideZone(brightness, mAmbientLux);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 7b52dde..7dc4d6e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -893,7 +893,7 @@
@Override
public void serviceDied(long cookie) {
if (cookie == HDMI_CEC_HAL_DEATH_COOKIE) {
- HdmiLogger.error(TAG, "Service died cokkie : " + cookie + "; reconnecting");
+ HdmiLogger.error("Service died cookie : " + cookie + "; reconnecting");
connectToHal();
}
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 813def4..6c14b2c 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -222,7 +222,7 @@
private static native void nativeRegisterInputChannel(long ptr, InputChannel inputChannel);
private static native void nativeRegisterInputMonitor(long ptr, InputChannel inputChannel,
int displayId, boolean isGestureMonitor);
- private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel);
+ private static native void nativeUnregisterInputChannel(long ptr, IBinder connectionToken);
private static native void nativePilferPointers(long ptr, IBinder token);
private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
private static native void nativeSetInTouchMode(long ptr, boolean inTouchMode);
@@ -581,17 +581,17 @@
/**
* Unregisters an input channel.
- * @param inputChannel The input channel to unregister.
+ * @param connectionToken The input channel to unregister.
*/
- public void unregisterInputChannel(InputChannel inputChannel) {
- if (inputChannel == null) {
- throw new IllegalArgumentException("inputChannel must not be null.");
+ public void unregisterInputChannel(IBinder connectionToken) {
+ if (connectionToken == null) {
+ throw new IllegalArgumentException("connectionToken must not be null.");
}
synchronized (mGestureMonitorPidsLock) {
- mGestureMonitorPidsByToken.remove(inputChannel.getToken());
+ mGestureMonitorPidsByToken.remove(connectionToken);
}
- nativeUnregisterInputChannel(mPtr, inputChannel);
+ nativeUnregisterInputChannel(mPtr, connectionToken);
}
/**
@@ -2455,7 +2455,7 @@
@Override
public void dispose() {
- nativeUnregisterInputChannel(mPtr, mInputChannel);
+ nativeUnregisterInputChannel(mPtr, mInputChannel.getToken());
mInputChannel.dispose();
}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 3e5b6e3..a4486d7 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -85,7 +85,9 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* A GNSS implementation of LocationProvider used by LocationManager.
@@ -181,7 +183,6 @@
private static final int INJECT_NTP_TIME = 5;
// PSDS stands for Predicted Satellite Data Service
private static final int DOWNLOAD_PSDS_DATA = 6;
- private static final int DOWNLOAD_PSDS_DATA_FINISHED = 11;
private static final int INITIALIZE_HANDLER = 13;
private static final int REQUEST_LOCATION = 16;
private static final int REPORT_LOCATION = 17; // HAL reports location
@@ -288,6 +289,7 @@
private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000;
private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000;
+ @GuardedBy("mLock")
private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
MAX_RETRY_INTERVAL);
@@ -297,14 +299,8 @@
private boolean mShutdown;
- // states for injecting ntp and downloading psds data
- private static final int STATE_PENDING_NETWORK = 0;
- private static final int STATE_DOWNLOADING = 1;
- private static final int STATE_IDLE = 2;
-
- // flags to trigger NTP or PSDS data download when network becomes available
- // initialized to true so we do NTP and PSDS when the network comes up after booting
- private int mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
+ @GuardedBy("mLock")
+ private Set<Integer> mPendingDownloadPsdsTypes = new HashSet<>();
// true if GPS is navigating
private boolean mNavigating;
@@ -610,6 +606,8 @@
mNIHandler = new GpsNetInitiatedHandler(context,
mNetInitiatedListener,
mSuplEsEnabled);
+ // Trigger PSDS data download when the network comes up after booting.
+ mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
GnssLocationProvider.this::onNetworkAvailable, mLooper, mNIHandler);
@@ -670,10 +668,13 @@
*/
private void onNetworkAvailable() {
mNtpTimeHelper.onNetworkAvailable();
- if (mDownloadPsdsDataPending == STATE_PENDING_NETWORK) {
- if (mSupportsPsds) {
- // Download only if supported, (prevents an unnecessary on-boot download)
- psdsDownloadRequest(/* psdsType= */ GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
+ // Download only if supported, (prevents an unnecessary on-boot download)
+ if (mSupportsPsds) {
+ synchronized (mLock) {
+ for (int psdsType : mPendingDownloadPsdsTypes) {
+ downloadPsdsData(psdsType);
+ }
+ mPendingDownloadPsdsTypes.clear();
}
}
}
@@ -799,17 +800,13 @@
Log.d(TAG, "handleDownloadPsdsData() called when PSDS not supported");
return;
}
- if (mDownloadPsdsDataPending == STATE_DOWNLOADING) {
- // already downloading data
- return;
- }
if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
// try again when network is up
- mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
+ synchronized (mLock) {
+ mPendingDownloadPsdsTypes.add(psdsType);
+ }
return;
}
- mDownloadPsdsDataPending = STATE_DOWNLOADING;
-
synchronized (mLock) {
// hold wake lock while task runs
mDownloadPsdsWakeLock.acquire(DOWNLOAD_PSDS_DATA_TIMEOUT_MS);
@@ -820,20 +817,24 @@
mGnssConfiguration.getProperties());
byte[] data = psdsDownloader.downloadPsdsData(psdsType);
if (data != null) {
- if (DEBUG) Log.d(TAG, "calling native_inject_psds_data");
- native_inject_psds_data(data, data.length, psdsType);
- mPsdsBackOff.reset();
- }
-
- sendMessage(DOWNLOAD_PSDS_DATA_FINISHED, 0, null);
-
- if (data == null) {
- // try again later
- // since this is delayed and not urgent we do not hold a wake lock here
- // the arg2 below should not be 1 otherwise the wakelock will be under-locked.
+ mHandler.post(() -> {
+ if (DEBUG) Log.d(TAG, "calling native_inject_psds_data");
+ native_inject_psds_data(data, data.length, psdsType);
+ synchronized (mLock) {
+ mPsdsBackOff.reset();
+ }
+ });
+ } else {
+ // Try download PSDS data again later according to backoff time.
+ // Since this is delayed and not urgent, we do not hold a wake lock here.
+ // The arg2 below should not be 1 otherwise the wakelock will be under-locked.
+ long backoffMillis;
+ synchronized (mLock) {
+ backoffMillis = mPsdsBackOff.nextBackoffMillis();
+ }
mHandler.sendMessageDelayed(
mHandler.obtainMessage(DOWNLOAD_PSDS_DATA, psdsType, 0, null),
- mPsdsBackOff.nextBackoffMillis());
+ backoffMillis);
}
// Release wake lock held by task, synchronize on mLock in case multiple
@@ -1128,7 +1129,7 @@
requestUtcTime();
} else if ("force_psds_injection".equals(command)) {
if (mSupportsPsds) {
- psdsDownloadRequest(/* psdsType= */
+ downloadPsdsData(/* psdsType= */
GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
}
} else {
@@ -1581,8 +1582,8 @@
reportLocation(locations);
}
- void psdsDownloadRequest(int psdsType) {
- if (DEBUG) Log.d(TAG, "psdsDownloadRequest. psdsType: " + psdsType);
+ void downloadPsdsData(int psdsType) {
+ if (DEBUG) Log.d(TAG, "downloadPsdsData. psdsType: " + psdsType);
sendMessage(DOWNLOAD_PSDS_DATA, psdsType, null);
}
@@ -1896,9 +1897,6 @@
case DOWNLOAD_PSDS_DATA:
handleDownloadPsdsData(msg.arg1);
break;
- case DOWNLOAD_PSDS_DATA_FINISHED:
- mDownloadPsdsDataPending = STATE_IDLE;
- break;
case INITIALIZE_HANDLER:
handleInitialize();
break;
@@ -2007,8 +2005,6 @@
return "REQUEST_LOCATION";
case DOWNLOAD_PSDS_DATA:
return "DOWNLOAD_PSDS_DATA";
- case DOWNLOAD_PSDS_DATA_FINISHED:
- return "DOWNLOAD_PSDS_DATA_FINISHED";
case INITIALIZE_HANDLER:
return "INITIALIZE_HANDLER";
case REPORT_LOCATION:
diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
index 8e81f29..2bf6af2 100644
--- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java
+++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
@@ -519,7 +519,7 @@
@Override
public void psdsDownloadRequest(int psdsType) {
- mGnssLocationProvider.psdsDownloadRequest(psdsType);
+ mGnssLocationProvider.downloadPsdsData(psdsType);
}
@Override
diff --git a/services/core/java/com/android/server/location/util/SystemSettingsHelper.java b/services/core/java/com/android/server/location/util/SystemSettingsHelper.java
index ff4ba91..39aeaba 100644
--- a/services/core/java/com/android/server/location/util/SystemSettingsHelper.java
+++ b/services/core/java/com/android/server/location/util/SystemSettingsHelper.java
@@ -29,6 +29,7 @@
import static com.android.server.location.LocationManagerService.TAG;
import android.app.ActivityManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
@@ -330,11 +331,13 @@
@Override
public float getCoarseLocationAccuracyM() {
long identity = Binder.clearCallingIdentity();
+ final ContentResolver cr = mContext.getContentResolver();
try {
- return Settings.Secure.getFloat(
- mContext.getContentResolver(),
+ return Settings.Secure.getFloatForUser(
+ cr,
LOCATION_COARSE_ACCURACY_M,
- DEFAULT_COARSE_LOCATION_ACCURACY_M);
+ DEFAULT_COARSE_LOCATION_ACCURACY_M,
+ cr.getUserId());
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 26c3132..dbc725e 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -837,7 +837,7 @@
if (getString("migrated", null, 0) == null) {
final ContentResolver cr = mContext.getContentResolver();
for (String validSetting : VALID_SETTINGS) {
- String value = Settings.Secure.getString(cr, validSetting);
+ String value = Settings.Secure.getStringForUser(cr, validSetting, cr.getUserId());
if (value != null) {
setString(validSetting, value, 0);
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 1e02f49..793cfcd 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -23,7 +23,6 @@
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.AudioManager;
-import android.media.AudioManagerInternal;
import android.media.AudioSystem;
import android.media.MediaMetadata;
import android.media.Rating;
@@ -53,8 +52,6 @@
import android.util.Log;
import android.view.KeyEvent;
-import com.android.server.LocalServices;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -144,7 +141,6 @@
// Volume handling fields
private AudioAttributes mAudioAttrs;
private AudioManager mAudioManager;
- private AudioManagerInternal mAudioManagerInternal;
private int mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
private int mMaxVolume = 0;
@@ -179,7 +175,6 @@
mContext = mService.getContext();
mHandler = new MessageHandler(handlerLooper);
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
mAudioAttrs = DEFAULT_ATTRIBUTES;
mPolicies = policies;
@@ -328,8 +323,9 @@
@Override
public void run() {
try {
- mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags,
- opPackageName, uid, pid);
+ mAudioManager.setStreamVolumeForUid(stream, volumeValue, flags,
+ opPackageName, uid, pid,
+ mContext.getApplicationInfo().targetSdkVersion);
} catch (IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue
+ ", flags=" + flags, e);
@@ -518,16 +514,19 @@
try {
if (useSuggested) {
if (AudioSystem.isStreamActive(stream, 0)) {
- mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream,
- direction, flags, opPackageName, uid, pid);
+ mAudioManager.adjustSuggestedStreamVolumeForUid(stream,
+ direction, flags, opPackageName, uid, pid,
+ mContext.getApplicationInfo().targetSdkVersion);
} else {
- mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
+ mAudioManager.adjustSuggestedStreamVolumeForUid(
AudioManager.USE_DEFAULT_STREAM_TYPE, direction,
- flags | previousFlagPlaySound, opPackageName, uid, pid);
+ flags | previousFlagPlaySound, opPackageName, uid, pid,
+ mContext.getApplicationInfo().targetSdkVersion);
}
} else {
- mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
- opPackageName, uid, pid);
+ mAudioManager.adjustStreamVolumeForUid(stream, direction, flags,
+ opPackageName, uid, pid,
+ mContext.getApplicationInfo().targetSdkVersion);
}
} catch (IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream="
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 9521611..d345029 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -42,7 +42,6 @@
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.media.AudioManager;
-import android.media.AudioManagerInternal;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioSystem;
import android.media.IRemoteVolumeController;
@@ -85,7 +84,6 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
-import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
import com.android.server.Watchdog;
@@ -136,7 +134,7 @@
new ArrayList<>();
private KeyguardManager mKeyguardManager;
- private AudioManagerInternal mAudioManagerInternal;
+ private AudioManager mAudioManager;
private ContentResolver mContentResolver;
private boolean mHasFeatureLeanback;
@@ -162,6 +160,7 @@
PowerManager pm = mContext.getSystemService(PowerManager.class);
mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
mNotificationManager = mContext.getSystemService(NotificationManager.class);
+ mAudioManager = mContext.getSystemService(AudioManager.class);
}
@Override
@@ -169,7 +168,6 @@
publishBinderService(Context.MEDIA_SESSION_SERVICE, mSessionManagerImpl);
Watchdog.getInstance().addMonitor(this);
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
- mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(mContext);
mAudioPlayerStateMonitor.registerListener(
(config, isRemoved) -> {
@@ -2057,8 +2055,9 @@
callingPid = pid;
}
try {
- mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(suggestedStream,
- direction, flags, callingOpPackageName, callingUid, callingPid);
+ mAudioManager.adjustSuggestedStreamVolumeForUid(suggestedStream,
+ direction, flags, callingOpPackageName, callingUid, callingPid,
+ getContext().getApplicationInfo().targetSdkVersion);
} catch (SecurityException | IllegalArgumentException e) {
Log.e(TAG, "Cannot adjust volume: direction=" + direction
+ ", suggestedStream=" + suggestedStream + ", flags=" + flags
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 12419a9..7401403 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1684,8 +1684,10 @@
final IntArray userIds = mUserProfiles.getCurrentProfileIds();
for (int i = 0; i < userIds.size(); i++) {
- mArchive.updateHistoryEnabled(userIds.get(i), Settings.Secure.getInt(resolver,
- Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0) == 1);
+ mArchive.updateHistoryEnabled(userIds.get(i),
+ Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0,
+ userIds.get(i)) == 1);
}
}
if (uri == null || NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI.equals(uri)) {
@@ -1956,6 +1958,13 @@
}
@Override
+ void onConsolidatedPolicyChanged() {
+ Binder.withCleanCallingIdentity(() -> {
+ mRankingHandler.requestSort();
+ });
+ }
+
+ @Override
void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
Binder.withCleanCallingIdentity(() -> {
Intent intent = new Intent(ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED);
@@ -6259,6 +6268,8 @@
for (NotificationRecord r : enqueued) {
if (r.mUpdateTimeMs > mWhen) {
// At least one enqueue was posted after the cancel, so we're invalid
+ Slog.i(TAG, "notification cancel ignored due to newer enqueued entry"
+ + "key=" + r.getSbn().getKey());
return;
}
}
@@ -7146,9 +7157,10 @@
}
protected void playInCallNotification() {
+ final ContentResolver cr = getContext().getContentResolver();
if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL
- && Settings.Secure.getInt(getContext().getContentResolver(),
- Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1) != 0) {
+ && Settings.Secure.getIntForUser(cr,
+ Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1, cr.getUserId()) != 0) {
new Thread() {
@Override
public void run() {
@@ -8460,7 +8472,10 @@
if (Notification.CATEGORY_CAR_EMERGENCY.equals(notification.category)
|| Notification.CATEGORY_CAR_WARNING.equals(notification.category)
|| Notification.CATEGORY_CAR_INFORMATION.equals(notification.category)) {
- checkCallerIsSystem();
+ getContext().enforceCallingPermission(
+ android.Manifest.permission.SEND_CATEGORY_CAR_NOTIFICATIONS,
+ String.format("Notification category %s restricted",
+ notification.category));
}
}
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index 8c03c6c..8121a43e9 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -26,6 +26,7 @@
import android.text.TextUtils;
import android.util.Pair;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
@@ -66,7 +67,7 @@
String actorNamespace = actorUri.getAuthority();
Map<String, String> namespace = namedActors.get(actorNamespace);
- if (namespace == null) {
+ if (ArrayUtils.isEmpty(namespace)) {
return Pair.create(null, ActorState.MISSING_NAMESPACE);
}
@@ -102,21 +103,32 @@
* See {@link OverlayActorEnforcer} class comment for actor requirements.
* @return true if the actor is allowed to act on the target overlayInfo
*/
- private ActorState isAllowedActor(String methodName, OverlayInfo overlayInfo,
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ public ActorState isAllowedActor(String methodName, OverlayInfo overlayInfo,
int callingUid, int userId) {
+ // Checked first to avoid package not found errors, which are ignored for calls from shell
switch (callingUid) {
case Process.ROOT_UID:
case Process.SYSTEM_UID:
return ActorState.ALLOWED;
}
+ final String targetPackageName = overlayInfo.targetPackageName;
+ final PackageInfo targetPkgInfo = mPackageManager.getPackageInfo(targetPackageName, userId);
+ if (targetPkgInfo == null) {
+ return ActorState.TARGET_NOT_FOUND;
+ }
+
+ if ((targetPkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+ return ActorState.ALLOWED;
+ }
+
String[] callingPackageNames = mPackageManager.getPackagesForUid(callingUid);
if (ArrayUtils.isEmpty(callingPackageNames)) {
return ActorState.NO_PACKAGES_FOR_UID;
}
// A target is always an allowed actor for itself
- String targetPackageName = overlayInfo.targetPackageName;
if (ArrayUtils.contains(callingPackageNames, targetPackageName)) {
return ActorState.ALLOWED;
}
@@ -149,7 +161,7 @@
targetOverlayable = mPackageManager.getOverlayableForTarget(targetPackageName,
targetOverlayableName, userId);
} catch (IOException e) {
- return ActorState.UNABLE_TO_GET_TARGET;
+ return ActorState.UNABLE_TO_GET_TARGET_OVERLAYABLE;
}
if (targetOverlayable == null) {
@@ -189,7 +201,7 @@
}
// Currently only pre-installed apps can be actors
- if (!appInfo.isSystemApp() && !appInfo.isUpdatedSystemApp()) {
+ if (!appInfo.isSystemApp()) {
return ActorState.ACTOR_NOT_PREINSTALLED;
}
@@ -203,22 +215,25 @@
/**
* For easier logging/debugging, a set of all possible failure/success states when running
* enforcement.
+ *
+ * The ordering of this enum should be maintained in the order that cases are checked in code,
+ * as this ordering is used inside OverlayActorEnforcerTests.
*/
public enum ActorState {
- ALLOWED,
- INVALID_ACTOR,
- MISSING_NAMESPACE,
- MISSING_PACKAGE,
- MISSING_APP_INFO,
- ACTOR_NOT_PREINSTALLED,
+ TARGET_NOT_FOUND,
NO_PACKAGES_FOR_UID,
- MISSING_ACTOR_NAME,
- ERROR_READING_OVERLAYABLE,
MISSING_TARGET_OVERLAYABLE_NAME,
+ MISSING_LEGACY_PERMISSION,
+ ERROR_READING_OVERLAYABLE,
+ UNABLE_TO_GET_TARGET_OVERLAYABLE,
MISSING_OVERLAYABLE,
INVALID_OVERLAYABLE_ACTOR_NAME,
NO_NAMED_ACTORS,
- UNABLE_TO_GET_TARGET,
- MISSING_LEGACY_PERMISSION
+ MISSING_NAMESPACE,
+ MISSING_ACTOR_NAME,
+ MISSING_APP_INFO,
+ ACTOR_NOT_PREINSTALLED,
+ INVALID_ACTOR,
+ ALLOWED
}
}
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 07527c2..5b5ec42 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -778,7 +778,7 @@
void registerApkInApex(AndroidPackage pkg) {
synchronized (mLock) {
for (ActiveApexInfo aai : mActiveApexInfosCache) {
- if (pkg.getBaseCodePath().startsWith(aai.apexDirectory.getAbsolutePath())) {
+ if (pkg.getBaseApkPath().startsWith(aai.apexDirectory.getAbsolutePath())) {
List<String> apks = mApksInApex.get(aai.apexModuleName);
if (apks == null) {
apks = Lists.newArrayList();
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index f168ac7..dac2e4f 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -303,7 +303,8 @@
private void updateEnabledState(@NonNull AndroidPackage pkg) {
// TODO(b/135203078): Do not use toAppInfo
- final boolean enabled = mInjector.getCompatibility().isChangeEnabledInternal(
+ // TODO(b/167551701): Make changeId non-logging
+ final boolean enabled = mInjector.getCompatibility().isChangeEnabledInternalNoLogging(
PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState());
if (enabled) {
mDisabledPackages.remove(pkg.getPackageName());
@@ -639,24 +640,74 @@
}
}
- private void updateEntireShouldFilterCacheAsync() {
- mBackgroundExecutor.execute(this::updateEntireShouldFilterCache);
- }
-
private void updateEntireShouldFilterCache() {
mStateProvider.runWithState((settings, users) -> {
SparseArray<SparseBooleanArray> cache =
- new SparseArray<>(users.length * settings.size());
- for (int i = settings.size() - 1; i >= 0; i--) {
- updateShouldFilterCacheForPackage(cache,
- null /*skipPackage*/, settings.valueAt(i), settings, users, i);
- }
+ updateEntireShouldFilterCacheInner(settings, users);
synchronized (mCacheLock) {
mShouldFilterCache = cache;
}
});
}
+ private SparseArray<SparseBooleanArray> updateEntireShouldFilterCacheInner(
+ ArrayMap<String, PackageSetting> settings, UserInfo[] users) {
+ SparseArray<SparseBooleanArray> cache =
+ new SparseArray<>(users.length * settings.size());
+ for (int i = settings.size() - 1; i >= 0; i--) {
+ updateShouldFilterCacheForPackage(cache,
+ null /*skipPackage*/, settings.valueAt(i), settings, users, i);
+ }
+ return cache;
+ }
+
+ private void updateEntireShouldFilterCacheAsync() {
+ mBackgroundExecutor.execute(() -> {
+ final ArrayMap<String, PackageSetting> settingsCopy = new ArrayMap<>();
+ final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>();
+ final UserInfo[][] usersRef = new UserInfo[1][];
+ mStateProvider.runWithState((settings, users) -> {
+ packagesCache.ensureCapacity(settings.size());
+ settingsCopy.putAll(settings);
+ usersRef[0] = users;
+ // store away the references to the immutable packages, since settings are retained
+ // during updates.
+ for (int i = 0, max = settings.size(); i < max; i++) {
+ final AndroidPackage pkg = settings.valueAt(i).pkg;
+ packagesCache.put(settings.keyAt(i), pkg);
+ }
+ });
+ SparseArray<SparseBooleanArray> cache =
+ updateEntireShouldFilterCacheInner(settingsCopy, usersRef[0]);
+ boolean[] changed = new boolean[1];
+ // We have a cache, let's make sure the world hasn't changed out from under us.
+ mStateProvider.runWithState((settings, users) -> {
+ if (settings.size() != settingsCopy.size()) {
+ changed[0] = true;
+ return;
+ }
+ for (int i = 0, max = settings.size(); i < max; i++) {
+ final AndroidPackage pkg = settings.valueAt(i).pkg;
+ if (!Objects.equals(pkg, packagesCache.get(settings.keyAt(i)))) {
+ changed[0] = true;
+ return;
+ }
+ }
+ });
+ if (changed[0]) {
+ // Something has changed, just update the cache inline with the lock held
+ updateEntireShouldFilterCache();
+ if (DEBUG_LOGGING) {
+ Slog.i(TAG, "Rebuilding cache with lock due to package change.");
+ }
+ } else {
+ synchronized (mCacheLock) {
+ mShouldFilterCache = cache;
+ }
+ }
+ });
+ }
+
public void onUsersChanged() {
synchronized (mCacheLock) {
if (mShouldFilterCache != null) {
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index d25ddad..4be509b 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -623,7 +623,6 @@
AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
if (pkg != null) {
- // TODO(b/135203078): Print AppInfo?
pw.print(" applicationInfo="); pw.println(pkg.toAppInfoWithoutState());
}
}
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index eddab76..7db2319 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -384,17 +384,17 @@
if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
continue;
}
- if (pkg.getCodePath() == null) {
+ if (pkg.getPath() == null) {
Slog.w(TAG, "Package " + pkg + " can be optimized but has null codePath");
continue;
}
// If the path is in /system, /vendor, /product or /system_ext, ignore. It will
// have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
- if (pkg.getCodePath().startsWith("/system")
- || pkg.getCodePath().startsWith("/vendor")
- || pkg.getCodePath().startsWith("/product")
- || pkg.getCodePath().startsWith("/system_ext")) {
+ if (pkg.getPath().startsWith("/system")
+ || pkg.getPath().startsWith("/vendor")
+ || pkg.getPath().startsWith("/product")
+ || pkg.getPath().startsWith("/system_ext")) {
continue;
}
@@ -408,7 +408,7 @@
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (String path : paths) {
String oatDir = PackageDexOptimizer.getOatDir(
- new File(pkg.getCodePath())).getAbsolutePath();
+ new File(pkg.getPath())).getAbsolutePath();
// TODO: Check first whether there is an artifact, to save the roundtrip time.
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 8af7e1f..da4ea16 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -136,7 +136,7 @@
// Trying to derive the paths, thus need the raw ABI info from the parsed package, and the
// current state in PackageSetting is irrelevant.
return deriveNativeLibraryPaths(new Abis(pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi()),
- appLib32InstallDir, pkg.getCodePath(), pkg.getBaseCodePath(), pkg.isSystem(),
+ appLib32InstallDir, pkg.getPath(), pkg.getBaseApkPath(), pkg.isSystem(),
isUpdatedSystemApp);
}
@@ -205,11 +205,11 @@
@Override
public Abis getBundledAppAbis(AndroidPackage pkg) {
- final String apkName = deriveCodePathName(pkg.getCodePath());
+ final String apkName = deriveCodePathName(pkg.getPath());
// If "/system/lib64/apkname" exists, assume that is the per-package
// native library directory to use; otherwise use "/system/lib/apkname".
- final String apkRoot = calculateBundledApkRoot(pkg.getBaseCodePath());
+ final String apkRoot = calculateBundledApkRoot(pkg.getBaseApkPath());
final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName);
return abis;
}
@@ -223,7 +223,7 @@
* @param apkName the name of the installed package.
*/
private Abis getBundledAppAbi(AndroidPackage pkg, String apkRoot, String apkName) {
- final File codeFile = new File(pkg.getCodePath());
+ final File codeFile = new File(pkg.getPath());
final boolean has64BitLibs;
final boolean has32BitLibs;
@@ -304,15 +304,15 @@
String pkgRawSecondaryCpuAbi = AndroidPackageUtils.getRawSecondaryCpuAbi(pkg);
final NativeLibraryPaths initialLibraryPaths = deriveNativeLibraryPaths(
new Abis(pkgRawPrimaryCpuAbi, pkgRawSecondaryCpuAbi),
- PackageManagerService.sAppLib32InstallDir, pkg.getCodePath(),
- pkg.getBaseCodePath(), pkg.isSystem(),
+ PackageManagerService.sAppLib32InstallDir, pkg.getPath(),
+ pkg.getBaseApkPath(), pkg.isSystem(),
isUpdatedSystemApp);
final boolean extractLibs = shouldExtractLibs(pkg, isUpdatedSystemApp);
final String nativeLibraryRootStr = initialLibraryPaths.nativeLibraryRootDir;
final boolean useIsaSpecificSubdirs = initialLibraryPaths.nativeLibraryRootRequiresIsa;
- final boolean onIncremental = isIncrementalPath(pkg.getCodePath());
+ final boolean onIncremental = isIncrementalPath(pkg.getPath());
String primaryCpuAbi = null;
String secondaryCpuAbi = null;
@@ -453,7 +453,7 @@
final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi);
return new Pair<>(abis,
deriveNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir,
- pkg.getCodePath(), pkg.getBaseCodePath(), pkg.isSystem(),
+ pkg.getPath(), pkg.getBaseApkPath(), pkg.isSystem(),
isUpdatedSystemApp));
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 0d8ba3e..42e6d8f 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -199,7 +199,7 @@
throw new IllegalStateException("Inconsistent information "
+ "between PackageParser.Package and its ApplicationInfo. "
+ "pkg.getAllCodePaths=" + paths
- + " pkg.getBaseCodePath=" + pkg.getBaseCodePath()
+ + " pkg.getBaseCodePath=" + pkg.getBaseApkPath()
+ " pkg.getSplitCodePaths="
+ (splitCodePaths == null ? "null" : Arrays.toString(splitCodePaths)));
}
@@ -772,7 +772,7 @@
if (!AndroidPackageUtils.canHaveOatDir(pkg, isUpdatedSystemApp)) {
return null;
}
- File codePath = new File(pkg.getCodePath());
+ File codePath = new File(pkg.getPath());
if (!codePath.isDirectory()) {
return null;
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 162bfee..155af82 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -656,7 +656,7 @@
throw new IllegalArgumentException("Invalid install mode: " + params.mode);
}
- // If caller requested explicit location, sanity check it, otherwise
+ // If caller requested explicit location, validity check it, otherwise
// resolve the best internal or adopted location.
if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
if (!PackageHelper.fitsOnInternal(mContext, params)) {
@@ -688,7 +688,7 @@
final int sessionId;
final PackageInstallerSession session;
synchronized (mSessions) {
- // Sanity check that installer isn't going crazy
+ // Check that the installer does not have too many active sessions.
final int activeCount = getSessionCount(mSessions, callingUid);
if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
== PackageManager.PERMISSION_GRANTED) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 51164ba..17cd8f5 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -249,6 +249,9 @@
private final PackageManagerService mPm;
private final Handler mHandler;
private final PackageSessionProvider mSessionProvider;
+ /**
+ * Note all calls must be done outside {@link #mLock} to prevent lock inversion.
+ */
private final StagingManager mStagingManager;
final int sessionId;
@@ -389,6 +392,20 @@
private String mStagedSessionErrorMessage;
/**
+ * The callback to run when pre-reboot verification has ended. Used by {@link #abandonStaged()}
+ * to delay session clean-up until it is safe to do so.
+ */
+ @GuardedBy("mLock")
+ @Nullable
+ private Runnable mPendingAbandonCallback;
+ /**
+ * {@code true} if pre-reboot verification is ongoing which means it is not safe for
+ * {@link #abandon()} to clean up staging directories.
+ */
+ @GuardedBy("mLock")
+ private boolean mInPreRebootVerification;
+
+ /**
* Path to the validated base APK for this session, which may point at an
* APK inside the session (when the session defines the base), or it may
* point at the existing base APK (when adding splits to an existing app).
@@ -978,7 +995,7 @@
private ParcelFileDescriptor doWriteInternal(String name, long offsetBytes, long lengthBytes,
ParcelFileDescriptor incomingFd) throws IOException {
- // Quick sanity check of state, and allocate a pipe for ourselves. We
+ // Quick validity check of state, and allocate a pipe for ourselves. We
// then do heavy disk allocation outside the lock, but this open pipe
// will block any attempted install transitions.
final RevocableFileDescriptor fd;
@@ -1454,26 +1471,54 @@
// TODO(patb): since the work done here for a parent session in a multi-package install is
// mostly superficial, consider splitting this method for the parent and
// single / child sessions.
- synchronized (mLock) {
- if (mCommitted) {
- return true;
+ try {
+ synchronized (mLock) {
+ if (mCommitted) {
+ return true;
+ }
+ // Read transfers from the original owner stay open, but as the session's data
+ // cannot be modified anymore, there is no leak of information. For staged sessions,
+ // further validation is performed by the staging manager.
+ if (!params.isMultiPackage) {
+ if (!prepareDataLoaderLocked()) {
+ return false;
+ }
+
+ if (isApexInstallation()) {
+ validateApexInstallLocked();
+ } else {
+ validateApkInstallLocked();
+ }
+ }
}
- if (!streamAndValidateLocked()) {
- return false;
+ if (params.isStaged) {
+ mStagingManager.checkNonOverlappingWithStagedSessions(this);
}
- // Client staging is fully done at this point
- mClientProgress = 1f;
- computeProgressLocked(true);
+ synchronized (mLock) {
+ if (mDestroyed) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session destroyed");
+ }
+ // Client staging is fully done at this point
+ mClientProgress = 1f;
+ computeProgressLocked(true);
- // This ongoing commit should keep session active, even though client
- // will probably close their end.
- mActiveCount.incrementAndGet();
+ // This ongoing commit should keep session active, even though client
+ // will probably close their end.
+ mActiveCount.incrementAndGet();
- mCommitted = true;
+ mCommitted = true;
+ }
+ return true;
+ } catch (PackageManagerException e) {
+ throw onSessionValidationFailure(e);
+ } catch (Throwable e) {
+ // Convert all exceptions into package manager exceptions as only those are handled
+ // in the code above.
+ throw onSessionValidationFailure(new PackageManagerException(e));
}
- return true;
}
@GuardedBy("mLock")
@@ -1511,44 +1556,6 @@
}
}
- /**
- * Prepare DataLoader and stream content for DataLoader sessions.
- * Validate the contents of all session.
- *
- * @return false if the data loader could not be prepared.
- * @throws PackageManagerException when an unrecoverable exception is encountered
- */
- @GuardedBy("mLock")
- private boolean streamAndValidateLocked() throws PackageManagerException {
- try {
- // Read transfers from the original owner stay open, but as the session's data cannot
- // be modified anymore, there is no leak of information. For staged sessions, further
- // validation is performed by the staging manager.
- if (!params.isMultiPackage) {
- if (!prepareDataLoaderLocked()) {
- return false;
- }
-
- if (isApexInstallation()) {
- validateApexInstallLocked();
- } else {
- validateApkInstallLocked();
- }
- }
-
- if (params.isStaged) {
- mStagingManager.checkNonOverlappingWithStagedSessions(this);
- }
- return true;
- } catch (PackageManagerException e) {
- throw onSessionValidationFailure(e);
- } catch (Throwable e) {
- // Convert all exceptions into package manager exceptions as only those are handled
- // in the code above.
- throw onSessionValidationFailure(new PackageManagerException(e));
- }
- }
-
private PackageManagerException onSessionValidationFailure(PackageManagerException e) {
onSessionValidationFailure(e.error, ExceptionUtils.getCompleteMessage(e));
return e;
@@ -1571,7 +1578,7 @@
SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, msgWithErrorCode);
// TODO(b/136257624): Remove this once all verification logic has been transferred out
// of StagingManager.
- mStagingManager.notifyVerificationComplete(sessionId);
+ mStagingManager.notifyVerificationComplete(this);
} else {
// Dispatch message to remove session from PackageInstallerService.
dispatchSessionFinished(error, msg, null);
@@ -1837,21 +1844,6 @@
throws PackageManagerException {
assertNotLocked("makeSessionActive");
- synchronized (mLock) {
- if (mRelinquished) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Session relinquished");
- }
- if (mDestroyed) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Session destroyed");
- }
- if (!mSealed) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Session not sealed");
- }
- }
-
// TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc
if (!params.isMultiPackage && needToAskForPermissions()) {
// User needs to confirm installation;
@@ -1881,6 +1873,19 @@
@GuardedBy("mLock")
private PackageManagerService.VerificationParams makeVerificationParamsLocked()
throws PackageManagerException {
+ if (mRelinquished) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session relinquished");
+ }
+ if (mDestroyed) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session destroyed");
+ }
+ if (!mSealed) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session not sealed");
+ }
+
// TODO(b/136257624): Some logic in this if block probably belongs in
// makeInstallParams().
if (!params.isMultiPackage && !isApexInstallation()) {
@@ -2078,7 +2083,7 @@
if (ps == null) {
return 0;
}
- final File apkDirOrPath = ps.getCodePath();
+ final File apkDirOrPath = ps.getPath();
if (apkDirOrPath == null) {
return 0;
}
@@ -2787,14 +2792,9 @@
}
private void abandonStaged() {
+ final Runnable r;
synchronized (mLock) {
- if (mDestroyed) {
- // If a user abandons staged session in an unsafe state, then system will try to
- // abandon the destroyed staged session when it is safe on behalf of the user.
- assertCallerIsOwnerOrRootOrSystemLocked();
- } else {
- assertCallerIsOwnerOrRootLocked();
- }
+ assertCallerIsOwnerOrRootLocked();
if (isStagedAndInTerminalState()) {
// We keep the session in the database if it's in a finalized state. It will be
// removed by PackageInstallerService when the last update time is old enough.
@@ -2803,17 +2803,25 @@
return;
}
mDestroyed = true;
- if (mCommitted) {
- if (!mStagingManager.abortCommittedSessionLocked(this)) {
- // Do not clean up the staged session from system. It is not safe yet.
- mCallback.onStagedSessionChanged(this);
- return;
+ boolean isCommitted = mCommitted;
+ List<PackageInstallerSession> childSessions = getChildSessionsLocked();
+ r = () -> {
+ assertNotLocked("abandonStaged");
+ if (isCommitted) {
+ mStagingManager.abortCommittedSession(this);
}
+ cleanStageDir(childSessions);
+ destroyInternal();
+ dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
+ };
+ if (mInPreRebootVerification) {
+ // Pre-reboot verification is ongoing. It is not safe to clean up the session yet.
+ mPendingAbandonCallback = r;
+ mCallback.onStagedSessionChanged(this);
+ return;
}
- cleanStageDir(getChildSessionsLocked());
- destroyInternal();
}
- dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
+ r.run();
}
@Override
@@ -2830,6 +2838,50 @@
}
}
+ /**
+ * Notified by the staging manager that pre-reboot verification is about to start. The return
+ * value should be checked to decide whether it is OK to start pre-reboot verification. In
+ * the case of a destroyed session, {@code false} is returned and there is no need to start
+ * pre-reboot verification.
+ */
+ boolean notifyStagedStartPreRebootVerification() {
+ synchronized (mLock) {
+ if (mInPreRebootVerification) {
+ throw new IllegalStateException("Pre-reboot verification has started");
+ }
+ if (mDestroyed) {
+ return false;
+ }
+ mInPreRebootVerification = true;
+ return true;
+ }
+ }
+
+ private void dispatchPendingAbandonCallback() {
+ final Runnable callback;
+ synchronized (mLock) {
+ callback = mPendingAbandonCallback;
+ mPendingAbandonCallback = null;
+ }
+ if (callback != null) {
+ callback.run();
+ }
+ }
+
+ /**
+ * Notified by the staging manager that pre-reboot verification has ended. Now it is safe to
+ * clean up the session if {@link #abandon()} has been called previously.
+ */
+ void notifyStagedEndPreRebootVerification() {
+ synchronized (mLock) {
+ if (!mInPreRebootVerification) {
+ throw new IllegalStateException("Pre-reboot verification not started");
+ }
+ mInPreRebootVerification = false;
+ }
+ dispatchPendingAbandonCallback();
+ }
+
@Override
public boolean isMultiPackage() {
return params.isMultiPackage;
@@ -3744,7 +3796,7 @@
out.endTag(null, TAG_SESSION);
}
- // Sanity check to be performed when the session is restored from an external file. Only one
+ // Validity check to be performed when the session is restored from an external file. Only one
// of the session states should be true, or none of them.
private static boolean isStagedSessionStateValid(boolean isReady, boolean isApplied,
boolean isFailed) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c6269eb..fcf5d96 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2220,7 +2220,7 @@
// Send installed broadcasts if the package is not a static shared lib.
if (res.pkg.getStaticSharedLibName() == null) {
mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(
- res.pkg.getBaseCodePath());
+ res.pkg.getBaseApkPath());
// Send added for users that see the package for the first time
// sendPackageAddedForNewUsers also deals with system apps
@@ -3101,7 +3101,7 @@
final int packageSettingCount = mSettings.mPackages.size();
for (int i = packageSettingCount - 1; i >= 0; i--) {
PackageSetting ps = mSettings.mPackages.valueAt(i);
- if (!isExternal(ps) && (ps.getCodePath() == null || !ps.getCodePath().exists())
+ if (!isExternal(ps) && (ps.getPath() == null || !ps.getPath().exists())
&& mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
mSettings.mPackages.removeAt(i);
mSettings.enableSystemPackageLPw(ps.name);
@@ -3266,11 +3266,11 @@
logCriticalInfo(Log.WARN,
"Expecting better updated system app for " + ps.name
+ "; removing system app. Last known"
- + " codePath=" + ps.getCodePathString()
+ + " codePath=" + ps.getPathString()
+ ", versionCode=" + ps.versionCode
+ "; scanned versionCode=" + scannedPkg.getLongVersionCode());
removePackageLI(scannedPkg, true);
- mExpectingBetter.put(ps.name, ps.getCodePath());
+ mExpectingBetter.put(ps.name, ps.getPath());
}
continue;
@@ -3293,14 +3293,14 @@
// code path, but, changes the package name.
final PackageSetting disabledPs =
mSettings.getDisabledSystemPkgLPr(ps.name);
- if (disabledPs.getCodePath() == null || !disabledPs.getCodePath().exists()
+ if (disabledPs.getPath() == null || !disabledPs.getPath().exists()
|| disabledPs.pkg == null) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
} else {
// We're expecting that the system app should remain disabled, but add
// it to expecting better to recover in case the data version cannot
// be scanned.
- mExpectingBetter.put(disabledPs.name, disabledPs.getCodePath());
+ mExpectingBetter.put(disabledPs.name, disabledPs.getPath());
}
}
}
@@ -3344,6 +3344,7 @@
// Remove disable package settings for updated system apps that were
// removed via an OTA. If the update is no longer present, remove the
// app completely. Otherwise, revoke their system privileges.
+ final int[] userIds = mUserManager.getUserIds();
for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
final AndroidPackage pkg = mPackages.get(packageName);
@@ -3372,7 +3373,7 @@
// special privileges
removePackageLI(pkg, true);
try {
- final File codePath = new File(pkg.getCodePath());
+ final File codePath = new File(pkg.getPath());
scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
@@ -3386,7 +3387,7 @@
// partition], completely remove the package data.
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null && mPackages.get(packageName) == null) {
- removePackageDataLIF(ps, null, null, 0, false);
+ removePackageDataLIF(ps, userIds, null, 0, false);
}
logCriticalInfo(Log.WARN, msg);
@@ -3853,8 +3854,9 @@
// If we don't, installing the system package fails during scan
enableSystemPackageLPw(stubPkg);
}
- installPackageFromSystemLIF(stubPkg.getCodePath(), null /*allUserHandles*/,
- null /*origUserHandles*/, true /*writeSettings*/);
+ installPackageFromSystemLIF(stubPkg.getPath(),
+ mUserManager.getUserIds() /*allUserHandles*/, null /*origUserHandles*/,
+ true /*writeSettings*/);
} catch (PackageManagerException pme) {
// Serious WTF; we have to be able to install the stub
Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
@@ -3876,7 +3878,7 @@
clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
| FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
mDexManager.notifyPackageUpdated(pkg.getPackageName(),
- pkg.getBaseCodePath(), pkg.getSplitCodePaths());
+ pkg.getBaseApkPath(), pkg.getSplitCodePaths());
}
return true;
}
@@ -3888,10 +3890,10 @@
Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
}
// uncompress the binary to its eventual destination on /data
- final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath());
+ final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath());
if (scanFile == null) {
throw new PackageManagerException(
- "Unable to decompress stub at " + stubPkg.getCodePath());
+ "Unable to decompress stub at " + stubPkg.getPath());
}
synchronized (mLock) {
mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
@@ -9259,11 +9261,11 @@
// When upgrading from pre-N MR1, verify the package time stamp using the package
// directory and not the APK file.
final long lastModifiedTime = mIsPreNMR1Upgrade
- ? new File(parsedPackage.getCodePath()).lastModified()
+ ? new File(parsedPackage.getPath()).lastModified()
: getLastModifiedTime(parsedPackage);
final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
if (ps != null && !forceCollect
- && ps.getCodePathString().equals(parsedPackage.getCodePath())
+ && ps.getPathString().equals(parsedPackage.getPath())
&& ps.timeStamp == lastModifiedTime
&& !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
&& !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
@@ -9281,8 +9283,8 @@
Slog.w(TAG, "PackageSetting for " + ps.name
+ " is missing signatures. Collecting certs again to recover them.");
} else {
- Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" +
- (forceCollect ? " (forced)" : ""));
+ Slog.i(TAG, parsedPackage.getPath() + " changed; collecting certs"
+ + (forceCollect ? " (forced)" : ""));
}
try {
@@ -9366,7 +9368,7 @@
* Returns if forced apk verification can be skipped for the whole package, including splits.
*/
private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
- if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) {
+ if (!canSkipForcedApkVerification(pkg.getBaseApkPath())) {
return false;
}
// TODO: Allow base and splits to be verified individually.
@@ -9497,7 +9499,7 @@
}
final boolean newPkgChangedPaths = pkgAlreadyExists
- && !pkgSetting.getCodePathString().equals(parsedPackage.getCodePath());
+ && !pkgSetting.getPathString().equals(parsedPackage.getPath());
final boolean newPkgVersionGreater =
pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
@@ -9516,11 +9518,11 @@
"System package updated;"
+ " name: " + pkgSetting.name
+ "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
- + "; " + pkgSetting.getCodePathString()
- + " --> " + parsedPackage.getCodePath());
+ + "; " + pkgSetting.getPathString()
+ + " --> " + parsedPackage.getPath());
final InstallArgs args = createInstallArgsForExisting(
- pkgSetting.getCodePathString(), getAppDexInstructionSets(
+ pkgSetting.getPathString(), getAppDexInstructionSets(
pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
args.cleanUpResourcesLI();
synchronized (mLock) {
@@ -9533,7 +9535,7 @@
// equal to the version on the /data partition. Throw an exception and use
// the application already installed on the /data partition.
throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
- + " at " + parsedPackage.getCodePath() + " ignored: updated version "
+ + " at " + parsedPackage.getPath() + " ignored: updated version "
+ pkgSetting.versionCode + " better than this "
+ parsedPackage.getLongVersionCode());
}
@@ -9582,8 +9584,8 @@
try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
parsedPackage.getPackageName(),
"scanPackageInternalLI")) {
- deletePackageLIF(parsedPackage.getPackageName(), null, true, null, 0, null,
- false, null);
+ deletePackageLIF(parsedPackage.getPackageName(), null, true,
+ mUserManager.getUserIds(), 0, null, false, null);
}
pkgSetting = null;
} else if (newPkgVersionGreater) {
@@ -9595,10 +9597,10 @@
+ " name: " + pkgSetting.name
+ "; " + pkgSetting.versionCode + " --> "
+ parsedPackage.getLongVersionCode()
- + "; " + pkgSetting.getCodePathString() + " --> "
- + parsedPackage.getCodePath());
+ + "; " + pkgSetting.getPathString() + " --> "
+ + parsedPackage.getPath());
InstallArgs args = createInstallArgsForExisting(
- pkgSetting.getCodePathString(), getAppDexInstructionSets(
+ pkgSetting.getPathString(), getAppDexInstructionSets(
pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
synchronized (mInstallLock) {
args.cleanUpResourcesLI();
@@ -9611,10 +9613,10 @@
logCriticalInfo(Log.INFO,
"System package disabled;"
+ " name: " + pkgSetting.name
- + "; old: " + pkgSetting.getCodePathString() + " @ "
+ + "; old: " + pkgSetting.getPathString() + " @ "
+ pkgSetting.versionCode
- + "; new: " + parsedPackage.getCodePath() + " @ "
- + parsedPackage.getCodePath());
+ + "; new: " + parsedPackage.getPath() + " @ "
+ + parsedPackage.getPath());
}
}
@@ -9795,7 +9797,7 @@
* Return the prebuilt profile path given a package base code path.
*/
private static String getPrebuildProfilePath(AndroidPackage pkg) {
- return pkg.getBaseCodePath() + ".prof";
+ return pkg.getBaseApkPath() + ".prof";
}
/**
@@ -11448,7 +11450,7 @@
if (changedAbiCodePath == null) {
changedAbiCodePath = new ArrayList<>();
}
- changedAbiCodePath.add(ps.getCodePathString());
+ changedAbiCodePath.add(ps.getPathString());
}
}
}
@@ -11543,7 +11545,7 @@
}
// Initialize package source and resource directories
- final File destCodeFile = new File(parsedPackage.getCodePath());
+ final File destCodeFile = new File(parsedPackage.getPath());
// We keep references to the derived CPU Abis from settings in oder to reuse
// them in the case where we're not upgrading or booting for the first time.
@@ -11881,9 +11883,9 @@
private static void assertCodePolicy(AndroidPackage pkg)
throws PackageManagerException {
final boolean shouldHaveCode = pkg.isHasCode();
- if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) {
+ if (shouldHaveCode && !apkHasCode(pkg.getBaseApkPath())) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
- "Package " + pkg.getBaseCodePath() + " code is missing");
+ "Package " + pkg.getBaseApkPath() + " code is missing");
}
if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
@@ -11915,7 +11917,7 @@
if (parsedPackage.isDirectBootAware()) {
parsedPackage.setAllComponentsDirectBootAware(true);
}
- if (compressedFileExists(parsedPackage.getCodePath())) {
+ if (compressedFileExists(parsedPackage.getPath())) {
parsedPackage.setStub(true);
}
} else {
@@ -12006,7 +12008,7 @@
assertCodePolicy(pkg);
}
- if (pkg.getCodePath() == null) {
+ if (pkg.getPath() == null) {
// Bail out. The resource and code paths haven't been set.
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Code and resource paths haven't been set correctly");
@@ -12033,7 +12035,7 @@
if (mAndroidApplication != null) {
Slog.w(TAG, "*************************************************");
Slog.w(TAG, "Core android package being redefined. Skipping.");
- Slog.w(TAG, " codePath=" + pkg.getCodePath());
+ Slog.w(TAG, " codePath=" + pkg.getPath());
Slog.w(TAG, "*************************************************");
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
"Core android package being redefined. Skipping.");
@@ -12189,14 +12191,14 @@
PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
if (known != null) {
if (DEBUG_PACKAGE_SCANNING) {
- Log.d(TAG, "Examining " + pkg.getCodePath()
- + " and requiring known path " + known.getCodePathString());
+ Log.d(TAG, "Examining " + pkg.getPath()
+ + " and requiring known path " + known.getPathString());
}
- if (!pkg.getCodePath().equals(known.getCodePathString())) {
+ if (!pkg.getPath().equals(known.getPathString())) {
throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
"Application package " + pkg.getPackageName()
- + " found at " + pkg.getCodePath()
- + " but expected at " + known.getCodePathString()
+ + " found at " + pkg.getPath()
+ + " but expected at " + known.getPathString()
+ "; ignoring.");
}
} else {
@@ -14530,13 +14532,11 @@
Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
}
- // A restore should be performed at this point if (a) the install
- // succeeded, (b) the operation is not an update, and (c) the new
- // package has not opted out of backup participation.
+ // A restore should be requested at this point if (a) the install
+ // succeeded, (b) the operation is not an update.
final boolean update = res.removedInfo != null
&& res.removedInfo.removedPackage != null;
- boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup();
- boolean doRestore = !update && allowBackup;
+ boolean doRestore = !update && res.pkg != null;
// Set up the post-install work request bookkeeping. This will be used
// and cleaned up by the post-install event handling regardless of whether
@@ -15785,7 +15785,7 @@
abstract boolean doRename(int status, ParsedPackage parsedPackage);
abstract int doPostInstall(int status, int uid);
- /** @see PackageSettingBase#getCodePath() */
+ /** @see PackageSettingBase#getPath() */
abstract String getCodePath();
// Need installer lock especially for dex file removal.
@@ -15966,7 +15966,7 @@
return false;
}
parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
- afterCodeFile, parsedPackage.getBaseCodePath()));
+ afterCodeFile, parsedPackage.getBaseApkPath()));
parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
afterCodeFile, parsedPackage.getSplitCodePaths()));
@@ -16233,7 +16233,7 @@
InstallSource installSource = installArgs.installSource;
final String installerPackageName = installSource.installerPackageName;
- if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath());
+ if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath());
synchronized (mLock) {
// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
mPermissionManager.updatePermissions(pkgName, pkg);
@@ -16388,9 +16388,11 @@
*/
private static class CommitRequest {
final Map<String, ReconciledPackage> reconciledPackages;
+ @NonNull
final int[] mAllUsers;
- private CommitRequest(Map<String, ReconciledPackage> reconciledPackages, int[] allUsers) {
+ private CommitRequest(Map<String, ReconciledPackage> reconciledPackages,
+ @NonNull int[] allUsers) {
this.reconciledPackages = reconciledPackages;
this.mAllUsers = allUsers;
}
@@ -16870,7 +16872,7 @@
// which means we are replacing another update that is already
// installed. We need to make sure to delete the older one's .apk.
res.removedInfo.args = createInstallArgsForExisting(
- oldPackage.getCodePath(),
+ oldPackage.getPath(),
getAppDexInstructionSets(
AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
deletedPkgSetting),
@@ -16913,7 +16915,7 @@
if (ps1.mOldCodePaths == null) {
ps1.mOldCodePaths = new ArraySet<>();
}
- Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath());
+ Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseApkPath());
if (oldPackage.getSplitCodePaths() != null) {
Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
}
@@ -17078,7 +17080,7 @@
// For incremental installs, we bypass the verifier prior to install. Now
// that we know the package is valid, send a notice to the verifier with
// the root hash of the base.apk.
- final String baseCodePath = request.installResult.pkg.getBaseCodePath();
+ final String baseCodePath = request.installResult.pkg.getBaseApkPath();
final String[] splitCodePaths = request.installResult.pkg.getSplitCodePaths();
final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
final int verificationId = mPendingVerificationToken++;
@@ -17123,9 +17125,9 @@
final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
final String packageName = pkg.getPackageName();
final boolean onIncremental = mIncrementalManager != null
- && isIncrementalPath(pkg.getCodePath());
+ && isIncrementalPath(pkg.getPath());
if (onIncremental) {
- IncrementalStorage storage = mIncrementalManager.openStorage(pkg.getCodePath());
+ IncrementalStorage storage = mIncrementalManager.openStorage(pkg.getPath());
if (storage == null) {
throw new IllegalArgumentException(
"Install: null storage for incremental package " + packageName);
@@ -17139,7 +17141,7 @@
}
if (reconciledPkg.prepareResult.replace) {
mDexManager.notifyPackageUpdated(pkg.getPackageName(),
- pkg.getBaseCodePath(), pkg.getSplitCodePaths());
+ pkg.getBaseApkPath(), pkg.getSplitCodePaths());
}
// Prepare the application profiles for the new code paths.
@@ -17735,12 +17737,10 @@
if (parsedPackage.isStaticSharedLibrary()) {
// Static libs have a synthetic package name containing the version
// and cannot be updated as an update would get a new package name,
- // unless this is the exact same version code which is useful for
- // development.
+ // unless this is installed from adb which is useful for development.
AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
if (existingPkg != null
- && existingPkg.getLongVersionCode()
- != parsedPackage.getLongVersionCode()) {
+ && (installFlags & PackageManager.INSTALL_FROM_ADB) == 0) {
throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
"Packages declaring "
+ "static-shared libs cannot be updated");
@@ -17759,7 +17759,6 @@
oldPackage = mPackages.get(pkgName11);
existingPackage = oldPackage;
if (DEBUG_INSTALL) {
- // TODO(b/135203078): PackageImpl.toString()
Slog.d(TAG,
"replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
}
@@ -17793,7 +17792,7 @@
final byte[] digestBytes;
try {
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
- updateDigest(digest, new File(parsedPackage.getBaseCodePath()));
+ updateDigest(digest, new File(parsedPackage.getBaseApkPath()));
if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
for (String path : parsedPackage.getSplitCodePaths()) {
updateDigest(digest, new File(path));
@@ -17973,7 +17972,7 @@
synchronized (mLock) {
final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
if (ps != null && ps.isPrivileged()) {
- fsverityCandidates.put(pkg.getBaseCodePath(), null);
+ fsverityCandidates.put(pkg.getBaseApkPath(), null);
if (pkg.getSplitCodePaths() != null) {
for (String splitPath : pkg.getSplitCodePaths()) {
fsverityCandidates.put(splitPath, null);
@@ -17984,11 +17983,11 @@
} else {
// NB: These files will become only accessible if the signing key is loaded in kernel's
// .fs-verity keyring.
- fsverityCandidates.put(pkg.getBaseCodePath(),
- VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath()));
+ fsverityCandidates.put(pkg.getBaseApkPath(),
+ VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath()));
final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
- pkg.getBaseCodePath());
+ pkg.getBaseApkPath());
if (new File(dmPath).exists()) {
fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
}
@@ -18903,7 +18902,7 @@
* make sure this flag is set for partially installed apps. If not its meaningless to
* delete a partially installed application.
*/
- private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
+ private void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
String packageName = deletedPs.name;
if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
@@ -18991,7 +18990,7 @@
}
// make sure to preserve per-user disabled state if this removal was just
// a downgrade of a system app to the factory package
- if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
+ if (outInfo != null && outInfo.origUsers != null) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across downgrade");
}
@@ -19044,11 +19043,10 @@
* Tries to delete system package.
*/
private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
- int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
+ @NonNull int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
boolean writeSettings)
throws SystemDeleteException {
- final boolean applyUserRestrictions =
- (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
+ final boolean applyUserRestrictions = outInfo != null && (outInfo.origUsers != null);
final AndroidPackage deletedPkg = deletedPs.pkg;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
@@ -19100,7 +19098,7 @@
// Install the system package
if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
try {
- installPackageFromSystemLIF(disabledPs.getCodePathString(), allUserHandles,
+ installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
outInfo == null ? null : outInfo.origUsers, writeSettings);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
@@ -19132,7 +19130,7 @@
* Installs a package that's already on the system partition.
*/
private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
- @Nullable int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)
+ @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)
throws PackageManagerException {
final File codePath = new File(codePathString);
@ParseFlags int parseFlags =
@@ -19174,8 +19172,7 @@
// and granting install permissions.
mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
- final boolean applyUserRestrictions
- = (allUserHandles != null) && (origUserHandles != null);
+ final boolean applyUserRestrictions = origUserHandles != null;
if (applyUserRestrictions) {
boolean installedStateChanged = false;
if (DEBUG_REMOVE) {
@@ -19212,7 +19209,7 @@
}
private void deleteInstalledPackageLIF(PackageSetting ps,
- boolean deleteCodeAndResources, int flags, int[] allUserHandles,
+ boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
PackageRemovedInfo outInfo, boolean writeSettings) {
synchronized (mLock) {
if (outInfo != null) {
@@ -19226,7 +19223,7 @@
// Delete application code and resources only for parent packages
if (deleteCodeAndResources && (outInfo != null)) {
outInfo.args = createInstallArgsForExisting(
- ps.getCodePathString(), getAppDexInstructionSets(
+ ps.getPathString(), getAppDexInstructionSets(
ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
}
@@ -19332,7 +19329,7 @@
* This method handles package deletion in general
*/
private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
- boolean deleteCodeAndResources, int[] allUserHandles, int flags,
+ boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags,
PackageRemovedInfo outInfo, boolean writeSettings,
ParsedPackage replacingPackage) {
final DeletePackageAction action;
@@ -19369,7 +19366,7 @@
/** Deletes a package. Only throws when install of a disabled package fails. */
private void executeDeletePackageLIF(DeletePackageAction action,
String packageName, boolean deleteCodeAndResources,
- int[] allUserHandles, boolean writeSettings,
+ @NonNull int[] allUserHandles, boolean writeSettings,
ParsedPackage replacingPackage) throws SystemDeleteException {
final PackageSetting ps = action.deletingPs;
final PackageRemovedInfo outInfo = action.outInfo;
@@ -19768,7 +19765,7 @@
final String[] packageNames = { packageName };
final long[] ceDataInodes = { ps.getCeDataInode(userId) };
- final String[] codePaths = { ps.getCodePathString() };
+ final String[] codePaths = { ps.getPathString() };
try {
mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
@@ -19865,7 +19862,7 @@
final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
if (removeExisting && existing != null) {
- removeFiltersLocked(pir, filter, existing);
+ mSettings.removeFiltersLPw(pir, filter, existing);
}
pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
scheduleWritePackageRestrictionsLocked(userId);
@@ -19966,7 +19963,7 @@
}
}
if (existing != null) {
- removeFiltersLocked(pir, filter, existing);
+ mSettings.removeFiltersLPw(pir, filter, existing);
}
}
}
@@ -19974,22 +19971,6 @@
"Replacing preferred", false);
}
- private void removeFiltersLocked(@NonNull PreferredIntentResolver pir,
- @NonNull IntentFilter filter, @NonNull List<PreferredActivity> existing) {
- if (DEBUG_PREFERRED) {
- Slog.i(TAG, existing.size() + " preferred matches for:");
- filter.dump(new LogPrinter(Log.INFO, TAG), " ");
- }
- for (int i = existing.size() - 1; i >= 0; --i) {
- final PreferredActivity pa = existing.get(i);
- if (DEBUG_PREFERRED) {
- Slog.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
- pa.dump(new LogPrinter(Log.INFO, TAG), " ");
- }
- pir.removeFilter(pa);
- }
- }
-
@Override
public void clearPackagePreferredActivities(String packageName) {
final int callingUid = Binder.getCallingUid();
@@ -21647,6 +21628,8 @@
.getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
co.onChange(true);
+ mAppsFilter.onSystemReady();
+
// Disable any carrier apps. We do this very early in boot to prevent the apps from being
// disabled after already being started.
CarrierAppUtils.disableCarrierAppsUntilPrivileged(
@@ -21795,9 +21778,6 @@
mInstallerService.restoreAndApplyStagedSessionIfNeeded();
mExistingPackages = null;
-
- // We'll do this last as it builds its cache while holding mLock via callback.
- mAppsFilter.onSystemReady();
}
public void waitForAppDataPrepared() {
@@ -22711,11 +22691,11 @@
synchronized (mInstallLock) {
final AndroidPackage pkg;
try {
- pkg = scanPackageTracedLI(ps.getCodePath(), parseFlags, SCAN_INITIAL, 0, null);
+ pkg = scanPackageTracedLI(ps.getPath(), parseFlags, SCAN_INITIAL, 0, null);
loaded.add(pkg);
} catch (PackageManagerException e) {
- Slog.w(TAG, "Failed to scan " + ps.getCodePath() + ": " + e.getMessage());
+ Slog.w(TAG, "Failed to scan " + ps.getPath() + ": " + e.getMessage());
}
if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
@@ -22784,6 +22764,7 @@
return;
}
+ final int[] userIds = mUserManager.getUserIds();
final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
synchronized (mInstallLock) {
synchronized (mLock) {
@@ -22797,11 +22778,11 @@
try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
"unloadPrivatePackagesInner")) {
- if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
+ if (deletePackageLIF(ps.name, null, false, userIds, deleteFlags, outInfo,
false, null)) {
unloaded.add(pkg);
} else {
- Slog.w(TAG, "Failed to unload " + ps.getCodePath());
+ Slog.w(TAG, "Failed to unload " + ps.getPath());
}
}
@@ -22855,7 +22836,7 @@
final int packageCount = mSettings.mPackages.size();
for (int i = 0; i < packageCount; i++) {
final PackageSetting ps = mSettings.mPackages.valueAt(i);
- codePaths.add(ps.getCodePath().getAbsolutePath());
+ codePaths.add(ps.getPath().getAbsolutePath());
}
return codePaths;
}
@@ -23431,7 +23412,7 @@
currentVolumeUuid = ps.volumeUuid;
- final File probe = new File(pkg.getCodePath());
+ final File probe = new File(pkg.getPath());
final File probeOat = new File(probe, "oat");
if (!probe.isDirectory() || !probeOat.isDirectory()) {
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
@@ -23453,7 +23434,7 @@
}
isCurrentLocationExternal = pkg.isExternalStorage();
- codeFile = new File(pkg.getCodePath());
+ codeFile = new File(pkg.getPath());
installSource = ps.installSource;
packageAbiOverride = ps.cpuAbiOverrideString;
appId = UserHandle.getAppId(pkg.getUid());
@@ -24884,7 +24865,7 @@
mApexManager.getApksInApex(apexPackages.get(i).packageName);
for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) {
final AndroidPackage pkg = getPackage(apkNames.get(j));
- cacher.cleanCachedResult(new File(pkg.getCodePath()));
+ cacher.cleanCachedResult(new File(pkg.getPath()));
}
}
}
@@ -24960,7 +24941,7 @@
Slog.e(TAG, "failed to find package " + packageName);
return false;
}
- overlayPaths.add(pkg.getBaseCodePath());
+ overlayPaths.add(pkg.getBaseApkPath());
}
}
@@ -25676,7 +25657,7 @@
pkgSetting.getPkgState().isUpdatedSystemApp())) {
return null;
}
- File codePath = new File(pkg.getCodePath());
+ File codePath = new File(pkg.getPath());
if (codePath.isDirectory()) {
return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 5553cd0..e5dad85 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -326,11 +326,11 @@
}
public static long getLastModifiedTime(AndroidPackage pkg) {
- final File srcFile = new File(pkg.getCodePath());
+ final File srcFile = new File(pkg.getPath());
if (!srcFile.isDirectory()) {
return srcFile.lastModified();
}
- final File baseFile = new File(pkg.getBaseCodePath());
+ final File baseFile = new File(pkg.getBaseApkPath());
long maxModifiedTime = baseFile.lastModified();
if (pkg.getSplitCodePaths() != null) {
for (int i = pkg.getSplitCodePaths().length - 1; i >=0; --i) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
index 3614cc0..2bbca79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
@@ -67,7 +67,6 @@
}
}
- // Sanity check.
if (sShellCommands.size() > TOO_MANY_PENDING_SHELL_COMMANDS) {
Slog.e(TAG, "Too many pending shell commands: " + sShellCommands.size());
}
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index a3a7273..4476e8a 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -44,8 +44,33 @@
public class PackageSetting extends PackageSettingBase {
int appId;
+ /**
+ * This can be null whenever a physical APK on device is missing. This can be the result of
+ * removing an external storage device where the APK resides.
+ *
+ * This will result in the system reading the {@link PackageSetting} from disk, but without
+ * being able to parse the base APK's AndroidManifest.xml to read all of its metadata. The data
+ * that is written and read in {@link Settings} includes a minimal set of metadata needed to
+ * perform other checks in the system.
+ *
+ * This is important in order to enforce uniqueness within the system, as the package, even if
+ * on a removed storage device, is still considered installed. Another package of the same
+ * application ID or declaring the same permissions or similar cannot be installed.
+ *
+ * Re-attaching the storage device to make the APK available should allow the user to use the
+ * app once the device reboots or otherwise re-scans it.
+ *
+ * It is expected that all code that uses a {@link PackageSetting} understands this inner field
+ * may be null. Note that this relationship only works one way. It should not be possible to
+ * have an entry inside {@link PackageManagerService#mPackages} without a corresponding
+ * {@link PackageSetting} inside {@link Settings#mPackages}.
+ *
+ * @deprecated Use {@link #getPkg()}. The setter is favored to avoid unintended mutation.
+ */
@Nullable
+ @Deprecated
public AndroidPackage pkg;
+
/**
* WARNING. The object reference is important. We perform integer equality and NOT
* object equality to check whether shared user settings are the same.
@@ -104,6 +129,12 @@
doCopy(orig);
}
+ /** @see #pkg **/
+ @Nullable
+ public AndroidPackage getPkg() {
+ return pkg;
+ }
+
public int getSharedUserId() {
if (sharedUser != null) {
return sharedUser.userId;
@@ -200,7 +231,6 @@
return installPermissionsFixed;
}
- // TODO(b/135203078): Remove these in favor of reading from the package directly
public boolean isPrivileged() {
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 6010344..a7bbf8d 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -40,6 +40,7 @@
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.File;
import java.util.Arrays;
@@ -59,13 +60,9 @@
public final String name;
final String realName;
- /**
- * Path where this package was found on disk. For monolithic packages
- * this is path to single base APK file; for cluster packages this is
- * path to the cluster directory.
- */
- private File mCodePath;
- private String mCodePathString;
+ /** @see AndroidPackage#getPath() */
+ private File mPath;
+ private String mPathString;
String[] usesStaticLibraries;
long[] usesStaticLibrariesVersions;
@@ -136,7 +133,7 @@
boolean forceQueryableOverride;
- PackageSettingBase(String name, String realName, @NonNull File codePath,
+ PackageSettingBase(String name, String realName, @NonNull File path,
String legacyNativeLibraryPathString, String primaryCpuAbiString,
String secondaryCpuAbiString, String cpuAbiOverrideString,
long pVersionCode, int pkgFlags, int pkgPrivateFlags,
@@ -146,7 +143,7 @@
this.realName = realName;
this.usesStaticLibraries = usesStaticLibraries;
this.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
- setCodePath(codePath);
+ setPath(path);
this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
this.primaryCpuAbiString = primaryCpuAbiString;
this.secondaryCpuAbiString = secondaryCpuAbiString;
@@ -230,7 +227,7 @@
}
private void doCopy(PackageSettingBase orig) {
- setCodePath(orig.getCodePath());
+ setPath(orig.getPath());
cpuAbiOverrideString = orig.cpuAbiOverrideString;
firstInstallTime = orig.firstInstallTime;
installPermissionsFixed = orig.installPermissionsFixed;
@@ -697,18 +694,23 @@
return userState.harmfulAppWarning;
}
- PackageSettingBase setCodePath(@NonNull File codePath) {
- this.mCodePath = codePath;
- this.mCodePathString = codePath.toString();
+ /**
+ * @see #mPath
+ */
+ PackageSettingBase setPath(@NonNull File path) {
+ this.mPath = path;
+ this.mPathString = path.toString();
return this;
}
- File getCodePath() {
- return mCodePath;
+ /** @see #mPath */
+ File getPath() {
+ return mPath;
}
- String getCodePathString() {
- return mCodePathString;
+ /** @see #mPath */
+ String getPathString() {
+ return mPathString;
}
/**
@@ -733,7 +735,7 @@
protected PackageSettingBase updateFrom(PackageSettingBase other) {
super.copyFrom(other);
- setCodePath(other.getCodePath());
+ setPath(other.getPath());
this.usesStaticLibraries = other.usesStaticLibraries;
this.usesStaticLibrariesVersions = other.usesStaticLibrariesVersions;
this.legacyNativeLibraryPathString = other.legacyNativeLibraryPathString;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 659e2a3..74bc49d 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -102,7 +102,6 @@
import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.LocalServices;
-import com.android.server.pm.Installer.Batch;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -307,8 +306,8 @@
private final ArrayMap<String, KernelPackageState> mKernelMapping = new ArrayMap<>();
// List of replaced system applications
- private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
- new ArrayMap<String, PackageSetting>();
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ final ArrayMap<String, PackageSetting> mDisabledSysPackages = new ArrayMap<>();
/** List of packages that are blocked for uninstall for specific users */
private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>();
@@ -539,7 +538,7 @@
return null;
}
p.getPkgState().setUpdatedSystemApp(false);
- PackageSetting ret = addPackageLPw(name, p.realName, p.getCodePath(),
+ PackageSetting ret = addPackageLPw(name, p.realName, p.getPath(),
p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
p.secondaryCpuAbiString, p.cpuAbiOverrideString,
p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
@@ -646,7 +645,7 @@
if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
+ pkgName + " is adopting original package " + originalPkg.name);
pkgSetting = new PackageSetting(originalPkg, pkgName /*realPkgName*/);
- pkgSetting.setCodePath(codePath);
+ pkgSetting.setPath(codePath);
pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath;
pkgSetting.pkgFlags = pkgFlags;
pkgSetting.pkgPrivateFlags = pkgPrivateFlags;
@@ -771,12 +770,12 @@
"Updating application package " + pkgName + " failed");
}
- if (!pkgSetting.getCodePath().equals(codePath)) {
+ if (!pkgSetting.getPath().equals(codePath)) {
final boolean isSystem = pkgSetting.isSystem();
Slog.i(PackageManagerService.TAG,
"Update" + (isSystem ? " system" : "")
+ " package " + pkgName
- + " code path from " + pkgSetting.getCodePathString()
+ + " code path from " + pkgSetting.getPathString()
+ " to " + codePath.toString()
+ "; Retain data and using new");
if (!isSystem) {
@@ -798,7 +797,7 @@
// internal to external storage or vice versa.
pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath;
}
- pkgSetting.setCodePath(codePath);
+ pkgSetting.setPath(codePath);
}
// If what we are scanning is a system (and possibly privileged) package,
// then make it so, regardless of whether it was previously installed only
@@ -2175,32 +2174,24 @@
void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)
throws IOException, XmlPullParserException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- String libName = parser.getAttributeValue(null, ATTR_NAME);
- String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
+ String libName = parser.getAttributeValue(null, ATTR_NAME);
+ String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
- long libVersion = -1;
- try {
- libVersion = Long.parseLong(libVersionStr);
- } catch (NumberFormatException e) {
- // ignore
- }
-
- if (libName != null && libVersion >= 0) {
- outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
- outPs.usesStaticLibraries, libName);
- outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong(
- outPs.usesStaticLibrariesVersions, libVersion);
- }
-
- XmlUtils.skipCurrentTag(parser);
+ long libVersion = -1;
+ try {
+ libVersion = Long.parseLong(libVersionStr);
+ } catch (NumberFormatException e) {
+ // ignore
}
+
+ if (libName != null && libVersion >= 0) {
+ outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
+ outPs.usesStaticLibraries, libName);
+ outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong(
+ outPs.usesStaticLibrariesVersions, libVersion);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
}
void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries,
@@ -2711,7 +2702,7 @@
if (pkg.realName != null) {
serializer.attribute(null, "realName", pkg.realName);
}
- serializer.attribute(null, "codePath", pkg.getCodePathString());
+ serializer.attribute(null, "codePath", pkg.getPathString());
serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
@@ -2753,7 +2744,7 @@
if (pkg.realName != null) {
serializer.attribute(null, "realName", pkg.realName);
}
- serializer.attribute(null, "codePath", pkg.getCodePathString());
+ serializer.attribute(null, "codePath", pkg.getPathString());
if (pkg.legacyNativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
@@ -3192,6 +3183,22 @@
}
}
+ void removeFiltersLPw(@NonNull PreferredIntentResolver pir,
+ @NonNull IntentFilter filter, @NonNull List<PreferredActivity> existing) {
+ if (PackageManagerService.DEBUG_PREFERRED) {
+ Slog.i(TAG, existing.size() + " preferred matches for:");
+ filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ for (int i = existing.size() - 1; i >= 0; --i) {
+ final PreferredActivity pa = existing.get(i);
+ if (PackageManagerService.DEBUG_PREFERRED) {
+ Slog.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
+ pa.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ pir.removeFilter(pa);
+ }
+ }
+
private void applyDefaultPreferredActivityLPw(
PackageManagerInternal pmInternal, IntentFilter tmpPa, ComponentName cn, int userId) {
// The initial preferences only specify the target activity
@@ -3395,8 +3402,13 @@
Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
}
}
+ final PreferredIntentResolver pir = editPreferredActivitiesLPw(userId);
+ final List<PreferredActivity> existing = pir.findFilters(filter);
+ if (existing != null) {
+ removeFiltersLPw(pir, filter, existing);
+ }
PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
- editPreferredActivitiesLPw(userId).addFilter(pa);
+ pir.addFilter(pa);
} else if (haveNonSys == null) {
StringBuilder sb = new StringBuilder();
sb.append("No component ");
@@ -3855,6 +3867,8 @@
readDomainVerificationLPw(parser, packageSetting);
} else if (tagName.equals(TAG_MIME_GROUP)) {
packageSetting.mimeGroups = readMimeGroupLPw(parser, packageSetting.mimeGroups);
+ } else if (tagName.equals(TAG_USES_STATIC_LIB)) {
+ readUsesStaticLibLPw(parser, packageSetting);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Unknown element under <package>: " + parser.getName());
@@ -4541,9 +4555,9 @@
pw.print(prefix); pw.print(" sharedUser="); pw.println(ps.sharedUser);
}
pw.print(prefix); pw.print(" pkg="); pw.println(pkg);
- pw.print(prefix); pw.print(" codePath="); pw.println(ps.getCodePathString());
+ pw.print(prefix); pw.print(" codePath="); pw.println(ps.getPathString());
if (permissionNames == null) {
- pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.getCodePathString());
+ pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.getPathString());
pw.print(prefix); pw.print(" legacyNativeLibraryDir=");
pw.println(ps.legacyNativeLibraryPathString);
pw.print(prefix); pw.print(" extractNativeLibs=");
@@ -4561,10 +4575,10 @@
pw.println();
if (pkg != null) {
pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName());
+ pw.print(prefix); pw.print(" usesNonSdkApi="); pw.println(pkg.isUsesNonSdkApi());
pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, pkg); pw.println();
final int apkSigningVersion = pkg.getSigningDetails().signatureSchemeVersion;
pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion);
- // TODO(b/135203078): Is there anything to print here with AppInfo removed?
pw.print(prefix); pw.print(" applicationInfo=");
pw.println(pkg.toAppInfoToString());
pw.print(prefix); pw.print(" flags=");
@@ -5160,7 +5174,6 @@
}
void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps) {
- // TODO(b/135203078): ParsedComponent toString methods for dumping
dumpComponents(pw, prefix, "activities:", ps.pkg.getActivities());
dumpComponents(pw, prefix, "services:", ps.pkg.getServices());
dumpComponents(pw, prefix, "receivers:", ps.pkg.getReceivers());
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 0c4eaec3..462b215 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -60,7 +60,6 @@
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.apk.ApkSignatureVerifier;
@@ -1028,22 +1027,12 @@
/**
* <p>Abort committed staged session
- *
- * <p>This method must be called while holding {@link PackageInstallerSession#mLock}.
- *
- * <p>The method returns {@code false} to indicate it is not safe to clean up the session from
- * system yet. When it is safe, the method returns {@code true}.
- *
- * <p> When it is safe to clean up, {@link StagingManager} will call
- * {@link PackageInstallerSession#abandon()} on the session again.
- *
- * @return {@code true} if it is safe to cleanup the session resources, otherwise {@code false}.
*/
- boolean abortCommittedSessionLocked(@NonNull PackageInstallerSession session) {
+ void abortCommittedSession(@NonNull PackageInstallerSession session) {
int sessionId = session.sessionId;
- if (session.isStagedSessionApplied()) {
- Slog.w(TAG, "Cannot abort applied session : " + sessionId);
- return false;
+ if (session.isStagedAndInTerminalState()) {
+ Slog.w(TAG, "Cannot abort session in final state: " + sessionId);
+ return;
}
if (!session.isDestroyed()) {
throw new IllegalStateException("Committed session must be destroyed before aborting it"
@@ -1051,15 +1040,7 @@
}
if (getStagedSession(sessionId) == null) {
Slog.w(TAG, "Session " + sessionId + " has been abandoned already");
- return false;
- }
-
- // If pre-reboot verification is running, then return false. StagingManager will call
- // abandon again when pre-reboot verification ends.
- if (mPreRebootVerificationHandler.isVerificationRunning(sessionId)) {
- Slog.w(TAG, "Session " + sessionId + " aborted before pre-reboot "
- + "verification completed.");
- return false;
+ return;
}
// A session could be marked ready once its pre-reboot verification ends
@@ -1075,7 +1056,6 @@
// Session was successfully aborted from apexd (if required) and pre-reboot verification
// is also complete. It is now safe to clean up the session from system.
abortSession(session);
- return true;
}
/**
@@ -1264,8 +1244,8 @@
// TODO(b/136257624): Temporary API to let PMS communicate with StagingManager. When all
// verification logic is extracted out of StagingManager into PMS, we can remove
// this.
- void notifyVerificationComplete(int sessionId) {
- mPreRebootVerificationHandler.onPreRebootVerificationComplete(sessionId);
+ void notifyVerificationComplete(PackageInstallerSession session) {
+ mPreRebootVerificationHandler.onPreRebootVerificationComplete(session);
}
// TODO(b/136257624): Temporary API to let PMS communicate with StagingManager. When all
@@ -1279,8 +1259,6 @@
// Hold session ids before handler gets ready to do the verification.
private IntArray mPendingSessionIds;
private boolean mIsReady;
- @GuardedBy("mVerificationRunning")
- private final SparseBooleanArray mVerificationRunning = new SparseBooleanArray();
PreRebootVerificationHandler(Looper looper) {
super(looper);
@@ -1316,7 +1294,7 @@
}
if (session.isDestroyed() || session.isStagedSessionFailed()) {
// No point in running verification on a destroyed/failed session
- onPreRebootVerificationComplete(sessionId);
+ onPreRebootVerificationComplete(session);
return;
}
switch (msg.what) {
@@ -1357,15 +1335,10 @@
}
PackageInstallerSession session = getStagedSession(sessionId);
- synchronized (mVerificationRunning) {
- // Do not start verification on a session that has been abandoned
- if (session == null || session.isDestroyed()) {
- return;
- }
+ if (session != null && session.notifyStagedStartPreRebootVerification()) {
Slog.d(TAG, "Starting preRebootVerification for session " + sessionId);
- mVerificationRunning.put(sessionId, true);
+ obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget();
}
- obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget();
}
private void onPreRebootVerificationFailure(PackageInstallerSession session,
@@ -1376,28 +1349,14 @@
// failed on next step and staging directory for session will be deleted.
}
session.setStagedSessionFailed(errorCode, errorMessage);
- onPreRebootVerificationComplete(session.sessionId);
+ onPreRebootVerificationComplete(session);
}
// Things to do when pre-reboot verification completes for a particular sessionId
- private void onPreRebootVerificationComplete(int sessionId) {
- // Remove it from mVerificationRunning so that verification is considered complete
- synchronized (mVerificationRunning) {
- Slog.d(TAG, "Stopping preRebootVerification for session " + sessionId);
- mVerificationRunning.delete(sessionId);
- }
- // Check if the session was destroyed while pre-reboot verification was running. If so,
- // abandon it again.
- PackageInstallerSession session = getStagedSession(sessionId);
- if (session != null && session.isDestroyed()) {
- session.abandon();
- }
- }
-
- private boolean isVerificationRunning(int sessionId) {
- synchronized (mVerificationRunning) {
- return mVerificationRunning.get(sessionId);
- }
+ private void onPreRebootVerificationComplete(PackageInstallerSession session) {
+ int sessionId = session.sessionId;
+ Slog.d(TAG, "Stopping preRebootVerification for session " + sessionId);
+ session.notifyStagedEndPreRebootVerification();
}
private void notifyPreRebootVerification_Start_Complete(int sessionId) {
@@ -1516,7 +1475,7 @@
// or activate its apex, there won't be any files to work with as they will be cleaned
// up by the system as part of abandonment. If session is abandoned before this point,
// then the session is already destroyed and cannot be marked ready anymore.
- onPreRebootVerificationComplete(session.sessionId);
+ onPreRebootVerificationComplete(session);
// Proactively mark session as ready before calling apexd. Although this call order
// looks counter-intuitive, this is the easiest way to ensure that session won't end up
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 8000c63..587cb825 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -486,7 +486,7 @@
public boolean compileLayouts(AndroidPackage pkg) {
try {
final String packageName = pkg.getPackageName();
- final String apkPath = pkg.getBaseCodePath();
+ final String apkPath = pkg.getBaseApkPath();
// TODO(b/143971007): Use a cross-user directory
File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
@@ -524,7 +524,7 @@
private ArrayMap<String, String> getPackageProfileNames(AndroidPackage pkg) {
ArrayMap<String, String> result = new ArrayMap<>();
if (pkg.isHasCode()) {
- result.put(pkg.getBaseCodePath(), ArtManager.getProfileName(null));
+ result.put(pkg.getBaseApkPath(), ArtManager.getProfileName(null));
}
String[] splitCodePaths = pkg.getSplitCodePaths();
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
index 6807388..fa01836 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -18,12 +18,12 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.SharedLibraryInfo;
-import com.android.server.pm.parsing.pkg.AndroidPackage;
import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.os.ClassLoaderFactory;
import com.android.internal.util.ArrayUtils;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.File;
import java.util.List;
@@ -90,7 +90,7 @@
// The splits have an implicit dependency on the base apk.
// This means that we have to add the base apk file in addition to the shared libraries.
- String baseApkName = new File(pkg.getBaseCodePath()).getName();
+ String baseApkName = new File(pkg.getBaseApkPath()).getName();
String baseClassPath = baseApkName;
// The result is stored in classLoaderContexts.
@@ -401,7 +401,7 @@
* Assumes that the application declares a non-null array of splits.
*/
private static String[] getSplitRelativeCodePaths(AndroidPackage pkg) {
- String baseCodePath = new File(pkg.getBaseCodePath()).getParent();
+ String baseCodePath = new File(pkg.getBaseApkPath()).getParent();
String[] splitCodePaths = pkg.getSplitCodePaths();
String[] splitRelativeCodePaths = new String[ArrayUtils.size(splitCodePaths)];
for (int i = 0; i < splitRelativeCodePaths.length; i++) {
diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
index 5506a52..a567266 100644
--- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java
+++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
@@ -40,7 +40,7 @@
public boolean compileLayouts(AndroidPackage pkg) {
try {
final String packageName = pkg.getPackageName();
- final String apkPath = pkg.getBaseCodePath();
+ final String apkPath = pkg.getBaseApkPath();
// TODO(b/143971007): Use a cross-user directory
File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
diff --git a/services/core/java/com/android/server/pm/parsing/PackageCacher.java b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
index 99c6dd1..74ec161 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageCacher.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
@@ -79,7 +79,6 @@
final PackageParserCacheHelper.ReadHelper helper = new PackageParserCacheHelper.ReadHelper(p);
helper.startAndInstall();
- // TODO(b/135203078): Hide PackageImpl constructor?
ParsedPackage pkg = new PackageImpl(p);
p.recycle();
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 09b4f89..d695a01 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -35,6 +35,7 @@
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
+import android.content.pm.parsing.ParsingUtils;
import android.content.pm.parsing.component.ComponentParseUtils;
import android.content.pm.parsing.component.ParsedActivity;
import android.content.pm.parsing.component.ParsedComponent;
@@ -73,7 +74,7 @@
* @hide
**/
public class PackageInfoUtils {
- private static final String TAG = PackageParser2.TAG;
+ private static final String TAG = ParsingUtils.TAG;
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
@@ -207,7 +208,6 @@
public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg,
@PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId,
@Nullable PackageSetting pkgSetting) {
- // TODO(b/135203078): Consider cases where we don't have a PkgSetting
if (pkg == null) {
return null;
}
@@ -354,7 +354,6 @@
return null;
}
- // TODO(b/135203078): Add setting related state
info.primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
info.secondaryCpuAbi = AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting);
info.nativeLibraryDir = pkg.getNativeLibraryDir();
@@ -454,7 +453,6 @@
/** @see ApplicationInfo#flags */
public static int appInfoFlags(AndroidPackage pkg, @Nullable PackageSetting pkgSetting) {
- // TODO(b/135203078): Add setting related state
// @formatter:off
int pkgWithoutStateFlags = PackageInfoWithoutStateUtils.appInfoFlags(pkg)
| flag(pkg.isSystem(), ApplicationInfo.FLAG_SYSTEM)
diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/services/core/java/com/android/server/pm/parsing/PackageParser2.java
index 1145057..851ddd1 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageParser2.java
@@ -71,7 +71,7 @@
return platformCompat.isChangeEnabled(changeId, appInfo);
} catch (Exception e) {
// This shouldn't happen, but assume enforcement if it does
- Slog.wtf(ParsingUtils.TAG, "IPlatformCompat query failed", e);
+ Slog.wtf(TAG, "IPlatformCompat query failed", e);
return true;
}
}
@@ -87,7 +87,7 @@
});
}
- static final String TAG = "PackageParser2";
+ private static final String TAG = ParsingUtils.TAG;
private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE;
private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100;
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java
index 39784cf..a13680a 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java
@@ -23,7 +23,6 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.content.pm.PermissionGroupInfo;
-import android.content.pm.SharedLibraryInfo;
import android.content.pm.parsing.ParsingPackageRead;
import android.content.pm.parsing.component.ParsedAttribution;
import android.content.pm.parsing.component.ParsedIntentInfo;
@@ -65,18 +64,16 @@
/** Path of base APK */
@NonNull
- String getBaseCodePath();
+ String getBaseApkPath();
/** Revision code of base APK */
int getBaseRevisionCode();
/**
- * Path where this package was found on disk. For monolithic packages
- * this is path to single base APK file; for cluster packages this is
- * path to the cluster directory.
+ * The path to the folder containing the base APK and any installed splits.
*/
@NonNull
- String getCodePath();
+ String getPath();
/**
* Permissions requested but not in the manifest. These may have been split or migrated from
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
index a6f02e7..0a56e13 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
@@ -58,7 +58,7 @@
PackageImpl pkg = (PackageImpl) aPkg;
ArrayList<String> paths = new ArrayList<>();
if (pkg.isHasCode()) {
- paths.add(pkg.getBaseCodePath());
+ paths.add(pkg.getBaseApkPath());
}
String[] splitCodePaths = pkg.getSplitCodePaths();
if (!ArrayUtils.isEmpty(splitCodePaths)) {
@@ -77,7 +77,7 @@
public static List<String> getAllCodePaths(AndroidPackage aPkg) {
PackageImpl pkg = (PackageImpl) aPkg;
ArrayList<String> paths = new ArrayList<>();
- paths.add(pkg.getBaseCodePath());
+ paths.add(pkg.getBaseApkPath());
String[] splitCodePaths = pkg.getSplitCodePaths();
if (!ArrayUtils.isEmpty(splitCodePaths)) {
@@ -147,7 +147,7 @@
if (pkg.isSystem() && !isUpdatedSystemApp) {
return false;
}
- if (IncrementalManager.isIncrementalPath(pkg.getCodePath())) {
+ if (IncrementalManager.isIncrementalPath(pkg.getPath())) {
return false;
}
return true;
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
index 43365fa..0e3e110 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
@@ -136,9 +136,9 @@
private int uid = -1;
@VisibleForTesting
- public PackageImpl(@NonNull String packageName, @NonNull String baseCodePath,
- @NonNull String codePath, @Nullable TypedArray manifestArray, boolean isCoreApp) {
- super(packageName, baseCodePath, codePath, manifestArray);
+ public PackageImpl(@NonNull String packageName, @NonNull String baseApkPath,
+ @NonNull String path, @Nullable TypedArray manifestArray, boolean isCoreApp) {
+ super(packageName, baseApkPath, path, manifestArray);
this.manifestPackageName = this.packageName;
this.coreApp = isCoreApp;
}
@@ -247,7 +247,7 @@
@Override
public PackageImpl setCodePath(@NonNull String value) {
- this.codePath = value;
+ this.mPath = value;
return this;
}
@@ -322,7 +322,7 @@
@Override
public PackageImpl setBaseCodePath(@NonNull String baseCodePath) {
- this.baseCodePath = TextUtils.safeIntern(baseCodePath);
+ this.mBaseApkPath = TextUtils.safeIntern(baseCodePath);
return this;
}
@@ -430,7 +430,7 @@
@Deprecated
@Override
public String toAppInfoToString() {
- return "ApplicationInfo{"
+ return "PackageImpl{"
+ Integer.toHexString(System.identityHashCode(this))
+ " " + getPackageName() + "}";
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index ffdcc22..1cfc5b1 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -3526,7 +3526,7 @@
deniedPermissions == null || !deniedPermissions.contains(perm);
if (permissionViolation) {
Slog.w(TAG, "Privileged permission " + perm + " for package "
- + pkg.getPackageName() + " (" + pkg.getCodePath()
+ + pkg.getPackageName() + " (" + pkg.getPath()
+ ") not in privapp-permissions whitelist");
if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
@@ -3534,7 +3534,7 @@
mPrivappPermissionsViolations = new ArraySet<>();
}
mPrivappPermissionsViolations.add(
- pkg.getPackageName() + " (" + pkg.getCodePath() + "): "
+ pkg.getPackageName() + " (" + pkg.getPath() + "): "
+ perm);
}
} else {
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index ae2b040..e1cd9e3 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -31,6 +31,7 @@
import android.app.AppOpsManager;
import android.app.AppOpsManagerInternal;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -242,8 +243,9 @@
public void onReceive(Context context, Intent intent) {
boolean hasSetupRun = true;
try {
- hasSetupRun = Settings.Secure.getInt(getContext().getContentResolver(),
- Settings.Secure.USER_SETUP_COMPLETE) != 0;
+ final ContentResolver cr = getContext().getContentResolver();
+ hasSetupRun = Settings.Secure.getIntForUser(cr,
+ Settings.Secure.USER_SETUP_COMPLETE, cr.getUserId()) != 0;
} catch (Settings.SettingNotFoundException e) {
// Ignore error, assume setup has run
}
diff --git a/services/core/java/com/android/server/search/Searchables.java b/services/core/java/com/android/server/search/Searchables.java
index 8af76a1..c769a50 100644
--- a/services/core/java/com/android/server/search/Searchables.java
+++ b/services/core/java/com/android/server/search/Searchables.java
@@ -20,6 +20,7 @@
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -397,8 +398,9 @@
}
private String getGlobalSearchProviderSetting() {
- return Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY);
+ final ContentResolver cr = mContext.getContentResolver();
+ return Settings.Secure.getStringForUser(cr,
+ Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY, cr.getUserId());
}
/**
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 5aedfc1..2a74b3d 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -28,6 +28,8 @@
import android.Manifest.permission;
import android.annotation.NonNull;
import android.app.AppOpsManager;
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
import android.app.slice.ISliceManager;
import android.app.slice.SliceSpec;
import android.app.usage.UsageStatsManagerInternal;
@@ -39,7 +41,9 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
@@ -61,6 +65,7 @@
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -72,7 +77,10 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.function.Supplier;
public class SliceManagerService extends ISliceManager.Stub {
@@ -80,13 +88,16 @@
private final Object mLock = new Object();
private final Context mContext;
+ private final PackageManagerInternal mPackageManagerInternal;
private final AppOpsManager mAppOps;
private final AssistUtils mAssistUtils;
@GuardedBy("mLock")
private final ArrayMap<Uri, PinnedSliceState> mPinnedSlicesByUri = new ArrayMap<>();
@GuardedBy("mLock")
- private final SparseArray<String> mLastAssistantPackage = new SparseArray<>();
+ private final SparseArray<PackageMatchingCache> mAssistantLookup = new SparseArray<>();
+ @GuardedBy("mLock")
+ private final SparseArray<PackageMatchingCache> mHomeLookup = new SparseArray<>();
private final Handler mHandler;
private final SlicePermissionManager mPermissions;
@@ -99,6 +110,8 @@
@VisibleForTesting
SliceManagerService(Context context, Looper looper) {
mContext = context;
+ mPackageManagerInternal = Objects.requireNonNull(
+ LocalServices.getService(PackageManagerInternal.class));
mAppOps = context.getSystemService(AppOpsManager.class);
mAssistUtils = new AssistUtils(context);
mHandler = new Handler(looper);
@@ -111,6 +124,7 @@
filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
+ mRoleObserver = new RoleObserver();
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
}
@@ -160,7 +174,8 @@
mHandler.post(() -> {
if (slicePkg != null && !Objects.equals(pkg, slicePkg)) {
mAppUsageStats.reportEvent(slicePkg, user,
- isAssistant(pkg, user) ? SLICE_PINNED_PRIV : SLICE_PINNED);
+ isAssistant(pkg, user) || isDefaultHomeApp(pkg, user)
+ ? SLICE_PINNED_PRIV : SLICE_PINNED);
}
});
}
@@ -425,19 +440,38 @@
private boolean hasFullSliceAccess(String pkg, int userId) {
long ident = Binder.clearCallingIdentity();
try {
- return isAssistant(pkg, userId) || isGrantedFullAccess(pkg, userId);
+ boolean ret = isDefaultHomeApp(pkg, userId) || isAssistant(pkg, userId)
+ || isGrantedFullAccess(pkg, userId);
+ return ret;
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private boolean isAssistant(String pkg, int userId) {
- if (pkg == null) return false;
- if (!pkg.equals(mLastAssistantPackage.get(userId))) {
- // Failed on cached value, try updating.
- mLastAssistantPackage.put(userId, getAssistant(userId));
+ return getAssistantMatcher(userId).matches(pkg);
+ }
+
+ private boolean isDefaultHomeApp(String pkg, int userId) {
+ return getHomeMatcher(userId).matches(pkg);
+ }
+
+ private PackageMatchingCache getAssistantMatcher(int userId) {
+ PackageMatchingCache matcher = mAssistantLookup.get(userId);
+ if (matcher == null) {
+ matcher = new PackageMatchingCache(() -> getAssistant(userId));
+ mAssistantLookup.put(userId, matcher);
}
- return pkg.equals(mLastAssistantPackage.get(userId));
+ return matcher;
+ }
+
+ private PackageMatchingCache getHomeMatcher(int userId) {
+ PackageMatchingCache matcher = mHomeLookup.get(userId);
+ if (matcher == null) {
+ matcher = new PackageMatchingCache(() -> getDefaultHome(userId));
+ mHomeLookup.put(userId, matcher);
+ }
+ return matcher;
}
private String getAssistant(int userId) {
@@ -448,6 +482,111 @@
return cn.getPackageName();
}
+ /**
+ * A cached value of the default home app
+ */
+ private String mCachedDefaultHome = null;
+
+ // Based on getDefaultHome in ShortcutService.
+ // TODO: Unify if possible
+ @VisibleForTesting
+ protected String getDefaultHome(int userId) {
+
+ // Set VERIFY to true to run the cache in "shadow" mode for cache
+ // testing. Do not commit set to true;
+ final boolean VERIFY = false;
+
+ if (mCachedDefaultHome != null) {
+ if (!VERIFY) {
+ return mCachedDefaultHome;
+ }
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
+
+ // Default launcher from package manager.
+ final ComponentName defaultLauncher = mPackageManagerInternal
+ .getHomeActivitiesAsUser(allHomeCandidates, userId);
+
+ ComponentName detected = defaultLauncher;
+
+ // Cache the default launcher. It is not a problem if the
+ // launcher is null - eventually, the default launcher will be
+ // set to something non-null.
+ mCachedDefaultHome = ((detected != null) ? detected.getPackageName() : null);
+
+ if (detected == null) {
+ // If we reach here, that means it's the first check since the user was created,
+ // and there's already multiple launchers and there's no default set.
+ // Find the system one with the highest priority.
+ // (We need to check the priority too because of FallbackHome in Settings.)
+ // If there's no system launcher yet, then no one can access slices, until
+ // the user explicitly sets one.
+ final int size = allHomeCandidates.size();
+
+ int lastPriority = Integer.MIN_VALUE;
+ for (int i = 0; i < size; i++) {
+ final ResolveInfo ri = allHomeCandidates.get(i);
+ if (!ri.activityInfo.applicationInfo.isSystemApp()) {
+ continue;
+ }
+ if (ri.priority < lastPriority) {
+ continue;
+ }
+ detected = ri.activityInfo.getComponentName();
+ lastPriority = ri.priority;
+ }
+ }
+ final String ret = ((detected != null) ? detected.getPackageName() : null);
+ if (VERIFY) {
+ if (mCachedDefaultHome != null && !mCachedDefaultHome.equals(ret)) {
+ Slog.e(TAG, "getDefaultHome() cache failure, is " +
+ mCachedDefaultHome + " should be " + ret);
+ }
+ }
+ return ret;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ public void invalidateCachedDefaultHome() {
+ mCachedDefaultHome = null;
+ }
+
+ /**
+ * Listen for changes in the roles, and invalidate the cached default
+ * home as necessary.
+ */
+ private RoleObserver mRoleObserver;
+
+ class RoleObserver implements OnRoleHoldersChangedListener {
+ private RoleManager mRm;
+ private final Executor mExecutor;
+
+ RoleObserver() {
+ mExecutor = mContext.getMainExecutor();
+ register();
+ }
+
+ public void register() {
+ mRm = mContext.getSystemService(RoleManager.class);
+ if (mRm != null) {
+ mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
+ invalidateCachedDefaultHome();
+ }
+ }
+
+ @Override
+ public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+ if (RoleManager.ROLE_HOME.equals(roleName)) {
+ invalidateCachedDefaultHome();
+ }
+ }
+ }
+
private boolean isGrantedFullAccess(String pkg, int userId) {
return mPermissions.hasFullAccess(pkg, userId);
}
@@ -496,6 +635,30 @@
return mPermissions.getAllPackagesGranted(pkg);
}
+ /**
+ * Holder that caches a package that has access to a slice.
+ */
+ static class PackageMatchingCache {
+
+ private final Supplier<String> mPkgSource;
+ private String mCurrentPkg;
+
+ public PackageMatchingCache(Supplier<String> pkgSource) {
+ mPkgSource = pkgSource;
+ }
+
+ public boolean matches(String pkgCandidate) {
+ if (pkgCandidate == null) return false;
+
+ if (Objects.equals(pkgCandidate, mCurrentPkg)) {
+ return true;
+ }
+ // Failed on cached value, try updating.
+ mCurrentPkg = mPkgSource.get();
+ return Objects.equals(pkgCandidate, mCurrentPkg);
+ }
+ }
+
public static class Lifecycle extends SystemService {
private SliceManagerService mService;
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index f74cd611..0314cf8 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -3005,10 +3005,10 @@
Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId);
int unlockDismissesKeyguard = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
- Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0, userId);
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 1, userId);
int unlockAttentionRequired = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
- Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, userId);
+ Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 0, userId);
int unlockAppEnabled = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId);
diff --git a/services/core/java/com/android/server/telecom/InternalServiceRepository.java b/services/core/java/com/android/server/telecom/InternalServiceRepository.java
new file mode 100644
index 0000000..76ea5c7
--- /dev/null
+++ b/services/core/java/com/android/server/telecom/InternalServiceRepository.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 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.server.telecom;
+
+import android.content.Context;
+import android.os.Binder;
+import android.os.Process;
+
+import com.android.internal.telecom.IDeviceIdleControllerAdapter;
+import com.android.internal.telecom.IInternalServiceRetriever;
+import com.android.server.DeviceIdleInternal;
+
+/**
+ * The Telecom APK can not access services stored in LocalService directly and since it is in the
+ * SYSTEM process, it also can not use the *Manager interfaces
+ * (see {@link Context#enforceCallingPermission(String, String)}). Instead, we must wrap these local
+ * services in binder interfaces to allow Telecom access.
+ */
+public class InternalServiceRepository extends IInternalServiceRetriever.Stub {
+
+ private final IDeviceIdleControllerAdapter.Stub mDeviceIdleControllerAdapter =
+ new IDeviceIdleControllerAdapter.Stub() {
+ @Override
+ public void exemptAppTemporarilyForEvent(String packageName, long duration, int userHandle,
+ String reason) {
+ mDeviceIdleController.addPowerSaveTempWhitelistApp(Process.myUid(), packageName,
+ duration, userHandle, true /*sync*/, reason);
+ }
+ };
+
+ private final DeviceIdleInternal mDeviceIdleController;
+
+ public InternalServiceRepository(DeviceIdleInternal deviceIdleController) {
+ mDeviceIdleController = deviceIdleController;
+ }
+
+ @Override
+ public IDeviceIdleControllerAdapter getDeviceIdleController() {
+ ensureSystemProcess();
+ return mDeviceIdleControllerAdapter;
+ }
+
+ private void ensureSystemProcess() {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ // Correctness check - this should never happen.
+ throw new SecurityException("SYSTEM ONLY API.");
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/telecom/OWNERS b/services/core/java/com/android/server/telecom/OWNERS
new file mode 100644
index 0000000..39be2c1
--- /dev/null
+++ b/services/core/java/com/android/server/telecom/OWNERS
@@ -0,0 +1,6 @@
+breadley@google.com
+hallliu@google.com
+tgunn@google.com
+xiaotonj@google.com
+shuoq@google.com
+rgreenwalt@google.com
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index a853529..52ad893 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -35,7 +35,10 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.telecom.ITelecomLoader;
+import com.android.internal.telecom.ITelecomService;
import com.android.internal.telephony.SmsApplication;
+import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerService;
@@ -53,16 +56,13 @@
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// Normally, we would listen for death here, but since telecom runs in the same process
- // as this loader (process="system") thats redundant here.
+ // as this loader (process="system") that's redundant here.
try {
- service.linkToDeath(new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- connectToTelecom();
- }
- }, 0);
+ ITelecomLoader telecomLoader = ITelecomLoader.Stub.asInterface(service);
+ ITelecomService telecomService = telecomLoader.createTelecomService(mServiceRepo);
+
SmsApplication.getDefaultMmsApplication(mContext, false);
- ServiceManager.addService(Context.TELECOM_SERVICE, service);
+ ServiceManager.addService(Context.TELECOM_SERVICE, telecomService.asBinder());
synchronized (mLock) {
final PermissionManagerServiceInternal permissionManager =
@@ -114,6 +114,8 @@
@GuardedBy("mLock")
private TelecomServiceConnection mServiceConnection;
+ private InternalServiceRepository mServiceRepo;
+
public TelecomLoaderService(Context context) {
super(context);
mContext = context;
@@ -129,6 +131,8 @@
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
registerDefaultAppNotifier();
registerCarrierConfigChangedReceiver();
+ // core services will have already been loaded.
+ setupServiceRepository();
connectToTelecom();
}
}
@@ -154,6 +158,11 @@
}
}
+ private void setupServiceRepository() {
+ DeviceIdleInternal deviceIdleInternal = getLocalService(DeviceIdleInternal.class);
+ mServiceRepo = new InternalServiceRepository(deviceIdleInternal);
+ }
+
private void registerDefaultAppProviders() {
final PermissionManagerServiceInternal permissionManager =
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
index aee3d8d..b68c54f 100644
--- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
+++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
@@ -25,6 +25,7 @@
import android.annotation.UserIdInt;
import android.app.timezonedetector.TimeZoneCapabilities;
import android.app.timezonedetector.TimeZoneConfiguration;
+import android.os.UserHandle;
import java.util.Objects;
@@ -56,6 +57,12 @@
return mUserId;
}
+ /** Returns the handle of the user this configuration is associated with. */
+ @NonNull
+ public UserHandle getUserHandle() {
+ return UserHandle.of(mUserId);
+ }
+
/** Returns true if the user allowed to modify time zone configuration. */
public boolean isUserConfigAllowed() {
return mUserConfigAllowed;
@@ -198,13 +205,13 @@
@Override
public String toString() {
- return "TimeZoneDetectorConfiguration{"
+ return "ConfigurationInternal{"
+ "mUserId=" + mUserId
- + "mUserConfigAllowed=" + mUserConfigAllowed
- + "mAutoDetectionSupported=" + mAutoDetectionSupported
- + "mAutoDetectionEnabled=" + mAutoDetectionEnabled
- + "mLocationEnabled=" + mLocationEnabled
- + "mGeoDetectionEnabled=" + mGeoDetectionEnabled
+ + ", mUserConfigAllowed=" + mUserConfigAllowed
+ + ", mAutoDetectionSupported=" + mAutoDetectionSupported
+ + ", mAutoDetectionEnabled=" + mAutoDetectionEnabled
+ + ", mLocationEnabled=" + mLocationEnabled
+ + ", mGeoDetectionEnabled=" + mGeoDetectionEnabled
+ '}';
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
index 3230ef1..a8d5c02 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
@@ -23,7 +23,7 @@
import java.util.function.Consumer;
import java.util.function.Supplier;
-/** Implemented the shell command interface for {@link TimeZoneDetectorService}. */
+/** Implements the shell command interface for {@link TimeZoneDetectorService}. */
class TimeZoneDetectorShellCommand extends ShellCommand {
private final TimeZoneDetectorService mInterface;
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 386f390..89b108c 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -126,6 +126,8 @@
private static final String TRUST_TIMEOUT_ALARM_TAG = "TrustManagerService.trustTimeoutForUser";
private static final long TRUST_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000;
+ private static final String PRIV_NAMESPACE = "http://schemas.android.com/apk/prv/res/android";
+
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
private final Receiver mReceiver = new Receiver();
@@ -811,8 +813,8 @@
TypedArray sa = res
.obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
- canUnlockProfile = sa.getBoolean(
- com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
+ canUnlockProfile = attrs.getAttributeBooleanValue(
+ PRIV_NAMESPACE, "unlockProfile", false);
sa.recycle();
} catch (PackageManager.NameNotFoundException e) {
caughtException = e;
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 0b0bb70..53d5146 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -115,7 +115,7 @@
private static final String TAG = "UriGrantsManagerService";
// Maximum number of persisted Uri grants a package is allowed
private static final int MAX_PERSISTED_URI_GRANTS = 512;
- private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true;
+ private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
private final Object mLock = new Object();
private final H mH;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 9f68d62..ad28124 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -133,6 +133,7 @@
import static com.android.server.wm.ActivityRecordProto.NAME;
import static com.android.server.wm.ActivityRecordProto.NUM_DRAWN_WINDOWS;
import static com.android.server.wm.ActivityRecordProto.NUM_INTERESTING_WINDOWS;
+import static com.android.server.wm.ActivityRecordProto.PIP_AUTO_ENTER_ALLOWED;
import static com.android.server.wm.ActivityRecordProto.PROC_ID;
import static com.android.server.wm.ActivityRecordProto.REPORTED_DRAWN;
import static com.android.server.wm.ActivityRecordProto.REPORTED_VISIBLE;
@@ -4627,18 +4628,26 @@
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(this);
}
- /** @return {@code true} if this activity should be made visible. */
- boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
+ private void updateVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
// Check whether activity should be visible without Keyguard influence
visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
&& okToShowLocked();
+ }
+
+ /** @return {@code true} if this activity should be made visible. */
+ private boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
+ updateVisibleIgnoringKeyguard(behindFullscreenActivity);
if (ignoringKeyguard) {
return visibleIgnoringKeyguard;
}
+ return shouldBeVisibleUnchecked();
+ }
+
+ boolean shouldBeVisibleUnchecked() {
final Task stack = getRootTask();
- if (stack == null) {
+ if (stack == null || !visibleIgnoringKeyguard) {
return false;
}
@@ -4651,26 +4660,30 @@
return false;
}
- // Check if the activity is on a sleeping display, and if it can turn it ON.
- if (mDisplayContent.isSleeping()) {
- final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn()
- || canShowWhenLocked() || containsDismissKeyguardWindow();
- if (!canTurnScreenOn) {
- return false;
- }
+ // Check if the activity is on a sleeping display
+ // TODO b/163993448 mSetToSleep is required when restarting an existing activity, try to
+ // remove it if possible.
+ if (mSetToSleep && mDisplayContent.isSleeping()) {
+ return false;
}
+ return mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
+ }
+
+ void updateVisibility(boolean behindFullscreenActivity) {
+ updateVisibleIgnoringKeyguard(behindFullscreenActivity);
+ final Task task = getRootTask();
+ if (task == null || !visibleIgnoringKeyguard) {
+ return;
+ }
// Now check whether it's really visible depending on Keyguard state, and update
// {@link ActivityStack} internal states.
// Inform the method if this activity is the top activity of this stack, but exclude the
// case where this is the top activity in a pinned stack.
- final boolean isTop = this == stack.getTopNonFinishingActivity();
- final boolean isTopNotPinnedStack = stack.isAttached()
- && stack.getDisplayArea().isTopNotFinishNotPinnedStack(stack);
- final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
- visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
-
- return visibleIgnoringDisplayStatus;
+ final boolean isTop = this == task.getTopNonFinishingActivity();
+ final boolean isTopNotPinnedStack = task.isAttached()
+ && task.getDisplayArea().isTopNotFinishNotPinnedStack(task);
+ task.updateKeyguardVisibility(this, isTop && isTopNotPinnedStack);
}
boolean shouldBeVisible() {
@@ -4741,6 +4754,11 @@
// returns. Just need to confirm this reasoning makes sense.
final boolean deferHidingClient = canEnterPictureInPicture
&& !isState(STARTED, STOPPING, STOPPED, PAUSED);
+ if (deferHidingClient && pictureInPictureArgs.isAutoEnterAllowed()) {
+ // Go ahead and just put the activity in pip if it supports auto-pip.
+ mAtmService.enterPictureInPictureMode(this, pictureInPictureArgs);
+ return;
+ }
setDeferHidingClient(deferHidingClient);
setVisibility(false);
@@ -6637,8 +6655,7 @@
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
final int requestedOrientation = getRequestedConfigurationOrientation();
- final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED
- && !mDisplayContent.ignoreRotationForApps();
+ final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED;
final int orientation = orientationRequested
? requestedOrientation
: newParentConfiguration.orientation;
@@ -7532,10 +7549,8 @@
return false;
}
final Task stack = getRootTask();
- return stack != null
- && !stack.inMultiWindowMode()
- && stack.checkKeyguardVisibility(this, true /* shouldBeVisible */,
- stack.topRunningActivity() == this /* isTop */);
+ return stack != null && !stack.inMultiWindowMode()
+ && mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
}
void setTurnScreenOn(boolean turnScreenOn) {
@@ -7678,6 +7693,7 @@
if (hasProcess()) {
proto.write(PROC_ID, app.getPid());
}
+ proto.write(PIP_AUTO_ENTER_ALLOWED, pictureInPictureArgs.isAutoEnterAllowed());
}
@Override
@@ -7786,42 +7802,40 @@
/** Gets the horizontal centered container bounds for size compatibility mode. */
void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation,
boolean orientationRequested, boolean canChangeOrientation) {
+ getFrameByOrientation(outBounds, orientation);
if (mIsFloating) {
- getFrameByOrientation(outBounds, orientation);
outAppBounds.set(outBounds);
return;
}
- if (canChangeOrientation) {
- getBoundsByRotation(outBounds, rotation);
- if (orientationRequested) {
- getFrameByOrientation(outAppBounds, orientation);
- } else {
- outAppBounds.set(outBounds);
- }
- } else {
- if (orientationRequested) {
- getFrameByOrientation(outBounds, orientation);
- if ((outBounds.width() > outBounds.height()) != (mWidth > mHeight)) {
- // The orientation is mismatched but the display cannot rotate. The bounds
- // will fit to the short side of display.
- if (orientation == ORIENTATION_LANDSCAPE) {
- outBounds.bottom = (int) ((float) mWidth * mWidth / mHeight);
- outBounds.right = mWidth;
- } else {
- outBounds.bottom = mHeight;
- outBounds.right = (int) ((float) mHeight * mHeight / mWidth);
- }
- outBounds.offset(
- getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
- }
- } else {
- outBounds.set(0, 0, mWidth, mHeight);
- }
- outAppBounds.set(outBounds);
- }
+ getBoundsByRotation(outAppBounds, rotation);
+ final int dW = outAppBounds.width();
+ final int dH = outAppBounds.height();
+ final boolean isOrientationMismatched =
+ ((outBounds.width() > outBounds.height()) != (dW > dH));
- if (rotation != ROTATION_UNDEFINED) {
+ if (isOrientationMismatched && !canChangeOrientation && orientationRequested) {
+ // The orientation is mismatched but the display cannot rotate. The bounds will fit
+ // to the short side of container.
+ if (orientation == ORIENTATION_LANDSCAPE) {
+ outBounds.bottom = (int) ((float) dW * dW / dH);
+ outBounds.right = dW;
+ } else {
+ outBounds.bottom = dH;
+ outBounds.right = (int) ((float) dH * dH / dW);
+ }
+ outBounds.offset(getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
+ }
+ outAppBounds.set(outBounds);
+
+ if (isOrientationMismatched) {
+ // One side of container is smaller than the requested size, then it will be scaled
+ // and the final position will be calculated according to the parent container and
+ // scale, so the original size shouldn't be shrunk by insets.
+ final Rect insets = mNonDecorInsets[rotation];
+ outBounds.offset(insets.left, insets.top);
+ outAppBounds.offset(insets.left, insets.top);
+ } else if (rotation != ROTATION_UNDEFINED) {
// Ensure the app bounds won't overlap with insets.
Task.intersectWithInsetsIfFits(outAppBounds, outBounds, mNonDecorInsets[rotation]);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 9df192b7..5196416 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -759,8 +759,7 @@
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
- if (r.getRootTask().checkKeyguardVisibility(r, true /* shouldBeVisible */,
- true /* isTop */) && r.allowMoveToFront()) {
+ if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) {
// We only set the visibility to true if the activity is not being launched in
// background, and is allowed to be visible based on keyguard state. This avoids
// setting this into motion in window manager that is later cancelled due to later
@@ -2298,11 +2297,15 @@
}
/** Ends a batch of visibility updates. */
- void endActivityVisibilityUpdate() {
- mVisibilityTransactionDepth--;
- if (mVisibilityTransactionDepth == 0) {
+ void endActivityVisibilityUpdate(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ if (mVisibilityTransactionDepth == 1) {
getKeyguardController().visibilitiesUpdated();
+ // commit visibility to activities
+ mRootWindowContainer.commitActivitiesVisible(starting, configChanges, preserveWindows,
+ notifyClients);
}
+ mVisibilityTransactionDepth--;
}
/** Returns {@code true} if the caller is on the path to update visibility. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 505233c..2657eb2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -137,6 +137,7 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.AppGlobals;
@@ -253,7 +254,6 @@
import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
import com.android.server.SystemServiceManager;
import com.android.server.UiThread;
import com.android.server.Watchdog;
@@ -2159,14 +2159,14 @@
}
@Override
- public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException {
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getFocusedRootTaskInfo()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
Task focusedStack = getTopDisplayFocusedStack();
if (focusedStack != null) {
- return mRootWindowContainer.getStackInfo(focusedStack.mTaskId);
+ return mRootWindowContainer.getRootTaskInfo(focusedStack.mTaskId);
}
return null;
}
@@ -2894,14 +2894,13 @@
}
}
- // TODO(148895075): deprecate and replace with task equivalents
@Override
- public List<ActivityManager.StackInfo> getAllStackInfos() {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
+ public List<RootTaskInfo> getAllRootTaskInfos() {
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllRootTaskInfos()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- return mRootWindowContainer.getAllStackInfos(INVALID_DISPLAY);
+ return mRootWindowContainer.getAllRootTaskInfos(INVALID_DISPLAY);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2909,26 +2908,12 @@
}
@Override
- public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ public RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) {
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getRootTaskInfo()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- return mRootWindowContainer.getStackInfo(windowingMode, activityType);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- // TODO(148895075): deprecate and replace with task equivalents
- @Override
- public List<ActivityManager.StackInfo> getAllStackInfosOnDisplay(int displayId) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mGlobalLock) {
- return mRootWindowContainer.getAllStackInfos(displayId);
+ return mRootWindowContainer.getRootTaskInfo(windowingMode, activityType);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2936,13 +2921,27 @@
}
@Override
- public ActivityManager.StackInfo getStackInfoOnDisplay(int windowingMode, int activityType,
+ public List<RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId) {
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ "getAllRootTaskInfosOnDisplay()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ return mRootWindowContainer.getAllRootTaskInfos(displayId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public RootTaskInfo getRootTaskInfoOnDisplay(int windowingMode, int activityType,
int displayId) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getRootTaskInfoOnDisplay()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- return mRootWindowContainer.getStackInfo(windowingMode, activityType, displayId);
+ return mRootWindowContainer.getRootTaskInfo(windowingMode, activityType, displayId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -4059,6 +4058,60 @@
&& r.getRootTask().isInTask(r) != null;
}
+ /**
+ * Puts the given activity in picture in picture mode if possible.
+ *
+ * @return true if the activity is now in picture-in-picture mode, or false if it could not
+ * enter picture-in-picture mode.
+ */
+ boolean enterPictureInPictureMode(ActivityRecord r, final PictureInPictureParams params) {
+ // If the activity is already in picture in picture mode, then just return early
+ if (isInPictureInPictureMode(r)) {
+ return true;
+ }
+
+ // Activity supports picture-in-picture, now check that we can enter PiP at this
+ // point, if it is
+ if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
+ false /* beforeStopping */)) {
+ return false;
+ }
+
+ final Runnable enterPipRunnable = () -> {
+ synchronized (mGlobalLock) {
+ if (r.getParent() == null) {
+ Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r);
+ return;
+ }
+ // Only update the saved args from the args that are set
+ r.setPictureInPictureParams(params);
+ final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
+ final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
+ mRootWindowContainer.moveActivityToPinnedStack(
+ r, "enterPictureInPictureMode");
+ final Task stack = r.getRootTask();
+ stack.setPictureInPictureAspectRatio(aspectRatio);
+ stack.setPictureInPictureActions(actions);
+ }
+ };
+
+ if (isKeyguardLocked()) {
+ // If the keyguard is showing or occluded, then try and dismiss it before
+ // entering picture-in-picture (this will prompt the user to authenticate if the
+ // device is currently locked).
+ dismissKeyguard(r.appToken, new KeyguardDismissCallback() {
+ @Override
+ public void onDismissSucceeded() {
+ mH.post(enterPipRunnable);
+ }
+ }, null /* message */);
+ } else {
+ // Enter picture in picture immediately otherwise
+ enterPipRunnable.run();
+ }
+ return true;
+ }
+
@Override
public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
final long origId = Binder.clearCallingIdentity();
@@ -4066,52 +4119,7 @@
synchronized (mGlobalLock) {
final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
"enterPictureInPictureMode", token, params);
-
- // If the activity is already in picture in picture mode, then just return early
- if (isInPictureInPictureMode(r)) {
- return true;
- }
-
- // Activity supports picture-in-picture, now check that we can enter PiP at this
- // point, if it is
- if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
- false /* beforeStopping */)) {
- return false;
- }
-
- final Runnable enterPipRunnable = () -> {
- synchronized (mGlobalLock) {
- if (r.getParent() == null) {
- Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r);
- return;
- }
- // Only update the saved args from the args that are set
- r.setPictureInPictureParams(params);
- final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
- final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
- mRootWindowContainer.moveActivityToPinnedStack(
- r, "enterPictureInPictureMode");
- final Task stack = r.getRootTask();
- stack.setPictureInPictureAspectRatio(aspectRatio);
- stack.setPictureInPictureActions(actions);
- }
- };
-
- if (isKeyguardLocked()) {
- // If the keyguard is showing or occluded, then try and dismiss it before
- // entering picture-in-picture (this will prompt the user to authenticate if the
- // device is currently locked).
- dismissKeyguard(token, new KeyguardDismissCallback() {
- @Override
- public void onDismissSucceeded() {
- mH.post(enterPipRunnable);
- }
- }, null /* message */);
- } else {
- // Enter picture in picture immediately otherwise
- enterPipRunnable.run();
- }
- return true;
+ return enterPictureInPictureMode(r, params);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -4857,6 +4865,11 @@
"Requested PIP on an activity that doesn't support it");
}
+ if (activity.pictureInPictureArgs.isAutoEnterAllowed()) {
+ enterPictureInPictureMode(activity, activity.pictureInPictureArgs);
+ return;
+ }
+
try {
final ClientTransaction transaction = ClientTransaction.obtain(
activity.app.getThread(),
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index aa8069a..4db121b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -28,7 +28,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
@@ -36,20 +35,21 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.GONE;
-import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -367,13 +367,6 @@
final float mCloseToSquareMaxAspectRatio;
/**
- * If this is true, we would not rotate the display for apps. The rotation would be either the
- * sensor rotation or the user rotation, controlled by
- * {@link WindowManagerPolicy.UserRotationMode}.
- */
- private boolean mIgnoreRotationForApps;
-
- /**
* Keep track of wallpaper visibility to notify changes.
*/
private boolean mLastWallpaperVisible = false;
@@ -618,6 +611,12 @@
*/
private boolean mInEnsureActivitiesVisible = false;
+ /**
+ * Last window to be requested focus via {@code SurfaceControl.Transaction#setFocusedWindow} to
+ * prevent duplicate requests to input.
+ */
+ WindowState mLastRequestedFocus = null;
+
private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
WindowStateAnimator winAnimator = w.mWinAnimator;
final ActivityRecord activity = w.mActivityRecord;
@@ -1751,26 +1750,6 @@
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
-
- // Not much of use to rotate the display for apps since it's close to square.
- mIgnoreRotationForApps = isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height);
- }
-
- /** @return {@code true} if the orientation requested from application will be ignored. */
- boolean ignoreRotationForApps() {
- return mIgnoreRotationForApps;
- }
-
- private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) {
- final DisplayCutout displayCutout =
- calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
- final int uiMode = mWmService.mPolicy.getUiMode();
- final int w = mDisplayPolicy.getNonDecorDisplayWidth(
- width, height, rotation, uiMode, displayCutout);
- final int h = mDisplayPolicy.getNonDecorDisplayHeight(
- width, height, rotation, uiMode, displayCutout);
- final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h);
- return aspectRatio <= mCloseToSquareMaxAspectRatio;
}
/**
@@ -2336,10 +2315,6 @@
int getOrientation() {
mLastOrientationSource = null;
- if (mIgnoreRotationForApps) {
- return SCREEN_ORIENTATION_USER;
- }
-
if (mWmService.mDisplayFrozen) {
if (mWmService.mPolicy.isKeyguardLocked()) {
// Use the last orientation the while the display is frozen with the keyguard
@@ -3488,7 +3463,11 @@
return false;
}
return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this)
- || mWmService.mForceDesktopModeOnExternalDisplays;
+ || forceDesktopMode();
+ }
+
+ boolean forceDesktopMode() {
+ return mWmService.mForceDesktopModeOnExternalDisplays && !isDefaultDisplay && !isPrivate();
}
private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) {
@@ -4542,7 +4521,7 @@
boolean supportsSystemDecorations() {
return (mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(this)
|| (mDisplay.getFlags() & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0
- || mWmService.mForceDesktopModeOnExternalDisplays)
+ || forceDesktopMode())
// VR virtual display will be used to run and render 2D app within a VR experience.
&& mDisplayId != mWmService.mVr2dDisplayId
// Do not show system decorations on untrusted virtual display.
@@ -4749,7 +4728,7 @@
}
// Apply restriction if necessary.
- if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
+ if (needsGestureExclusionRestrictions(w, false /* ignoreRequest */)) {
// Processes the region along the left edge.
remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
@@ -4766,7 +4745,7 @@
outExclusion.op(middle, Op.UNION);
middle.recycle();
} else {
- boolean loggable = needsGestureExclusionRestrictions(w, 0 /* lastSysUiVis */);
+ boolean loggable = needsGestureExclusionRestrictions(w, true /* ignoreRequest */);
if (loggable) {
addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
Integer.MAX_VALUE, w, EXCLUSION_LEFT);
@@ -4788,17 +4767,21 @@
}
/**
- * @return Whether gesture exclusion area should be restricted from the window depending on the
- * current SystemUI visibility flags.
+ * Returns whether gesture exclusion area should be restricted from the window depending on the
+ * window/activity types and the requested navigation bar visibility and the behavior.
+ *
+ * @param win The target window.
+ * @param ignoreRequest If this is {@code true}, only the window/activity types are considered.
+ * @return {@code true} if the gesture exclusion restrictions are needed.
*/
- private static boolean needsGestureExclusionRestrictions(WindowState win, int sysUiVisibility) {
+ private static boolean needsGestureExclusionRestrictions(WindowState win,
+ boolean ignoreRequest) {
final int type = win.mAttrs.type;
- final int stickyHideNavFlags =
- SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
final boolean stickyHideNav =
- (sysUiVisibility & stickyHideNavFlags) == stickyHideNavFlags;
- return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_NOTIFICATION_SHADE
- && win.getActivityType() != ACTIVITY_TYPE_HOME;
+ !win.getRequestedInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR)
+ && win.mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+ return (!stickyHideNav || ignoreRequest) && type != TYPE_INPUT_METHOD
+ && type != TYPE_NOTIFICATION_SHADE && win.getActivityType() != ACTIVITY_TYPE_HOME;
}
/**
@@ -4814,7 +4797,7 @@
&& type != TYPE_APPLICATION_STARTING
&& type != TYPE_NAVIGATION_BAR
&& (attrs.flags & FLAG_NOT_TOUCHABLE) == 0
- && needsGestureExclusionRestrictions(win, 0 /* sysUiVisibility */)
+ && needsGestureExclusionRestrictions(win, true /* ignoreRequest */)
&& win.getDisplayContent().mDisplayPolicy.hasSideGestures();
}
@@ -5289,6 +5272,14 @@
mSingleTaskInstance = true;
}
+ /**
+ * Check if the display has {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
+ */
+ boolean canShowWithInsecureKeyguard() {
+ final int flags = mDisplay.getFlags();
+ return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
+ }
+
/** Returns true if the display can only contain one task */
boolean isSingleTaskInstance() {
return mSingleTaskInstance;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index abfbf2e..779f6b2 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -29,6 +29,7 @@
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
+import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
@@ -63,6 +64,7 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
@@ -898,10 +900,6 @@
(int) attrs.hideTimeoutMilliseconds,
AccessibilityManager.FLAG_CONTENT_TEXT);
attrs.windowAnimations = com.android.internal.R.style.Animation_Toast;
- // Toast can show with below conditions when the screen is locked.
- if (canToastShowWhenLocked(callingPid)) {
- attrs.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
- }
// Toasts can't be clickable
attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
break;
@@ -932,16 +930,6 @@
}
/**
- * @return {@code true} if the calling activity initiate toast and is visible with
- * {@link WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} flag.
- */
- boolean canToastShowWhenLocked(int callingPid) {
- return mDisplayContent.forAllWindows(w -> {
- return callingPid == w.mSession.mPid && w.isVisible() && w.canShowWhenLocked();
- }, true /* traverseTopToBottom */);
- }
-
- /**
* Check if a window can be added to the system.
*
* Currently enforces that two window types are singletons per display:
@@ -1526,7 +1514,7 @@
if (mInputConsumer == null) {
return;
}
- showNavigationBar();
+ showSystemBars();
// Any user activity always causes us to show the
// navigation controls, if they had been hidden.
// We also clear the low profile and only content
@@ -1561,13 +1549,13 @@
}
}
- private void showNavigationBar() {
+ private void showSystemBars() {
final InsetsSourceProvider provider = mDisplayContent.getInsetsStateController()
.peekSourceProvider(ITYPE_NAVIGATION_BAR);
final InsetsControlTarget target =
provider != null ? provider.getControlTarget() : null;
if (target != null) {
- target.showInsets(Type.navigationBars(), false /* fromIme */);
+ target.showInsets(Type.systemBars(), false /* fromIme */);
}
}
}
@@ -2055,6 +2043,7 @@
final int type = attrs.type;
final int fl = PolicyControl.getWindowFlags(win, attrs);
+ final int pfl = attrs.privateFlags;
final int sim = attrs.softInputMode;
displayFrames = win.getDisplayFrames(displayFrames);
@@ -2102,6 +2091,13 @@
df.set(dfu.left + left, dfu.top + top, dfu.right - right, dfu.bottom - bottom);
if (attached == null) {
pf.set(df);
+ if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) {
+ final InsetsSource source = mDisplayContent.getInsetsPolicy()
+ .getInsetsForDispatch(win).peekSource(ITYPE_IME);
+ if (source != null) {
+ pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */));
+ }
+ }
vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING
? displayFrames.mCurrent : displayFrames.mDock);
} else {
@@ -2118,8 +2114,8 @@
if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
final boolean attachedInParent = attached != null && !layoutInScreen;
final InsetsState requestedInsetsState = win.getRequestedInsetsState();
- final boolean requestedFullscreen =
- !requestedInsetsState.getSourceOrDefaultVisibility(ITYPE_STATUS_BAR);
+ final boolean requestedFullscreen = (fl & FLAG_FULLSCREEN) != 0
+ || !requestedInsetsState.getSourceOrDefaultVisibility(ITYPE_STATUS_BAR);
final boolean requestedHideNavigation =
!requestedInsetsState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 0206787..0f43e49 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -330,10 +330,8 @@
// It's also not likely to rotate a TV screen.
final boolean isTv = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_LEANBACK);
- final boolean forceDesktopMode =
- mService.mForceDesktopModeOnExternalDisplays && !isDefaultDisplay;
mDefaultFixedToUserRotation =
- (isCar || isTv || mService.mIsPc || forceDesktopMode)
+ (isCar || isTv || mService.mIsPc || mDisplayContent.forceDesktopMode())
// For debug purposes the next line turns this feature off with:
// $ adb shell setprop config.override_forced_orient true
// $ adb shell wm size reset
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index df7c070..c8c83a6 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -248,7 +248,7 @@
writeSettingsIfNeeded(entry, displayInfo);
}
- private int getWindowingModeLocked(Entry entry, int displayId) {
+ private int getWindowingModeLocked(Entry entry, DisplayContent dc) {
int windowingMode = entry != null ? entry.mWindowingMode
: WindowConfiguration.WINDOWING_MODE_UNDEFINED;
// This display used to be in freeform, but we don't support freeform anymore, so fall
@@ -259,10 +259,8 @@
}
// No record is present so use default windowing mode policy.
if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- final boolean forceDesktopMode = mService.mForceDesktopModeOnExternalDisplays
- && displayId != Display.DEFAULT_DISPLAY;
windowingMode = mService.mAtmService.mSupportsFreeformWindowManagement
- && (mService.mIsPc || forceDesktopMode)
+ && (mService.mIsPc || dc.forceDesktopMode())
? WindowConfiguration.WINDOWING_MODE_FREEFORM
: WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
}
@@ -272,7 +270,7 @@
int getWindowingModeLocked(DisplayContent dc) {
final DisplayInfo displayInfo = dc.getDisplayInfo();
final Entry entry = getEntry(displayInfo);
- return getWindowingModeLocked(entry, dc.getDisplayId());
+ return getWindowingModeLocked(entry, dc);
}
void setWindowingModeLocked(DisplayContent dc, int mode) {
@@ -382,7 +380,7 @@
final Entry entry = getOrCreateEntry(displayInfo);
// Setting windowing mode first, because it may override overscan values later.
- dc.setWindowingMode(getWindowingModeLocked(entry, dc.getDisplayId()));
+ dc.setWindowingMode(getWindowingModeLocked(entry, dc));
dc.getDisplayRotation().restoreSettings(entry.mUserRotationMode,
entry.mUserRotation, entry.mFixedToUserRotation);
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index c9f463b..6e32d0e 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -308,7 +308,7 @@
}
void tearDown() {
- mService.mInputManager.unregisterInputChannel(mServerChannel);
+ mService.mInputManager.unregisterInputChannel(mServerChannel.getToken());
mInputEventReceiver.dispose();
mInputEventReceiver = null;
mClientChannel.dispose();
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 5a24847..8d20bb8 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -192,7 +192,7 @@
void onRemoved() {
if (mInputChannel != null) {
- mWmService.mInputManager.unregisterInputChannel(mInputChannel);
+ mWmService.mInputManager.unregisterInputChannel(mInputChannel.getToken());
mInputChannel.dispose();
mInputChannel = null;
}
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index e2c0749..251c014 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -22,12 +22,9 @@
import android.annotation.Nullable;
import android.util.Slog;
-import com.android.internal.util.function.pooled.PooledConsumer;
-import com.android.internal.util.function.pooled.PooledLambda;
-
/** Helper class to ensure activities are in the right visible state for a container. */
class EnsureActivitiesVisibleHelper {
- private final Task mContiner;
+ private final Task mTask;
private ActivityRecord mTop;
private ActivityRecord mStarting;
private boolean mAboveTop;
@@ -38,11 +35,11 @@
private boolean mNotifyClients;
EnsureActivitiesVisibleHelper(Task container) {
- mContiner = container;
+ mTask = container;
}
/**
- * Update all attributes except {@link mContiner} to use in subsequent calculations.
+ * Update all attributes except {@link mTask} to use in subsequent calculations.
*
* @param starting The activity that is being started
* @param configChanges Parts of the configuration that changed for this activity for evaluating
@@ -54,11 +51,11 @@
void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
boolean notifyClients) {
mStarting = starting;
- mTop = mContiner.topRunningActivity();
+ mTop = mTask.topRunningActivity();
// If the top activity is not fullscreen, then we need to make sure any activities under it
// are now visible.
mAboveTop = mTop != null;
- mContainerShouldBeVisible = mContiner.shouldBeVisible(mStarting);
+ mContainerShouldBeVisible = mTask.shouldBeVisible(mStarting);
mBehindFullscreenActivity = !mContainerShouldBeVisible;
mConfigChanges = configChanges;
mPreserveWindows = preserveWindows;
@@ -66,7 +63,26 @@
}
/**
- * Ensure visibility with an option to also update the configuration of visible activities.
+ * Update visibility to activities.
+ * @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
+ * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
+ * @param starting The top most activity in the task.
+ * The activity is either starting or resuming.
+ * Caller should ensure starting activity is visible.
+ *
+ */
+ void processUpdate(@Nullable ActivityRecord starting) {
+ reset(starting, 0 /* configChanges */, false /* preserveWindows */,
+ false /* notifyClients */);
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible processUpdate behind " + mTop);
+ }
+
+ mTask.forAllActivities(this::updateActivityVisibility);
+ }
+
+ /**
+ * Commit visibility with an option to also update the configuration of visible activities.
* @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
* @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
* @param starting The top most activity in the task.
@@ -79,54 +95,84 @@
* @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
* be sent to the clients.
*/
- void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
- boolean notifyClients) {
+ void processCommit(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
reset(starting, configChanges, preserveWindows, notifyClients);
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
- + " configChanges=0x" + Integer.toHexString(configChanges));
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible processCommit behind " + mTop);
+ }
if (mTop != null) {
- mContiner.checkTranslucentActivityWaiting(mTop);
+ mTask.checkTranslucentActivityWaiting(mTop);
}
// We should not resume activities that being launched behind because these
// activities are actually behind other fullscreen activities, but still required
// to be visible (such as performing Recents animation).
final boolean resumeTopActivity = mTop != null && !mTop.mLaunchTaskBehind
- && mContiner.isTopActivityFocusable()
- && (starting == null || !starting.isDescendantOf(mContiner));
+ && mTask.isTopActivityFocusable()
+ && (starting == null || !starting.isDescendantOf(mTask));
- final PooledConsumer f = PooledLambda.obtainConsumer(
- EnsureActivitiesVisibleHelper::setActivityVisibilityState, this,
- PooledLambda.__(ActivityRecord.class), starting, resumeTopActivity);
- mContiner.forAllActivities(f);
- f.recycle();
+ mTask.forAllActivities(a -> {
+ commitActivityVisibility(a, starting, resumeTopActivity);
+ });
}
- private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
- final boolean resumeTopActivity) {
- final boolean isTop = r == mTop;
+ private boolean isAboveTop(boolean isTop) {
if (mAboveTop && !isTop) {
- return;
+ return true;
}
mAboveTop = false;
+ return false;
+ }
- final boolean reallyVisible = r.shouldBeVisible(
- mBehindFullscreenActivity, false /* ignoringKeyguard */);
+ private void updateActivityVisibility(ActivityRecord r) {
+ final boolean isTop = r == mTop;
+ if (isAboveTop(isTop)) {
+ return;
+ }
+
+ r.updateVisibility(mBehindFullscreenActivity);
// Check whether activity should be visible without Keyguard influence
if (r.visibleIgnoringKeyguard) {
if (r.occludesParent()) {
// At this point, nothing else needs to be shown in this task.
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
- + " stackVisible=" + mContainerShouldBeVisible
- + " behindFullscreen=" + mBehindFullscreenActivity);
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
+ + " stackVisible=" + mContainerShouldBeVisible
+ + " behindFullscreen=" + mBehindFullscreenActivity);
+ }
mBehindFullscreenActivity = true;
} else {
mBehindFullscreenActivity = false;
}
}
+ if (!mBehindFullscreenActivity && mTask.isActivityTypeHome() && r.isRootOfTask()) {
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "Home task: at " + mTask
+ + " stackShouldBeVisible=" + mContainerShouldBeVisible
+ + " behindFullscreenActivity=" + mBehindFullscreenActivity);
+ }
+ // No other task in the home stack should be visible behind the home activity.
+ // Home activities is usually a translucent activity with the wallpaper behind
+ // them. However, when they don't have the wallpaper behind them, we want to
+ // show activities in the next application stack behind them vs. another
+ // task in the home stack like recents.
+ mBehindFullscreenActivity = true;
+ }
+ }
+
+ private void commitActivityVisibility(ActivityRecord r, ActivityRecord starting,
+ final boolean resumeTopActivity) {
+ final boolean isTop = r == mTop;
+ if (isAboveTop(isTop)) {
+ return;
+ }
+
+ final boolean reallyVisible = r.shouldBeVisibleUnchecked();
+
if (reallyVisible) {
if (r.finishing) {
return;
@@ -170,20 +216,6 @@
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
r.makeInvisible();
}
-
- final int windowingMode = mContiner.getWindowingMode();
- if (!mBehindFullscreenActivity && mContiner.isActivityTypeHome()
- && r.isRootOfTask()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + mContiner
- + " stackShouldBeVisible=" + mContainerShouldBeVisible
- + " behindFullscreenActivity=" + mBehindFullscreenActivity);
- // No other task in the home stack should be visible behind the home activity.
- // Home activities is usually a translucent activity with the wallpaper behind
- // them. However, when they don't have the wallpaper behind them, we want to
- // show activities in the next application stack behind them vs. another
- // task in the home stack like recents.
- mBehindFullscreenActivity = true;
- }
}
private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
@@ -207,7 +239,7 @@
r.setVisibility(true);
}
if (r != starting) {
- mContiner.mStackSupervisor.startSpecificActivity(r, andResume, true /* checkConfig */);
+ mTask.mStackSupervisor.startSpecificActivity(r, andResume, true /* checkConfig */);
}
}
}
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index a79d3bb..1d1a266 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -156,7 +156,7 @@
}
void disposeChannelsLw(SurfaceControl.Transaction t) {
- mService.mInputManager.unregisterInputChannel(mServerChannel);
+ mService.mInputManager.unregisterInputChannel(mServerChannel.getToken());
mClientChannel.dispose();
mServerChannel.dispose();
t.remove(mInputSurface);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 4efd687..714591a 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
@@ -275,7 +276,7 @@
void populateInputWindowHandle(final InputWindowHandle inputWindowHandle,
final WindowState child, int flags, final int type, final boolean isVisible,
- final boolean hasFocus, final boolean hasWallpaper) {
+ final boolean focusable, final boolean hasWallpaper) {
// Add a window to our list of input windows.
inputWindowHandle.name = child.toString();
flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags);
@@ -283,7 +284,7 @@
inputWindowHandle.layoutParamsType = type;
inputWindowHandle.dispatchingTimeoutMillis = child.getInputDispatchingTimeoutMillis();
inputWindowHandle.visible = isVisible;
- inputWindowHandle.focusable = hasFocus;
+ inputWindowHandle.focusable = focusable;
inputWindowHandle.hasWallpaper = hasWallpaper;
inputWindowHandle.paused = child.mActivityRecord != null ? child.mActivityRecord.paused : false;
inputWindowHandle.ownerPid = child.mSession.mPid;
@@ -308,10 +309,13 @@
* This means we need to make sure that these changes in crop are reflected
* in the input windows, and so ensure this flag is set so that
* the input crop always reflects the surface hierarchy.
- * we may have some issues with modal-windows, but I guess we can
- * cross that bridge when we come to implementing full-screen TaskOrg
+ *
+ * TODO(b/168252846): we have some issues with modal-windows, so we need to
+ * cross that bridge now that we organize full-screen Tasks.
*/
- if (child.getTask() != null && child.getTask().isOrganized()) {
+ if (child.getTask() != null
+ && child.getTask().isOrganized()
+ && child.getTask().getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
inputWindowHandle.replaceTouchableRegionWithCrop(null /* Use this surfaces crop */);
}
@@ -472,8 +476,9 @@
resetInputConsumers(mInputTransaction);
- mDisplayContent.forAllWindows(this,
- true /* traverseTopToBottom */);
+ mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */);
+
+ updateInputFocusRequest();
if (!mUpdateInputWindowsImmediately) {
mDisplayContent.getPendingTransaction().merge(mInputTransaction);
@@ -483,6 +488,29 @@
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
+ private void updateInputFocusRequest() {
+ if (mDisplayContent.mLastRequestedFocus == mDisplayContent.mCurrentFocus) {
+ return;
+ }
+
+ final WindowState focus = mDisplayContent.mCurrentFocus;
+ if (focus == null || focus.mInputWindowHandle.token == null) {
+ mDisplayContent.mLastRequestedFocus = focus;
+ return;
+ }
+
+ if (!focus.mWinAnimator.hasSurface()) {
+ ProtoLog.d(WM_DEBUG_FOCUS_LIGHT,
+ "Focus not requested for window=%s because it has no surface",
+ focus);
+ return;
+ }
+
+ mInputTransaction.setFocusedWindow(focus.mInputWindowHandle.token, mDisplayId);
+ mDisplayContent.mLastRequestedFocus = focus;
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Focus requested for window=%s", focus);
+ }
+
@Override
public void accept(WindowState w) {
final InputChannel inputChannel = w.mInputChannel;
@@ -510,11 +538,12 @@
final int flags = w.mAttrs.flags;
final int privateFlags = w.mAttrs.privateFlags;
- final boolean hasFocus = w.isFocused();
+ final boolean focusable = w.canReceiveKeys()
+ && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
if (recentsAnimationController.updateInputConsumerForApp(
- mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) {
+ mRecentsAnimationInputConsumer.mWindowHandle, focusable)) {
mRecentsAnimationInputConsumer.show(mInputTransaction, w);
mAddRecentsAnimationInputConsumerHandle = false;
}
@@ -559,7 +588,7 @@
}
populateInputWindowHandle(
- inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper);
+ inputWindowHandle, w, flags, type, isVisible, focusable, hasWallpaper);
// register key interception info
mService.mKeyInterceptionInfoForToken.put(inputWindowHandle.token,
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index ab1074e..5520ad3 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -286,6 +286,7 @@
}
if (changed) {
notifyInsetsChanged();
+ mDisplayContent.updateSystemGestureExclusion();
mDisplayContent.getDisplayPolicy().updateSystemUiVisibilityLw();
}
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 69e8c57..bad28ba 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -278,6 +278,27 @@
}
/**
+ * Checks whether {@param r} should be visible depending on Keyguard state.
+ *
+ * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
+ */
+ boolean checkKeyguardVisibility(ActivityRecord r) {
+ if (r.mDisplayContent.canShowWithInsecureKeyguard() && canDismissKeyguard()) {
+ return true;
+ }
+
+ if (isKeyguardOrAodShowing(r.mDisplayContent.getDisplayId())) {
+ // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
+ // right away and AOD isn't visible.
+ return canShowActivityWhileKeyguardShowing(r, r.containsDismissKeyguardWindow());
+ } else if (isKeyguardLocked()) {
+ return canShowWhileOccluded(r.containsDismissKeyguardWindow(), r.canShowWhenLocked());
+ } else {
+ return true;
+ }
+ }
+
+ /**
* Makes sure to update lockscreen occluded/dismiss state if needed after completing all
* visibility updates ({@link ActivityStackSupervisor#endActivityVisibilityUpdate}).
*/
@@ -442,6 +463,7 @@
private final int mDisplayId;
private boolean mOccluded;
private ActivityRecord mDismissingKeyguardActivity;
+ private ActivityRecord mTopTurnScreenOnActivity;
private boolean mRequestDismissKeyguard;
private final ActivityTaskManagerService mService;
private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
@@ -455,30 +477,38 @@
void onRemoved() {
mDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
mSleepTokenAcquirer.release(mDisplayId);
}
void visibilitiesUpdated(KeyguardController controller, DisplayContent display) {
final boolean lastOccluded = mOccluded;
final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity;
+ final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;
mRequestDismissKeyguard = false;
mOccluded = false;
mDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
+ // only top + focusable + visible task can control occluding.
final Task stack = getStackForControllingOccluding(display);
if (stack != null) {
final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
+ final ActivityRecord topTurnScreenOn = stack.getTopTurnScreenOnActivity();
mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null
&& stack.topRunningActivity() == topDismissing
&& controller.canShowWhileOccluded(
true /* dismissKeyguard */,
false /* showWhenLocked */));
- if (stack.getTopDismissingKeyguardActivity() != null) {
- mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity();
+ if (topDismissing != null) {
+ mDismissingKeyguardActivity = topDismissing;
+ }
+ if (topTurnScreenOn != null) {
+ mTopTurnScreenOnActivity = topTurnScreenOn;
}
// FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display.
- if (mDisplayId != DEFAULT_DISPLAY) {
- mOccluded |= stack.canShowWithInsecureKeyguard()
+ if (mDisplayId != DEFAULT_DISPLAY && stack.mDisplayContent != null) {
+ mOccluded |= stack.mDisplayContent.canShowWithInsecureKeyguard()
&& controller.canDismissKeyguard();
}
}
@@ -488,14 +518,20 @@
.getDisplayPolicy().isShowingDreamLw();
}
- if (lastOccluded != mOccluded) {
- controller.handleOccludedChanged(mDisplayId);
- }
- if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
+ mRequestDismissKeyguard = lastDismissActivity != mDismissingKeyguardActivity
+ && !mOccluded
&& mDismissingKeyguardActivity != null
&& controller.mWindowManager.isKeyguardSecure(
- controller.mService.getCurrentUserId())) {
- mRequestDismissKeyguard = true;
+ controller.mService.getCurrentUserId());
+
+ if (mTopTurnScreenOnActivity != null
+ && mTopTurnScreenOnActivity != lastTurnScreenOnActivity
+ && !mService.mWindowManager.mPowerManager.isInteractive()) {
+ controller.mStackSupervisor.wakeUp("handleTurnScreenOn");
+ }
+
+ if (lastOccluded != mOccluded) {
+ controller.handleOccludedChanged(mDisplayId);
}
}
@@ -525,6 +561,8 @@
sb.append(" Occluded=").append(mOccluded)
.append(" DismissingKeyguardActivity=")
.append(mDismissingKeyguardActivity)
+ .append(" TurnScreenOnActivity=")
+ .append(mTopTurnScreenOnActivity)
.append(" at display=")
.append(mDisplayId);
pw.println(sb.toString());
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index dccd3a6..4fe678d 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -239,7 +239,7 @@
}
void dispose() {
- mWmService.mInputManager.unregisterInputChannel(mServerChannel);
+ mWmService.mInputManager.unregisterInputChannel(mServerChannel.getToken());
mInputEventReceiver.dispose();
mServerChannel.dispose();
mClientChannel.dispose();
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 4be4c89..1077736 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -11,3 +11,4 @@
riddlehsu@google.com
louischang@google.com
winsonc@google.com
+tigerhuang@google.com
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 6882dc4..b50cb4c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -814,14 +814,14 @@
}
boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle,
- boolean hasFocus) {
+ boolean focusable) {
// Update the input consumer touchable region to match the target app main window
final WindowState targetAppMainWindow = mTargetActivityRecord != null
? mTargetActivityRecord.findMainWindow()
: null;
if (targetAppMainWindow != null) {
targetAppMainWindow.getBounds(mTmpRect);
- inputWindowHandle.focusable = hasFocus;
+ inputWindowHandle.focusable = focusable;
inputWindowHandle.touchableRegion.set(mTmpRect);
return true;
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 6539e13..d149db6 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -99,6 +99,7 @@
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AppGlobals;
import android.app.WindowConfiguration;
import android.content.ComponentName;
@@ -1982,10 +1983,22 @@
notifyClients);
}
} finally {
- mStackSupervisor.endActivityVisibilityUpdate();
+ mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges, preserveWindows,
+ notifyClients);
}
}
+ void commitActivitiesVisible(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ forAllTaskDisplayAreas(taskDisplayArea -> {
+ for (int stackNdx = taskDisplayArea.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final Task task = taskDisplayArea.getStackAt(stackNdx);
+ task.commitActivitiesVisible(starting, configChanges, preserveWindows,
+ notifyClients);
+ }
+ });
+ }
+
boolean switchUser(int userId, UserState uss) {
final Task topFocusedStack = getTopDisplayFocusedStack();
final int focusStackId = topFocusedStack != null
@@ -2201,7 +2214,22 @@
ensureActivitiesVisible(null, 0, false /* preserveWindows */);
resumeFocusedStacksTopActivities();
- mService.getTaskChangeNotificationController().notifyActivityPinned(r);
+ notifyActivityPipModeChanged(r);
+ }
+
+ /**
+ * Notifies when an activity enters or leaves PIP mode.
+ * @param r indicates the activity currently in PIP, can be null to indicate no activity is
+ * currently in PIP mode.
+ */
+ void notifyActivityPipModeChanged(@Nullable ActivityRecord r) {
+ final boolean inPip = r != null;
+ if (inPip) {
+ mService.getTaskChangeNotificationController().notifyActivityPinned(r);
+ } else {
+ mService.getTaskChangeNotificationController().notifyActivityUnpinned();
+ }
+ mWindowManager.mPolicy.setPipVisibilityLw(inPip);
}
void executeAppTransitionForAllDisplay() {
@@ -2423,77 +2451,73 @@
return display.getStack(windowingMode, activityType);
}
- private ActivityManager.StackInfo getStackInfo(Task stack) {
- final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
- ActivityManager.StackInfo info = new ActivityManager.StackInfo();
- stack.getBounds(info.bounds);
- info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY;
- info.stackId = stack.mTaskId;
- info.stackToken = stack.mRemoteToken.toWindowContainerToken();
- info.userId = stack.mCurrentUser;
- info.visible = stack.shouldBeVisible(null);
- // A stack might be not attached to a display.
- // TODO: Can be removed since no one is using it.
- info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(stack) : 0;
- info.configuration.setTo(stack.getConfiguration());
+ private RootTaskInfo getRootTaskInfo(Task task) {
+ final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
+ RootTaskInfo info = new RootTaskInfo();
+ task.fillTaskInfo(info);
- final int numTasks = stack.getDescendantTaskCount();
- info.taskIds = new int[numTasks];
- info.taskNames = new String[numTasks];
- info.taskBounds = new Rect[numTasks];
- info.taskUserIds = new int[numTasks];
+ // A task might be not attached to a display.
+ info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(task) : 0;
+ info.visible = task.shouldBeVisible(null);
+ task.getBounds(info.bounds);
+
+ final int numTasks = task.getDescendantTaskCount();
+ info.childTaskIds = new int[numTasks];
+ info.childTaskNames = new String[numTasks];
+ info.childTaskBounds = new Rect[numTasks];
+ info.childTaskUserIds = new int[numTasks];
final int[] currentIndex = {0};
final PooledConsumer c = PooledLambda.obtainConsumer(
- RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
+ RootWindowContainer::processTaskForTaskInfo, PooledLambda.__(Task.class), info,
currentIndex);
- stack.forAllLeafTasks(c, false /* traverseTopToBottom */);
+ task.forAllLeafTasks(c, false /* traverseTopToBottom */);
c.recycle();
- final ActivityRecord top = stack.topRunningActivity();
+ final ActivityRecord top = task.topRunningActivity();
info.topActivity = top != null ? top.intent.getComponent() : null;
return info;
}
- private static void processTaskForStackInfo(
- Task task, ActivityManager.StackInfo info, int[] currentIndex) {
+ private static void processTaskForTaskInfo(
+ Task task, RootTaskInfo info, int[] currentIndex) {
int i = currentIndex[0];
- info.taskIds[i] = task.mTaskId;
- info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
+ info.childTaskIds[i] = task.mTaskId;
+ info.childTaskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
: task.realActivity != null ? task.realActivity.flattenToString()
: task.getTopNonFinishingActivity() != null
? task.getTopNonFinishingActivity().packageName : "unknown";
- info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
- info.taskUserIds[i] = task.mUserId;
+ info.childTaskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
+ info.childTaskUserIds[i] = task.mUserId;
currentIndex[0] = ++i;
}
- ActivityManager.StackInfo getStackInfo(int stackId) {
- Task stack = getStack(stackId);
- if (stack != null) {
- return getStackInfo(stack);
+ RootTaskInfo getRootTaskInfo(int taskId) {
+ Task task = getStack(taskId);
+ if (task != null) {
+ return getRootTaskInfo(task);
}
return null;
}
- ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
+ RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) {
final Task stack = getStack(windowingMode, activityType);
- return (stack != null) ? getStackInfo(stack) : null;
+ return (stack != null) ? getRootTaskInfo(stack) : null;
}
- ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) {
+ RootTaskInfo getRootTaskInfo(int windowingMode, int activityType, int displayId) {
final Task stack = getStack(windowingMode, activityType, displayId);
- return (stack != null) ? getStackInfo(stack) : null;
+ return (stack != null) ? getRootTaskInfo(stack) : null;
}
- /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */
- ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) {
- ArrayList<ActivityManager.StackInfo> list = new ArrayList<>();
+ /** If displayId == INVALID_DISPLAY, this will get root task infos on all displays */
+ ArrayList<RootTaskInfo> getAllRootTaskInfos(int displayId) {
+ ArrayList<RootTaskInfo> list = new ArrayList<>();
if (displayId == INVALID_DISPLAY) {
forAllTaskDisplayAreas(taskDisplayArea -> {
for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
final Task stack = taskDisplayArea.getStackAt(sNdx);
- list.add(getStackInfo(stack));
+ list.add(getRootTaskInfo(stack));
}
});
return list;
@@ -2505,7 +2529,7 @@
display.forAllTaskDisplayAreas(taskDisplayArea -> {
for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
final Task stack = taskDisplayArea.getStackAt(sNdx);
- list.add(getStackInfo(stack));
+ list.add(getRootTaskInfo(stack));
}
});
return list;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 3b32a9d76..3d6d7b7 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -56,6 +56,7 @@
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
+import android.window.ClientWindowFrames;
import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.protolog.common.ProtoLog;
@@ -201,9 +202,7 @@
@Override
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
- Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
- Rect outStableInsets, Rect outBackdropFrame,
- DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
+ ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
SurfaceControl outBLASTSurfaceControl) {
@@ -212,10 +211,8 @@
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
- outFrame, outContentInsets, outVisibleInsets,
- outStableInsets, outBackdropFrame, cutout,
- mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls,
- outSurfaceSize, outBLASTSurfaceControl);
+ outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
+ outActiveControls, outSurfaceSize, outBLASTSurfaceControl);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
@@ -240,11 +237,6 @@
}
@Override
- public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
- mService.getWindowDisplayFrame(this, window, outDisplayFrame);
- }
-
- @Override
public void finishDrawing(IWindow window,
@Nullable SurfaceControl.Transaction postDrawTransaction) {
if (DEBUG) Slog.v(TAG_WM, "IWindow finishDrawing called for " + window);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 70fd860..15a44e8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -61,7 +61,6 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.SurfaceControl.METADATA_TASK_ID;
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
@@ -197,7 +196,6 @@
import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
-import android.view.Display;
import android.view.DisplayInfo;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
@@ -600,6 +598,7 @@
private boolean mTopActivityOccludesKeyguard;
private ActivityRecord mTopDismissingKeyguardActivity;
+ private ActivityRecord mTopTurnScreenOnActivity;
private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1;
@@ -1394,7 +1393,8 @@
}
if (display != null) {
- // TODO(NOW!): Chat with the erosky@ of this code to see if this really makes sense here...
+ // TODO(b/168037178): Chat with the erosky@ of this code to see if this really makes
+ // sense here...
// Rotations are relative to the display. This means if there are 2 displays rotated
// differently (eg. 2 monitors with one landscape and one portrait), moving a stack
// from one to the other could look like a rotation change. To prevent this
@@ -1408,11 +1408,16 @@
super.onParentChanged(newParent, oldParent);
- // TODO(NOW): The check for null display content and setting it to null doesn't really
- // make sense here...
+ // Call this again after super onParentChanged in-case the surface wasn't created yet
+ // (happens when the task is first inserted into the hierarchy). It's a no-op if it
+ // already ran fully within super.onParentChanged
+ updateTaskOrganizerState(false /* forceUpdate */);
- // TODO(stack-merge): This is mostly taking care of the case where the stask is removing from
- // the display, so we should probably consolidate it there instead.
+ // TODO(b/168037178): The check for null display content and setting it to null doesn't
+ // really make sense here...
+
+ // TODO(b/168037178): This is mostly taking care of the case where the stask is removing
+ // from the display, so we should probably consolidate it there instead.
if (getParent() == null && mDisplayContent != null) {
EventLogTags.writeWmStackRemoved(getRootTaskId());
@@ -1434,7 +1439,7 @@
&& (newParent == null || !newParent.inPinnedWindowingMode())) {
// Notify if a task from the pinned stack is being removed
// (or moved depending on the mode).
- mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned();
+ mRootWindowContainer.notifyActivityPipModeChanged(null);
}
}
@@ -4019,7 +4024,7 @@
*/
void fillTaskInfo(TaskInfo info, boolean stripExtras) {
getNumRunningActivities(mReuseActivitiesReport);
- info.userId = mUserId;
+ info.userId = isLeafTask() ? mUserId : mCurrentUser;
info.stackId = getRootTaskId();
info.taskId = mTaskId;
info.displayId = getDisplayId();
@@ -4850,6 +4855,11 @@
* @return {@code true} if task organizer changed.
*/
boolean updateTaskOrganizerState(boolean forceUpdate) {
+ if (getSurfaceControl() == null) {
+ // Can't call onTaskAppeared without a surfacecontrol, so defer this until after one
+ // is created.
+ return false;
+ }
if (!isRootTask()) {
return setTaskOrganizer(null);
}
@@ -5102,10 +5112,11 @@
: WINDOWING_MODE_FULLSCREEN;
}
if (currentMode == WINDOWING_MODE_PINNED) {
- mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned();
+ mRootWindowContainer.notifyActivityPipModeChanged(null);
}
if (likelyResolvedMode == WINDOWING_MODE_PINNED
&& taskDisplayArea.getRootPinnedTask() != null) {
+
// Can only have 1 pip at a time, so replace an existing pip
taskDisplayArea.getRootPinnedTask().dismissPip();
}
@@ -5428,6 +5439,7 @@
mAtmService.updateCpuStats();
boolean pauseImmediately = false;
+ boolean shouldAutoPip = false;
if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) {
// If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous
// activity to be paused, while at the same time resuming the new resume activity
@@ -5435,26 +5447,39 @@
// activities a chance to enter Pip before resuming the next activity.
final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState(
"shouldResumeWhilePausing", userLeaving);
- if (!lastResumedCanPip) {
+ if (lastResumedCanPip && prev.pictureInPictureArgs.isAutoEnterAllowed()) {
+ shouldAutoPip = true;
+ } else if (!lastResumedCanPip) {
pauseImmediately = true;
+ } else {
+ // The previous activity may still enter PIP even though it did not allow auto-PIP.
}
}
+ boolean didAutoPip = false;
if (prev.attachedToProcess()) {
- if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
- try {
- EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
- prev.shortComponentName, "userLeaving=" + userLeaving);
-
- mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
- prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
- prev.configChangeFlags, pauseImmediately));
- } catch (Exception e) {
- // Ignore exception, if process died other code will cleanup.
- Slog.w(TAG, "Exception thrown during pause", e);
+ if (shouldAutoPip) {
+ if (DEBUG_PAUSE) {
+ Slog.d(TAG_PAUSE, "Auto-PIP allowed, entering PIP mode directly: " + prev);
+ }
+ didAutoPip = mAtmService.enterPictureInPictureMode(prev, prev.pictureInPictureArgs);
mPausingActivity = null;
- mLastPausedActivity = null;
- mLastNoHistoryActivity = null;
+ } else {
+ if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
+ try {
+ EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
+ prev.shortComponentName, "userLeaving=" + userLeaving);
+
+ mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
+ prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
+ prev.configChangeFlags, pauseImmediately));
+ } catch (Exception e) {
+ // Ignore exception, if process died other code will cleanup.
+ Slog.w(TAG, "Exception thrown during pause", e);
+ mPausingActivity = null;
+ mLastPausedActivity = null;
+ mLastNoHistoryActivity = null;
+ }
}
} else {
mPausingActivity = null;
@@ -5468,6 +5493,11 @@
mStackSupervisor.acquireLaunchWakelock();
}
+ if (didAutoPip) {
+ // Already entered PIP mode, no need to keep pausing.
+ return true;
+ }
+
if (mPausingActivity != null) {
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
@@ -5644,21 +5674,29 @@
boolean preserveWindows, boolean notifyClients) {
mTopActivityOccludesKeyguard = false;
mTopDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
mStackSupervisor.beginActivityVisibilityUpdate();
try {
- mEnsureActivitiesVisibleHelper.process(
- starting, configChanges, preserveWindows, notifyClients);
+ mEnsureActivitiesVisibleHelper.processUpdate(starting);
if (mTranslucentActivityWaiting != null &&
mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
- // Nothing is getting drawn or everything was already visible, don't wait for timeout.
+ // Nothing is getting drawn or everything was already visible, don't wait for
+ // timeout.
notifyActivityDrawnLocked(null);
}
} finally {
- mStackSupervisor.endActivityVisibilityUpdate();
+ mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges, preserveWindows,
+ notifyClients);
}
}
+ void commitActivitiesVisible(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ mEnsureActivitiesVisibleHelper.processCommit(starting, configChanges, preserveWindows,
+ notifyClients);
+ }
+
/**
* @return true if the top visible activity wants to occlude the Keyguard, false otherwise
*/
@@ -5692,64 +5730,34 @@
}
/**
- * Checks whether {@param r} should be visible depending on Keyguard state and updates
- * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
- * necessary.
- *
- * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
+ * @return the top most visible activity that wants to turn screen on
*/
- boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) {
- int displayId = getDisplayId();
- if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
-
- final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController()
- .isKeyguardOrAodShowing(displayId);
- final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
- final boolean showWhenLocked = r.canShowWhenLocked();
- final boolean dismissKeyguard = r.containsDismissKeyguardWindow();
- if (shouldBeVisible) {
- if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
- mTopDismissingKeyguardActivity = r;
- }
-
- // Only the top activity may control occluded, as we can't occlude the Keyguard if the
- // top app doesn't want to occlude it.
- if (isTop) {
- mTopActivityOccludesKeyguard |= showWhenLocked;
- }
-
- final boolean canShowWithKeyguard = canShowWithInsecureKeyguard()
- && mStackSupervisor.getKeyguardController().canDismissKeyguard();
- if (canShowWithKeyguard) {
- return true;
- }
- }
- if (keyguardOrAodShowing) {
- // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
- // right away and AOD isn't visible.
- return shouldBeVisible && mStackSupervisor.getKeyguardController()
- .canShowActivityWhileKeyguardShowing(r, dismissKeyguard);
- } else if (keyguardLocked) {
- return shouldBeVisible && mStackSupervisor.getKeyguardController().canShowWhileOccluded(
- dismissKeyguard, showWhenLocked);
- } else {
- return shouldBeVisible;
- }
+ ActivityRecord getTopTurnScreenOnActivity() {
+ return mTopTurnScreenOnActivity;
}
/**
- * Check if the display to which this stack is attached has
- * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
+ * Updates {@link #mTopActivityOccludesKeyguard}, {@link #mTopTurnScreenOnActivity} and
+ * {@link #mTopDismissingKeyguardActivity} if this task could be visible.
+ *
*/
- boolean canShowWithInsecureKeyguard() {
- final DisplayContent displayContent = mDisplayContent;
- if (displayContent == null) {
- throw new IllegalStateException("Stack is not attached to any display, stackId="
- + getRootTaskId());
+ void updateKeyguardVisibility(ActivityRecord r, boolean isTop) {
+ final boolean showWhenLocked = r.canShowWhenLocked();
+ final boolean dismissKeyguard = r.containsDismissKeyguardWindow();
+ final boolean turnScreenOn = r.canTurnScreenOn();
+ if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
+ mTopDismissingKeyguardActivity = r;
}
- final int flags = displayContent.mDisplay.getFlags();
- return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
+ if (turnScreenOn && mTopTurnScreenOnActivity == null) {
+ mTopTurnScreenOnActivity = r;
+ }
+
+ // Only the top activity may control occluded, as we can't occlude the Keyguard if the
+ // top app doesn't want to occlude it.
+ if (isTop) {
+ mTopActivityOccludesKeyguard |= showWhenLocked;
+ }
}
void checkTranslucentActivityWaiting(ActivityRecord top) {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 6550167..2b32e40 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1779,7 +1779,8 @@
notifyClients);
}
} finally {
- mAtmService.mStackSupervisor.endActivityVisibilityUpdate();
+ mAtmService.mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges,
+ preserveWindows, notifyClients);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 63a595e..e07c567 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -18,10 +18,8 @@
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-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_SPLIT_SCREEN_SECONDARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS;
@@ -38,7 +36,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
-import android.util.SparseBooleanArray;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
@@ -54,7 +51,6 @@
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.Consumer;
@@ -75,11 +71,9 @@
// The set of modes that are currently supports
// TODO: Remove once the task organizer can support all modes
@VisibleForTesting
- static final int[] SUPPORTED_WINDOWING_MODES = {
- WINDOWING_MODE_PINNED,
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
- WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
- WINDOWING_MODE_MULTI_WINDOW,
+ static final int[] UNSUPPORTED_WINDOWING_MODES = {
+ WINDOWING_MODE_UNDEFINED,
+ WINDOWING_MODE_FREEFORM
};
private final WindowManagerGlobalLock mGlobalLock;
@@ -313,18 +307,17 @@
synchronized (mGlobalLock) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register task organizer=%s uid=%d",
organizer.asBinder(), uid);
- for (int winMode : SUPPORTED_WINDOWING_MODES) {
- if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
- mTaskOrganizers.add(organizer);
- mTaskOrganizerStates.put(organizer.asBinder(),
- new TaskOrganizerState(organizer, uid));
- }
- mService.mRootWindowContainer.forAllTasks((task) -> {
- if (task.getWindowingMode() == winMode) {
- task.updateTaskOrganizerState(true /* forceUpdate */);
- }
- });
+ if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
+ mTaskOrganizers.add(organizer);
+ mTaskOrganizerStates.put(organizer.asBinder(),
+ new TaskOrganizerState(organizer, uid));
}
+ mService.mRootWindowContainer.forAllTasks((task) -> {
+ if (ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, task.getWindowingMode())) {
+ return;
+ }
+ task.updateTaskOrganizerState(true /* forceUpdate */);
+ });
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -362,12 +355,7 @@
}
private boolean isSupportedWindowingMode(int winMode) {
- for (int i = 0; i < SUPPORTED_WINDOWING_MODES.length; i++) {
- if (SUPPORTED_WINDOWING_MODES[i] == winMode) {
- return true;
- }
- }
- return false;
+ return !ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, winMode);
}
void onTaskAppeared(ITaskOrganizer organizer, Task task) {
@@ -661,21 +649,18 @@
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.print(prefix); pw.println("TaskOrganizerController:");
- pw.print(innerPrefix); pw.println("Per windowing mode:");
- for (int i = 0; i < SUPPORTED_WINDOWING_MODES.length; i++) {
- final int windowingMode = SUPPORTED_WINDOWING_MODES[i];
- pw.println(innerPrefix + " "
- + WindowConfiguration.windowingModeToString(windowingMode) + ":");
- for (final TaskOrganizerState state : mTaskOrganizerStates.values()) {
- final ArrayList<Task> tasks = state.mOrganizedTasks;
- pw.print(innerPrefix + " ");
- pw.println(state.mOrganizer.mTaskOrganizer + " uid=" + state.mUid + ":");
- for (int k = 0; k < tasks.size(); k++) {
- final Task task = tasks.get(k);
- if (windowingMode == task.getWindowingMode()) {
- pw.println(innerPrefix + " " + task);
- }
+ for (final TaskOrganizerState state : mTaskOrganizerStates.values()) {
+ final ArrayList<Task> tasks = state.mOrganizedTasks;
+ pw.print(innerPrefix + " ");
+ pw.println(state.mOrganizer.mTaskOrganizer + " uid=" + state.mUid + ":");
+ for (int k = 0; k < tasks.size(); k++) {
+ final Task task = tasks.get(k);
+ final int mode = task.getWindowingMode();
+ if (ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, mode)) {
+ continue;
}
+ pw.println(innerPrefix + " ("
+ + WindowConfiguration.windowingModeToString(mode) + ") " + task);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index f32781a..abe6329 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -299,7 +299,7 @@
}
mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId());
- mService.mInputManager.unregisterInputChannel(mServerChannel);
+ mService.mInputManager.unregisterInputChannel(mServerChannel.getToken());
mInputEventReceiver.dispose();
mInputEventReceiver = null;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index e3112ef..f39fa1b 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -16,7 +16,9 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -615,8 +617,8 @@
return state.calculateInsets(frame, null /* ignoringVisibilityState */,
false /* isScreenRound */, false /* alwaysConsumeSystemBars */,
null /* displayCutout */, 0 /* legacySoftInputMode */, 0 /* legacyWindowFlags */,
- 0 /* legacySystemUiFlags */, null /* typeSideMap */).getInsets(
- WindowInsets.Type.systemBars()).toRect();
+ 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
+ null /* typeSideMap */).getInsets(WindowInsets.Type.systemBars()).toRect();
}
void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index e9ada6b..100f1bf 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -67,7 +67,6 @@
import android.os.SystemClock;
import android.util.MergedConfiguration;
import android.util.Slog;
-import android.view.DisplayCutout;
import android.view.IWindowSession;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
@@ -79,6 +78,7 @@
import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.window.ClientWindowFrames;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -159,12 +159,8 @@
final IWindowSession session = WindowManagerGlobal.getWindowSession();
window.setSession(session);
final SurfaceControl surfaceControl = new SurfaceControl();
- final Rect tmpRect = new Rect();
- final DisplayCutout.ParcelableWrapper tmpCutout = new DisplayCutout.ParcelableWrapper();
- final Rect tmpFrame = new Rect();
+ final ClientWindowFrames tmpFrames = new ClientWindowFrames();
final Rect taskBounds;
- final Rect tmpContentInsets = new Rect();
- final Rect tmpStableInsets = new Rect();
final InsetsState mTmpInsetsState = new InsetsState();
final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0];
final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
@@ -254,8 +250,9 @@
}
try {
final int res = session.addToDisplay(window, window.mSeq, layoutParams,
- View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrame, tmpRect,
- tmpRect, tmpCutout, null, mTmpInsetsState, mTempControls);
+ View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrames.frame,
+ tmpFrames.contentInsets, tmpFrames.stableInsets, tmpFrames.displayCutout,
+ null /* outInputChannel */, mTmpInsetsState, mTempControls);
if (res < 0) {
Slog.w(TAG, "Failed to add snapshot starting window res=" + res);
return null;
@@ -270,15 +267,14 @@
window.setOuter(snapshotSurface);
try {
session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1,
- tmpFrame, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect,
- tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
+ tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
mTempControls, sTmpSurfaceSize, sTmpSurfaceControl);
} catch (RemoteException e) {
// Local call.
}
- final Rect systemBarInsets = getSystemBarInsets(tmpFrame, insetsState);
- snapshotSurface.setFrames(tmpFrame, systemBarInsets);
+ final Rect systemBarInsets = getSystemBarInsets(tmpFrames.frame, insetsState);
+ snapshotSurface.setFrames(tmpFrames.frame, systemBarInsets);
snapshotSurface.drawSnapshot();
return snapshotSurface;
}
@@ -528,11 +524,9 @@
}
@Override
- public void resized(Rect frame, Rect contentInsets, Rect visibleInsets,
- Rect stableInsets, boolean reportDraw,
- MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {
+ public void resized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration mergedConfiguration, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId) {
if (mergedConfiguration != null && mOuter != null
&& mOuter.mOrientationOnCreation
!= mergedConfiguration.getMergedConfiguration().orientation) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 8a5e70f..ae8f7a5 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -2464,8 +2465,9 @@
private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
boolean isVoiceInteraction) {
- if (isOrganized()) {
- // Defer to the task organizer to run animations
+ if (isOrganized()
+ // TODO(b/161711458): Clean-up when moved to shell.
+ && getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 19179a8..8eb6432 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -258,6 +258,7 @@
import android.view.WindowManager.TransitionType;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
+import android.window.ClientWindowFrames;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -1410,7 +1411,8 @@
if (!displayContent.hasAccess(session.mUid)) {
ProtoLog.w(WM_ERROR,
"Attempted to add window to a display for which the application "
- + "does not have access: %d. Aborting.", displayId);
+ + "does not have access: %d. Aborting.",
+ displayContent.getDisplayId());
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
@@ -2064,21 +2066,6 @@
}
}
- public void getWindowDisplayFrame(Session session, IWindow client,
- Rect outDisplayFrame) {
- synchronized (mGlobalLock) {
- WindowState win = windowForClientLocked(session, client, false);
- if (win == null) {
- outDisplayFrame.setEmpty();
- return;
- }
- outDisplayFrame.set(win.getDisplayFrame());
- if (win.inSizeCompatMode()) {
- outDisplayFrame.scale(win.mInvGlobalScale);
- }
- }
- }
-
public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
synchronized (mGlobalLock) {
if (mAccessibilityController != null) {
@@ -2114,9 +2101,7 @@
public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
- long frameNumber, Rect outFrame, Rect outContentInsets,
- Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame,
- DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
+ long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
SurfaceControl outBLASTSurfaceControl) {
@@ -2385,10 +2370,6 @@
if (win.mActivityRecord != null) {
win.mActivityRecord.updateReportedVisibilityLocked();
}
- if (winAnimator.mReportSurfaceResized) {
- winAnimator.mReportSurfaceResized = false;
- result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED;
- }
if (displayPolicy.areSystemBarsForcedShownLw(win)) {
result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
}
@@ -2418,18 +2399,14 @@
// The last inset values represent the last client state
win.updateLastInsetValues();
- win.getCompatFrame(outFrame);
- win.getInsetsForRelayout(outContentInsets, outVisibleInsets,
- outStableInsets);
- outCutout.set(win.getWmDisplayCutout().getDisplayCutout());
- outBackdropFrame.set(win.getBackdropFrame(win.getFrame()));
+ win.fillClientWindowFrames(outFrames);
outInsetsState.set(win.getInsetsState(), win.isClientLocal());
if (DEBUG) {
Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
+ ", requestedWidth=" + requestedWidth
+ ", requestedHeight=" + requestedHeight
+ ", viewVisibility=" + viewVisibility
- + "\nRelayout returning frame=" + outFrame
+ + "\nRelayout returning frame=" + outFrames.frame
+ ", surface=" + outSurfaceControl);
}
@@ -2439,8 +2416,7 @@
result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
if (DEBUG_LAYOUT) {
- Slog.v(TAG_WM,
- "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
+ Slog.v(TAG_WM, "Relayout complete " + win + ": outFrames=" + outFrames);
}
win.mInRelayout = false;
@@ -5752,19 +5728,6 @@
}
@Override
- public void setPipVisibility(boolean visible) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Caller does not hold permission "
- + android.Manifest.permission.STATUS_BAR);
- }
-
- synchronized (mGlobalLock) {
- mPolicy.setPipVisibilityLw(visible);
- }
- }
-
- @Override
public void statusBarVisibilityChanged(int displayId, int visibility) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 84a9c75..cf73def 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -209,7 +209,6 @@
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
-import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IApplicationToken;
@@ -233,6 +232,7 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.window.ClientWindowFrames;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
@@ -388,15 +388,6 @@
private final Configuration mTempConfiguration = new Configuration();
/**
- * The last content insets returned to the client in relayout. We use
- * these in the bounds animation to ensure we only observe inset changes
- * at the same time that a client resizes it's surface so that we may use
- * the geometryAppliesWithResize synchronization mechanism to keep
- * the contents in place.
- */
- final Rect mLastRelayoutContentInsets = new Rect();
-
- /**
* Set to true if we are waiting for this window to receive its
* given internal insets before laying out other windows based on it.
*/
@@ -437,6 +428,8 @@
private final WindowFrames mWindowFrames = new WindowFrames();
+ private final ClientWindowFrames mClientWindowFrames = new ClientWindowFrames();
+
/** The frames used to compute a temporal layout appearance. */
private WindowFrames mSimulatedWindowFrames;
@@ -1299,7 +1292,10 @@
return mWindowFrames.mRelFrame;
}
- /** Retrieves the frame of the display that this window was last laid out in. */
+ /**
+ * Gets the frame that excludes the area of side insets according to the layout parameter from
+ * {@link WindowManager.LayoutParams#setFitInsetsSides}.
+ */
Rect getDisplayFrame() {
return mWindowFrames.mDisplayFrame;
}
@@ -2504,7 +2500,7 @@
// unregister server channel first otherwise it complains about broken channel
if (mInputChannel != null) {
- mWmService.mInputManager.unregisterInputChannel(mInputChannel);
+ mWmService.mInputManager.unregisterInputChannel(mInputChannel.getToken());
mInputChannel.dispose();
mInputChannel = null;
@@ -3585,6 +3581,39 @@
return wpc != null && wpc.registeredForDisplayConfigChanges();
}
+ void fillClientWindowFrames(ClientWindowFrames outFrames) {
+ outFrames.frame.set(mWindowFrames.mCompatFrame);
+ outFrames.displayFrame.set(mWindowFrames.mDisplayFrame);
+ if (mInvGlobalScale != 1.0f && inSizeCompatMode()) {
+ outFrames.displayFrame.scale(mInvGlobalScale);
+ }
+
+ final Rect backdropFrame = outFrames.backdropFrame;
+ // When the task is docked, we send fullscreen sized backdropFrame as soon as resizing
+ // start even if we haven't received the relayout window, so that the client requests
+ // the relayout sooner. When dragging stops, backdropFrame needs to stay fullscreen
+ // until the window to small size, otherwise the multithread renderer will shift last
+ // one or more frame to wrong offset. So here we send fullscreen backdrop if either
+ // isDragResizing() or isDragResizeChanged() is true.
+ final boolean resizing = isDragResizing() || isDragResizeChanged();
+ if (!resizing || getWindowConfiguration().useWindowFrameForBackdrop()) {
+ // Surface position is now inherited from parent, and BackdropFrameRenderer uses
+ // backdrop frame to position content. Thus we just keep the size of backdrop frame,
+ // and remove the offset to avoid double offset from display origin.
+ backdropFrame.set(outFrames.frame);
+ backdropFrame.offsetTo(0, 0);
+ } else {
+ final DisplayInfo displayInfo = getDisplayInfo();
+ backdropFrame.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+ }
+ outFrames.displayCutout.set(mWindowFrames.mDisplayCutout.getDisplayCutout());
+
+ // TODO(b/149813814): Remove legacy insets.
+ outFrames.contentInsets.set(mWindowFrames.mLastContentInsets);
+ outFrames.visibleInsets.set(mWindowFrames.mLastVisibleInsets);
+ outFrames.stableInsets.set(mWindowFrames.mLastStableInsets);
+ }
+
void reportResized() {
// If the activity is scheduled to relaunch, skip sending the resized to ViewRootImpl now
// since it will be destroyed anyway. This also prevents the client from receiving
@@ -3616,23 +3645,18 @@
mWinAnimator.mSurfaceResized = false;
mWindowFrames.resetInsetsChanged();
- final Rect frame = mWindowFrames.mCompatFrame;
- final Rect contentInsets = mWindowFrames.mLastContentInsets;
- final Rect visibleInsets = mWindowFrames.mLastVisibleInsets;
- final Rect stableInsets = mWindowFrames.mLastStableInsets;
final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;
final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported;
final boolean forceRelayout = reportOrientation || isDragResizeChanged() || !mRedrawForSyncReported;
final int displayId = getDisplayId();
- final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout();
+ fillClientWindowFrames(mClientWindowFrames);
mRedrawForSyncReported = true;
try {
- mClient.resized(frame, contentInsets, visibleInsets, stableInsets, reportDraw,
- mergedConfiguration, getBackdropFrame(frame), forceRelayout,
+ mClient.resized(mClientWindowFrames, reportDraw, mergedConfiguration, forceRelayout,
getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this),
- displayId, new DisplayCutout.ParcelableWrapper(displayCutout));
+ displayId);
if (mWmService.mAccessibilityController != null) {
mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId);
@@ -3738,27 +3762,6 @@
return (mAttrs.insetsFlags.behavior & BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) != 0;
}
- Rect getBackdropFrame(Rect frame) {
- // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
- // start even if we haven't received the relayout window, so that the client requests
- // the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen
- // until the window to small size, otherwise the multithread renderer will shift last
- // one or more frame to wrong offset. So here we send fullscreen backdrop if either
- // isDragResizing() or isDragResizeChanged() is true.
- boolean resizing = isDragResizing() || isDragResizeChanged();
- if (getWindowConfiguration().useWindowFrameForBackdrop() || !resizing) {
- // Surface position is now inherited from parent, and BackdropFrameRenderer uses
- // backdrop frame to position content. Thus we just keep the size of backdrop frame, and
- // remove the offset to avoid double offset from display origin.
- mTmpRect.set(frame);
- mTmpRect.offsetTo(0, 0);
- return mTmpRect;
- }
- final DisplayInfo displayInfo = getDisplayInfo();
- mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
- return mTmpRect;
- }
-
private int getRootTaskId() {
final Task stack = getRootTask();
if (stack == null) {
@@ -5670,18 +5673,6 @@
}
}
- /**
- * Copy the inset values over so they can be sent back to the client when a relayout occurs.
- */
- void getInsetsForRelayout(Rect outContentInsets, Rect outVisibleInsets,
- Rect outStableInsets) {
- outContentInsets.set(mWindowFrames.mContentInsets);
- outVisibleInsets.set(mWindowFrames.mVisibleInsets);
- outStableInsets.set(mWindowFrames.mStableInsets);
-
- mLastRelayoutContentInsets.set(mWindowFrames.mContentInsets);
- }
-
void getContentInsets(Rect outContentInsets) {
outContentInsets.set(mWindowFrames.mContentInsets);
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1bd712c..5e81400 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -126,11 +126,7 @@
* we must tell them application to resize (and thus redraw itself).
*/
boolean mSurfaceResized;
- /**
- * Whether we should inform the client on next relayoutWindow that
- * the surface has been resized since last time.
- */
- boolean mReportSurfaceResized;
+
WindowSurfaceController mSurfaceController;
private WindowSurfaceController mPendingDestroySurface;
@@ -872,7 +868,6 @@
}
if (mSurfaceResized) {
- mReportSurfaceResized = true;
mWin.getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
}
}
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 7e9e11d..95d4ba7 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -29,6 +29,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <binder/IPCThreadState.h>
#include <jni.h>
#include <processgroup/processgroup.h>
@@ -90,11 +91,20 @@
}
}
+static void com_android_server_am_CachedAppOptimizer_freezeBinder(
+ JNIEnv *env, jobject clazz, jint pid, jboolean freeze) {
+
+ if (IPCThreadState::freeze(pid, freeze, 100 /* timeout [ms] */) != 0) {
+ jniThrowException(env, "java/lang/RuntimeException", "Unable to freeze/unfreeze binder");
+ }
+}
+
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
{"enableFreezerInternal", "(Z)V",
(void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal},
+ {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder}
};
int register_android_server_am_CachedAppOptimizer(JNIEnv* env)
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 5dd6cd7..46136ca 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -209,7 +209,7 @@
status_t registerInputChannel(JNIEnv* env, const std::shared_ptr<InputChannel>& inputChannel);
status_t registerInputMonitor(JNIEnv* env, const std::shared_ptr<InputChannel>& inputChannel,
int32_t displayId, bool isGestureMonitor);
- status_t unregisterInputChannel(JNIEnv* env, const InputChannel& inputChannel);
+ status_t unregisterInputChannel(JNIEnv* env, const sp<IBinder>& connectionToken);
status_t pilferPointers(const sp<IBinder>& token);
void displayRemoved(JNIEnv* env, int32_t displayId);
@@ -447,9 +447,9 @@
}
status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */,
- const InputChannel& inputChannel) {
+ const sp<IBinder>& connectionToken) {
ATRACE_CALL();
- return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
+ return mInputManager->getDispatcher()->unregisterInputChannel(connectionToken);
}
status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) {
@@ -1364,7 +1364,7 @@
ALOGW("Input channel object '%s' was disposed without first being unregistered with "
"the input manager!", inputChannel->getName().c_str());
- im->unregisterInputChannel(env, *inputChannel);
+ im->unregisterInputChannel(env, inputChannel->getConnectionToken());
}
static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,
@@ -1417,20 +1417,12 @@
}
}
-static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */,
- jlong ptr, jobject inputChannelObj) {
+static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr,
+ jobject tokenObj) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+ sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
- std::shared_ptr<InputChannel> inputChannel =
- android_view_InputChannel_getInputChannel(env, inputChannelObj);
- if (inputChannel == nullptr) {
- throwInputChannelNotInitialized(env);
- return;
- }
-
- android_view_InputChannel_setDisposeCallback(env, inputChannelObj, nullptr, nullptr);
-
- status_t status = im->unregisterInputChannel(env, *inputChannel);
+ status_t status = im->unregisterInputChannel(env, token);
if (status && status != BAD_VALUE) { // ignore already unregistered channel
std::string message;
message += StringPrintf("Failed to unregister input channel. status=%d", status);
@@ -1792,7 +1784,7 @@
(void*)nativeRegisterInputChannel},
{"nativeRegisterInputMonitor", "(JLandroid/view/InputChannel;IZ)V",
(void*)nativeRegisterInputMonitor},
- {"nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V",
+ {"nativeUnregisterInputChannel", "(JLandroid/os/IBinder;)V",
(void*)nativeUnregisterInputChannel},
{"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers},
{"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled},
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8045583..33b1213 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2159,6 +2159,11 @@
return getDeviceOwnerOfCallerLocked(caller);
}
+ @NonNull ActiveAdmin getParentOfAdminIfRequired(ActiveAdmin admin, boolean parent) {
+ Objects.requireNonNull(admin);
+ return parent ? admin.getParentActiveAdmin() : admin;
+ }
+
/**
* Finds an active admin for the caller then checks {@code permission} if admin check failed.
*
@@ -4527,6 +4532,8 @@
}
Objects.requireNonNull(who, "ComponentName is null");
Preconditions.checkArgument(timeoutMs >= 0, "Timeout must not be a negative number.");
+ final CallerIdentity caller = getCallerIdentity(who);
+ Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
// timeoutMs with value 0 means that the admin doesn't participate
// timeoutMs is clamped to the interval in case the internal constants change in the future
final long minimumStrongAuthTimeout = getMinimumStrongAuthTimeoutMs();
@@ -4537,11 +4544,11 @@
timeoutMs = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
}
- final int userHandle = mInjector.userHandleGetCallingUserId();
+ final int userHandle = caller.getUserId();
boolean changed = false;
synchronized (getLockObject()) {
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
+ ActiveAdmin ap = getParentOfAdminIfRequired(getProfileOwnerOrDeviceOwnerLocked(caller),
+ parent);
if (ap.strongAuthUnlockTimeout != timeoutMs) {
ap.strongAuthUnlockTimeout = timeoutMs;
saveSettingsLocked(userHandle);
@@ -5646,8 +5653,9 @@
List<String> lockdownWhitelist)
throws SecurityException {
enforceProfileOrDeviceOwner(who);
+ final CallerIdentity caller = getCallerIdentity(who);
- final int userId = mInjector.userHandleGetCallingUserId();
+ final int userId = caller.getUserId();
mInjector.binderWithCleanCallingIdentity(() -> {
if (vpnPackage != null && !isPackageInstalledForUser(vpnPackage, userId)) {
Slog.w(LOG_TAG, "Non-existent VPN package specified: " + vpnPackage);
@@ -5678,8 +5686,7 @@
.write();
});
synchronized (getLockObject()) {
- ActiveAdmin admin = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
if (!TextUtils.equals(vpnPackage, admin.mAlwaysOnVpnPackage)
|| lockdown != admin.mAlwaysOnVpnLockdown) {
admin.mAlwaysOnVpnPackage = vpnPackage;
@@ -7132,9 +7139,22 @@
return (deviceOwner != null) ? deviceOwner.keepUninstalledPackages : null;
}
+ /**
+ * Logs a warning when the device doesn't have {@code PackageManager.FEATURE_DEVICE_ADMIN}.
+ *
+ * @param message action that was not executed; should not end with a period because the missing
+ * feature will be appended to it.
+ */
+ private void logMissingFeatureAction(String message) {
+ Slog.w(LOG_TAG, message + " because device does not have the "
+ + PackageManager.FEATURE_DEVICE_ADMIN + " feature.");
+ }
+
@Override
public boolean setDeviceOwner(ComponentName admin, String ownerName, int userId) {
if (!mHasFeature) {
+ logMissingFeatureAction("Cannot set " + ComponentName.flattenToShortString(admin)
+ + " as device owner for user " + userId);
return false;
}
if (admin == null
@@ -7456,6 +7476,8 @@
@Override
public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) {
if (!mHasFeature) {
+ logMissingFeatureAction("Cannot set " + ComponentName.flattenToShortString(who)
+ + " as profile owner for user " + userHandle);
return false;
}
if (who == null
@@ -7676,6 +7698,8 @@
@Override
public void setUserProvisioningState(int newState, int userHandle) {
if (!mHasFeature) {
+ logMissingFeatureAction("Cannot set provisioning state " + newState + " for user "
+ + userHandle);
return;
}
@@ -7753,6 +7777,8 @@
@Override
public void setProfileEnabled(ComponentName who) {
if (!mHasFeature) {
+ logMissingFeatureAction("Cannot enable profile for "
+ + ComponentName.flattenToShortString(who));
return;
}
Objects.requireNonNull(who, "ComponentName is null");
@@ -9656,10 +9682,11 @@
return null;
}
Objects.requireNonNull(who, "ComponentName is null");
+ final CallerIdentity caller = getCallerIdentity(who);
synchronized (getLockObject()) {
- final ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
+ final ActiveAdmin activeAdmin = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller), parent);
if (parent) {
enforceProfileOwnerOfOrganizationOwnedDevice(activeAdmin);
}
@@ -9910,6 +9937,7 @@
return;
}
Objects.requireNonNull(who, "ComponentName is null");
+ final CallerIdentity caller = getCallerIdentity(who);
synchronized (getLockObject()) {
/*
* When called on the parent DPM instance (parent == true), affects active admin
@@ -9917,9 +9945,14 @@
* * The ActiveAdmin must be of an org-owned profile owner.
* * The parent ActiveAdmin instance should be used for managing the restriction.
*/
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- parent ? DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER
- : DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
+ final ActiveAdmin ap;
+ if (parent) {
+ ap = getParentOfAdminIfRequired(getOrganizationOwnedProfileOwnerLocked(caller),
+ parent);
+ } else {
+ ap = getParentOfAdminIfRequired(getProfileOwnerOrDeviceOwnerLocked(caller), parent);
+ }
+
if (disabled) {
ap.accountTypesWithManagementDisabled.add(accountType);
} else {
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 12c69ea..ddd1f75 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -16,6 +16,11 @@
package com.android.server.profcollect;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
@@ -34,6 +39,7 @@
import com.android.server.wm.ActivityTaskManagerInternal;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
/**
* System-server-local proxy into the {@code IProfcollectd} native service.
@@ -41,28 +47,43 @@
public final class ProfcollectForwardingService extends SystemService {
public static final String LOG_TAG = "ProfcollectForwardingService";
+ private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+
+ private static final long BG_PROCESS_PERIOD = DEBUG
+ ? TimeUnit.MINUTES.toMillis(1)
+ : TimeUnit.DAYS.toMillis(1);
+
private IProfCollectd mIProfcollect;
- private ProfcollectForwardingService mSelfService;
+ private static ProfcollectForwardingService sSelfService;
private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper());
public ProfcollectForwardingService(Context context) {
super(context);
- if (mSelfService != null) {
+ if (sSelfService != null) {
throw new AssertionError("only one service instance allowed");
}
- mSelfService = this;
+ sSelfService = this;
}
@Override
public void onStart() {
- Log.i(LOG_TAG, "Profcollect forwarding service start");
- connectNativeService();
- if (mIProfcollect == null) {
- return;
+ if (DEBUG) {
+ Log.d(LOG_TAG, "Profcollect forwarding service start");
}
- if (serviceHasSupportedTraceProvider()) {
- registerObservers();
+ connectNativeService();
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_BOOT_COMPLETED) {
+ if (mIProfcollect == null) {
+ return;
+ }
+ if (serviceHasSupportedTraceProvider()) {
+ registerObservers();
+ }
+ ProfcollectBGJobService.schedule(getContext());
}
}
@@ -130,6 +151,50 @@
}
}
+ /**
+ * Background trace process service.
+ */
+ public static class ProfcollectBGJobService extends JobService {
+ // Unique ID in system service
+ private static final int JOB_IDLE_PROCESS = 260817;
+ private static final ComponentName JOB_SERVICE_NAME = new ComponentName(
+ "android",
+ ProfcollectBGJobService.class.getName());
+
+ /**
+ * Attach the service to the system job scheduler.
+ */
+ public static void schedule(Context context) {
+ JobScheduler js = context.getSystemService(JobScheduler.class);
+
+ js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME)
+ .setRequiresDeviceIdle(true)
+ .setRequiresCharging(true)
+ .setPeriodic(BG_PROCESS_PERIOD)
+ .build());
+ }
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ if (DEBUG) {
+ Log.d(LOG_TAG, "Starting background process job");
+ }
+
+ try {
+ sSelfService.mIProfcollect.ProcessProfile();
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, e.getMessage());
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ // TODO: Handle this?
+ return false;
+ }
+ }
+
// Event observers
private void registerObservers() {
registerAppLaunchObserver();
@@ -155,7 +220,9 @@
int randomNum = ThreadLocalRandom.current().nextInt(100);
if (randomNum < traceFrequency) {
try {
- Log.i(LOG_TAG, "Tracing on app launch event: " + packageName);
+ if (DEBUG) {
+ Log.d(LOG_TAG, "Tracing on app launch event: " + packageName);
+ }
mIProfcollect.TraceOnce("applaunch");
} catch (RemoteException e) {
Log.e(LOG_TAG, e.getMessage());
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index 4f636ef..a941331 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -21,12 +21,15 @@
"truth-prebuilt",
],
static_libs: [
+ "cts-host-utils",
"frameworks-base-hostutils",
"PackageManagerServiceHostTestsIntentVerifyUtils",
],
test_suites: ["general-tests"],
java_resources: [
+ ":PackageManagerTestAppDeclaresStaticLibrary",
":PackageManagerTestAppStub",
+ ":PackageManagerTestAppUsesStaticLibrary",
":PackageManagerTestAppVersion1",
":PackageManagerTestAppVersion2",
":PackageManagerTestAppVersion3",
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
index 24c714c..9399030 100644
--- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt
@@ -18,6 +18,7 @@
import com.android.internal.util.test.SystemPreparer
import com.android.tradefed.device.ITestDevice
+import com.google.common.truth.Truth
import org.junit.rules.TemporaryFolder
import java.io.File
import java.io.FileOutputStream
@@ -48,6 +49,44 @@
internal fun ITestDevice.uninstallPackages(vararg pkgNames: String) =
pkgNames.forEach { uninstallPackage(it) }
+/**
+ * Retry [block] a total of [maxAttempts] times, waiting [millisBetweenAttempts] milliseconds
+ * between each iteration, until a non-null result is returned, providing that result back to the
+ * caller.
+ *
+ * If an [AssertionError] is thrown by the [block] and a non-null result is never returned, that
+ * error will be re-thrown. This allows the use of [Truth.assertThat] to indicate success while
+ * providing a meaningful error message in case of failure.
+ */
+internal fun <T> retryUntilNonNull(
+ maxAttempts: Int = 10,
+ millisBetweenAttempts: Long = 1000,
+ block: () -> T?
+): T {
+ var attempt = 0
+ var failure: AssertionError? = null
+ while (attempt++ < maxAttempts) {
+ val result = try {
+ block()
+ } catch (e: AssertionError) {
+ failure = e
+ null
+ }
+
+ if (result != null) {
+ return result
+ } else {
+ Thread.sleep(millisBetweenAttempts)
+ }
+ }
+
+ throw failure ?: AssertionError("Never succeeded")
+}
+
+internal fun retryUntilSuccess(block: () -> Boolean) {
+ retryUntilNonNull { block().takeIf { it } }
+}
+
internal object HostUtils {
fun getDataDir(device: ITestDevice, pkgName: String) =
@@ -78,6 +117,25 @@
* dumpsys package and therefore device.getAppPackageInfo doesn't work immediately after reboot,
* so the following methods parse the package dump directly to see if the path matches.
*/
+
+ /**
+ * Reads the pm dump for a package name starting from the Packages: metadata section until
+ * the following section.
+ */
+ fun packageSection(
+ device: ITestDevice,
+ pkgName: String,
+ sectionName: String = "Packages"
+ ) = device.executeShellCommand("pm dump $pkgName")
+ .lineSequence()
+ .dropWhile { !it.startsWith(sectionName) } // Wait until the header
+ .drop(1) // Drop the header itself
+ .takeWhile {
+ // Until next top level header, a non-empty line that doesn't start with whitespace
+ it.isEmpty() || it.first().isWhitespace()
+ }
+ .map(String::trim)
+
fun getCodePaths(device: ITestDevice, pkgName: String) =
device.executeShellCommand("pm dump $pkgName")
.lineSequence()
@@ -87,14 +145,7 @@
.toList()
private fun userIdLineSequence(device: ITestDevice, pkgName: String) =
- device.executeShellCommand("pm dump $pkgName")
- .lineSequence()
- .dropWhile { !it.startsWith("Packages:") }
- .takeWhile {
- !it.startsWith("Hidden system packages:") &&
- !it.startsWith("Queries:")
- }
- .map(String::trim)
+ packageSection(device, pkgName)
.filter { it.startsWith("User ") }
fun getUserIdToPkgEnabledState(device: ITestDevice, pkgName: String) =
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SdCardEjectionTests.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SdCardEjectionTests.kt
new file mode 100644
index 0000000..9f9e6a3
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SdCardEjectionTests.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2020 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.server.pm.test
+
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters
+import android.cts.host.utils.DeviceJUnit4Parameterized
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import java.io.File
+import java.util.regex.Pattern
+
+/**
+ * Verifies PackageManagerService behavior when an app is moved to an adoptable storage device.
+ *
+ * Also has the effect of verifying system behavior when the PackageSetting for a package has no
+ * corresponding AndroidPackage which can be parsed from the APK on disk. This is done by removing
+ * the storage device and causing a reboot, at which point PMS will read PackageSettings from disk
+ * and fail to find the package path.
+ */
+@RunWith(DeviceJUnit4Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(
+ DeviceJUnit4ClassRunnerWithParameters.RunnerFactory::class)
+class SdCardEjectionTests : BaseHostJUnit4Test() {
+
+ companion object {
+ private const val VERSION_DECLARES = "PackageManagerTestAppDeclaresStaticLibrary.apk"
+ private const val VERSION_DECLARES_PKG_NAME =
+ "com.android.server.pm.test.test_app_declares_static_library"
+ private const val VERSION_USES = "PackageManagerTestAppUsesStaticLibrary.apk"
+ private const val VERSION_USES_PKG_NAME =
+ "com.android.server.pm.test.test_app_uses_static_library"
+
+ // TODO(chiuwinson): Use the HostUtils constants when merged
+ private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
+ private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk"
+
+ @Parameterized.Parameters(name = "reboot={0}")
+ @JvmStatic
+ fun parameters() = arrayOf(false, true)
+
+ data class Volume(
+ val diskId: String,
+ val fsUuid: String
+ )
+ }
+
+ @Rule
+ @JvmField
+ val tempFolder = TemporaryFolder()
+
+ @Parameterized.Parameter(0)
+ @JvmField
+ var reboot: Boolean = false
+
+ @Before
+ @After
+ fun removePackagesAndDeleteVirtualDisk() {
+ device.uninstallPackages(VERSION_ONE, VERSION_USES_PKG_NAME, VERSION_DECLARES_PKG_NAME)
+ removeVirtualDisk()
+ device.reboot()
+ }
+
+ @Test
+ fun launchActivity() {
+ val hostApkFile = HostUtils.copyResourceToHostFile(VERSION_ONE, tempFolder.newFile())
+ assertThat(device.installPackage(hostApkFile, true)).isNull()
+
+ val errorRegex = Pattern.compile("error", Pattern.CASE_INSENSITIVE)
+ fun assertStartResponse(launched: Boolean) {
+ val response = device.executeShellCommand("am start -n $TEST_PKG_NAME/.TestActivity")
+ if (launched) {
+ assertThat(response).doesNotContainMatch(errorRegex)
+ } else {
+ assertThat(response).containsMatch(errorRegex)
+ }
+ }
+
+ assertStartResponse(launched = true)
+
+ val volume = initializeVirtualDisk()
+
+ movePackage(TEST_PKG_NAME, volume)
+ assertStartResponse(launched = true)
+
+ unmount(volume, TEST_PKG_NAME)
+ assertStartResponse(launched = false)
+
+ remount(volume, hostApkFile, TEST_PKG_NAME)
+ assertStartResponse(launched = true)
+ }
+
+ @Test
+ fun uninstallStaticLibraryInUse() {
+ assertThat(device.installJavaResourceApk(tempFolder, VERSION_DECLARES)).isNull()
+
+ val usesApkFile = HostUtils.copyResourceToHostFile(VERSION_USES, tempFolder.newFile())
+ assertThat(device.installPackage(usesApkFile, true)).isNull()
+
+ fun assertUninstallFails() = assertThat(device.uninstallPackage(VERSION_DECLARES_PKG_NAME))
+ .isEqualTo("DELETE_FAILED_USED_SHARED_LIBRARY")
+
+ assertUninstallFails()
+
+ val volume = initializeVirtualDisk()
+
+ movePackage(VERSION_USES_PKG_NAME, volume)
+ assertUninstallFails()
+
+ unmount(volume, VERSION_USES_PKG_NAME)
+ assertUninstallFails()
+
+ remount(volume, usesApkFile, VERSION_USES_PKG_NAME)
+ assertUninstallFails()
+
+ // Check that install in the correct order (uses first) passes
+ assertThat(device.uninstallPackage(VERSION_USES_PKG_NAME)).isNull()
+ assertThat(device.uninstallPackage(VERSION_DECLARES_PKG_NAME)).isNull()
+ }
+
+ private fun initializeVirtualDisk(): Volume {
+ // Rather than making any assumption about what disks/volumes exist on the device,
+ // save the existing disks/volumes to compare and see when a new one pops up, assuming
+ // it was created as the result of the calls in this test.
+ val existingDisks = device.executeShellCommand("sm list-disks adoptable").lines()
+ val existingVolumes = device.executeShellCommand("sm list-volumes private").lines()
+ device.executeShellCommand("sm set-virtual-disk true")
+
+ val diskId = retryUntilNonNull {
+ device.executeShellCommand("sm list-disks adoptable")
+ .lines()
+ .filterNot(existingDisks::contains)
+ .filterNot(String::isEmpty)
+ .firstOrNull()
+ }
+
+ device.executeShellCommand("sm partition $diskId private")
+
+ return retrieveNewVolume(existingVolumes)
+ }
+
+ private fun retrieveNewVolume(existingVolumes: List<String>): Volume {
+ val newVolume = retryUntilNonNull {
+ device.executeShellCommand("sm list-volumes private")
+ .lines()
+ .toMutableList()
+ .apply { removeAll(existingVolumes) }
+ .firstOrNull()
+ ?.takeIf { it.isNotEmpty() }
+ }
+
+ val sections = newVolume.split(" ")
+ return Volume(diskId = sections.first(), fsUuid = sections.last()).also {
+ assertThat(it.diskId).isNotEmpty()
+ assertThat(it.fsUuid).isNotEmpty()
+ }
+ }
+
+ private fun removeVirtualDisk() {
+ device.executeShellCommand("sm set-virtual-disk false")
+ retryUntilSuccess {
+ !device.executeShellCommand("sm list-volumes").contains("ejecting")
+ }
+ }
+
+ private fun movePackage(pkgName: String, volume: Volume) {
+ // TODO(b/167241596): oat dir must exist for a move install
+ val codePath = HostUtils.getCodePaths(device, pkgName).first()
+ device.executeShellCommand("mkdir $codePath/oat")
+ assertThat(device.executeShellCommand(
+ "pm move-package $pkgName ${volume.fsUuid}").trim())
+ .isEqualTo("Success")
+ }
+
+ private fun unmount(volume: Volume, pkgName: String) {
+ assertThat(device.executeShellCommand("sm unmount ${volume.diskId}")).isEmpty()
+ if (reboot) {
+ // The system automatically mounts the virtual disk on startup, which would mean the
+ // app files are available to the system. To prevent this, disable the disk entirely.
+ // TODO: There must be a better way to prevent it from auto-mounting.
+ removeVirtualDisk()
+ device.reboot()
+ } else {
+ // Because PackageManager unmount scan is asynchronous, need to retry until the package
+ // has been unloaded. This only has to be done in the non-reboot case. Reboot will
+ // clear the data structure by its nature.
+ retryUntilSuccess {
+ // The compiler section will print the state of the physical APK
+ HostUtils.packageSection(device, pkgName, sectionName = "Compiler stats")
+ .any { it.contains("Unable to find package: $pkgName") }
+ }
+ }
+ }
+
+ private fun remount(volume: Volume, hostApkFile: File, pkgName: String) {
+ if (reboot) {
+ // Because the disk was destroyed when unmounting, it now has to be rebuilt manually.
+ // This enables a new virtual disk, unmounts it, mutates its UUID to match the previous
+ // partition's, remounts it, and pushes the base.apk back onto the device. This
+ // simulates the same disk being re-inserted. This is very hacky.
+ val newVolume = initializeVirtualDisk()
+ val mountPoint = device.executeShellCommand("mount")
+ .lineSequence()
+ .first { it.contains(newVolume.fsUuid) }
+ .takeWhile { !it.isWhitespace() }
+
+ device.executeShellCommand("sm unmount ${newVolume.diskId}")
+
+ // Save without renamed UUID to compare and see when the renamed pops up
+ val existingVolumes = device.executeShellCommand("sm list-volumes private").lines()
+
+ device.executeShellCommand("make_f2fs -U ${volume.fsUuid} $mountPoint")
+ device.executeShellCommand("sm mount ${newVolume.diskId}")
+
+ val reparsedVolume = retrieveNewVolume(existingVolumes)
+ assertThat(reparsedVolume.fsUuid).isEqualTo(volume.fsUuid)
+
+ val codePath = HostUtils.getCodePaths(device, pkgName).first()
+ device.pushFile(hostApkFile, "$codePath/base.apk")
+
+ // Unmount so following remount will re-kick package scan
+ device.executeShellCommand("sm unmount ${newVolume.diskId}")
+ }
+
+ device.executeShellCommand("sm mount ${volume.diskId}")
+
+ // Because PackageManager remount scan is asynchronous, need to retry until the package
+ // has been loaded and added to the internal structures. Otherwise resolution will fail.
+ retryUntilSuccess {
+ // The compiler section will print the state of the physical APK
+ HostUtils.packageSection(device, pkgName, sectionName = "Compiler stats")
+ .none { it.contains("Unable to find package: $pkgName") }
+ }
+ }
+}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/Android.bp
similarity index 100%
rename from services/tests/PackageManagerServiceTests/host/test-apps/Android.bp
rename to services/tests/PackageManagerServiceTests/host/test-apps/Generic/Android.bp
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestOriginalOverride.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestOriginalOverride.xml
similarity index 100%
rename from services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestOriginalOverride.xml
rename to services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestOriginalOverride.xml
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion1.xml
similarity index 84%
rename from services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml
rename to services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion1.xml
index efc7372..05b6248 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion1.xml
@@ -25,4 +25,9 @@
android:protectionLevel="normal"
/>
+ <application>
+ <activity android:name="com.android.server.pm.test.test_app.TestActivity"
+ android:label="PackageManagerTestApp" />
+ </application>
+
</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion2.xml
similarity index 97%
rename from services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml
rename to services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion2.xml
index 620054c..d6eb3e0 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion2.xml
@@ -25,4 +25,6 @@
android:protectionLevel="normal"
/>
+ <application/>
+
</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion3.xml
similarity index 97%
rename from services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
rename to services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion3.xml
index 1997771..90317cb 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion3.xml
@@ -25,4 +25,6 @@
android:protectionLevel="normal"
/>
+ <application/>
+
</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion4.xml
similarity index 97%
rename from services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml
rename to services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion4.xml
index d6ade03..795c3c1 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion4.xml
@@ -25,4 +25,6 @@
android:protectionLevel="normal"
/>
+ <application/>
+
</manifest>
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/src/com/android/server/pm/test/test_app/TestActivity.kt
similarity index 61%
copy from packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
copy to services/tests/PackageManagerServiceTests/host/test-apps/Generic/src/com/android/server/pm/test/test_app/TestActivity.kt
index e65f19d..0c9b8d4 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/src/com/android/server/pm/test/test_app/TestActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,17 +14,8 @@
* limitations under the License.
*/
-package com.android.keyguard.dagger;
+package com.android.server.pm.test.test_app
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import android.app.Activity
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface ContainerView {
-}
+class TestActivity : Activity()
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/Android.bp
new file mode 100644
index 0000000..58f17f2
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/Android.bp
@@ -0,0 +1,24 @@
+// Copyright (C) 2020 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.
+
+android_test_helper_app {
+ name: "PackageManagerTestAppDeclaresStaticLibrary",
+ manifest: "AndroidManifestDeclaresStaticLibrary.xml",
+ certificate: ":FrameworksCoreTests_keyset_A_cert",
+}
+
+android_test_helper_app {
+ name: "PackageManagerTestAppUsesStaticLibrary",
+ manifest: "AndroidManifestUsesStaticLibrary.xml",
+}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestDeclaresStaticLibrary.xml
similarity index 64%
copy from services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
copy to services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestDeclaresStaticLibrary.xml
index 1997771..8a6c01a 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestDeclaresStaticLibrary.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,15 +13,12 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.pm.test.test_app"
- android:versionCode="3"
- >
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.pm.test.test_app_declares_static_library">
- <permission
- android:name="com.android.server.pm.test.test_app.TEST_PERMISSION"
- android:protectionLevel="normal"
- />
+ <application>
+ <static-library android:name="com.android.server.pm.test.static_library"
+ android:version="1" />
+ </application>
</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestUsesStaticLibrary.xml b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestUsesStaticLibrary.xml
new file mode 100644
index 0000000..82d9ac4
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestUsesStaticLibrary.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2020 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.pm.test.test_app_uses_static_library">
+
+ <application>
+ <activity android:name="com.android.server.pm.test.static_library.TestActivity"
+ android:label="TestActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <uses-static-library android:name="com.android.server.pm.test.static_library"
+ android:certDigest="1F:BE:5F:FB:B0:AD:DC:0C:CD:BF:22:B9:8A:2F:5A:58:A5:C8:29:80:E1:30:2F:65:0E:6B:CA:ED:03:82:BF:CF"
+ android:version="1" />
+ </application>
+
+</manifest>
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/src/com/android/server/pm/test/static_library/TestActivity.kt b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/src/com/android/server/pm/test/static_library/TestActivity.kt
new file mode 100644
index 0000000..fa85258
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/src/com/android/server/pm/test/static_library/TestActivity.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.server.pm.test.static_library
+
+import android.app.Activity
+import android.graphics.Color
+import android.os.Bundle
+import android.view.ViewGroup
+import android.widget.FrameLayout
+
+class TestActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(FrameLayout(this).apply {
+ setBackgroundColor(Color.BLUE)
+ }, ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ ))
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 6cd083e..f4c6918 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -67,7 +67,6 @@
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.IActivityManager;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
@@ -87,6 +86,7 @@
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.SystemClock;
+import android.provider.DeviceConfig;
import androidx.test.runner.AndroidJUnit4;
@@ -99,6 +99,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoSession;
@@ -106,6 +107,8 @@
import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;
+import java.util.concurrent.Executor;
+
/**
* Tests for {@link com.android.server.DeviceIdleController}.
*/
@@ -124,8 +127,6 @@
@Mock
private ConnectivityManager mConnectivityManager;
@Mock
- private ContentResolver mContentResolver;
- @Mock
private IActivityManager mIActivityManager;
@Mock
private LocationManager mLocationManager;
@@ -294,6 +295,7 @@
mMockingSession = mockitoSession()
.initMocks(this)
.strictness(Strictness.LENIENT)
+ .spyStatic(DeviceConfig.class)
.spyStatic(LocalServices.class)
.startMocking();
spyOn(getContext());
@@ -310,6 +312,14 @@
.thenReturn(mock(PowerSaveState.class));
doReturn(mock(NetworkPolicyManagerInternal.class))
.when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class));
+ doAnswer((Answer<Void>) invocationOnMock -> null)
+ .when(() -> DeviceConfig.addOnPropertiesChangedListener(
+ anyString(), any(Executor.class),
+ any(DeviceConfig.OnPropertiesChangedListener.class)));
+ doAnswer((Answer<DeviceConfig.Properties>) invocationOnMock
+ -> mock(DeviceConfig.Properties.class))
+ .when(() -> DeviceConfig.getProperties(
+ anyString(), ArgumentMatchers.<String>any()));
when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
doNothing().when(mWakeLock).acquire();
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any());
@@ -319,7 +329,6 @@
mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
mAnyMotionDetector = new AnyMotionDetectorForTest();
mInjector = new InjectorForTest(getContext());
- doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any());
mDeviceIdleController = new DeviceIdleController(getContext(), mInjector);
spyOn(mDeviceIdleController);
@@ -330,8 +339,7 @@
mDeviceIdleController.setLightEnabledForTest(true);
// Get the same Constants object that mDeviceIdleController got.
- mConstants = mInjector.getConstants(mDeviceIdleController,
- mInjector.getHandler(mDeviceIdleController), mContentResolver);
+ mConstants = mInjector.getConstants(mDeviceIdleController);
}
@After
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
index c8baca6..8062bfe 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
@@ -170,6 +170,30 @@
verify(mMockSystemSupport).onClientChangeLocked(false);
}
+ @Test
+ public void uiAutomationWithDontUseAccessibilityFlagAfterUnregistering_notifiesSystem()
+ throws Exception {
+ register(UiAutomation.FLAG_DONT_USE_ACCESSIBILITY);
+ unregister();
+ verify(mMockSystemSupport).onClientChangeLocked(false);
+ }
+
+ @Test
+ public void uiAutomationWithDontUseAccessibilityFlag_disableAccessibilityFunctions()
+ throws Exception {
+ register(0);
+ assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
+ unregister();
+ assertFalse(mUiAutomationManager.isUiAutomationRunningLocked());
+ register(UiAutomation.FLAG_DONT_USE_ACCESSIBILITY);
+ assertTrue(mUiAutomationManager.isUiAutomationRunningLocked());
+ assertFalse(mUiAutomationManager.useAccessibility());
+ assertFalse(mUiAutomationManager.canRetrieveInteractiveWindowsLocked());
+ assertFalse(mUiAutomationManager.isTouchExplorationEnabledLocked());
+ assertEquals(0, mUiAutomationManager.getRelevantEventTypes());
+ assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked());
+ }
+
private void register(int flags) {
mUiAutomationManager.registerUiTestAutomationServiceLocked(mMockOwner,
mMockAccessibilityServiceClient, mMockContext, mMockServiceInfo, SERVICE_ID,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index 57bfbf3..6acd9b6 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -44,6 +44,7 @@
import android.graphics.Region;
import android.os.Looper;
import android.view.MagnificationSpec;
+import android.view.accessibility.MagnificationAnimationCallback;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -99,12 +100,12 @@
ValueAnimator.AnimatorListener mStateListener;
FullScreenMagnificationController mFullScreenMagnificationController;
- Runnable mEndCallback;
+ MagnificationAnimationCallback mAnimationCallback;
@Before
public void setUp() {
Looper looper = InstrumentationRegistry.getContext().getMainLooper();
- mEndCallback = Mockito.mock(Runnable.class);
+ mAnimationCallback = Mockito.mock(MagnificationAnimationCallback.class);
// Pretending ID of the Thread associated with looper as main thread ID in controller
when(mMockContext.getMainLooper()).thenReturn(looper);
when(mMockControllerCtx.getContext()).thenReturn(mMockContext);
@@ -323,7 +324,6 @@
for (int i = 0; i < DISPLAY_COUNT; i++) {
setScaleAndCenter_animated_stateChangesAndAnimationHappens(i);
resetMockWindowManager();
- Mockito.reset(mEndCallback);
}
}
@@ -336,7 +336,7 @@
MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, scale,
- newCenter.x, newCenter.y, mEndCallback, SERVICE_ID_1));
+ newCenter.x, newCenter.y, mAnimationCallback, SERVICE_ID_1));
mMessageCapturingHandler.sendAllMessages();
assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
@@ -365,18 +365,17 @@
mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
mStateListener.onAnimationEnd(mMockValueAnimator);
verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(endSpec)));
- verify(mEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
public void testSetScaleAndCenterWithAnimation_sameSpec_noAnimationButInvokeEndCallback() {
for (int i = 0; i < DISPLAY_COUNT; i++) {
- setScaleAndCenter_sameSpec_noAnimationButInvokeEndCallback(i);
- Mockito.reset(mEndCallback);
+ setScaleAndCenter_sameSpec_noAnimationButInvokeCallbacks(i);
}
}
- private void setScaleAndCenter_sameSpec_noAnimationButInvokeEndCallback(int displayId) {
+ private void setScaleAndCenter_sameSpec_noAnimationButInvokeCallbacks(int displayId) {
register(displayId);
final PointF center = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
final float targetScale = 2.0f;
@@ -385,11 +384,11 @@
mMessageCapturingHandler.sendAllMessages();
assertFalse(mFullScreenMagnificationController.setScaleAndCenter(displayId,
- targetScale, center.x, center.y, mEndCallback, SERVICE_ID_1));
+ targetScale, center.x, center.y, mAnimationCallback, SERVICE_ID_1));
mMessageCapturingHandler.sendAllMessages();
verify(mMockValueAnimator, never()).start();
- verify(mEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
@@ -673,38 +672,38 @@
public void testReset_notMagnifying_noStateChangeButInvokeCallback() {
for (int i = 0; i < DISPLAY_COUNT; i++) {
reset_notMagnifying_noStateChangeButInvokeCallback(i);
- Mockito.reset(mEndCallback);
}
}
private void reset_notMagnifying_noStateChangeButInvokeCallback(int displayId) {
register(displayId);
- assertFalse(mFullScreenMagnificationController.reset(displayId, mEndCallback));
+ assertFalse(mFullScreenMagnificationController.reset(displayId, mAnimationCallback));
mMessageCapturingHandler.sendAllMessages();
verify(mMockAms, never()).notifyMagnificationChanged(eq(displayId),
any(Region.class), anyFloat(), anyFloat(), anyFloat());
- verify(mEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
- public void testReset_Magnifying_resetsMagnificationAndInvokeLastEndCallback() {
+ public void testReset_Magnifying_resetsMagnificationAndInvokeCallbacks() {
for (int i = 0; i < DISPLAY_COUNT; i++) {
- reset_Magnifying_resetsMagnificationAndInvokeLastEndCallback(i);
+ reset_Magnifying_resetsMagnificationAndInvokeCallbacks(i);
}
}
- private void reset_Magnifying_resetsMagnificationAndInvokeLastEndCallback(int displayId) {
+ private void reset_Magnifying_resetsMagnificationAndInvokeCallbacks(int displayId) {
register(displayId);
float scale = 2.5f;
PointF firstCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
- scale, firstCenter.x, firstCenter.y, mEndCallback, SERVICE_ID_1));
+ scale, firstCenter.x, firstCenter.y, mAnimationCallback, SERVICE_ID_1));
mMessageCapturingHandler.sendAllMessages();
Mockito.reset(mMockValueAnimator);
// Stubs the logic after the animation is started.
doAnswer(invocation -> {
+ mStateListener.onAnimationCancel(mMockValueAnimator);
mStateListener.onAnimationEnd(mMockValueAnimator);
return null;
}).when(mMockValueAnimator).cancel();
@@ -713,13 +712,14 @@
float fraction = 0.33f;
when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction);
mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
- Runnable lastEndCallback = Mockito.mock(Runnable.class);
+ MagnificationAnimationCallback lastAnimationCallback = Mockito.mock(
+ MagnificationAnimationCallback.class);
- assertTrue(mFullScreenMagnificationController.reset(displayId, lastEndCallback));
+ assertTrue(mFullScreenMagnificationController.reset(displayId, lastAnimationCallback));
mMessageCapturingHandler.sendAllMessages();
// Verify expected actions.
- verify(mEndCallback, never()).run();
+ verify(mAnimationCallback).onResult(false);
verify(mMockValueAnimator).start();
verify(mMockValueAnimator).cancel();
@@ -729,7 +729,7 @@
mStateListener.onAnimationEnd(mMockValueAnimator);
assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_0));
- verify(lastEndCallback).run();
+ verify(lastAnimationCallback).onResult(true);
}
@Test
@@ -1142,6 +1142,7 @@
verify(mMockValueAnimator).addListener(animatorListenerArgumentCaptor.capture());
mStateListener = animatorListenerArgumentCaptor.getValue();
Mockito.reset(mMockValueAnimator); // Ignore other initialization
+ Mockito.reset(mAnimationCallback);
}
private void zoomIn2xToMiddle(int displayId) {
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
index 609af8d..8d706cb 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -79,6 +79,23 @@
}
@Override
+ public int setDevicesRoleForCapturePreset(int capturePreset, int role,
+ @NonNull List<AudioDeviceAttributes> devices) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int removeDevicesRoleForCapturePreset(
+ int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devicesToRemove) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int clearDevicesRoleForCapturePreset(int capturePreset, int role) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
public int setParameters(String keyValuePairs) {
return AudioSystem.AUDIO_STATUS_OK;
}
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 1d04c83..e02a46af 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -24,7 +24,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.app.ActivityManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -984,8 +984,8 @@
}
@Override
- public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
- ActivityManager.StackInfo focusedStack = new ActivityManager.StackInfo();
+ public RootTaskInfo getFocusedStack() throws RemoteException {
+ RootTaskInfo focusedStack = new RootTaskInfo();
focusedStack.userId = 0;
focusedStack.topActivity = new ComponentName("a.package", "a.class");
return focusedStack;
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index b1f3871..73dda07 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -19,6 +19,7 @@
import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -28,18 +29,23 @@
import android.app.PropertyInvalidatedCache;
import android.content.Context;
+import android.graphics.Insets;
+import android.graphics.Rect;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.Curve;
import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.DisplayViewport;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
+import android.hardware.display.IDisplayManagerCallback;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
import android.hardware.input.InputManagerInternal;
import android.os.Handler;
import android.os.IBinder;
import android.view.Display;
+import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -282,6 +288,68 @@
}
/**
+ * Tests that there should be a display change notification to WindowManager to update its own
+ * internal state for things like display cutout when nonOverrideDisplayInfo is changed.
+ */
+ @Test
+ public void testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged() throws Exception {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mShortMockedInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+
+ // Add the FakeDisplayDevice
+ FakeDisplayDevice displayDevice = new FakeDisplayDevice();
+ DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
+ displayDeviceInfo.width = 100;
+ displayDeviceInfo.height = 200;
+ final Rect zeroRect = new Rect();
+ displayDeviceInfo.displayCutout = new DisplayCutout(
+ Insets.of(0, 10, 0, 0),
+ zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
+ displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
+ displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
+ displayManager.handleDisplayDeviceAdded(displayDevice);
+
+ // Find the display id of the added FakeDisplayDevice
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+ final int[] displayIds = bs.getDisplayIds();
+ assertTrue(displayIds.length > 0);
+ int displayId = Display.INVALID_DISPLAY;
+ for (int i = 0; i < displayIds.length; i++) {
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]);
+ if (displayDeviceInfo.equals(ddi)) {
+ displayId = displayIds[i];
+ break;
+ }
+ }
+ assertFalse(displayId == Display.INVALID_DISPLAY);
+
+ // Setup override DisplayInfo
+ DisplayInfo overrideInfo = bs.getDisplayInfo(displayId);
+ displayManager.setDisplayInfoOverrideFromWindowManagerInternal(displayId, overrideInfo);
+
+ Handler handler = displayManager.getDisplayHandler();
+ handler.runWithScissors(() -> {
+ }, 0 /* now */);
+
+ // register display listener callback
+ FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId);
+ bs.registerCallback(callback);
+
+ // Simulate DisplayDevice change
+ DisplayDeviceInfo displayDeviceInfo2 = new DisplayDeviceInfo();
+ displayDeviceInfo2.copyFrom(displayDeviceInfo);
+ displayDeviceInfo2.displayCutout = null;
+ displayDevice.setDisplayDeviceInfo(displayDeviceInfo2);
+ displayManager.handleDisplayDeviceChanged(displayDevice);
+
+ handler.runWithScissors(() -> {
+ }, 0 /* now */);
+ assertTrue(callback.mCalled);
+ }
+
+ /**
* Tests that we get a Runtime exception when we cannot initialize the default display.
*/
@Test
@@ -512,4 +580,42 @@
// flush the handler
handler.runWithScissors(() -> {}, 0 /* now */);
}
+
+ private class FakeDisplayManagerCallback extends IDisplayManagerCallback.Stub {
+ int mDisplayId;
+ boolean mCalled = false;
+
+ FakeDisplayManagerCallback(int displayId) {
+ mDisplayId = displayId;
+ }
+
+ @Override
+ public void onDisplayEvent(int displayId, int event) {
+ if (displayId == mDisplayId && event == DisplayManagerGlobal.EVENT_DISPLAY_CHANGED) {
+ mCalled = true;
+ }
+ }
+ }
+
+ private class FakeDisplayDevice extends DisplayDevice {
+ private DisplayDeviceInfo mDisplayDeviceInfo;
+
+ FakeDisplayDevice() {
+ super(null, null, "");
+ }
+
+ public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
+ mDisplayDeviceInfo = displayDeviceInfo;
+ }
+
+ @Override
+ public boolean hasStableUniqueId() {
+ return false;
+ }
+
+ @Override
+ public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+ return mDisplayDeviceInfo;
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
index 0839273..154d42c 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
@@ -21,172 +21,387 @@
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.os.Process
-import org.junit.Rule
+import com.android.server.om.OverlayActorEnforcer.ActorState
+import com.android.server.testutils.mockThrowOnUnmocked
+import com.android.server.testutils.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.BeforeClass
import org.junit.Test
-import org.junit.rules.ExpectedException
-import java.lang.UnsupportedOperationException
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.mockito.Mockito.spy
+import java.io.IOException
+@RunWith(Parameterized::class)
class OverlayActorEnforcerTests {
+
companion object {
- private const val NAMESPACE = "testnamespace"
- private const val ACTOR_NAME = "testactor"
- private const val ACTOR_PKG_NAME = "com.test.actor.one"
+ private const val TARGET_PKG = "com.test.target"
+ private const val OVERLAY_PKG = "com.test.overlay"
+
+ private const val VALID_NAMESPACE = "testNamespaceValid"
+ private const val INVALID_NAMESPACE = "testNamespaceInvalid"
+ private const val VALID_ACTOR_NAME = "testActorOne"
+ private const val INVALID_ACTOR_NAME = "testActorTwo"
+ private const val VALID_ACTOR_PKG = "com.test.actor.valid"
+ private const val INVALID_ACTOR_PKG = "com.test.actor.invalid"
private const val OVERLAYABLE_NAME = "TestOverlayable"
- private const val UID = 3536
+ private const val NULL_UID = 3536
+ private const val EMPTY_UID = NULL_UID + 1
+ private const val INVALID_ACTOR_UID = NULL_UID + 2
+ private const val VALID_ACTOR_UID = NULL_UID + 3
+ private const val TARGET_UID = NULL_UID + 4
private const val USER_ID = 55
- }
- @get:Rule
- val expectedException = ExpectedException.none()!!
+ @JvmStatic
+ @Parameterized.Parameters(name = "{0}")
+ fun parameters() = CASES.mapIndexed { caseIndex, testCase ->
+ fun param(pair: Pair<String, TestState.() -> Unit>, type: Params.Type): Params {
+ val expectedState = testCase.state.takeUnless { type == Params.Type.ALLOWED }
+ ?: ActorState.ALLOWED
+ val (caseName, case) = pair
+ val testName = makeTestName(testCase, caseName, type)
+ return Params(caseIndex, expectedState, testName, type, case)
+ }
- @Test
- fun isRoot() {
- verify(callingUid = Process.ROOT_UID)
- }
+ testCase.failures.map { param(it, Params.Type.FAILURE) } +
+ testCase.allowed.map { param(it, Params.Type.ALLOWED) }
+ }.flatten()
- @Test(expected = SecurityException::class)
- fun isShell() {
- verify(callingUid = Process.SHELL_UID)
- }
-
- @Test
- fun isSystem() {
- verify(callingUid = Process.SYSTEM_UID)
- }
-
- @Test(expected = SecurityException::class)
- fun noOverlayable_noTarget() {
- verify(targetOverlayableName = null)
- }
-
- @Test
- fun noOverlayable_noTarget_withPermission() {
- verify(targetOverlayableName = null, hasPermission = true)
- }
-
- @Test(expected = SecurityException::class)
- fun noOverlayable_withTarget() {
- verify(targetOverlayableName = OVERLAYABLE_NAME)
- }
-
- @Test(expected = SecurityException::class)
- fun withOverlayable_noTarget() {
- verify(
- targetOverlayableName = null,
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
- )
- }
-
- @Test(expected = SecurityException::class)
- fun withOverlayable_noActor() {
- verify(
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
- )
- }
-
- @Test
- fun withOverlayable_noActor_withPermission() {
- verify(
- hasPermission = true,
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
- )
- }
-
- @Test(expected = SecurityException::class)
- fun withOverlayable_withActor_notActor() {
- verify(
- isActor = false,
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
- "overlay://$NAMESPACE/$ACTOR_NAME")
- )
- }
-
- @Test(expected = SecurityException::class)
- fun withOverlayable_withActor_isActor_notPreInstalled() {
- verify(
- isActor = true,
- isPreInstalled = false,
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
- "overlay://$NAMESPACE/$ACTOR_NAME")
- )
- }
-
- @Test
- fun withOverlayable_withActor_isActor_isPreInstalled() {
- verify(
- isActor = true,
- isPreInstalled = true,
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
- "overlay://$NAMESPACE/$ACTOR_NAME")
- )
- }
-
- @Test(expected = SecurityException::class)
- fun withOverlayable_invalidActor() {
- verify(
- isActor = true,
- isPreInstalled = true,
- overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, "notValidActor")
- )
- }
-
- private fun verify(
- isActor: Boolean = false,
- isPreInstalled: Boolean = false,
- hasPermission: Boolean = false,
- overlayableInfo: OverlayableInfo? = null,
- callingUid: Int = UID,
- targetOverlayableName: String? = OVERLAYABLE_NAME
- ) {
- val callback = MockCallback(
- isActor = isActor,
- isPreInstalled = isPreInstalled,
- hasPermission = hasPermission,
- overlayableInfo = overlayableInfo
- )
-
- val overlayInfo = overlayInfo(targetOverlayableName)
- OverlayActorEnforcer(callback)
- .enforceActor(overlayInfo, "test", callingUid, USER_ID)
- }
-
- private fun overlayInfo(targetOverlayableName: String?) = OverlayInfo("com.test.overlay",
- "com.test.target", targetOverlayableName, null, "/path", OverlayInfo.STATE_UNKNOWN, 0,
- 0, false)
-
- private class MockCallback(
- private val isActor: Boolean = false,
- private val isPreInstalled: Boolean = false,
- private val hasPermission: Boolean = false,
- private val overlayableInfo: OverlayableInfo? = null,
- private vararg val packageNames: String = arrayOf("com.test.actor.one")
- ) : PackageManagerHelper {
-
- override fun getNamedActors() = if (isActor) {
- mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
- } else {
- emptyMap()
+ @BeforeClass
+ @JvmStatic
+ fun checkAllCasesHandled() {
+ // Assert that all states have been tested at least once.
+ assertThat(CASES.map { it.state }.distinct()).containsAllIn(ActorState.values())
}
+ @BeforeClass
+ @JvmStatic
+ fun checkAllCasesUniquelyNamed() {
+ val duplicateCaseNames = CASES.mapIndexed { caseIndex, testCase ->
+ testCase.failures.map {
+ makeTestName(testCase, it.first, Params.Type.FAILURE)
+ } + testCase.allowed.map {
+ makeTestName(testCase, it.first, Params.Type.ALLOWED)
+ }
+ }
+ .flatten()
+ .groupingBy { it }
+ .eachCount()
+ .filterValues { it > 1 }
+ .keys
+
+ assertThat(duplicateCaseNames).isEmpty()
+ }
+
+ /*
+ The pattern in this block is a result of the incredible number of branches in
+ enforcement logic. It serves to verify failures with the assumption that all errors
+ are checked in order. The idea is to emulate the if-else branches from code, but using
+ actual test data instead of if statements.
+
+ Each state is verified by providing a failure or exclusive set of failures which cause
+ a failure state to be returned. Each state also provides a success case which will
+ "skip" the state. This allows subsequent failure cases to cascade from the first case
+ by calling all the skip branches for preceding states and then choosing only 1 of
+ the failures to test.
+
+ Given the failure states A, B, and C: testA calls A.failure + assert, testB calls
+ A.skip + B.failure + assert, testC calls A.skip + B.skip + C.failure + assert, etc.
+
+ Calling `allowed` is a special case for when there is a combination of parameters that
+ skips the remaining checks and immediately allows the actor through. For these cases,
+ the first failure branch will be run, assert that it's not allowed, and the
+ allowed branch will run, asserting that it now results in ALLOWED, skipping all
+ remaining functions.
+
+ This is an ordered list of TestCase objects, with the possibility to repeat failure
+ states if any can occur multiple times in the logic tree.
+
+ Each failure must be handled at least once.
+ */
+ private val CASES = listOf(
+ ActorState.TARGET_NOT_FOUND withCases {
+ failure("nullPkgInfo") { targetPkgInfo = null }
+ allowed("debuggable") {
+ targetPkgInfo = pkgInfo(TARGET_PKG).apply {
+ applicationInfo.flags = ApplicationInfo.FLAG_DEBUGGABLE
+ }
+ }
+ skip { targetPkgInfo = pkgInfo(TARGET_PKG) }
+ },
+ ActorState.NO_PACKAGES_FOR_UID withCases {
+ failure("empty") { callingUid = EMPTY_UID }
+ failure("null") { callingUid = NULL_UID }
+ failure("shell") { callingUid = Process.SHELL_UID }
+ allowed("targetUid") { callingUid = TARGET_UID }
+ allowed("rootUid") { callingUid = Process.ROOT_UID }
+ allowed("systemUid") { callingUid = Process.SYSTEM_UID }
+ skip { callingUid = INVALID_ACTOR_UID }
+ },
+ ActorState.MISSING_TARGET_OVERLAYABLE_NAME withCases {
+ failure("nullTargetOverlayableName") {
+ overlayInfoParams.targetOverlayableName = null
+ targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
+ "overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME")
+ }
+ skip { overlayInfoParams.targetOverlayableName = OVERLAYABLE_NAME }
+ },
+ ActorState.MISSING_LEGACY_PERMISSION withCases {
+ failure("noPermission") {
+ overlayInfoParams.targetOverlayableName = null
+ targetOverlayableInfo = null
+ hasPermission = false
+ }
+ allowed("hasPermission") { hasPermission = true }
+ skip { overlayInfoParams.targetOverlayableName = OVERLAYABLE_NAME }
+ },
+ ActorState.ERROR_READING_OVERLAYABLE withCases {
+ failure("doesTargetDefineOverlayableIOException") {
+ overlayInfoParams.targetOverlayableName = null
+ whenever(doesTargetDefineOverlayable(TARGET_PKG, USER_ID))
+ .thenThrow(IOException::class.java)
+ }
+ skip { overlayInfoParams.targetOverlayableName = OVERLAYABLE_NAME }
+ },
+ ActorState.UNABLE_TO_GET_TARGET_OVERLAYABLE withCases {
+ failure("getOverlayableForTargetIOException") {
+ whenever(getOverlayableForTarget(TARGET_PKG, OVERLAYABLE_NAME,
+ USER_ID)).thenThrow(IOException::class.java)
+ }
+ },
+ ActorState.MISSING_OVERLAYABLE withCases {
+ failure("nullTargetOverlayableInfo") { targetOverlayableInfo = null }
+ skip {
+ targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
+ "overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME")
+ }
+ },
+ ActorState.MISSING_LEGACY_PERMISSION withCases {
+ failure("noPermissionNullActor") {
+ targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
+ hasPermission = false
+ }
+ failure("noPermissionEmptyActor") {
+ targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, "")
+ hasPermission = false
+ }
+ allowed("hasPermissionNullActor") {
+ hasPermission = true
+ }
+ skip {
+ targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
+ "overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME")
+ }
+ },
+ ActorState.INVALID_OVERLAYABLE_ACTOR_NAME withCases {
+ fun TestState.mockActor(actorUri: String) {
+ targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, actorUri)
+ }
+ failure("wrongScheme") {
+ mockActor("notoverlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME")
+ }
+ failure("extraPath") {
+ mockActor("overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME/extraPath")
+ }
+ failure("missingPath") { mockActor("overlay://$VALID_NAMESPACE") }
+ failure("missingAuthority") { mockActor("overlay://") }
+ skip { mockActor("overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME") }
+ },
+ ActorState.NO_NAMED_ACTORS withCases {
+ failure("empty") { namedActorsMap = emptyMap() }
+ skip {
+ namedActorsMap = mapOf(INVALID_NAMESPACE to
+ mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG))
+ }
+ },
+ ActorState.MISSING_NAMESPACE withCases {
+ failure("invalidNamespace") {
+ namedActorsMap = mapOf(INVALID_NAMESPACE to
+ mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG))
+ }
+ skip {
+ namedActorsMap = mapOf(VALID_NAMESPACE to
+ mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG))
+ }
+ },
+ ActorState.MISSING_ACTOR_NAME withCases {
+ failure("invalidActorName") {
+ namedActorsMap = mapOf(VALID_NAMESPACE to
+ mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG))
+ }
+ skip {
+ namedActorsMap = mapOf(VALID_NAMESPACE to
+ mapOf(VALID_ACTOR_NAME to VALID_ACTOR_PKG))
+ }
+ },
+ ActorState.MISSING_APP_INFO withCases {
+ failure("nullActorPkgInfo") { actorPkgInfo = null }
+ failure("nullActorAppInfo") {
+ actorPkgInfo = PackageInfo().apply { applicationInfo = null }
+ }
+ skip { actorPkgInfo = pkgInfo(VALID_ACTOR_PKG) }
+ },
+ ActorState.ACTOR_NOT_PREINSTALLED withCases {
+ failure("notSystem") {
+ actorPkgInfo = pkgInfo(VALID_ACTOR_PKG).apply {
+ applicationInfo.flags = 0
+ }
+ }
+ skip {
+ actorPkgInfo = pkgInfo(VALID_ACTOR_PKG).apply {
+ applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM
+ }
+ }
+ },
+ ActorState.INVALID_ACTOR withCases {
+ failure("invalidUid") { callingUid = INVALID_ACTOR_UID }
+ skip { callingUid = VALID_ACTOR_UID }
+ },
+ ActorState.ALLOWED withCases {
+ // No point making an exception for this case in all of the test code, so
+ // just pretend this is a failure that results in a success result code.
+ failure("allowed") { /* Do nothing */ }
+ }
+ )
+
+ data class OverlayInfoParams(
+ var targetPackageName: String = TARGET_PKG,
+ var targetOverlayableName: String? = null
+ ) {
+ fun toOverlayInfo() = OverlayInfo(
+ OVERLAY_PKG,
+ targetPackageName,
+ targetOverlayableName,
+ null,
+ "/path",
+ OverlayInfo.STATE_UNKNOWN, 0,
+ 0, false)
+ }
+
+ private infix fun ActorState.withCases(block: TestCase.() -> Unit) =
+ TestCase(this).apply(block)
+
+ private fun pkgInfo(pkgName: String): PackageInfo = mockThrowOnUnmocked {
+ this.packageName = pkgName
+ this.applicationInfo = ApplicationInfo().apply {
+ this.packageName = pkgName
+ }
+ }
+
+ private fun makeTestName(testCase: TestCase, caseName: String, type: Params.Type): String {
+ val resultSuffix = if (type == Params.Type.ALLOWED) "allowed" else "failed"
+ return "${testCase.state}_${resultSuffix}_$caseName"
+ }
+ }
+
+ @Parameterized.Parameter(0)
+ lateinit var params: Params
+
+ @Test
+ fun verify() {
+ // Apply all the skip states before the failure to be verified
+ val testState = CASES.take(params.index)
+ .fold(TestState.create()) { testState, case ->
+ testState.apply(case.skip)
+ }
+
+ // If testing an allowed branch, first apply a failure to ensure it fails
+ if (params.type == Params.Type.ALLOWED) {
+ CASES[params.index].failures.firstOrNull()?.second?.run(testState::apply)
+ assertThat(testState.toResult()).isNotEqualTo(ActorState.ALLOWED)
+ }
+
+ // Apply the test case in the params to the collected state
+ testState.apply(params.function)
+
+ // Assert the result matches the expected state
+ assertThat(testState.toResult()).isEqualTo(params.expectedState)
+ }
+
+ private fun TestState.toResult() = OverlayActorEnforcer(this)
+ .isAllowedActor("test", overlayInfoParams.toOverlayInfo(), callingUid, USER_ID)
+
+ data class Params(
+ var index: Int,
+ var expectedState: ActorState,
+ val testName: String,
+ val type: Type,
+ val function: TestState.() -> Unit
+ ) {
+ override fun toString() = testName
+
+ enum class Type {
+ FAILURE,
+ ALLOWED
+ }
+ }
+
+ data class TestCase(
+ val state: ActorState,
+ val failures: MutableList<Pair<String, TestState.() -> Unit>> = mutableListOf(),
+ var allowed: MutableList<Pair<String, TestState.() -> Unit>> = mutableListOf(),
+ var skip: (TestState.() -> Unit) = {}
+ ) {
+ fun failure(caseName: String, block: TestState.() -> Unit) {
+ failures.add(caseName to block)
+ }
+
+ fun allowed(caseName: String, block: TestState.() -> Unit) {
+ allowed.add(caseName to block)
+ }
+
+ fun skip(block: TestState.() -> Unit) {
+ this.skip = block
+ }
+ }
+
+ open class TestState private constructor(
+ var callingUid: Int = NULL_UID,
+ val overlayInfoParams: OverlayInfoParams = OverlayInfoParams(),
+ var namedActorsMap: Map<String, Map<String, String>> = emptyMap(),
+ var hasPermission: Boolean = false,
+ var targetOverlayableInfo: OverlayableInfo? = null,
+ var targetPkgInfo: PackageInfo? = null,
+ var actorPkgInfo: PackageInfo? = null,
+ vararg val packageNames: String = arrayOf("com.test.actor.one")
+ ) : PackageManagerHelper {
+
+ companion object {
+ // Enforce that new instances are spied
+ fun create() = spy(TestState())!!
+ }
+
+ override fun getNamedActors() = namedActorsMap
+
+ @Throws(IOException::class)
override fun getOverlayableForTarget(
packageName: String,
targetOverlayableName: String,
userId: Int
- ) = overlayableInfo
+ ) = targetOverlayableInfo?.takeIf {
+ // Protect against this method being called with the wrong package name
+ targetPkgInfo == null || targetPkgInfo?.packageName == packageName
+ }
override fun getPackagesForUid(uid: Int) = when (uid) {
- UID -> packageNames
+ EMPTY_UID -> emptyArray()
+ INVALID_ACTOR_UID -> arrayOf(INVALID_ACTOR_PKG)
+ VALID_ACTOR_UID -> arrayOf(VALID_ACTOR_PKG)
+ TARGET_UID -> arrayOf(TARGET_PKG)
+ NULL_UID -> null
else -> null
}
- override fun getPackageInfo(packageName: String, userId: Int) = PackageInfo().apply {
- applicationInfo = ApplicationInfo().apply {
- flags = if (isPreInstalled) ApplicationInfo.FLAG_SYSTEM else 0
- }
- }
+ override fun getPackageInfo(packageName: String, userId: Int) =
+ listOfNotNull(targetPkgInfo, actorPkgInfo).find { it.packageName == packageName }
+ @Throws(IOException::class) // Mockito requires this checked exception to be declared
override fun doesTargetDefineOverlayable(targetPackageName: String?, userId: Int): Boolean {
- return overlayableInfo != null
+ return targetOverlayableInfo?.takeIf {
+ // Protect against this method being called with the wrong package name
+ targetPkgInfo == null || targetPkgInfo?.packageName == targetPackageName
+ } != null
}
override fun enforcePermission(permission: String?, message: String?) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 0bf06bb..dac0542 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -45,6 +45,7 @@
import android.content.pm.UserInfo;
import android.os.BaseBundle;
import android.os.PersistableBundle;
+import android.os.Process;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.util.ArrayMap;
@@ -59,8 +60,12 @@
import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.server.LocalServices;
+import com.android.server.pm.parsing.pkg.PackageImpl;
+import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.permission.PermissionSettings;
+import com.google.common.truth.Truth;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -380,6 +385,74 @@
}
@Test
+ public void testWriteReadUsesStaticLibraries() {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final Object lock = new Object();
+ final Settings settingsUnderTest = new Settings(context.getFilesDir(), mPermissionSettings,
+ mRuntimePermissionsPersistence, lock);
+ final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1);
+ ps1.appId = Process.FIRST_APPLICATION_UID;
+ ps1.pkg = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed())
+ .setUid(ps1.appId)
+ .setSystem(true)
+ .hideAsFinal();
+ final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2);
+ ps2.appId = Process.FIRST_APPLICATION_UID + 1;
+ ps2.pkg = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_2).hideAsParsed())
+ .setUid(ps2.appId)
+ .hideAsFinal();
+
+ ps1.usesStaticLibraries = new String[] { "com.example.shared.one" };
+ ps1.usesStaticLibrariesVersions = new long[] { 12 };
+ ps1.setFlags(ps1.pkgFlags | ApplicationInfo.FLAG_SYSTEM);
+ settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1);
+ assertThat(settingsUnderTest.disableSystemPackageLPw(PACKAGE_NAME_1, false), is(true));
+
+ ps2.usesStaticLibraries = new String[] { "com.example.shared.two" };
+ ps2.usesStaticLibrariesVersions = new long[] { 34 };
+ settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
+
+ settingsUnderTest.writeLPr();
+
+ settingsUnderTest.mPackages.clear();
+ settingsUnderTest.mDisabledSysPackages.clear();
+
+ assertThat(settingsUnderTest.readLPw(createFakeUsers()), is(true));
+
+ PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1);
+ PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2);
+
+ Truth.assertThat(readPs1).isNotNull();
+ Truth.assertThat(readPs1.usesStaticLibraries).isNotNull();
+ Truth.assertThat(readPs1.usesStaticLibrariesVersions).isNotNull();
+ Truth.assertThat(readPs2).isNotNull();
+ Truth.assertThat(readPs2.usesStaticLibraries).isNotNull();
+ Truth.assertThat(readPs2.usesStaticLibrariesVersions).isNotNull();
+
+ List<Long> ps1VersionsAsList = new ArrayList<>();
+ for (long version : ps1.usesStaticLibrariesVersions) {
+ ps1VersionsAsList.add(version);
+ }
+
+ List<Long> ps2VersionsAsList = new ArrayList<>();
+ for (long version : ps2.usesStaticLibrariesVersions) {
+ ps2VersionsAsList.add(version);
+ }
+
+ Truth.assertThat(readPs1.usesStaticLibraries).asList()
+ .containsExactlyElementsIn(ps1.usesStaticLibraries).inOrder();
+
+ Truth.assertThat(readPs1.usesStaticLibrariesVersions).asList()
+ .containsExactlyElementsIn(ps1VersionsAsList).inOrder();
+
+ Truth.assertThat(readPs2.usesStaticLibraries).asList()
+ .containsExactlyElementsIn(ps2.usesStaticLibraries).inOrder();
+
+ Truth.assertThat(readPs2.usesStaticLibrariesVersions).asList()
+ .containsExactlyElementsIn(ps2VersionsAsList).inOrder();
+ }
+
+ @Test
public void testPackageRestrictionsDistractionFlagsDefault() {
final PackageSetting defaultSetting = createPackageSetting(PACKAGE_NAME_1);
assertThat(defaultSetting.getDistractionFlags(0), is(PackageManager.RESTRICTION_NONE));
@@ -617,7 +690,7 @@
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/);
- assertThat(testPkgSetting01.getCodePath(), is(UPDATED_CODE_PATH));
+ assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH));
assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM));
assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
@@ -656,7 +729,7 @@
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/);
assertThat(testPkgSetting01.appId, is(0));
- assertThat(testPkgSetting01.getCodePath(), is(INITIAL_CODE_PATH));
+ assertThat(testPkgSetting01.getPath(), is(INITIAL_CODE_PATH));
assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
assertThat(testPkgSetting01.pkgFlags, is(0));
assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
@@ -700,7 +773,7 @@
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/);
assertThat(testPkgSetting01.appId, is(10064));
- assertThat(testPkgSetting01.getCodePath(), is(INITIAL_CODE_PATH));
+ assertThat(testPkgSetting01.getPath(), is(INITIAL_CODE_PATH));
assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
assertThat(testPkgSetting01.pkgFlags, is(0));
assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
@@ -741,7 +814,7 @@
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/);
assertThat(testPkgSetting01.appId, is(10064));
- assertThat(testPkgSetting01.getCodePath(), is(UPDATED_CODE_PATH));
+ assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH));
assertThat(testPkgSetting01.name, is(PACKAGE_NAME));
assertThat(testPkgSetting01.pkgFlags, is(0));
assertThat(testPkgSetting01.pkgPrivateFlags, is(0));
@@ -792,10 +865,10 @@
private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) {
assertThat(origPkgSetting, is(not(testPkgSetting)));
assertThat(origPkgSetting.appId, is(testPkgSetting.appId));
- assertSame(origPkgSetting.getCodePath(), testPkgSetting.getCodePath());
- assertThat(origPkgSetting.getCodePath(), is(testPkgSetting.getCodePath()));
- assertSame(origPkgSetting.getCodePathString(), testPkgSetting.getCodePathString());
- assertThat(origPkgSetting.getCodePathString(), is(testPkgSetting.getCodePathString()));
+ assertSame(origPkgSetting.getPath(), testPkgSetting.getPath());
+ assertThat(origPkgSetting.getPath(), is(testPkgSetting.getPath()));
+ assertSame(origPkgSetting.getPathString(), testPkgSetting.getPathString());
+ assertThat(origPkgSetting.getPathString(), is(testPkgSetting.getPathString()));
assertSame(origPkgSetting.cpuAbiOverrideString, testPkgSetting.cpuAbiOverrideString);
assertThat(origPkgSetting.cpuAbiOverrideString, is(testPkgSetting.cpuAbiOverrideString));
assertThat(origPkgSetting.firstInstallTime, is(testPkgSetting.firstInstallTime));
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 2651cfa..1d384e9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -312,7 +312,7 @@
private static PackageSetting mockPkgSetting(AndroidPackage pkg) {
return new PackageSetting(pkg.getPackageName(), pkg.getRealPackage(),
- new File(pkg.getCodePath()), null, pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi(),
+ new File(pkg.getPath()), null, pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi(),
null, pkg.getVersionCode(),
PackageInfoUtils.appInfoFlags(pkg, null),
PackageInfoUtils.appInfoPrivateFlags(pkg, null),
@@ -335,8 +335,8 @@
assertEquals(a.getPackageName(), b.getPackageName());
assertArrayEquals(a.getSplitNames(), b.getSplitNames());
assertEquals(a.getVolumeUuid(), b.getVolumeUuid());
- assertEquals(a.getCodePath(), b.getCodePath());
- assertEquals(a.getBaseCodePath(), b.getBaseCodePath());
+ assertEquals(a.getPath(), b.getPath());
+ assertEquals(a.getBaseApkPath(), b.getBaseApkPath());
assertArrayEquals(a.getSplitCodePaths(), b.getSplitCodePaths());
assertArrayEquals(a.getSplitRevisionCodes(), b.getSplitRevisionCodes());
assertArrayEquals(a.getSplitFlags(), b.getSplitFlags());
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
index 56dddb0..4d8cc4647 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -533,7 +533,7 @@
arrayContaining("some.static.library", "some.other.static.library"));
assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L}));
assertThat(pkgSetting.pkg, is(scanResult.request.parsedPackage));
- assertThat(pkgSetting.getCodePath(), is(new File(createCodePath(packageName))));
+ assertThat(pkgSetting.getPath(), is(new File(createCodePath(packageName))));
assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345)));
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
index caa8ae5..3ce7a7d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
@@ -29,12 +29,10 @@
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.parsing.ApkLiteParseUtils;
-import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.os.FileUtils;
-import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -106,9 +104,9 @@
Map<String, String> packageDexMetadata = AndroidPackageUtils.getPackageDexMetadata(pkg);
assertEquals(1, packageDexMetadata.size());
- String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath());
+ String baseDexMetadata = packageDexMetadata.get(pkg.getBaseApkPath());
assertNotNull(baseDexMetadata);
- assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath()));
+ assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseApkPath()));
}
@Test
@@ -122,9 +120,9 @@
Map<String, String> packageDexMetadata = AndroidPackageUtils.getPackageDexMetadata(pkg);
assertEquals(2, packageDexMetadata.size());
- String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath());
+ String baseDexMetadata = packageDexMetadata.get(pkg.getBaseApkPath());
assertNotNull(baseDexMetadata);
- assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath()));
+ assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseApkPath()));
String splitDexMetadata = packageDexMetadata.get(pkg.getSplitCodePaths()[0]);
assertNotNull(splitDexMetadata);
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java
new file mode 100644
index 0000000..7049efa1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TestState.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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.server.timezonedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+
+/**
+ * A test support class used for tracking a piece of state in test objects like fakes and mocks.
+ * State can optionally be initialized using {@link #init}, which sets the value to an initial
+ * value, but is not treated as a change. Calls to {@link #set} are tracked and can be checked for
+ * during tests. The change-tracking can be cleared by calling {@link #commitLatest}, which puts the
+ * object into an unchanged state and sets the initial value to the latest value passed to
+ * {@link #set}.
+ */
+public class TestState<T> {
+ private T mInitialValue;
+ private final ArrayList<T> mValues = new ArrayList<>(5);
+
+ /** Sets the initial value for the state. */
+ public void init(T value) {
+ mValues.clear();
+ mInitialValue = value;
+ }
+
+ /** Sets the latest value for the state. */
+ public void set(T value) {
+ mValues.add(value);
+ }
+
+ /** Returns {@code true} if {@link #set} has been called. */
+ public boolean hasBeenSet() {
+ return mValues.size() > 0;
+ }
+
+ /** Fails if {@link #set} has been called. */
+ public void assertHasNotBeenSet() {
+ assertFalse(hasBeenSet());
+ }
+
+ /** Fails if {@link #set} has not been called. */
+ public void assertHasBeenSet() {
+ assertTrue(hasBeenSet());
+ }
+
+ /**
+ * Clears tracked changes and re-initializes using the latest set value as the initial value.
+ */
+ public void commitLatest() {
+ if (hasBeenSet()) {
+ mInitialValue = mValues.get(mValues.size() - 1);
+ mValues.clear();
+ }
+ }
+
+ /** Asserts the latest value passed to {@link #set} equals {@code expected}. */
+ public void assertLatestEquals(T expected) {
+ assertEquals(expected, getLatest());
+ }
+
+ /** Asserts the number of times {@link #set} has been called. */
+ public void assertChangeCount(int expectedCount) {
+ assertEquals(expectedCount, mValues.size());
+ }
+
+ /**
+ * Returns the latest value passed to {@link #set}. If {@link #set} hasn't been called then the
+ * initial value is returned.
+ */
+ public T getLatest() {
+ if (hasBeenSet()) {
+ return mValues.get(mValues.size() - 1);
+ }
+ return mInitialValue;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index 2bee5e5..1cdf193 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -54,7 +54,6 @@
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -994,55 +993,6 @@
}
}
- /** Some piece of state that tests want to track. */
- private static class TestState<T> {
- private T mInitialValue;
- private LinkedList<T> mValues = new LinkedList<>();
-
- void init(T value) {
- mValues.clear();
- mInitialValue = value;
- }
-
- void set(T value) {
- mValues.addFirst(value);
- }
-
- boolean hasBeenSet() {
- return mValues.size() > 0;
- }
-
- void assertHasNotBeenSet() {
- assertFalse(hasBeenSet());
- }
-
- void assertHasBeenSet() {
- assertTrue(hasBeenSet());
- }
-
- void commitLatest() {
- if (hasBeenSet()) {
- mInitialValue = mValues.getLast();
- mValues.clear();
- }
- }
-
- void assertLatestEquals(T expected) {
- assertEquals(expected, getLatest());
- }
-
- void assertChangeCount(int expectedCount) {
- assertEquals(expectedCount, mValues.size());
- }
-
- public T getLatest() {
- if (hasBeenSet()) {
- return mValues.getFirst();
- }
- return mInitialValue;
- }
- }
-
/**
* A "fluent" class allows reuse of code in tests: initialization, simulation and verification
* logic.
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 7c7b1a2..2aeab20 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -139,10 +139,13 @@
private AppStandbyController mController;
private CountDownLatch mStateChangedLatch = new CountDownLatch(1);
+ private String mLatchPkgName = null;
private AppIdleStateChangeListener mListener = new AppIdleStateChangeListener() {
@Override
public void onAppIdleStateChanged(String packageName, int userId,
boolean idle, int bucket, int reason) {
+ // Ignore events not related to mLatchPkgName, if set.
+ if (mLatchPkgName != null && !mLatchPkgName.equals(packageName)) return;
mStateChangedLatch.countDown();
}
};
@@ -374,6 +377,7 @@
mInjector.mElapsedRealtime, false));
controller.addListener(mListener);
+ mLatchPkgName = null;
return controller;
}
@@ -1377,7 +1381,7 @@
@Test
public void testUnexemptedSyncScheduled() throws Exception {
- mStateChangedLatch = new CountDownLatch(1);
+ rearmLatch(PACKAGE_1);
mController.addListener(mListener);
assertEquals("Test package did not start in the Never bucket", STANDBY_BUCKET_NEVER,
getStandbyBucket(mController, PACKAGE_1));
@@ -1389,7 +1393,7 @@
setAndAssertBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM);
- mStateChangedLatch = new CountDownLatch(1);
+ rearmLatch(PACKAGE_1);
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, false);
mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Unexempted sync scheduled should not elevate a non Never bucket",
@@ -1400,7 +1404,7 @@
public void testExemptedSyncScheduled() throws Exception {
setAndAssertBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM);
mInjector.mDeviceIdleMode = true;
- mStateChangedLatch = new CountDownLatch(1);
+ rearmLatch(PACKAGE_1);
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, true);
mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Exempted sync scheduled in doze should set bucket to working set",
@@ -1408,7 +1412,7 @@
setAndAssertBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM);
mInjector.mDeviceIdleMode = false;
- mStateChangedLatch = new CountDownLatch(1);
+ rearmLatch(PACKAGE_1);
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, true);
mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Exempted sync scheduled while not in doze should set bucket to active",
@@ -1558,10 +1562,19 @@
}
private void setAndAssertBucket(String pkg, int user, int bucket, int reason) throws Exception {
- mStateChangedLatch = new CountDownLatch(1);
+ rearmLatch(pkg);
mController.setAppStandbyBucket(pkg, user, bucket, reason);
mStateChangedLatch.await(100, TimeUnit.MILLISECONDS);
assertEquals("Failed to set package bucket", bucket,
getStandbyBucket(mController, PACKAGE_1));
}
+
+ private void rearmLatch(String pkgName) {
+ mLatchPkgName = pkgName;
+ mStateChangedLatch = new CountDownLatch(1);
+ }
+
+ private void rearmLatch() {
+ rearmLatch(null);
+ }
}
diff --git a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
index 056fa88..59cbd1c 100644
--- a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
+++ b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
@@ -22,8 +22,6 @@
import org.mockito.stubbing.Answer
import org.mockito.stubbing.Stubber
-// TODO(chiuwinson): Move this entire file to a shared utility module
-// TODO(b/135203078): De-dupe utils added for overlays vs package refactor
object MockitoUtils {
val ANSWER_THROWS = Answer<Any?> {
when (val name = it.method.name) {
@@ -64,7 +62,7 @@
fun whenever(mock: Unit) = Mockito.`when`(mock).thenAnswer { }
-inline fun <reified T> spyThrowOnUnmocked(value: T?, block: T.() -> Unit): T {
+inline fun <reified T> spyThrowOnUnmocked(value: T?, block: T.() -> Unit = {}): T {
val swappingAnswer = object : Answer<Any?> {
var delegate: Answer<*> = Answers.RETURNS_DEFAULTS
@@ -81,4 +79,5 @@
}
}
-inline fun <reified T> mockThrowOnUnmocked(block: T.() -> Unit) = spyThrowOnUnmocked<T>(null, block)
+inline fun <reified T> mockThrowOnUnmocked(block: T.() -> Unit = {}) =
+ spyThrowOnUnmocked<T>(null, block)
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 8644719..9e7226e7 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -1086,12 +1086,18 @@
}
/**
- * Confirm the system user on automotive devices can use car categories
+ * Confirm an application with the SEND_CATEGORY_CAR_NOTIFICATIONS permission on automotive
+ * devices can use car categories.
*/
@Test
- public void testEnqueuedRestrictedNotifications_asSystem() throws Exception {
+ public void testEnqueuedRestrictedNotifications_hasPermission() throws Exception {
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
.thenReturn(true);
+ // SEND_CATEGORY_CAR_NOTIFICATIONS is a system-level permission that this test cannot
+ // obtain. Mocking out enforce permission call to ensure notifications can be created when
+ // permitted.
+ doNothing().when(mContext).enforceCallingPermission(
+ eq("android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"), anyString());
List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
Notification.CATEGORY_CAR_WARNING,
Notification.CATEGORY_CAR_INFORMATION);
@@ -1114,7 +1120,6 @@
*/
@Test
public void testEnqueuedRestrictedNotifications_notAutomotive() throws Exception {
- mService.isSystemUid = false;
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
.thenReturn(false);
List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
@@ -1134,12 +1139,11 @@
}
/**
- * Confirm if a non-system user tries to use the car categories on a automotive device that
- * they will get a security exception
+ * Confirm if an application tries to use the car categories on a automotive device without the
+ * SEND_CATEGORY_CAR_NOTIFICATIONS permission that a security exception will be thrown.
*/
@Test
- public void testEnqueuedRestrictedNotifications_badUser() throws Exception {
- mService.isSystemUid = false;
+ public void testEnqueuedRestrictedNotifications_noPermission() throws Exception {
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
.thenReturn(true);
List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java
new file mode 100644
index 0000000..f6c854e
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.slice;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.UiServiceTestCase;
+import com.android.server.slice.SliceManagerService.PackageMatchingCache;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.function.Supplier;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class PackageMatchingCacheTest extends UiServiceTestCase {
+
+ private final Supplier<String> supplier = mock(Supplier.class);
+ private final PackageMatchingCache cache = new PackageMatchingCache(supplier);
+
+ @Test
+ public void testNulls() {
+ // Doesn't get for a null input
+ cache.matches(null);
+ verify(supplier, never()).get();
+
+ // Gets once valid input in sent.
+ cache.matches("");
+ verify(supplier).get();
+ }
+
+ @Test
+ public void testCaching() {
+ when(supplier.get()).thenReturn("ret.pkg");
+
+ assertTrue(cache.matches("ret.pkg"));
+ assertTrue(cache.matches("ret.pkg"));
+ assertTrue(cache.matches("ret.pkg"));
+
+ verify(supplier, times(1)).get();
+ }
+
+ @Test
+ public void testGetOnFailure() {
+ when(supplier.get()).thenReturn("ret.pkg");
+ assertTrue(cache.matches("ret.pkg"));
+
+ when(supplier.get()).thenReturn("other.pkg");
+ assertTrue(cache.matches("other.pkg"));
+ verify(supplier, times(2)).get();
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index cf1c36c..a443695 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -90,6 +90,8 @@
@Test
public void testAddPinCreatesPinned() throws RemoteException {
+ doReturn("pkg").when(mService).getDefaultHome(anyInt());
+
mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
verify(mService, times(1)).createPinnedSlice(eq(maybeAddUserId(TEST_URI, 0)), anyString());
@@ -97,6 +99,8 @@
@Test
public void testRemovePinDestroysPinned() throws RemoteException {
+ doReturn("pkg").when(mService).getDefaultHome(anyInt());
+
mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
when(mCreatedSliceState.unpin(eq("pkg"), eq(mToken))).thenReturn(false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 1eb45d5..cf07183 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -67,7 +67,7 @@
final TaskDisplayArea taskDisplayAreas =
mRootWindowContainer.getDefaultDisplay().getDefaultTaskDisplayArea();
final Task stack =
- new StackBuilder(mRootWindowContainer).setOnTop(!ON_TOP).build();
+ new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
final Task prevFocusedStack = taskDisplayAreas.getFocusedStack();
stack.moveToFront("moveStackToFront");
@@ -90,7 +90,7 @@
final Task pinnedStack = mRootWindowContainer.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task pinnedTask = new TaskBuilder(mAtm.mStackSupervisor)
- .setStack(pinnedStack).build();
+ .setParentTask(pinnedStack).build();
new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
.setTask(pinnedTask).build();
pinnedStack.moveToFront("movePinnedStackToFront");
@@ -144,7 +144,7 @@
doReturn(false).when(display).shouldDestroyContentOnRemove();
// Put home stack on the display.
- final Task homeStack = new StackBuilder(mRootWindowContainer)
+ final Task homeStack = new TaskBuilder(mSupervisor)
.setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build();
// Put a finishing standard activity which will be reparented.
@@ -163,7 +163,7 @@
final Task fullscreenStack = display.getDefaultTaskDisplayArea().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task fullscreenTask = new TaskBuilder(mAtm.mStackSupervisor)
- .setStack(fullscreenStack).build();
+ .setParentTask(fullscreenStack).build();
new ActivityBuilder(mAtm).setTask(fullscreenTask).build();
return fullscreenStack;
}
@@ -175,12 +175,11 @@
public void testTopRunningActivity() {
final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
final KeyguardController keyguard = mSupervisor.getKeyguardController();
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = stack.getTopNonFinishingActivity();
// Create empty stack on top.
- final Task emptyStack =
- new StackBuilder(mRootWindowContainer).setCreateActivity(false).build();
+ final Task emptyStack = new TaskBuilder(mSupervisor).build();
// Make sure the top running activity is not affected when keyguard is not locked.
assertTopRunningActivity(activity, display);
@@ -322,10 +321,10 @@
ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task stack4 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task task1 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack1).build();
- final Task task2 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack2).build();
- final Task task3 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack3).build();
- final Task task4 = new TaskBuilder(mAtm.mStackSupervisor).setStack(stack4).build();
+ final Task task1 = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(stack1).build();
+ final Task task2 = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(stack2).build();
+ final Task task3 = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(stack3).build();
+ final Task task4 = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(stack4).build();
// Reordering stacks while removing stacks.
doAnswer(invocation -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index eb78172..e860f25 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -341,9 +341,8 @@
public void testConsecutiveLaunchOnDifferentDisplay() {
onActivityLaunched(mTopActivity);
- final Task stack = new StackBuilder(mRootWindowContainer)
+ final Task stack = new TaskBuilder(mSupervisor)
.setDisplay(addNewDisplayContentAt(DisplayContent.POSITION_BOTTOM))
- .setCreateActivity(false)
.build();
final ActivityRecord activityOnNewDisplay = new ActivityBuilder(mAtm)
.setStack(stack)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index bca990c..89a0c7c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -73,7 +73,6 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
@@ -131,7 +130,7 @@
@Before
public void setUp() throws Exception {
- mStack = new StackBuilder(mRootWindowContainer).build();
+ mStack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
mTask = mStack.getBottomMostTask();
mActivity = mTask.getTopNonFinishingActivity();
@@ -172,7 +171,7 @@
@Test
public void testNoCleanupMovingActivityInSameStack() {
- final Task newTask = new TaskBuilder(mAtm.mStackSupervisor).setStack(mStack).build();
+ final Task newTask = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(mStack).build();
mActivity.reparent(newTask, 0, null /*reason*/);
verify(mStack, times(0)).cleanUpActivityReferences(any());
}
@@ -262,7 +261,7 @@
// Set options for two ActivityRecords in separate Tasks. Apply one ActivityRecord options.
// Pending options should be cleared for only ActivityRecord that was applied
- Task task2 = new TaskBuilder(mAtm.mStackSupervisor).setStack(mStack).build();
+ Task task2 = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(mStack).build();
activity2 = new ActivityBuilder(mAtm).setTask(task2).build();
activity2.updateOptionsLocked(activityOptions);
mActivity.updateOptionsLocked(activityOptions);
@@ -548,7 +547,7 @@
.build();
mActivity.setState(Task.ActivityState.STOPPED, "Testing");
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
try {
doReturn(false).when(stack).isTranslucent(any());
assertFalse(mStack.shouldBeVisible(null /* starting */));
@@ -756,14 +755,14 @@
@Test
public void testFinishActivityIfPossible_adjustStackOrder() {
// Prepare the stacks with order (top to bottom): mStack, stack1, stack2.
- final Task stack1 = new StackBuilder(mRootWindowContainer).build();
+ final Task stack1 = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
mStack.moveToFront("test");
// The stack2 is needed here for moving back to simulate the
// {@link DisplayContent#mPreferredTopFocusableStack} is cleared, so
// {@link DisplayContent#getFocusedStack} will rely on the order of focusable-and-visible
// stacks. Then when mActivity is finishing, its stack will be invisible (no running
// activities in the stack) that is the key condition to verify.
- final Task stack2 = new StackBuilder(mRootWindowContainer).build();
+ final Task stack2 = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
stack2.moveToBack("test", stack2.getBottomMostTask());
assertTrue(mStack.isTopStackInDisplayArea());
@@ -973,7 +972,7 @@
// Simulates that {@code currentTop} starts an existing activity from background (so its
// state is stopped) and the starting flow just goes to place it at top.
- final Task nextStack = new StackBuilder(mRootWindowContainer).build();
+ final Task nextStack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord nextTop = nextStack.getTopNonFinishingActivity();
nextTop.setState(STOPPED, "test");
@@ -1095,7 +1094,7 @@
// Add another stack to become focused and make the activity there visible. This way it
// simulates finishing in non-focused stack in split-screen.
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord focusedActivity = stack.getTopMostActivity();
focusedActivity.nowVisible = true;
focusedActivity.mVisibleRequested = true;
@@ -1581,7 +1580,7 @@
// Create a new task with custom config to reparent the activity to.
final Task newTask =
- new TaskBuilder(mSupervisor).setStack(initialTask.getRootTask()).build();
+ new TaskBuilder(mSupervisor).setParentTask(initialTask.getRootTask()).build();
final Configuration newConfig = newTask.getConfiguration();
newConfig.densityDpi += 100;
newTask.onRequestedOverrideConfigurationChanged(newConfig);
@@ -1613,7 +1612,7 @@
// Create a new task with custom config to reparent the second activity to.
final Task newTask =
- new TaskBuilder(mSupervisor).setStack(initialTask.getRootTask()).build();
+ new TaskBuilder(mSupervisor).setParentTask(initialTask.getRootTask()).build();
final Configuration newConfig = newTask.getConfiguration();
newConfig.densityDpi += 100;
newTask.onRequestedOverrideConfigurationChanged(newConfig);
@@ -1671,8 +1670,6 @@
@Test
public void testCanTurnScreenOn() {
mStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- doReturn(true).when(mStack).checkKeyguardVisibility(
- same(mActivity), eq(true) /* shouldBeVisible */, anyBoolean());
doReturn(true).when(mActivity).getTurnScreenOnFlag();
assertTrue(mActivity.canTurnScreenOn());
@@ -1681,8 +1678,6 @@
@Test
public void testFreeformWindowCantTurnScreenOn() {
mStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
- doReturn(true).when(mStack).checkKeyguardVisibility(
- same(mActivity), eq(true) /* shouldBeVisible */, anyBoolean());
doReturn(true).when(mActivity).getTurnScreenOnFlag();
assertFalse(mActivity.canTurnScreenOn());
@@ -1750,7 +1745,7 @@
}
final Task stack = display.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
return new ActivityBuilder(mAtm).setTask(task).setUseProcess(process).build();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 27e2d13..f9ad49b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -115,8 +115,8 @@
public void testHandleNonResizableTaskOnSecondaryDisplay() {
// Create an unresizable task on secondary display.
final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
- final Task stack = new StackBuilder(mRootWindowContainer)
- .setDisplay(newDisplay).build();
+ final Task stack = new TaskBuilder(mSupervisor)
+ .setDisplay(newDisplay).setCreateActivity(true).build();
final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
final Task task = unresizableActivity.getTask();
unresizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 524f32d..a60f93a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -100,7 +100,7 @@
mStack = mDefaultTaskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
spyOn(mStack);
- mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
+ mTask = new TaskBuilder(mSupervisor).setParentTask(mStack).build();
}
@Test
@@ -330,7 +330,7 @@
targetActivity);
final ComponentName alias = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
aliasActivity);
- final Task task = new TaskBuilder(mAtm.mStackSupervisor).setStack(mStack).build();
+ final Task task = new TaskBuilder(mAtm.mStackSupervisor).setParentTask(mStack).build();
task.origActivity = alias;
task.realActivity = target;
new ActivityBuilder(mAtm).setComponent(target).setTask(task).setTargetActivity(
@@ -995,7 +995,7 @@
mDefaultTaskDisplayArea.positionChildAt(onTop ? POSITION_TOP : POSITION_BOTTOM, task,
false /* includingParents */);
} else {
- task = new StackBuilder(mRootWindowContainer)
+ task = new TaskBuilder(mSupervisor)
.setTaskDisplayArea(taskDisplayArea)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
@@ -1410,7 +1410,7 @@
new ActivityBuilder(mAtm).setTask(mTask).build();
new ActivityBuilder(mAtm).setTask(mTask).build();
doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
- doReturn(true).when(nonTopVisibleActivity).shouldBeVisible(anyBoolean(), anyBoolean());
+ doReturn(true).when(nonTopVisibleActivity).shouldBeVisibleUnchecked();
doNothing().when(mSupervisor).startSpecificActivity(any(), anyBoolean(),
anyBoolean());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index e537b7c..076047b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -217,7 +217,10 @@
// Create source token
final ActivityBuilder builder = new ActivityBuilder(service).setTask(
- new TaskBuilder(service.mStackSupervisor).setVoiceSession(voiceSession).build());
+ new TaskBuilder(service.mStackSupervisor)
+ .setVoiceSession(voiceSession)
+ .setCreateParentTask(true)
+ .build());
if (aInfo != null) {
aInfo.applicationInfo = new ApplicationInfo();
@@ -706,7 +709,9 @@
@Test
public void testBringTaskToFrontWhenFocusedStackIsFinising() {
// Put 2 tasks in the same stack (simulate the behavior of home stack).
+ final Task rootTask = new TaskBuilder(mSupervisor).build();
final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setStack(rootTask)
.setCreateTask(true).build();
new ActivityBuilder(mAtm)
.setStack(activity.getRootTask())
@@ -792,7 +797,7 @@
// Create another activity on top of the secondary display.
final Task topStack = secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task topTask = new TaskBuilder(mSupervisor).setStack(topStack).build();
+ final Task topTask = new TaskBuilder(mSupervisor).setParentTask(topStack).build();
new ActivityBuilder(mAtm).setTask(topTask).build();
// Start activity with the same intent as {@code singleTaskActivity} on secondary display.
@@ -851,7 +856,7 @@
DEFAULT_COMPONENT_PACKAGE_NAME + ".SingleTaskActivity");
final Task task = new TaskBuilder(mSupervisor)
.setComponent(componentName)
- .setStack(stack)
+ .setParentTask(stack)
.build();
return new ActivityBuilder(mAtm)
.setComponent(componentName)
@@ -987,7 +992,7 @@
final ActivityStarter starter = prepareStarter(0 /* flags */);
starter.mStartActivity = new ActivityBuilder(mAtm).build();
final Task task = new TaskBuilder(mAtm.mStackSupervisor)
- .setStack(mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
+ .setParentTask(mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
.setUserId(10)
.build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 5676100..0311657 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -73,7 +73,7 @@
/** Verify that activity is finished correctly upon request. */
@Test
public void testActivityFinish() {
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
assertTrue("Activity must be finished", mAtm.finishActivity(activity.appToken,
0 /* resultCode */, null /* resultData */,
@@ -87,7 +87,7 @@
@Test
public void testOnPictureInPictureRequested() throws RemoteException {
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
final ClientLifecycleManager mockLifecycleManager = mock(ClientLifecycleManager.class);
doReturn(mockLifecycleManager).when(mAtm).getLifecycleManager();
@@ -106,7 +106,7 @@
@Test(expected = IllegalStateException.class)
public void testOnPictureInPictureRequested_cannotEnterPip() throws RemoteException {
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doReturn(false).when(activity).inPinnedWindowingMode();
@@ -120,7 +120,7 @@
@Test(expected = IllegalStateException.class)
public void testOnPictureInPictureRequested_alreadyInPIPMode() throws RemoteException {
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doReturn(true).when(activity).inPinnedWindowingMode();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f8baf84..89a34cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -24,10 +24,10 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.os.Build.VERSION_CODES.P;
import static android.os.Build.VERSION_CODES.Q;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.FLAG_PRIVATE;
import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
@@ -95,6 +95,7 @@
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.view.DisplayCutout;
+import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IDisplayWindowRotationCallback;
import android.view.IDisplayWindowRotationController;
@@ -760,13 +761,14 @@
window.mAttrs.screenOrientation, dc.getOrientation());
// ----------------------------
- // Test close-to-square display
+ // Test close-to-square display - should be handled in the same way
// ----------------------------
dc.mBaseDisplayHeight = dc.mBaseDisplayWidth;
dc.configureDisplayPolicy();
- assertEquals("Screen orientation must be SCREEN_ORIENTATION_USER.",
- SCREEN_ORIENTATION_USER, dc.getOrientation());
+ assertEquals(
+ "Screen orientation must be defined by the window even on close-to-square display.",
+ window.mAttrs.screenOrientation, dc.getOrientation());
}
@Test
@@ -821,7 +823,14 @@
final DisplayContent newDisplay = createNewDisplay();
final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
+ final Task stack = mDisplayContent.getTopStack();
+ final ActivityRecord activity = stack.topRunningActivity();
+ doReturn(true).when(activity).shouldBeVisibleUnchecked();
+
final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
+ final Task stack1 = newDisplay.getTopStack();
+ final ActivityRecord activity1 = stack1.topRunningActivity();
+ doReturn(true).when(activity1).shouldBeVisibleUnchecked();
appWin.setHasSurface(true);
appWin1.setHasSurface(true);
@@ -847,17 +856,17 @@
dc.getDisplayRotation().setFixedToUserRotation(
IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
- final Task stack =
- new StackBuilder(mWm.mAtmService.mRootWindowContainer)
- .setDisplay(dc)
- .build();
+ final Task stack = new TaskBuilder(mSupervisor)
+ .setDisplay(dc)
+ .setCreateActivity(true)
+ .build();
doReturn(true).when(stack).isVisible();
- final Task freeformStack =
- new StackBuilder(mWm.mAtmService.mRootWindowContainer)
- .setDisplay(dc)
- .setWindowingMode(WINDOWING_MODE_FREEFORM)
- .build();
+ final Task freeformStack = new TaskBuilder(mSupervisor)
+ .setDisplay(dc)
+ .setCreateActivity(true)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .build();
doReturn(true).when(freeformStack).isVisible();
freeformStack.getTopChild().setBounds(100, 100, 300, 400);
@@ -879,8 +888,8 @@
IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
final int newOrientation = getRotatedOrientation(dc);
- final Task stack = new StackBuilder(mWm.mAtmService.mRootWindowContainer)
- .setDisplay(dc).build();
+ final Task stack = new TaskBuilder(mSupervisor)
+ .setDisplay(dc).setCreateActivity(true).build();
final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
@@ -898,8 +907,8 @@
IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
final int newOrientation = getRotatedOrientation(dc);
- final Task stack = new StackBuilder(mWm.mAtmService.mRootWindowContainer)
- .setDisplay(dc).build();
+ final Task stack = new TaskBuilder(mSupervisor)
+ .setDisplay(dc).setCreateActivity(true).build();
final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
@@ -1209,8 +1218,8 @@
verify(t, never()).setPosition(any(), eq(0), eq(0));
// Launch another activity before the transition is finished.
- final ActivityRecord app2 = new StackBuilder(mWm.mRoot)
- .setDisplay(mDisplayContent).build().getTopMostActivity();
+ final ActivityRecord app2 = new TaskBuilder(mSupervisor)
+ .setDisplay(mDisplayContent).setCreateActivity(true).build().getTopMostActivity();
app2.setVisible(false);
mDisplayContent.mOpeningApps.add(app2);
app2.setRequestedOrientation(newOrientation);
@@ -1508,7 +1517,7 @@
@Test
public void testSetWindowingModeAtomicallyUpdatesWindoingModeAndDisplayWindowingMode() {
final DisplayContent dc = createNewDisplay();
- final Task stack = new StackBuilder(mWm.mAtmService.mRootWindowContainer)
+ final Task stack = new TaskBuilder(mSupervisor)
.setDisplay(dc)
.build();
doAnswer(invocation -> {
@@ -1522,6 +1531,28 @@
dc.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
}
+ @Test
+ public void testForceDesktopMode() {
+ mWm.mForceDesktopModeOnExternalDisplays = true;
+ // Not applicable for default display
+ assertFalse(mDefaultDisplay.forceDesktopMode());
+
+ // Not applicable for private secondary display.
+ final DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.copyFrom(mDisplayInfo);
+ displayInfo.flags = FLAG_PRIVATE;
+ final DisplayContent privateDc = createNewDisplay(displayInfo);
+ assertFalse(privateDc.forceDesktopMode());
+
+ // Applicable for public secondary display.
+ final DisplayContent publicDc = createNewDisplay();
+ assertTrue(publicDc.forceDesktopMode());
+
+ // Make sure forceDesktopMode() is false when the force config is disabled.
+ mWm.mForceDesktopModeOnExternalDisplays = false;
+ assertFalse(publicDc.forceDesktopMode());
+ }
+
private boolean isOptionsPanelAtRight(int displayId) {
return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index a5585c0..94e4041 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -34,6 +34,7 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -369,6 +370,24 @@
}
@Test
+ public void layoutWindowLw_insetParentFrameByIme() {
+ final InsetsState state =
+ mDisplayContent.getInsetsStateController().getRawInsetsState();
+ state.getSource(InsetsState.ITYPE_IME).setVisible(true);
+ state.getSource(InsetsState.ITYPE_IME).setFrame(
+ 0, DISPLAY_HEIGHT - IME_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+ mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
+ mWindow.mBehindIme = true;
+ addWindow(mWindow);
+
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+ assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, IME_HEIGHT);
+ }
+
+ @Test
public void layoutWindowLw_fitDisplayCutout() {
addDisplayCutout();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index b50530e..b77d21c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -27,11 +27,9 @@
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
@@ -39,7 +37,6 @@
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
@@ -47,7 +44,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -235,18 +231,6 @@
assertEquals(mAppWindow, policy.getTopFullscreenOpaqueWindow());
}
- @Test
- public void testShouldShowToastWhenScreenLocked() {
- final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
- final WindowState activity = createApplicationWindow();
- final WindowState toast = createToastWindow();
-
- policy.adjustWindowParamsLw(toast, toast.mAttrs, 0 /* callingPid */, 0 /* callingUid */);
-
- assertTrue(policy.canToastShowWhenLocked(0 /* callingUid */));
- assertNotEquals(0, toast.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED);
- }
-
@Test(expected = RuntimeException.class)
public void testMainAppWindowDisallowFitSystemWindowTypes() {
final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
@@ -257,16 +241,6 @@
0 /* callingUid */);
}
- private WindowState createToastWindow() {
- final WindowState win = createWindow(null, TYPE_TOAST, "Toast");
- final WindowManager.LayoutParams attrs = win.mAttrs;
- attrs.width = WRAP_CONTENT;
- attrs.height = WRAP_CONTENT;
- attrs.flags = FLAG_KEEP_SCREEN_ON | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE;
- attrs.format = PixelFormat.TRANSLUCENT;
- return win;
- }
-
private WindowState createApplicationWindow() {
final WindowState win = createWindow(null, TYPE_APPLICATION, "Application");
final WindowManager.LayoutParams attrs = win.mAttrs;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index b4e1c37..af8cb02 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -62,7 +62,7 @@
static final int STATUS_BAR_HEIGHT = 10;
static final int NAV_BAR_HEIGHT = 15;
static final int DISPLAY_CUTOUT_HEIGHT = 8;
- static final int INPUT_METHOD_WINDOW_TOP = 585;
+ static final int IME_HEIGHT = 415;
DisplayPolicy mDisplayPolicy;
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 18a2d13..d701a9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -116,7 +116,7 @@
Task stack = mTestDisplay.getDefaultTaskDisplayArea()
.createStack(TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true);
- mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).setStack(stack)
+ mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).setParentTask(stack)
.build();
mTestTask.mUserId = TEST_USER_ID;
mTestTask.mLastNonFullscreenBounds = TEST_BOUNDS;
@@ -342,7 +342,7 @@
final Task anotherTaskOfTheSameUser = new TaskBuilder(mSupervisor)
.setComponent(ALTERNATIVE_COMPONENT)
.setUserId(TEST_USER_ID)
- .setStack(stack)
+ .setParentTask(stack)
.build();
anotherTaskOfTheSameUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
anotherTaskOfTheSameUser.setBounds(200, 300, 400, 500);
@@ -354,7 +354,7 @@
final Task anotherTaskOfDifferentUser = new TaskBuilder(mSupervisor)
.setComponent(TEST_COMPONENT)
.setUserId(ALTERNATIVE_USER_ID)
- .setStack(stack)
+ .setParentTask(stack)
.build();
anotherTaskOfDifferentUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
anotherTaskOfDifferentUser.setBounds(300, 400, 500, 600);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 9954f48..58d994c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -44,6 +44,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -291,7 +292,8 @@
mRecentTasks.add(mTasks.get(1));
invocation.callRealMethod();
return null;
- }).when(mSupervisor).endActivityVisibilityUpdate();
+ }).when(mSupervisor).endActivityVisibilityUpdate(any(), anyInt(), anyBoolean(),
+ anyBoolean());
mTaskContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */, false /* notifyClients */);
@@ -333,10 +335,10 @@
// other task
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
- .setStack(mTaskContainer.getRootHomeTask()).build();
+ .setParentTask(mTaskContainer.getRootHomeTask()).build();
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
- .setStack(mStack).build();
+ .setParentTask(mStack).build();
mRecentTasks.add(task1);
mRecentTasks.add(task2);
assertThat(mCallbacksRecorder.mAdded).hasSize(2);
@@ -352,7 +354,7 @@
// and we want to ensure that a new task will match a restored task
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.build();
setTaskActivityType(task1, ACTIVITY_TYPE_UNDEFINED);
assertThat(task1.getActivityType()).isEqualTo(ACTIVITY_TYPE_UNDEFINED);
@@ -361,7 +363,7 @@
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.build();
assertEquals(ACTIVITY_TYPE_STANDARD, task2.getActivityType());
mRecentTasks.add(task2);
@@ -376,7 +378,7 @@
public void testAddTaskCompatibleActivityTypeDifferentUser_expectNoRemove() {
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.setUserId(TEST_USER_0_ID)
.build();
setTaskActivityType(task1, ACTIVITY_TYPE_UNDEFINED);
@@ -386,7 +388,7 @@
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.setUserId(TEST_USER_1_ID)
.build();
assertEquals(ACTIVITY_TYPE_STANDARD, task2.getActivityType());
@@ -401,7 +403,7 @@
public void testAddTaskCompatibleWindowingMode_expectRemove() {
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.build();
setTaskWindowingMode(task1, WINDOWING_MODE_UNDEFINED);
assertEquals(WINDOWING_MODE_UNDEFINED, task1.getWindowingMode());
@@ -410,7 +412,7 @@
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.build();
setTaskWindowingMode(task2, WINDOWING_MODE_FULLSCREEN);
assertEquals(WINDOWING_MODE_FULLSCREEN, task2.getWindowingMode());
@@ -427,7 +429,7 @@
public void testAddTaskIncompatibleWindowingMode_expectNoRemove() {
Task task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.build();
setTaskWindowingMode(task1, WINDOWING_MODE_FULLSCREEN);
assertEquals(WINDOWING_MODE_FULLSCREEN, task1.getWindowingMode());
@@ -435,7 +437,7 @@
Task task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK)
- .setStack(mStack)
+ .setParentTask(mStack)
.build();
setTaskWindowingMode(task2, WINDOWING_MODE_PINNED);
assertEquals(WINDOWING_MODE_PINNED, task2.getWindowingMode());
@@ -453,19 +455,19 @@
// Add task to recents
final String taskAffinity = "affinity";
final int uid = 10123;
- final Task task1 = createTaskBuilder(".Task1").setStack(mStack).build();
+ final Task task1 = createTaskBuilder(".Task1").setParentTask(mStack).build();
task1.affinity = ActivityRecord.computeTaskAffinity(taskAffinity, uid, LAUNCH_MULTIPLE);
mRecentTasks.add(task1);
// Add another task to recents, and make sure the previous task was removed.
- final Task task2 = createTaskBuilder(".Task2").setStack(mStack).build();
+ final Task task2 = createTaskBuilder(".Task2").setParentTask(mStack).build();
task2.affinity = ActivityRecord.computeTaskAffinity(taskAffinity, uid, LAUNCH_MULTIPLE);
mRecentTasks.add(task2);
assertEquals(1, mRecentTasks.getRecentTasks(MAX_VALUE, 0 /* flags */,
true /* getTasksAllowed */, TEST_USER_0_ID, 0).getList().size());
// Add another single-instance task to recents, and make sure no task is removed.
- final Task task3 = createTaskBuilder(".Task3").setStack(mStack).build();
+ final Task task3 = createTaskBuilder(".Task3").setParentTask(mStack).build();
task3.affinity = ActivityRecord.computeTaskAffinity(taskAffinity, uid,
LAUNCH_SINGLE_INSTANCE);
mRecentTasks.add(task3);
@@ -497,7 +499,7 @@
// tasks because their intents are identical.
mRecentTasks.add(task1);
// Go home to trigger the removal of untracked tasks.
- mRecentTasks.add(createTaskBuilder(".Home").setStack(mTaskContainer.getRootHomeTask())
+ mRecentTasks.add(createTaskBuilder(".Home").setParentTask(mTaskContainer.getRootHomeTask())
.build());
// The task was added into recents again so it is not hidden and shouldn't be removed.
@@ -883,10 +885,10 @@
// Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all
// the tasks belong in stacks above the home stack
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setStack(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setStack(aboveHomeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setStack(aboveHomeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task3").setStack(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task3").setParentTask(aboveHomeStack).build());
assertNoTasksTrimmed();
}
@@ -904,11 +906,11 @@
// Add a number of tasks (beyond the max) but ensure that only the task in the stack behind
// the home stack is trimmed once a new task is added
final Task behindHomeTask = createTaskBuilder(".Task1")
- .setStack(behindHomeStack)
+ .setParentTask(behindHomeStack)
.build();
mRecentTasks.add(behindHomeTask);
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setStack(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setStack(aboveHomeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build());
assertTrimmed(behindHomeTask);
}
@@ -924,10 +926,10 @@
// Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
// removed
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setStack(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setStack(otherDisplayStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setStack(otherDisplayStack).build());
- mRecentTasks.add(createTaskBuilder(".HomeTask2").setStack(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(otherDisplayStack).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(otherDisplayStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTask(homeStack).build());
assertNoTasksTrimmed();
}
@@ -1170,12 +1172,12 @@
() -> mAtm.setTaskWindowingModeSplitScreenPrimary(0, true));
assertSecurityException(expectCallable,
() -> mAtm.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
- assertSecurityException(expectCallable, () -> mAtm.getAllStackInfos());
+ assertSecurityException(expectCallable, () -> mAtm.getAllRootTaskInfos());
assertSecurityException(expectCallable,
- () -> mAtm.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
+ () -> mAtm.getRootTaskInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
assertSecurityException(expectCallable, () -> {
try {
- mAtm.getFocusedStackInfo();
+ mAtm.getFocusedRootTaskInfo();
} catch (RemoteException e) {
// Ignore
}
@@ -1214,7 +1216,7 @@
private TaskBuilder createTaskBuilder(String packageName, String className) {
return new TaskBuilder(mAtm.mStackSupervisor)
.setComponent(new ComponentName(packageName, className))
- .setStack(mStack)
+ .setParentTask(mStack)
.setUserId(TEST_USER_0_ID);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 26b0bfb..901ed36 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -195,8 +195,7 @@
public void testApplySleepTokens() {
final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
final KeyguardController keyguard = mSupervisor.getKeyguardController();
- final Task stack = new StackBuilder(mRootWindowContainer)
- .setCreateActivity(false)
+ final Task stack = new TaskBuilder(mSupervisor)
.setDisplay(display)
.setOnTop(false)
.build();
@@ -384,7 +383,7 @@
final Task primaryStack = mRootWindowContainer.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
- final Task task = new TaskBuilder(mSupervisor).setStack(primaryStack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(primaryStack).build();
final ActivityRecord r = new ActivityBuilder(mAtm).setTask(task).build();
// Find a launch stack for the top activity in split-screen primary, while requesting
@@ -404,14 +403,17 @@
@Test
public void testFindTaskToMoveToFrontWhenRecentsOnTop() {
// Create stack/task on default display.
- final Task targetStack = new StackBuilder(mRootWindowContainer)
+ final Task targetStack = new TaskBuilder(mSupervisor)
+ .setCreateActivity(true)
.setOnTop(false)
.build();
final Task targetTask = targetStack.getBottomMostTask();
// Create Recents on top of the display.
- final Task stack = new StackBuilder(mRootWindowContainer).setActivityType(
- ACTIVITY_TYPE_RECENTS).build();
+ final Task stack = new TaskBuilder(mSupervisor)
+ .setCreateActivity(true)
+ .setActivityType(ACTIVITY_TYPE_RECENTS)
+ .build();
final String reason = "findTaskToMoveToFront";
mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
@@ -431,14 +433,14 @@
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task targetStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final Task targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+ final Task targetTask = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
// Create Recents on secondary display.
final TestDisplayContent secondDisplay = addNewDisplayContentAt(
DisplayContent.POSITION_TOP);
final Task stack = secondDisplay.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
- final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
new ActivityBuilder(mAtm).setTask(task).build();
final String reason = "findTaskToMoveToFront";
@@ -458,7 +460,7 @@
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
- final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
taskDisplayArea.positionChildAt(POSITION_BOTTOM, targetStack, false /*includingParents*/);
@@ -514,7 +516,7 @@
DisplayContent.POSITION_TOP);
final Task stack = secondDisplay.getDefaultTaskDisplayArea()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
new ActivityBuilder(mAtm).setTask(task).build();
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
@@ -538,7 +540,7 @@
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
- final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
activity.setState(ActivityState.RESUMED, "test");
@@ -558,7 +560,7 @@
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
- final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
activity.setState(ActivityState.RESUMED, "test");
taskDisplayArea.positionChildAt(POSITION_BOTTOM, targetStack, false /*includingParents*/);
@@ -884,7 +886,7 @@
// Create a root task with an activity on secondary display.
final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mAtm, 300,
600).build();
- final Task task = new StackBuilder(mRootWindowContainer)
+ final Task task = new TaskBuilder(mSupervisor)
.setDisplay(secondaryDisplay).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 191c33c..3053fe6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -174,7 +174,7 @@
@Test
public void testForceStopPackage() {
- final Task task = new StackBuilder(mWm.mRoot).build();
+ final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
final ActivityRecord activity = task.getTopMostActivity();
final WindowProcessController wpc = activity.app;
final ActivityRecord[] activities = {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index 3415093..8a5b13c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -62,8 +62,7 @@
final int numStacks = 2;
for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) {
- final Task stack = new StackBuilder(mRootWindowContainer)
- .setCreateActivity(false)
+ final Task stack = new TaskBuilder(mSupervisor)
.setDisplay(display)
.setOnTop(false)
.build();
@@ -104,8 +103,7 @@
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
final int numTasks = 10;
for (int i = 0; i < numTasks; i++) {
- final Task stack = new StackBuilder(mRootWindowContainer)
- .setCreateActivity(false)
+ final Task stack = new TaskBuilder(mSupervisor)
.setDisplay(display)
.setOnTop(true)
.build();
@@ -135,7 +133,7 @@
final Task task = new TaskBuilder(mAtm.mStackSupervisor)
.setComponent(new ComponentName(mContext.getPackageName(), className))
.setTaskId(taskId)
- .setStack(stack)
+ .setParentTask(stack)
.build();
task.lastActiveTime = lastActiveTime;
final ActivityRecord activity = new ActivityBuilder(mAtm)
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 6c648a8..edcf0d4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -35,7 +35,9 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doCallRealMethod;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -70,7 +72,7 @@
private ActivityRecord mActivity;
private void setUpApp(DisplayContent display) {
- mStack = new StackBuilder(mRootWindowContainer).setDisplay(display).build();
+ mStack = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true).build();
mTask = mStack.getBottomMostTask();
mActivity = mTask.getTopNonFinishingActivity();
}
@@ -136,8 +138,6 @@
public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() {
final int notchHeight = 100;
setUpApp(new TestDisplayContent.Builder(mAtm, 600, 800).setNotch(notchHeight).build());
- // Rotation is ignored so because the display size is close to square (700/600<1.333).
- assertTrue(mActivity.mDisplayContent.ignoreRotationForApps());
final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds();
final float aspectRatio = 1.2f;
@@ -161,23 +161,14 @@
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertFitted();
- // After the orientation of activity is changed, even display is not rotated, the aspect
- // ratio should be the same (bounds=[0, 0 - 600, 600], appBounds=[0, 100 - 600, 600]).
+ // After the orientation of activity is changed, the display is rotated, the aspect
+ // ratio should be the same (bounds=[100, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
- // The notch is still on top.
- assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);
+ // The notch is no longer on top.
+ assertEquals(appBounds, mActivity.getBounds());
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
-
- // Close-to-square display can rotate without being restricted by the requested orientation.
- // The notch becomes on the left side. The activity is horizontal centered in 100 ~ 800.
- // So the bounds and appBounds will be [200, 0 - 700, 600] (500x600) that is still fitted.
- // Left = 100 + (800 - 100 - 500) / 2 = 200.
- rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- assertFitted();
- assertEquals(appBounds.left,
- notchHeight + (displayBounds.width() - notchHeight - appBounds.width()) / 2);
}
@Test
@@ -216,22 +207,50 @@
final Rect origBounds = new Rect(mActivity.getBounds());
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
+ final DisplayContent display = mActivity.mDisplayContent;
// Change the size of current display.
- resizeDisplay(mStack.mDisplayContent, 1000, 2000);
-
+ resizeDisplay(display, 1000, 2000);
+ // The bounds should be [100, 0 - 1100, 2500].
assertEquals(origBounds.width(), currentBounds.width());
assertEquals(origBounds.height(), currentBounds.height());
assertScaled();
+ // The scale is 2000/2500=0.8. The horizontal centered offset is (1000-(1000*0.8))/2=100.
+ final float scale = (float) display.mBaseDisplayHeight / currentBounds.height();
+ final int offsetX = (int) (display.mBaseDisplayWidth - (origBounds.width() * scale)) / 2;
+ assertEquals(offsetX, currentBounds.left);
+
// The position of configuration bounds should be the same as compat bounds.
assertEquals(mActivity.getBounds().left, currentBounds.left);
assertEquals(mActivity.getBounds().top, currentBounds.top);
// Change display size to a different orientation
- resizeDisplay(mStack.mDisplayContent, 2000, 1000);
+ resizeDisplay(display, 2000, 1000);
+ // The bounds should be [800, 0 - 1800, 2500].
assertEquals(origBounds.width(), currentBounds.width());
assertEquals(origBounds.height(), currentBounds.height());
+ assertEquals(Configuration.ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
+ assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
+
+ // The previous resize operation doesn't consider the rotation change after size changed.
+ // These setups apply the requested orientation to rotation as real case that the top fixed
+ // portrait activity will determine the display rotation.
+ final DisplayRotation displayRotation = display.getDisplayRotation();
+ doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean());
+ // Skip unrelated layout procedures.
+ mAtm.deferWindowLayout();
+ display.reconfigureDisplayLocked();
+ displayRotation.updateOrientation(display.getOrientation(), true /* forceUpdate */);
+ display.sendNewConfiguration();
+
+ assertEquals(Configuration.ORIENTATION_PORTRAIT, display.getConfiguration().orientation);
+ assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
+ // The size should still be in portrait [100, 0 - 1100, 2500] = 1000x2500.
+ assertEquals(origBounds.width(), currentBounds.width());
+ assertEquals(origBounds.height(), currentBounds.height());
+ assertEquals(offsetX, currentBounds.left);
+ assertScaled();
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index eb7d9c2..6a29c5b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -534,11 +534,14 @@
doNothing().when(this).scheduleIdleTimeout(any());
// unit test version does not handle launch wake lock
doNothing().when(this).acquireLaunchWakelock();
- doReturn(mock(KeyguardController.class)).when(this).getKeyguardController();
mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
initialize();
+
+ final KeyguardController controller = getKeyguardController();
+ spyOn(controller);
+ doReturn(true).when(controller).checkKeyguardVisibility(any());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 260f1e9..bc3b3a4d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -218,7 +218,7 @@
final Task rootHomeTask = defaultTaskDisplayArea.getRootHomeTask();
rootHomeTask.mResizeMode = RESIZE_MODE_UNRESIZEABLE;
- final Task primarySplitTask = new StackBuilder(rootWindowContainer)
+ final Task primarySplitTask = new TaskBuilder(mSupervisor)
.setTaskDisplayArea(defaultTaskDisplayArea)
.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
.setActivityType(ACTIVITY_TYPE_STANDARD)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 42de5e6..1d32e17 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -1358,7 +1358,7 @@
final Task stack = display.getDefaultTaskDisplayArea()
.createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
- final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
// Just work around the unnecessary adjustments for bounds.
task.getWindowConfiguration().setBounds(bounds);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 08537a4..a908bfe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -176,7 +176,7 @@
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
- Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
final Configuration parentConfig = stack.getConfiguration();
parentConfig.windowConfiguration.setBounds(parentBounds);
parentConfig.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
@@ -212,7 +212,7 @@
@Test
public void testBoundsOnModeChangeFreeformToFullscreen() {
DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
- Task stack = new StackBuilder(mRootWindowContainer).setDisplay(display)
+ Task stack = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
Task task = stack.getBottomMostTask();
task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
@@ -253,7 +253,7 @@
dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
- final Task stack = new StackBuilder(mRootWindowContainer)
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
final Task task = stack.getBottomMostTask();
final ActivityRecord root = task.getTopNonFinishingActivity();
@@ -317,7 +317,7 @@
dr.setFixedToUserRotation(FIXED_TO_USER_ROTATION_ENABLED);
dr.setUserRotation(USER_ROTATION_FREE, ROTATION_0);
- final Task stack = new StackBuilder(mRootWindowContainer)
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
final Task task = stack.getBottomMostTask();
ActivityRecord root = task.getTopNonFinishingActivity();
@@ -341,7 +341,7 @@
Configuration.ORIENTATION_LANDSCAPE;
display.onRequestedOverrideConfigurationChanged(
display.getRequestedOverrideConfiguration());
- Task stack = new StackBuilder(mRootWindowContainer)
+ Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
Task task = stack.getBottomMostTask();
ActivityRecord root = task.getTopNonFinishingActivity();
@@ -497,7 +497,7 @@
DisplayInfo displayInfo = new DisplayInfo();
mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
final int displayHeight = displayInfo.logicalHeight;
- final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
final Configuration inOutConfig = new Configuration();
final Configuration parentConfig = new Configuration();
final int longSide = 1200;
@@ -1029,7 +1029,7 @@
}
private Task getTestTask() {
- final Task stack = new StackBuilder(mRootWindowContainer).build();
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
return stack.getBottomMostTask();
}
@@ -1039,7 +1039,7 @@
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
Task stack = taskDisplayArea.createStack(windowingMode, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
- Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
final Configuration parentConfig = stack.getConfiguration();
parentConfig.windowConfiguration.setAppBounds(parentBounds);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index e39b4bc..d37f3f4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -17,17 +17,16 @@
package com.android.server.wm;
import android.graphics.Point;
-import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.MergedConfiguration;
-import android.view.DisplayCutout;
import android.view.DragEvent;
import android.view.IScrollCaptureController;
import android.view.IWindow;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.window.ClientWindowFrames;
import com.android.internal.os.IResultReceiver;
@@ -38,10 +37,9 @@
}
@Override
- public void resized(Rect frame, Rect contentInsets, Rect visibleInsets,
- Rect stableInsets, boolean reportDraw, MergedConfiguration mergedConfig,
- Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException {
+ public void resized(ClientWindowFrames frames, boolean reportDraw,
+ MergedConfiguration mergedConfig, boolean forceLayout, boolean alwaysConsumeSystemBars,
+ int displayId) throws RemoteException {
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 4163a9a..36f3a21 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -829,7 +829,7 @@
final DisplayContent displayContent = createNewDisplay();
// Do not reparent activity to default display when removing the display.
doReturn(true).when(displayContent).shouldDestroyContentOnRemove();
- final ActivityRecord r = new StackBuilder(mWm.mRoot)
+ final ActivityRecord r = new TaskBuilder(mSupervisor).setCreateActivity(true)
.setDisplay(displayContent).build().getTopMostActivity();
// Add a window and make the activity animating so the removal of activity is deferred.
createWindow(null, TYPE_BASE_APPLICATION, r, "win");
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 46a6a82..11eaf8c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -52,7 +52,7 @@
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackInfo;
+import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.PictureInPictureParams;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
@@ -229,58 +229,32 @@
final Task task3 = createTask(stack3);
final ITaskOrganizer organizer = registerMockOrganizer();
- // First organizer is registered, verify a task appears when changing windowing mode
- stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer, times(1))
+ // verify that tasks are appeared on registration
+ verify(organizer, times(3))
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
assertTrue(stack.isOrganized());
// Now we replace the registration and1 verify the new organizer receives tasks
- // newly entering the windowing mode.
final ITaskOrganizer organizer2 = registerMockOrganizer();
- stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- // One each for task and task2
- verify(organizer2, times(2))
+ verify(organizer2, times(3))
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
verify(organizer2, times(0)).onTaskVanished(any());
// One for task
- verify(organizer).onTaskVanished(any());
+ verify(organizer, times(3)).onTaskVanished(any());
assertTrue(stack2.isOrganized());
// Now we unregister the second one, the first one should automatically be reregistered
// so we verify that it's now seeing changes.
mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
- verify(organizer, times(3))
+ verify(organizer, times(6))
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
- verify(organizer2, times(2)).onTaskVanished(any());
-
- stack3.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
- verify(organizer, times(4))
- .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
- verify(organizer2, times(2)).onTaskVanished(any());
- assertTrue(stack3.isOrganized());
- }
-
- @Test
- public void testRegisterTaskOrganizerStackWindowingModeChanges() throws RemoteException {
- final ITaskOrganizer organizer = registerMockOrganizer();
-
- final Task stack = createStack();
- final Task task = createTask(stack);
- final Task task2 = createTask(stack);
- stack.setWindowingMode(WINDOWING_MODE_PINNED);
- verify(organizer, times(1))
- .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
-
- stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- verify(organizer, times(1)).onTaskVanished(any());
+ verify(organizer2, times(3)).onTaskVanished(any());
}
@Test
public void testRegisterTaskOrganizerWithExistingTasks() throws RemoteException {
final Task stack = createStack();
final Task task = createTask(stack);
- stack.setWindowingMode(WINDOWING_MODE_PINNED);
final ITaskOrganizer organizer = registerMockOrganizer();
verify(organizer, times(1))
@@ -290,7 +264,7 @@
@Test
public void testTaskTransaction() {
removeGlobalMinSizeRestriction();
- final Task stack = new StackBuilder(mWm.mRoot)
+ final Task stack = new TaskBuilder(mSupervisor)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask();
testTransaction(task);
@@ -299,11 +273,11 @@
@Test
public void testStackTransaction() {
removeGlobalMinSizeRestriction();
- final Task stack = new StackBuilder(mWm.mRoot)
+ final Task stack = new TaskBuilder(mSupervisor)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
- StackInfo info =
- mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
- assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.stackToken);
+ RootTaskInfo info =
+ mWm.mAtmService.getRootTaskInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+ assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.token);
testTransaction(stack);
}
@@ -324,7 +298,7 @@
@Test
public void testSetWindowingMode() {
- final Task stack = new StackBuilder(mWm.mRoot)
+ final Task stack = new TaskBuilder(mSupervisor)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
testSetWindowingMode(stack);
@@ -358,7 +332,7 @@
@Test
public void testContainerFocusableChanges() {
removeGlobalMinSizeRestriction();
- final Task stack = new StackBuilder(mWm.mRoot)
+ final Task stack = new TaskBuilder(mSupervisor)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction();
@@ -374,7 +348,7 @@
@Test
public void testContainerHiddenChanges() {
removeGlobalMinSizeRestriction();
- final Task stack = new StackBuilder(mWm.mRoot)
+ final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
WindowContainerTransaction t = new WindowContainerTransaction();
assertTrue(stack.shouldBeVisible(null));
@@ -389,7 +363,7 @@
@Test
public void testOverrideConfigSize() {
removeGlobalMinSizeRestriction();
- final Task stack = new StackBuilder(mWm.mRoot)
+ final Task stack = new TaskBuilder(mSupervisor)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 3106ca2..c18043f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -581,12 +581,10 @@
mWm.mResizingWindows.remove(win);
spyOn(win.mClient);
try {
- doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frame */,
- any() /* contentInsets */, any() /* visibleInsets */, any() /* stableInsets */,
+ doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frames */,
anyBoolean() /* reportDraw */, any() /* mergedConfig */,
- any() /* backDropFrame */, anyBoolean() /* forceLayout */,
- anyBoolean() /* alwaysConsumeSystemBars */, anyInt() /* displayId */,
- any() /* displayCutout */);
+ anyBoolean() /* forceLayout */, anyBoolean() /* alwaysConsumeSystemBars */,
+ anyInt() /* displayId */);
} catch (RemoteException ignored) {
}
win.reportResized();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 38c4e0a..7daddd8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -90,6 +90,7 @@
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.Description;
+import org.mockito.Mockito;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -398,22 +399,20 @@
}
Task createTaskStackOnDisplay(int windowingMode, int activityType, DisplayContent dc) {
- return new StackBuilder(dc.mWmService.mRoot)
+ return new TaskBuilder(dc.mAtmService.mStackSupervisor)
.setDisplay(dc)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
- .setCreateActivity(false)
.setIntent(new Intent())
.build();
}
Task createTaskStackOnTaskDisplayArea(int windowingMode, int activityType,
TaskDisplayArea tda) {
- return new StackBuilder(tda.mWmService.mRoot)
+ return new TaskBuilder(tda.mDisplayContent.mAtmService.mStackSupervisor)
.setTaskDisplayArea(tda)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
- .setCreateActivity(false)
.setIntent(new Intent())
.build();
}
@@ -422,7 +421,7 @@
Task createTaskInStack(Task stack, int userId) {
final Task task = new TaskBuilder(stack.mStackSupervisor)
.setUserId(userId)
- .setStack(stack)
+ .setParentTask(stack)
.build();
return task;
}
@@ -733,7 +732,7 @@
if (mCreateTask) {
mTask = new TaskBuilder(mService.mStackSupervisor)
.setComponent(mComponent)
- .setStack(mStack).build();
+ .setParentTask(mStack).build();
} else if (mTask == null && mStack != null && DisplayContent.alwaysCreateStack(
mStack.getWindowingMode(), mStack.getActivityType())) {
// The stack can be the task root.
@@ -813,20 +812,42 @@
protected static class TaskBuilder {
private final ActivityStackSupervisor mSupervisor;
+ private TaskDisplayArea mTaskDisplayArea;
private ComponentName mComponent;
private String mPackage;
private int mFlags = 0;
- // Task id 0 is reserved in ARC for the home app.
- private int mTaskId = SystemServicesTestRule.sNextTaskId++;
+ private int mTaskId = -1;
private int mUserId = 0;
+ private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
+ private int mActivityType = ACTIVITY_TYPE_STANDARD;
+ private ActivityInfo mActivityInfo;
+ private Intent mIntent;
+ private boolean mOnTop = true;
private IVoiceInteractionSession mVoiceSession;
- private boolean mCreateStack = true;
- private Task mStack;
- private TaskDisplayArea mTaskDisplayArea;
+ private boolean mCreateParentTask = false;
+ private Task mParentTask;
+
+ private boolean mCreateActivity = false;
TaskBuilder(ActivityStackSupervisor supervisor) {
mSupervisor = supervisor;
+ mTaskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
+ }
+
+ /**
+ * Set the parent {@link DisplayContent} and use the default task display area. Overrides
+ * the task display area, if was set before.
+ */
+ TaskBuilder setDisplay(DisplayContent display) {
+ mTaskDisplayArea = display.getDefaultTaskDisplayArea();
+ return this;
+ }
+
+ /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
+ TaskBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
+ mTaskDisplayArea = taskDisplayArea;
+ return this;
}
TaskBuilder setComponent(ComponentName component) {
@@ -839,20 +860,6 @@
return this;
}
- /**
- * Set to {@code true} by default, set to {@code false} to prevent the task from
- * automatically creating a parent stack.
- */
- TaskBuilder setCreateStack(boolean createStack) {
- mCreateStack = createStack;
- return this;
- }
-
- TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
- mVoiceSession = session;
- return this;
- }
-
TaskBuilder setFlags(int flags) {
mFlags = flags;
return this;
@@ -868,158 +875,119 @@
return this;
}
- TaskBuilder setStack(Task stack) {
- mStack = stack;
+ TaskBuilder setWindowingMode(int windowingMode) {
+ mWindowingMode = windowingMode;
return this;
}
- TaskBuilder setDisplay(DisplayContent display) {
- mTaskDisplayArea = display.getDefaultTaskDisplayArea();
+ TaskBuilder setActivityType(int activityType) {
+ mActivityType = activityType;
+ return this;
+ }
+
+ TaskBuilder setActivityInfo(ActivityInfo info) {
+ mActivityInfo = info;
+ return this;
+ }
+
+ TaskBuilder setIntent(Intent intent) {
+ mIntent = intent;
+ return this;
+ }
+
+ TaskBuilder setOnTop(boolean onTop) {
+ mOnTop = onTop;
+ return this;
+ }
+
+ TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
+ mVoiceSession = session;
+ return this;
+ }
+
+ TaskBuilder setCreateParentTask(boolean createParentTask) {
+ mCreateParentTask = createParentTask;
+ return this;
+ }
+
+ TaskBuilder setParentTask(Task parentTask) {
+ mParentTask = parentTask;
+ return this;
+ }
+
+ TaskBuilder setCreateActivity(boolean createActivity) {
+ mCreateActivity = createActivity;
return this;
}
Task build() {
SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
- if (mStack == null && mCreateStack) {
- TaskDisplayArea displayArea = mTaskDisplayArea != null ? mTaskDisplayArea
- : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
- mStack = displayArea.createStack(
+ // Create parent task.
+ if (mParentTask == null && mCreateParentTask) {
+ mParentTask = mTaskDisplayArea.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- spyOn(mStack);
+ }
+ if (mParentTask != null && !Mockito.mockingDetails(mParentTask).isSpy()) {
+ spyOn(mParentTask);
}
- final ActivityInfo aInfo = new ActivityInfo();
- aInfo.applicationInfo = new ApplicationInfo();
- aInfo.applicationInfo.packageName = mPackage;
-
- Intent intent = new Intent();
- if (mComponent == null) {
- mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
- DEFAULT_COMPONENT_CLASS_NAME);
+ // Create task.
+ if (mActivityInfo == null) {
+ mActivityInfo = new ActivityInfo();
+ mActivityInfo.applicationInfo = new ApplicationInfo();
+ mActivityInfo.applicationInfo.packageName = mPackage;
}
- intent.setComponent(mComponent);
- intent.setFlags(mFlags);
+ if (mIntent == null) {
+ mIntent = new Intent();
+ if (mComponent == null) {
+ mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+ DEFAULT_COMPONENT_CLASS_NAME);
+ }
+ mIntent.setComponent(mComponent);
+ mIntent.setFlags(mFlags);
+ }
- final Task task = new Task(mSupervisor.mService, mTaskId, aInfo,
- intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
- null /*taskDescription*/, mStack);
+ Task task;
+ final int taskId = mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextStackId();
+ if (mParentTask == null) {
+ task = mTaskDisplayArea.createStackUnchecked(
+ mWindowingMode, mActivityType, taskId, mOnTop, mActivityInfo,
+ mIntent, false /* createdByOrganizer */);
+ } else {
+ task = new Task(mSupervisor.mService, taskId, mActivityInfo,
+ mIntent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
+ null /*taskDescription*/, mParentTask);
+ mParentTask.moveToFront("build-task");
+ mParentTask.addChild(task, true, true);
+ }
spyOn(task);
task.mUserId = mUserId;
+ Task rootTask = task.getRootTask();
+ doNothing().when(rootTask).startActivityLocked(
+ any(), any(), anyBoolean(), anyBoolean(), any());
- if (mStack != null) {
- mStack.moveToFront("test");
- mStack.addChild(task, true, true);
+ // Create child task with activity.
+ if (mCreateActivity) {
+ new ActivityBuilder(mSupervisor.mService)
+ .setCreateTask(true)
+ .setStack(task)
+ .build();
+ if (mOnTop) {
+ // We move the task to front again in order to regain focus after activity
+ // added to the stack. Or {@link TaskDisplayArea#mPreferredTopFocusableStack}
+ // could be other stacks (e.g. home stack).
+ task.moveToFront("createActivityTask");
+ } else {
+ task.moveToBack("createActivityTask", null);
+ }
}
return task;
}
}
- static class StackBuilder {
- private final RootWindowContainer mRootWindowContainer;
- private DisplayContent mDisplay;
- private TaskDisplayArea mTaskDisplayArea;
- private int mStackId = -1;
- private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
- private int mActivityType = ACTIVITY_TYPE_STANDARD;
- private boolean mOnTop = true;
- private boolean mCreateActivity = true;
- private ActivityInfo mInfo;
- private Intent mIntent;
-
- StackBuilder(RootWindowContainer root) {
- mRootWindowContainer = root;
- mDisplay = mRootWindowContainer.getDefaultDisplay();
- mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
- }
-
- StackBuilder setWindowingMode(int windowingMode) {
- mWindowingMode = windowingMode;
- return this;
- }
-
- StackBuilder setActivityType(int activityType) {
- mActivityType = activityType;
- return this;
- }
-
- StackBuilder setStackId(int stackId) {
- mStackId = stackId;
- return this;
- }
-
- /**
- * Set the parent {@link DisplayContent} and use the default task display area. Overrides
- * the task display area, if was set before.
- */
- StackBuilder setDisplay(DisplayContent display) {
- mDisplay = display;
- mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
- return this;
- }
-
- /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
- StackBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
- mTaskDisplayArea = taskDisplayArea;
- mDisplay = mTaskDisplayArea.mDisplayContent;
- return this;
- }
-
- StackBuilder setOnTop(boolean onTop) {
- mOnTop = onTop;
- return this;
- }
-
- StackBuilder setCreateActivity(boolean createActivity) {
- mCreateActivity = createActivity;
- return this;
- }
-
- StackBuilder setActivityInfo(ActivityInfo info) {
- mInfo = info;
- return this;
- }
-
- StackBuilder setIntent(Intent intent) {
- mIntent = intent;
- return this;
- }
-
- Task build() {
- SystemServicesTestRule.checkHoldsLock(mRootWindowContainer.mWmService.mGlobalLock);
-
- final int stackId = mStackId >= 0 ? mStackId : mTaskDisplayArea.getNextStackId();
- final Task stack = mTaskDisplayArea.createStackUnchecked(
- mWindowingMode, mActivityType, stackId, mOnTop, mInfo, mIntent,
- false /* createdByOrganizer */);
- final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor;
-
- if (mCreateActivity) {
- new ActivityBuilder(supervisor.mService)
- .setCreateTask(true)
- .setStack(stack)
- .build();
- if (mOnTop) {
- // We move the task to front again in order to regain focus after activity
- // added to the stack. Or {@link DisplayContent#mPreferredTopFocusableStack}
- // could be other stacks (e.g. home stack).
- stack.moveToFront("createActivityStack");
- } else {
- stack.moveToBack("createActivityStack", null);
- }
- }
- spyOn(stack);
-
- doNothing().when(stack).startActivityLocked(
- any(), any(), anyBoolean(), anyBoolean(), any());
-
- return stack;
- }
-
- }
-
static class TestSplitOrganizer extends ITaskOrganizer.Stub {
final ActivityTaskManagerService mService;
Task mPrimary;
diff --git a/telecomm/OWNERS b/telecomm/OWNERS
index 673a0a9..9969ee9 100644
--- a/telecomm/OWNERS
+++ b/telecomm/OWNERS
@@ -1,7 +1,8 @@
set noparent
-tgunn@google.com
breadley@google.com
hallliu@google.com
+tgunn@google.com
+xiaotonj@google.com
+shuoq@google.com
rgreenwalt@google.com
-paulye@google.com
diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java
index 67e5eab..9d17219 100644
--- a/telecomm/java/android/telecom/Logging/SessionManager.java
+++ b/telecomm/java/android/telecom/Logging/SessionManager.java
@@ -17,6 +17,7 @@
package android.telecom.Logging;
import android.annotation.Nullable;
+import android.content.ContentResolver;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
@@ -453,7 +454,9 @@
* perform a sweep to check and make sure that the session is still not incomplete (stale).
*/
private long getCleanupTimeout(Context context) {
- return Settings.Secure.getLong(context.getContentResolver(), TIMEOUTS_PREFIX +
- "stale_session_cleanup_timeout_millis", DEFAULT_SESSION_TIMEOUT_MS);
+ final ContentResolver cr = context.getContentResolver();
+ return Settings.Secure.getLongForUser(cr, TIMEOUTS_PREFIX
+ + "stale_session_cleanup_timeout_millis", DEFAULT_SESSION_TIMEOUT_MS,
+ cr.getUserId());
}
}
diff --git a/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl b/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl
new file mode 100644
index 0000000..50bbf4c
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 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.internal.telecom;
+
+/*
+ * Adapter interface for using DeviceIdleController, since the PowerWhitelistManager is not
+ * directly accessible in the SYSTEM process.
+ */
+interface IDeviceIdleControllerAdapter {
+ void exemptAppTemporarilyForEvent(String packageName, long duration, int userHandle,
+ String reason);
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java b/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl
similarity index 60%
copy from packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
copy to telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl
index e65f19d..b560106 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ContainerView.java
+++ b/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,17 +14,14 @@
* limitations under the License.
*/
-package com.android.keyguard.dagger;
+package com.android.internal.telecom;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import com.android.internal.telecom.IDeviceIdleControllerAdapter;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface ContainerView {
+/*
+ * Interface used to retrieve services that are only accessible via LocalService in the SYSTEM
+ * process.
+ */
+interface IInternalServiceRetriever {
+ IDeviceIdleControllerAdapter getDeviceIdleController();
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl b/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl
new file mode 100644
index 0000000..eda0f5b
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 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.internal.telecom;
+
+import com.android.internal.telecom.ITelecomService;
+import com.android.internal.telecom.IInternalServiceRetriever;
+
+/*
+ * Internal interface for getting an instance of the ITelecomService for external publication.
+ * Allows the TelecomLoaderService to pass additional dependencies required for creation.
+ */
+interface ITelecomLoader {
+ ITelecomService createTelecomService(IInternalServiceRetriever retriever);
+}
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index 944edd5..72e11c8 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -291,6 +291,22 @@
method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
}
+ public final class PhysicalChannelConfig implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getCellBandwidthDownlink();
+ method public int getChannelNumber();
+ method public int getConnectionStatus();
+ method public int getNetworkType();
+ method @IntRange(from=0, to=1007) public int getPhysicalCellId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff
+ field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
+ field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2
+ field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhysicalChannelConfig> CREATOR;
+ field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
+ }
+
public final class PreciseCallState implements android.os.Parcelable {
ctor public PreciseCallState(int, int, int, int, int);
method public int describeContents();
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index af62ba4..8d49e15 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -17,6 +17,9 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Annotation.NetworkType;
@@ -29,9 +32,11 @@
/**
* @hide
*/
+@SystemApi
public final class PhysicalChannelConfig implements Parcelable {
// TODO(b/72993578) consolidate these enums in a central location.
+ /** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({CONNECTION_PRIMARY_SERVING, CONNECTION_SECONDARY_SERVING, CONNECTION_UNKNOWN})
public @interface ConnectionStatus {}
@@ -47,7 +52,13 @@
public static final int CONNECTION_SECONDARY_SERVING = 2;
/** Connection status is unknown. */
- public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE;
+ public static final int CONNECTION_UNKNOWN = -1;
+
+ /** Channel number is unknown. */
+ public static final int CHANNEL_NUMBER_UNKNOWN = -1;
+
+ /** Physical Cell Id is unknown. */
+ public static final int PHYSICAL_CELL_ID_UNKNOWN = -1;
/**
* Connection status of the cell.
@@ -75,7 +86,7 @@
private int mFrequencyRange;
/**
- * The absolute radio frequency channel number, {@link Integer#MAX_VALUE} if unknown.
+ * The absolute radio frequency channel number, {@link CHANNEL_NUMBER_UNKNOWN} if unknown.
*/
private int mChannelNumber;
@@ -86,7 +97,8 @@
private int[] mContextIds;
/**
- * The physical cell identifier for this cell - PCI, PSC, {@link Integer#MAX_VALUE} if known.
+ * The physical cell identifier for this cell - PCI, PSC, {@link PHYSICAL_CELL_ID_UNKNOWN}
+ * if unknown.
*/
private int mPhysicalCellId;
@@ -96,7 +108,7 @@
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mCellConnectionStatus);
dest.writeInt(mCellBandwidthDownlinkKhz);
dest.writeInt(mRat);
@@ -120,6 +132,7 @@
* physical channel has no data call mapped to it.
*
* @return an integer list indicates the data call ids.
+ * @hide
*/
public int[] getContextIds() {
return mContextIds;
@@ -131,6 +144,7 @@
* @see {@link ServiceState#FREQUENCY_RANGE_MID}
* @see {@link ServiceState#FREQUENCY_RANGE_HIGH}
* @see {@link ServiceState#FREQUENCY_RANGE_MMWAVE}
+ * @hide
*/
@ServiceState.FrequencyRange
public int getFrequencyRange() {
@@ -139,7 +153,7 @@
/**
* @return the absolute radio frequency channel number for this physical channel,
- * {@link Integer#MAX_VALUE} if unknown.
+ * {@link CHANNEL_NUMBER_UNKNOWN} if unknown.
*/
public int getChannelNumber() {
return mChannelNumber;
@@ -152,18 +166,20 @@
* In EUTRAN, this value is physical layer cell identity. The range is [0, 503].
* Reference: 3GPP TS 36.211 section 6.11.
*
- * In 5G RAN, this value is physical layer cell identity. The range is [0, 1008].
+ * In 5G RAN, this value is physical layer cell identity. The range is [0, 1007].
* Reference: 3GPP TS 38.211 section 7.4.2.1.
*
- * @return the physical cell identifier for this cell, {@link Integer#MAX_VALUE} if unknown.
+ * @return the physical cell identifier for this cell, {@link PHYSICAL_CELL_ID_UNKNOWN}
+ * if {@link android.telephony.CellInfo#UNAVAILABLE}.
*/
+ @IntRange(from = 0, to = 1007)
public int getPhysicalCellId() {
return mPhysicalCellId;
}
/**The radio technology for this physical channel. */
@NetworkType
- public int getRat() {
+ public int getNetworkType() {
return mRat;
}
@@ -181,7 +197,10 @@
return mCellConnectionStatus;
}
- /** @return String representation of the connection status */
+ /**
+ * @return String representation of the connection status
+ * @hide
+ */
private String getConnectionStatusString() {
switch(mCellConnectionStatus) {
case CONNECTION_PRIMARY_SERVING:
@@ -254,6 +273,12 @@
.toString();
}
+ /** @hide */
+ public PhysicalChannelConfig(int status, int bandwidth) {
+ mCellConnectionStatus = status;
+ mCellBandwidthDownlinkKhz = bandwidth;
+ }
+
private PhysicalChannelConfig(Parcel in) {
mCellConnectionStatus = in.readInt();
mCellBandwidthDownlinkKhz = in.readInt();
@@ -274,7 +299,10 @@
mPhysicalCellId = builder.mPhysicalCellId;
}
- /** The builder of {@code PhysicalChannelConfig}. */
+ /**
+ * The builder of {@code PhysicalChannelConfig}.
+ * @hide
+ */
public static final class Builder {
private int mRat;
private int mFrequencyRange;
@@ -284,60 +312,51 @@
private int[] mContextIds;
private int mPhysicalCellId;
- /** @hide */
public Builder() {
mRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
- mChannelNumber = Integer.MAX_VALUE;
+ mChannelNumber = CHANNEL_NUMBER_UNKNOWN;
mCellBandwidthDownlinkKhz = 0;
mCellConnectionStatus = CONNECTION_UNKNOWN;
mContextIds = new int[0];
- mPhysicalCellId = Integer.MAX_VALUE;
+ mPhysicalCellId = PHYSICAL_CELL_ID_UNKNOWN;
}
- /** @hide */
public PhysicalChannelConfig build() {
return new PhysicalChannelConfig(this);
}
- /** @hide */
public Builder setRat(int rat) {
this.mRat = rat;
return this;
}
- /** @hide */
public Builder setFrequencyRange(int frequencyRange) {
this.mFrequencyRange = frequencyRange;
return this;
}
- /** @hide */
public Builder setChannelNumber(int channelNumber) {
this.mChannelNumber = channelNumber;
return this;
}
- /** @hide */
public Builder setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz) {
this.mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz;
return this;
}
- /** @hide */
public Builder setCellConnectionStatus(int connectionStatus) {
this.mCellConnectionStatus = connectionStatus;
return this;
}
- /** @hide */
public Builder setContextIds(int[] contextIds) {
if (contextIds != null) Arrays.sort(contextIds);
this.mContextIds = contextIds;
return this;
}
- /** @hide */
public Builder setPhysicalCellId(int physicalCellId) {
this.mPhysicalCellId = physicalCellId;
return this;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7a77922..969016b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5555,8 +5555,49 @@
* @param events The telephony state(s) of interest to the listener,
* as a bitwise-OR combination of {@link PhoneStateListener}
* LISTEN_ flags.
+ * @deprecated use {@link #listen(long, PhoneStateListener) instead due to the event number
+ * limit increased to 64.
*/
+ @Deprecated
public void listen(PhoneStateListener listener, int events) {
+ listen(events, listener);
+ }
+
+ /**
+ * Registers a listener object to receive notification of changes
+ * in specified telephony states.
+ * <p>
+ * To register a listener, pass a {@link PhoneStateListener} and specify at least one telephony
+ * state of interest in the events argument.
+ *
+ * At registration, and when a specified telephony state changes, the telephony manager invokes
+ * the appropriate callback method on the listener object and passes the current (updated)
+ * values.
+ * <p>
+ * To un-register a listener, pass the listener object and set the events argument to
+ * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
+ *
+ * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
+ * applies to the given subId. Otherwise, applies to
+ * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds,
+ * pass a separate listener object to each TelephonyManager object created with
+ * {@link #createForSubscriptionId}.
+ *
+ * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
+ * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
+ * {@link SecurityException} will be thrown otherwise.
+ *
+ * This API should be used sparingly -- large numbers of listeners will cause system
+ * instability. If a process has registered too many listeners without unregistering them, it
+ * may encounter an {@link IllegalStateException} when trying to register more listeners.
+ *
+ * @param events The telephony state(s) of interest to the listener,
+ * as a bitwise-OR combination of {@link PhoneStateListener}
+ * LISTEN_ flags.
+ * @param listener The {@link PhoneStateListener} object to register
+ * (or unregister)
+ */
+ public void listen(long events, @NonNull PhoneStateListener listener) {
if (mContext == null) return;
boolean notifyNow = (getITelephony() != null);
TelephonyRegistryManager telephonyRegistry =
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 943d783..a53ea16 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -28,7 +28,6 @@
"flickertestapplib",
"flickerlib",
"truth-prebuilt",
- "app-helpers-core",
"launcher-helper-lib",
"launcher-aosp-tapl"
],
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index c1a3ed69..69b1187 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -109,7 +109,7 @@
}
if (startingPos == endingPos) {
- all("navBarLayerRotatesAndScales", enabled, bugId) {
+ all("navBarLayerRotatesAndScales", enabled = false, bugId = 167747321) {
this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
deleted file mode 100644
index 7147577..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2020 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.server.wm.flicker.helpers
-
-import android.app.Instrumentation
-import android.support.test.launcherhelper.ILauncherStrategy
-import com.android.server.wm.flicker.StandardAppHelper
-
-abstract class FlickerAppHelper(
- instr: Instrumentation,
- launcherName: String,
- launcherStrategy: ILauncherStrategy
-) : StandardAppHelper(instr, sFlickerPackage, launcherName, launcherStrategy) {
- companion object {
- var sFlickerPackage = "com.android.server.wm.flicker.testapp"
- }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index c1b7657..f4de36e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -30,7 +30,7 @@
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : FlickerAppHelper(instr, launcherName, launcherStrategy) {
+) : StandardAppHelper(instr, launcherName, launcherStrategy) {
open fun openIME(device: UiDevice) {
val editText = device.wait(
Until.findObject(By.res(getPackage(), "plain_text_input")),
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index d10bb1e..0572a78 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -28,7 +28,7 @@
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : FlickerAppHelper(instr, "PipApp", launcherStrategy) {
+) : StandardAppHelper(instr, "PipApp", launcherStrategy) {
fun clickEnterPipButton(device: UiDevice) {
val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"))
Assert.assertNotNull("Pip button not found, this usually happens when the device " +
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 254209a..1759072 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -80,7 +80,7 @@
noUncoveredRegions(Surface.ROTATION_0, rotation, bugId = 141361128)
navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
- navBarLayerIsAlwaysVisible()
+ navBarLayerIsAlwaysVisible(enabled = rotation == Surface.ROTATION_0)
statusBarLayerIsAlwaysVisible(enabled = false)
wallpaperLayerBecomesInvisible()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
index 7d70812..98e05d5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTestBase.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.launch
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.dsl.LayersAssertion
import com.android.server.wm.flicker.dsl.WmAssertion
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index dda41a3..acd141a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -18,7 +18,7 @@
import android.view.Surface
import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.focusChanges
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
@@ -88,7 +88,7 @@
noUncoveredRegions(Surface.ROTATION_0, rotation, bugId = 141361128)
navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation)
statusBarLayerRotatesScales(Surface.ROTATION_0, rotation)
- navBarLayerIsAlwaysVisible(bugId = 140855415)
+ navBarLayerIsAlwaysVisible(enabled = rotation == Surface.ROTATION_0)
statusBarLayerIsAlwaysVisible(enabled = false)
wallpaperLayerBecomesInvisible()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 0ca1508..99218c2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -20,7 +20,7 @@
import android.view.Surface
import com.android.server.wm.flicker.NonRotationTestBase.Companion.SCREENSHOT_LAYER
import com.android.server.wm.flicker.RotationTestBase
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.WindowUtils
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index c5e48d9..3b5e669 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -19,7 +19,7 @@
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.focusChanges
import com.android.server.wm.flicker.helpers.exitSplitScreen
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
index 91211ca..abf41a1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
@@ -24,7 +24,7 @@
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import com.android.server.wm.flicker.FlickerTestBase
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.ImeAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
index 5c7dcd9..87c8633 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
@@ -19,7 +19,7 @@
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.NonRotationTestBase
-import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.dsl.flicker
import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.exitSplitScreen
diff --git a/tests/SilkFX/res/layout/activity_glass.xml b/tests/SilkFX/res/layout/activity_glass.xml
index 85dab93..aa09f27 100644
--- a/tests/SilkFX/res/layout/activity_glass.xml
+++ b/tests/SilkFX/res/layout/activity_glass.xml
@@ -41,7 +41,16 @@
app:layout_constraintBottom_toTopOf="@+id/bottomPanel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintTop_toTopOf="parent">
+ <TextView
+ android:id="@+id/textOverlay"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18dp"
+ android:layout_gravity="center"
+ android:textColor="#ffffff"
+ android:text="Lorem Ipsum dolor sit amet." />
+ </com.android.test.silkfx.materials.GlassView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottomPanel"
@@ -68,6 +77,21 @@
app:layout_constraintStart_toStartOf="parent" />
<SeekBar
+ android:id="@+id/zoom"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:layout_marginEnd="12dp"
+ android:layout_marginStart="12dp"
+ android:min="-100"
+ android:max="100"
+ android:progress="-15"
+ app:layout_constraintBottom_toTopOf="@+id/blurRadiusTitle"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <SeekBar
android:id="@+id/blurRadius"
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -75,7 +99,7 @@
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:max="150"
- android:progress="50"
+ android:progress="40"
app:layout_constraintBottom_toTopOf="@+id/materialOpacityTitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
@@ -103,7 +127,7 @@
android:layout_marginEnd="12dp"
android:layout_marginBottom="24dp"
android:max="100"
- android:progress="5"
+ android:progress="15"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
@@ -126,12 +150,23 @@
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginBottom="8dp"
- android:text="Material Opacity"
+ android:text="Soft light Opacity"
android:textColor="@android:color/white"
app:layout_constraintBottom_toTopOf="@+id/materialOpacity"
app:layout_constraintStart_toStartOf="parent" />
<TextView
+ android:id="@+id/zoomTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="24dp"
+ android:layout_marginBottom="8dp"
+ android:text="Zoom"
+ android:textColor="@android:color/white"
+ app:layout_constraintBottom_toTopOf="@+id/zoom"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <TextView
android:id="@+id/blurRadiusTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -193,6 +228,19 @@
app:layout_constraintStart_toEndOf="@+id/background2"
android:src="@drawable/background3" />
+ <Button
+ android:id="@+id/pickImage"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:layout_marginStart="8dp"
+ android:scaleType="centerCrop"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ android:clickable="true"
+ android:onClick="onPickImageClick"
+ app:layout_constraintBottom_toBottomOf="@+id/background1"
+ app:layout_constraintStart_toEndOf="@+id/background3"
+ android:text="Pick file" />
+
<Switch
android:id="@+id/lightMaterialSwitch"
android:layout_width="wrap_content"
@@ -200,7 +248,7 @@
android:layout_marginStart="24dp"
android:layout_marginBottom="8dp"
android:text="Light Material"
- app:layout_constraintBottom_toTopOf="@+id/blurRadiusTitle"
+ app:layout_constraintBottom_toTopOf="@+id/zoomTitle"
app:layout_constraintStart_toStartOf="parent" />
<TextView
@@ -213,6 +261,15 @@
app:layout_constraintStart_toEndOf="@+id/blurRadiusTitle" />
<TextView
+ android:id="@+id/zoomValue"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="TextView"
+ android:layout_marginLeft="8dp"
+ app:layout_constraintBottom_toBottomOf="@+id/zoomTitle"
+ app:layout_constraintStart_toEndOf="@+id/zoomTitle" />
+
+ <TextView
android:id="@+id/materialOpacityValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/SilkFX/src/com/android/test/silkfx/materials/GlassActivity.kt b/tests/SilkFX/src/com/android/test/silkfx/materials/GlassActivity.kt
index 6f5ddac..dde245f 100644
--- a/tests/SilkFX/src/com/android/test/silkfx/materials/GlassActivity.kt
+++ b/tests/SilkFX/src/com/android/test/silkfx/materials/GlassActivity.kt
@@ -16,6 +16,7 @@
package com.android.test.silkfx.materials
import android.app.Activity
+import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
@@ -39,13 +40,21 @@
lateinit var noiseOpacitySeekBar: SeekBar
lateinit var materialOpacitySeekBar: SeekBar
lateinit var scrimOpacitySeekBar: SeekBar
+ lateinit var zoomSeekBar: SeekBar
lateinit var blurRadiusSeekBar: SeekBar
lateinit var noiseOpacityValue: TextView
lateinit var materialOpacityValue: TextView
lateinit var scrimOpacityValue: TextView
lateinit var blurRadiusValue: TextView
+ lateinit var zoomValue: TextView
+ lateinit var textOverlay: TextView
- lateinit var background: Bitmap
+ var background: Bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
+ set(value) {
+ field = value
+ backgroundView.setImageBitmap(background)
+ materialView.backgroundBitmap = background
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -58,16 +67,17 @@
materialView = requireViewById(R.id.materialView)
materialOpacitySeekBar = requireViewById(R.id.materialOpacity)
blurRadiusSeekBar = requireViewById(R.id.blurRadius)
+ zoomSeekBar = requireViewById(R.id.zoom)
noiseOpacitySeekBar = requireViewById(R.id.noiseOpacity)
scrimOpacitySeekBar = requireViewById(R.id.scrimOpacity)
noiseOpacityValue = requireViewById(R.id.noiseOpacityValue)
materialOpacityValue = requireViewById(R.id.materialOpacityValue)
scrimOpacityValue = requireViewById(R.id.scrimOpacityValue)
blurRadiusValue = requireViewById(R.id.blurRadiusValue)
+ zoomValue = requireViewById(R.id.zoomValue)
+ textOverlay = requireViewById(R.id.textOverlay)
background = BitmapFactory.decodeResource(resources, R.drawable.background1)
- backgroundView.setImageBitmap(background)
- materialView.backgroundBitmap = background
blurRadiusSeekBar.setOnSeekBarChangeListener(this)
materialOpacitySeekBar.setOnSeekBarChangeListener(this)
@@ -75,13 +85,14 @@
scrimOpacitySeekBar.setOnSeekBarChangeListener(this)
arrayOf(blurRadiusSeekBar, materialOpacitySeekBar, noiseOpacitySeekBar,
- scrimOpacitySeekBar).forEach {
+ scrimOpacitySeekBar, zoomSeekBar).forEach {
it.setOnSeekBarChangeListener(this)
onProgressChanged(it, it.progress, fromUser = false)
}
lightMaterialSwitch.setOnCheckedChangeListener { _, isChecked ->
materialView.color = if (isChecked) Color.WHITE else Color.BLACK
+ textOverlay.setTextColor(if (isChecked) Color.BLACK else Color.WHITE)
}
}
@@ -104,10 +115,19 @@
materialView.scrimOpacity = progress / seekBar.max.toFloat()
scrimOpacityValue.text = progress.toString()
}
+ zoomSeekBar -> {
+ materialView.zoom = progress / seekBar.max.toFloat()
+ zoomValue.text = progress.toString()
+ }
else -> throw IllegalArgumentException("Unknown seek bar")
}
}
+ override fun onStop() {
+ super.onStop()
+ materialView.resetGyroOffsets()
+ }
+
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
@@ -120,7 +140,23 @@
}
background = BitmapFactory.decodeResource(resources, resource)
- backgroundView.setImageBitmap(background)
- materialView.backgroundBitmap = background
+ }
+
+ fun onPickImageClick(view: View) {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+ addCategory(Intent.CATEGORY_OPENABLE)
+ type = "image/*"
+ }
+ startActivityForResult(intent, 0)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ if (resultCode === RESULT_OK) {
+ data?.data?.also {
+ contentResolver.openFileDescriptor(it, "r").let {
+ background = BitmapFactory.decodeFileDescriptor(it?.fileDescriptor)
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/tests/SilkFX/src/com/android/test/silkfx/materials/GlassView.kt b/tests/SilkFX/src/com/android/test/silkfx/materials/GlassView.kt
index e100959..71175847 100644
--- a/tests/SilkFX/src/com/android/test/silkfx/materials/GlassView.kt
+++ b/tests/SilkFX/src/com/android/test/silkfx/materials/GlassView.kt
@@ -25,23 +25,83 @@
import android.graphics.Color
import android.graphics.Outline
import android.graphics.Paint
+import android.graphics.RadialGradient
import android.graphics.Rect
import android.graphics.Shader
+import android.hardware.Sensor
+import android.hardware.SensorEvent
+import android.hardware.SensorEventListener
+import android.hardware.SensorManager
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
+import android.widget.FrameLayout
+import com.android.internal.graphics.ColorUtils
import com.android.test.silkfx.R
+import kotlin.math.sin
+import kotlin.math.sqrt
-class GlassView(context: Context, attributeSet: AttributeSet) : View(context, attributeSet) {
+class GlassView(context: Context, attributeSet: AttributeSet) : FrameLayout(context, attributeSet) {
- var noise = BitmapFactory.decodeResource(resources, R.drawable.noise)
- var materialPaint = Paint()
- var scrimPaint = Paint()
- var noisePaint = Paint()
- var blurPaint = Paint()
+ private val textureTranslationMultiplier = 200f
- val src = Rect()
- val dst = Rect()
+ private var gyroXRotation = 0f
+ private var gyroYRotation = 0f
+
+ private var noise = BitmapFactory.decodeResource(resources, R.drawable.noise)
+ private var materialPaint = Paint()
+ private var scrimPaint = Paint()
+ private var noisePaint = Paint()
+ private var blurPaint = Paint()
+
+ private val src = Rect()
+ private val dst = Rect()
+
+ private val sensorManager = context.getSystemService(SensorManager::class.java)
+ private val sensorListener = object : SensorEventListener {
+
+ // Constant to convert nanoseconds to seconds.
+ private val NS2S = 1.0f / 1000000000.0f
+ private val EPSILON = 0.000001f
+ private var timestamp: Float = 0f
+
+ override fun onSensorChanged(event: SensorEvent?) {
+ // This timestep's delta rotation to be multiplied by the current rotation
+ // after computing it from the gyro sample data.
+ if (timestamp != 0f && event != null) {
+ val dT = (event.timestamp - timestamp) * NS2S
+ // Axis of the rotation sample, not normalized yet.
+ var axisX: Float = event.values[0]
+ var axisY: Float = event.values[1]
+ var axisZ: Float = event.values[2]
+
+ // Calculate the angular speed of the sample
+ val omegaMagnitude: Float = sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ)
+
+ // Normalize the rotation vector if it's big enough to get the axis
+ // (that is, EPSILON should represent your maximum allowable margin of error)
+ if (omegaMagnitude > EPSILON) {
+ axisX /= omegaMagnitude
+ axisY /= omegaMagnitude
+ axisZ /= omegaMagnitude
+ }
+
+ // Integrate around this axis with the angular speed by the timestep
+ // in order to get a delta rotation from this sample over the timestep
+ // We will convert this axis-angle representation of the delta rotation
+ // into a quaternion before turning it into the rotation matrix.
+ val thetaOverTwo: Float = omegaMagnitude * dT / 2.0f
+ val sinThetaOverTwo: Float = sin(thetaOverTwo)
+ gyroXRotation += sinThetaOverTwo * axisX
+ gyroYRotation += sinThetaOverTwo * axisY
+
+ invalidate()
+ }
+ timestamp = event?.timestamp?.toFloat() ?: 0f
+ }
+
+ override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { }
+ }
var backgroundBitmap: Bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
set(value) {
@@ -70,6 +130,12 @@
invalidate()
}
+ var zoom = 0.0f
+ set(value) {
+ field = value
+ invalidate()
+ }
+
var color = Color.BLACK
set(value) {
field = value
@@ -91,6 +157,7 @@
}
init {
+ setWillNotDraw(false)
materialPaint.blendMode = BlendMode.SOFT_LIGHT
noisePaint.blendMode = BlendMode.SOFT_LIGHT
noisePaint.shader = BitmapShader(noise, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
@@ -106,12 +173,36 @@
clipToOutline = true
}
+ override fun onAttachedToWindow() {
+ sensorManager?.getSensorList(Sensor.TYPE_GYROSCOPE)?.firstOrNull().let {
+ sensorManager?.registerListener(sensorListener, it, SensorManager.SENSOR_DELAY_GAME)
+ }
+ }
+
+ override fun onDetachedFromWindow() {
+ sensorManager?.unregisterListener(sensorListener)
+ }
+
override fun onDraw(canvas: Canvas?) {
- src.set(left, top, right, bottom)
+ src.set(-width / 2, -height / 2, width / 2, height / 2)
+ src.scale(1.0f + zoom)
+ val centerX = left + width / 2
+ val centerY = top + height / 2
+ val textureXOffset = (textureTranslationMultiplier * gyroYRotation).toInt()
+ val textureYOffset = (textureTranslationMultiplier * gyroXRotation).toInt()
+ src.set(src.left + centerX + textureXOffset, src.top + centerY + textureYOffset,
+ src.right + centerX + textureXOffset, src.bottom + centerY + textureYOffset)
+
dst.set(0, 0, width, height)
canvas?.drawBitmap(backgroundBitmap, src, dst, blurPaint)
canvas?.drawRect(dst, materialPaint)
canvas?.drawRect(dst, noisePaint)
canvas?.drawRect(dst, scrimPaint)
}
+
+ fun resetGyroOffsets() {
+ gyroXRotation = 0f
+ gyroYRotation = 0f
+ invalidate()
+ }
}
\ No newline at end of file
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 0aca13e..7c150f9 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -16,8 +16,8 @@
#include <input/KeyCharacterMap.h>
#include <input/KeyLayoutMap.h>
+#include <input/PropertyMap.h>
#include <input/VirtualKeyMap.h>
-#include <utils/PropertyMap.h>
#include <stdarg.h>
#include <stdio.h>
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 941ff61..3040041 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -129,12 +129,8 @@
},
hostdex: true, // for hiddenapi check
- // Allow access to the stubs from anywhere.
- visibility: ["//visibility:public"],
-
// Restrict access to implementation library.
impl_library_visibility: [
- "//visibility:override", // Ignore the visibility property.
"//frameworks/opt/net/wifi/service:__subpackages__",
] + test_access_hidden_api_whitelist,
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index b104dec..3f5c673 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -144,6 +144,7 @@
@Deprecated public static class WifiConfiguration.GroupCipher {
field @Deprecated public static final int CCMP = 3; // 0x3
+ field @Deprecated public static final int GCMP_128 = 7; // 0x7
field @Deprecated public static final int GCMP_256 = 5; // 0x5
field @Deprecated public static final int SMS4 = 6; // 0x6
field @Deprecated public static final int TKIP = 2; // 0x2
@@ -173,6 +174,7 @@
@Deprecated public static class WifiConfiguration.PairwiseCipher {
field @Deprecated public static final int CCMP = 2; // 0x2
+ field @Deprecated public static final int GCMP_128 = 5; // 0x5
field @Deprecated public static final int GCMP_256 = 3; // 0x3
field @Deprecated public static final int NONE = 0; // 0x0
field @Deprecated public static final int SMS4 = 4; // 0x4
@@ -579,6 +581,7 @@
method public void onPublishStarted(@NonNull android.net.wifi.aware.PublishDiscoverySession);
method public void onServiceDiscovered(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>);
method public void onServiceDiscoveredWithinRange(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>, int);
+ method public void onServiceLost(@NonNull android.net.wifi.aware.PeerHandle);
method public void onSessionConfigFailed();
method public void onSessionConfigUpdated();
method public void onSessionTerminated();
@@ -654,6 +657,7 @@
method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
method public android.net.wifi.aware.Characteristics getCharacteristics();
method public boolean isAvailable();
+ method public boolean isDeviceAttached();
field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0
field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
index eff64a3..c3e573c 100644
--- a/wifi/api/system-current.txt
+++ b/wifi/api/system-current.txt
@@ -449,6 +449,7 @@
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
+ method public boolean is60GHzBandSupported();
method public boolean isApMacRandomizationSupported();
method public boolean isConnectedMacRandomizationSupported();
method @Deprecated public boolean isDeviceToDeviceRttSupported();
@@ -651,6 +652,7 @@
field public static final int WIFI_BAND_5_GHZ = 2; // 0x2
field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4
field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6
+ field public static final int WIFI_BAND_60_GHZ = 16; // 0x10
field public static final int WIFI_BAND_6_GHZ = 8; // 0x8
field public static final int WIFI_BAND_BOTH = 3; // 0x3
field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index e493789..b3ed8ac 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -118,6 +118,8 @@
boolean is6GHzBandSupported();
+ boolean is60GHzBandSupported();
+
boolean isWifiStandardSupported(int standard);
DhcpInfo getDhcpInfo();
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 9302f78..54ec1e1 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -595,6 +595,27 @@
public static final int BAND_6_GHZ_END_FREQ_MHZ = 7105;
/**
+ * 60 GHz band first channel number
+ * @hide
+ */
+ public static final int BAND_60_GHZ_FIRST_CH_NUM = 1;
+ /**
+ * 60 GHz band last channel number
+ * @hide
+ */
+ public static final int BAND_60_GHZ_LAST_CH_NUM = 6;
+ /**
+ * 60 GHz band frequency of first channel in MHz
+ * @hide
+ */
+ public static final int BAND_60_GHZ_START_FREQ_MHZ = 58320;
+ /**
+ * 60 GHz band frequency of last channel in MHz
+ * @hide
+ */
+ public static final int BAND_60_GHZ_END_FREQ_MHZ = 70200;
+
+ /**
* Utility function to check if a frequency within 2.4 GHz band
* @param freqMhz frequency in MHz
* @return true if within 2.4GHz, false otherwise
@@ -628,6 +649,17 @@
}
/**
+ * Utility function to check if a frequency within 60 GHz band
+ * @param freqMhz
+ * @return true if within 60GHz, false otherwise
+ *
+ * @hide
+ */
+ public static boolean is60GHz(int freqMhz) {
+ return freqMhz >= BAND_60_GHZ_START_FREQ_MHZ && freqMhz <= BAND_60_GHZ_END_FREQ_MHZ;
+ }
+
+ /**
* Utility function to convert channel number/band to frequency in MHz
* @param channel number to convert
* @param band of channel to convert
@@ -707,6 +739,13 @@
}
/**
+ * @hide
+ */
+ public boolean is60GHz() {
+ return ScanResult.is60GHz(frequency);
+ }
+
+ /**
* @hide
* anqp lines from supplicant BSS response
*/
diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java
index 99c4eac..cf54f26 100644
--- a/wifi/java/android/net/wifi/SoftApCapability.java
+++ b/wifi/java/android/net/wifi/SoftApCapability.java
@@ -21,7 +21,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.wifi.SoftApConfiguration.BandType;
-import android.os.Build;
+import android.net.wifi.util.SdkLevelUtil;
import android.os.Parcel;
import android.os.Parcelable;
@@ -176,7 +176,7 @@
*/
@NonNull
public int[] getSupportedChannelList(@BandType int band) {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
+ if (!SdkLevelUtil.isAtLeastS()) {
throw new UnsupportedOperationException();
}
switch (band) {
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index 393fe8d..bc837b3 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -22,7 +22,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.MacAddress;
-import android.os.Build;
+import android.net.wifi.util.SdkLevelUtil;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -551,7 +551,7 @@
@SystemApi
@MacRandomizationSetting
public int getMacRandomizationSetting() {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
+ if (!SdkLevelUtil.isAtLeastS()) {
throw new UnsupportedOperationException();
}
return mMacRandomizationSetting;
@@ -1046,7 +1046,7 @@
@NonNull
public Builder setMacRandomizationSetting(
@MacRandomizationSetting int macRandomizationSetting) {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
+ if (!SdkLevelUtil.isAtLeastS()) {
throw new UnsupportedOperationException();
}
mMacRandomizationSetting = macRandomizationSetting;
diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java
index 4791275..40981f7 100644
--- a/wifi/java/android/net/wifi/SoftApInfo.java
+++ b/wifi/java/android/net/wifi/SoftApInfo.java
@@ -20,7 +20,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.MacAddress;
-import android.os.Build;
+import android.net.wifi.util.SdkLevelUtil;
import android.os.Parcel;
import android.os.Parcelable;
@@ -138,7 +138,7 @@
*/
@Nullable
public MacAddress getBssid() {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
+ if (!SdkLevelUtil.isAtLeastS()) {
throw new UnsupportedOperationException();
}
return mBssid;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 1588bf7..02b7a42 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -301,9 +301,16 @@
*/
public static final int SMS4 = 4;
+ /**
+ * AES in Galois/Counter Mode with a 128-bit integrity key
+ */
+ public static final int GCMP_128 = 5;
+
+
public static final String varName = "pairwise";
- public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4" };
+ public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4",
+ "GCMP_128" };
}
/**
@@ -345,13 +352,17 @@
* SMS4 cipher for WAPI
*/
public static final int SMS4 = 6;
+ /**
+ * AES in Galois/Counter Mode with a 128-bit integrity key
+ */
+ public static final int GCMP_128 = 7;
public static final String varName = "group";
public static final String[] strings =
{ /* deprecated */ "WEP40", /* deprecated */ "WEP104",
"TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256",
- "SMS4" };
+ "SMS4", "GCMP_128" };
}
/**
@@ -498,8 +509,10 @@
allowedProtocols.set(WifiConfiguration.Protocol.RSN);
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128);
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128);
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
requirePmf = true;
break;
@@ -508,7 +521,9 @@
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
+ allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128);
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+ allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128);
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
// Note: allowedSuiteBCiphers bitset will be set by the service once the
@@ -519,8 +534,10 @@
allowedProtocols.set(WifiConfiguration.Protocol.RSN);
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128);
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128);
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
requirePmf = true;
break;
@@ -596,6 +613,12 @@
public static final int AP_BAND_5GHZ = 1;
/**
+ * 60GHz band
+ * @hide
+ */
+ public static final int AP_BAND_60GHZ = 2;
+
+ /**
* Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability,
* operating country code and current radio conditions.
* @hide
@@ -2509,7 +2532,18 @@
@KeyMgmt.KeyMgmtScheme
public int getAuthType() {
if (allowedKeyManagement.cardinality() > 1) {
- throw new IllegalStateException("More than one auth type set");
+ if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
+ if (allowedKeyManagement.cardinality() == 2
+ && allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+ return KeyMgmt.WPA_EAP;
+ }
+ if (allowedKeyManagement.cardinality() == 3
+ && allowedKeyManagement.get(KeyMgmt.IEEE8021X)
+ && allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
+ return KeyMgmt.SUITE_B_192;
+ }
+ }
+ throw new IllegalStateException("Invalid auth type set: " + allowedKeyManagement);
}
if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
return KeyMgmt.WPA_PSK;
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 77fa673..90edc45 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -30,6 +30,9 @@
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECParameterSpec;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -1442,4 +1445,50 @@
}
return TextUtils.isEmpty(getCaPath());
}
+
+ /**
+ * Check if a given certificate Get the Suite-B cipher from the certificate
+ *
+ * @param x509Certificate Certificate to process
+ * @return true if the certificate OID matches the Suite-B requirements for RSA or ECDSA
+ * certificates, or false otherwise.
+ * @hide
+ */
+ public static boolean isSuiteBCipherCert(@Nullable X509Certificate x509Certificate) {
+ if (x509Certificate == null) {
+ return false;
+ }
+ final String sigAlgOid = x509Certificate.getSigAlgOID();
+
+ // Wi-Fi alliance requires the use of both ECDSA secp384r1 and RSA 3072 certificates
+ // in WPA3-Enterprise 192-bit security networks, which are also known as Suite-B-192
+ // networks, even though NSA Suite-B-192 mandates ECDSA only. The use of the term
+ // Suite-B was already coined in the IEEE 802.11-2016 specification for
+ // AKM 00-0F-AC but the test plan for WPA3-Enterprise 192-bit for APs mandates
+ // support for both RSA and ECDSA, and for STAs it mandates ECDSA and optionally
+ // RSA. In order to be compatible with all WPA3-Enterprise 192-bit deployments,
+ // we are supporting both types here.
+ if (sigAlgOid.equals("1.2.840.113549.1.1.12")) {
+ // sha384WithRSAEncryption
+ if (x509Certificate.getPublicKey() instanceof RSAPublicKey) {
+ final RSAPublicKey rsaPublicKey = (RSAPublicKey) x509Certificate.getPublicKey();
+ if (rsaPublicKey.getModulus() != null
+ && rsaPublicKey.getModulus().bitLength() >= 3072) {
+ return true;
+ }
+ }
+ } else if (sigAlgOid.equals("1.2.840.10045.4.3.3")) {
+ // ecdsa-with-SHA384
+ if (x509Certificate.getPublicKey() instanceof ECPublicKey) {
+ final ECPublicKey ecPublicKey = (ECPublicKey) x509Certificate.getPublicKey();
+ final ECParameterSpec ecParameterSpec = ecPublicKey.getParams();
+
+ if (ecParameterSpec != null && ecParameterSpec.getOrder() != null
+ && ecParameterSpec.getOrder().bitLength() >= 384) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index b28b902..c76f4a6 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2407,6 +2407,8 @@
public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support
/** @hide */
public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI
+ /** @hide */
+ public static final long WIFI_FEATURE_INFRA_60G = 0x4000000000L; // 60 GHz Band Support
/** @hide */
public static final long WIFI_FEATURE_FILS_SHA256 = 0x4000000000L; // FILS-SHA256
@@ -2569,6 +2571,21 @@
}
/**
+ * Check if the chipset supports the 60GHz frequency band.
+ *
+ * @return {@code true} if supported, {@code false} otherwise.
+ * @hide
+ */
+ @SystemApi
+ public boolean is60GHzBandSupported() {
+ try {
+ return mService.is60GHzBandSupported();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Check if the chipset supports 6GHz band.
* @return {@code true} if supported, {@code false} otherwise.
*/
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index b0213b0..e12bb91 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -78,12 +78,12 @@
private @Nullable String mWpa3SaePassphrase;
/**
* The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the WPA-EAP networks.
+ * certificates and other settings associated with the WPA/WPA2-Enterprise networks.
*/
private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
/**
* The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the SuiteB networks.
+ * certificates and other settings associated with the WPA3-Enterprise networks.
*/
private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
/**
@@ -243,7 +243,11 @@
/**
* Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description.
+ * to WPA3-Enterprise networks (standard and 192-bit security). See
+ * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the
+ * client and CA certificates must be provided, and must be of type of either
+ * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384
+ * (OID 1.2.840.10045.4.3.3).
*
* @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
* @return Instance of {@link Builder} to enable chaining of the builder method.
@@ -284,8 +288,25 @@
} else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
configuration.enterpriseConfig = mWpa2EnterpriseConfig;
- } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+ } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise
+ if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS
+ && WifiEnterpriseConfig.isSuiteBCipherCert(
+ mWpa3EnterpriseConfig.getClientCertificate())
+ && WifiEnterpriseConfig.isSuiteBCipherCert(
+ mWpa3EnterpriseConfig.getCaCertificate())) {
+ // WPA3-Enterprise in 192-bit security mode (Suite-B)
+ configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+ } else {
+ // WPA3-Enterprise
+ configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
+ configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ configuration.allowedPairwiseCiphers.set(
+ WifiConfiguration.PairwiseCipher.GCMP_256);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+ configuration.requirePmf = true;
+ }
configuration.enterpriseConfig = mWpa3EnterpriseConfig;
} else if (mIsEnhancedOpen) { // OWE network
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index e4e900f..e992c83 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -72,12 +72,12 @@
private @Nullable String mWpa3SaePassphrase;
/**
* The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the WPA-EAP networks.
+ * certificates and other settings associated with the WPA/WPA2-Enterprise networks.
*/
private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
/**
* The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the SuiteB networks.
+ * certificates and other settings associated with the WPA3-Enterprise networks.
*/
private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
/**
@@ -176,7 +176,7 @@
mWapiEnterpriseConfig = null;
mIsNetworkUntrusted = false;
mPriorityGroup = 0;
- mIsEnhancedMacRandomizationEnabled = true;
+ mIsEnhancedMacRandomizationEnabled = false;
}
/**
@@ -288,7 +288,11 @@
/**
* Set the associated enterprise configuration for this network. Needed for authenticating
- * to WPA3 enterprise networks. See {@link WifiEnterpriseConfig} for description.
+ * to WPA3-Enterprise networks (standard and 192-bit security). See
+ * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the
+ * client and CA certificates must be provided, and must be of type of either
+ * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384
+ * (OID 1.2.840.10045.4.3.3).
*
* @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
* @return Instance of {@link Builder} to enable chaining of the builder method.
@@ -405,11 +409,12 @@
* Suggested networks will never use the device (factory) MAC address to associate to the
* network - instead they use a locally generated random MAC address. This method controls
* the strategy for generating the random MAC address:
- * <li> Persisted MAC randomization (false): generates the MAC address from a secret seed
- * and information from the Wi-Fi configuration (SSID or Passpoint profile). That means that
- * the same generated MAC address will be used for each subsequent association. </li>
- * <li> Enhanced MAC randomization (true - the default): periodically generates a new MAC
- * address new connections. Under this option, the randomized MAC address should change
+ * <li> Persisted MAC randomization (false - the default): generates the MAC address from a
+ * secret seed and information from the Wi-Fi configuration (SSID or Passpoint profile).
+ * This means that the same generated MAC address will be used for each subsequent
+ * association. </li>
+ * <li> Enhanced MAC randomization (true): periodically generates a new MAC
+ * address for new connections. Under this option, the randomized MAC address should change
* if the suggestion is removed and then added back. </li>
*
* @param enabled {@code true} to periodically change the randomized MAC address.
@@ -570,8 +575,25 @@
} else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
configuration.enterpriseConfig = mWpa2EnterpriseConfig;
- } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
- configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+ } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise
+ if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS
+ && WifiEnterpriseConfig.isSuiteBCipherCert(
+ mWpa3EnterpriseConfig.getClientCertificate())
+ && WifiEnterpriseConfig.isSuiteBCipherCert(
+ mWpa3EnterpriseConfig.getCaCertificate())) {
+ // WPA3-Enterprise in 192-bit security mode (Suite-B)
+ configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
+ } else {
+ // WPA3-Enterprise
+ configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
+ configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ configuration.allowedPairwiseCiphers.set(
+ WifiConfiguration.PairwiseCipher.GCMP_256);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+ configuration.requirePmf = true;
+ }
configuration.enterpriseConfig = mWpa3EnterpriseConfig;
} else if (mIsEnhancedOpen) { // OWE network
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
@@ -710,6 +732,8 @@
+ "suggestion with Passpoint configuration");
}
wifiConfiguration = buildWifiConfigurationForPasspoint();
+ mPasspointConfiguration.setEnhancedMacRandomizationEnabled(
+ mIsEnhancedMacRandomizationEnabled);
} else {
if (mSsid == null) {
throw new IllegalStateException("setSsid should be invoked for suggestion");
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 94771ac..a68d7e2 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -68,7 +68,9 @@
/** @hide */
public static final int WIFI_BAND_INDEX_6_GHZ = 3;
/** @hide */
- public static final int WIFI_BAND_COUNT = 4;
+ public static final int WIFI_BAND_INDEX_60_GHZ = 4;
+ /** @hide */
+ public static final int WIFI_BAND_COUNT = 5;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -76,7 +78,8 @@
WIFI_BAND_INDEX_24_GHZ,
WIFI_BAND_INDEX_5_GHZ,
WIFI_BAND_INDEX_5_GHZ_DFS_ONLY,
- WIFI_BAND_INDEX_6_GHZ})
+ WIFI_BAND_INDEX_6_GHZ,
+ WIFI_BAND_INDEX_60_GHZ})
public @interface WifiBandIndex {}
/** no band specified; use channel list instead */
@@ -89,6 +92,8 @@
public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 1 << WIFI_BAND_INDEX_5_GHZ_DFS_ONLY;
/** 6 GHz band */
public static final int WIFI_BAND_6_GHZ = 1 << WIFI_BAND_INDEX_6_GHZ;
+ /** 60 GHz band */
+ public static final int WIFI_BAND_60_GHZ = 1 << WIFI_BAND_INDEX_60_GHZ;
/**
* Combination of bands
@@ -113,6 +118,12 @@
/** 2.4 GHz band and 5 GHz band; with DFS channels and 6 GHz */
public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ =
WIFI_BAND_BOTH_WITH_DFS | WIFI_BAND_6_GHZ;
+ /** @hide */
+ public static final int WIFI_BAND_24_5_6_60_GHZ =
+ WIFI_BAND_24_5_6_GHZ | WIFI_BAND_60_GHZ;
+ /** @hide */
+ public static final int WIFI_BAND_24_5_WITH_DFS_6_60_GHZ =
+ WIFI_BAND_24_5_6_60_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -127,7 +138,10 @@
WIFI_BAND_BOTH_WITH_DFS,
WIFI_BAND_6_GHZ,
WIFI_BAND_24_5_6_GHZ,
- WIFI_BAND_24_5_WITH_DFS_6_GHZ})
+ WIFI_BAND_24_5_WITH_DFS_6_GHZ,
+ WIFI_BAND_60_GHZ,
+ WIFI_BAND_24_5_6_60_GHZ,
+ WIFI_BAND_24_5_WITH_DFS_6_60_GHZ})
public @interface WifiBand {}
/**
@@ -179,7 +193,10 @@
* @hide
*/
public static boolean isFullBandScan(@WifiBand int bandScanned, boolean excludeDfs) {
- return (bandScanned | WIFI_BAND_6_GHZ | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0))
+ // 5GHz DFS channel is part of 5GHz, mark 5GHz scanned as well.
+ if ((bandScanned & WIFI_BAND_5_GHZ_DFS_ONLY) != 0) bandScanned |= WIFI_BAND_5_GHZ;
+ return (bandScanned | WIFI_BAND_6_GHZ | WIFI_BAND_60_GHZ
+ | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0))
== WIFI_BAND_ALL;
}
@@ -571,6 +588,19 @@
}
}
+ /** {@hide} */
+ public void addResults(@NonNull ScanData s) {
+ mBandScanned |= s.mBandScanned;
+ mFlags |= s.mFlags;
+ addResults(s.getResults());
+ }
+
+ /** {@hide} */
+ public boolean isFullBandScanResults() {
+ return (mBandScanned & WifiScanner.WIFI_BAND_24_GHZ) != 0
+ && (mBandScanned & WifiScanner.WIFI_BAND_5_GHZ) != 0;
+ }
+
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
index bfb0462..e3800ad 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
@@ -189,4 +189,16 @@
public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
/* empty */
}
+
+ /**
+ * Called when the discovered peer is no longer visible. All further operations on this
+ * discovery session will fail. If the peer is visible again,
+ * {@link #onServiceDiscovered(PeerHandle, byte[], List)} or
+ * {@link #onServiceDiscoveredWithinRange(PeerHandle, byte[], List, int)} will be called.
+ *
+ * @param peerHandle An opaque handle to the peer matching our discovery operation.
+ */
+ public void onServiceLost(@NonNull PeerHandle peerHandle) {
+ /* empty */
+ }
}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
index 421a8af..e3e7c8e 100644
--- a/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
@@ -35,4 +35,5 @@
void onMessageSendSuccess(int messageId);
void onMessageSendFail(int messageId, int reason);
void onMessageReceived(int peerId, in byte[] message);
+ void onMatchExpired(int peerId);
}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
index 88f95ad..f5b1edc 100644
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
@@ -36,6 +36,7 @@
// Aware API
boolean isUsageEnabled();
Characteristics getCharacteristics();
+ boolean isDeviceAttached();
// client API
void connect(in IBinder binder, in String callingPackage, in String callingFeatureId,
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index c2ae17c..d6e46fd 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -179,6 +179,22 @@
}
/**
+ * Return the current status of the Aware service: whether ot not the device is already attached
+ * to an Aware cluster. To attach to an Aware cluster, please use
+ * {@link #attach(AttachCallback, Handler)} or
+ * {@link #attach(AttachCallback, IdentityChangedListener, Handler)}.
+ * @return A boolean indicating whether the device is attached to a cluster at this time (true)
+ * or not (false).
+ */
+ public boolean isDeviceAttached() {
+ try {
+ return mService.isDeviceAttached();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Returns the characteristics of the Wi-Fi Aware interface: a set of parameters which specify
* limitations on configurations, e.g. the maximum service name length.
*
@@ -587,6 +603,7 @@
private static final int CALLBACK_MESSAGE_SEND_FAIL = 6;
private static final int CALLBACK_MESSAGE_RECEIVED = 7;
private static final int CALLBACK_MATCH_WITH_DISTANCE = 8;
+ private static final int CALLBACK_MATCH_EXPIRED = 9;
private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
@@ -676,6 +693,9 @@
mOriginalCallback.onMessageReceived(new PeerHandle(msg.arg1),
(byte[]) msg.obj);
break;
+ case CALLBACK_MATCH_EXPIRED:
+ mOriginalCallback
+ .onServiceLost(new PeerHandle(msg.arg1));
}
}
};
@@ -746,6 +766,15 @@
onMatchCommon(CALLBACK_MATCH_WITH_DISTANCE, peerId, serviceSpecificInfo, matchFilter,
distanceMm);
}
+ @Override
+ public void onMatchExpired(int peerId) {
+ if (VDBG) {
+ Log.v(TAG, "onMatchExpired: peerId=" + peerId);
+ }
+ Message msg = mHandler.obtainMessage(CALLBACK_MATCH_EXPIRED);
+ msg.arg1 = peerId;
+ mHandler.sendMessage(msg);
+ }
@Override
public void onMessageSendSuccess(int messageId) {
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index d1d1780..61a6e16 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -444,6 +444,11 @@
private boolean mIsMacRandomizationEnabled = true;
/**
+ * Whether this passpoint configuration should use enhanced MAC randomization.
+ */
+ private boolean mIsEnhancedMacRandomizationEnabled = false;
+
+ /**
* Indicates if the end user has expressed an explicit opinion about the
* meteredness of this network, such as through the Settings app.
* This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED},
@@ -481,6 +486,20 @@
}
/**
+ * This setting is only applicable if MAC randomization is enabled.
+ * If set to true, the framework will periodically generate new MAC addresses for new
+ * connections.
+ * If set to false (the default), the framework will use the same locally generated MAC address
+ * for connections to this passpoint configuration.
+ * @param enabled true to use enhanced MAC randomization, false to use persistent MAC
+ * randomization.
+ * @hide
+ */
+ public void setEnhancedMacRandomizationEnabled(boolean enabled) {
+ mIsEnhancedMacRandomizationEnabled = enabled;
+ }
+
+ /**
* Sets the metered override setting for this Passpoint configuration.
*
* @param meteredOverride One of the values in {@link MeteredOverride}
@@ -531,6 +550,19 @@
}
/**
+ * When MAC randomization is enabled, this indicates whether enhanced MAC randomization or
+ * persistent MAC randomization will be used for connections to this Passpoint network.
+ * If true, the MAC address used for connections will periodically change. Otherwise, the same
+ * locally generated MAC will be used for all connections to this passpoint configuration.
+ *
+ * @return true for enhanced MAC randomization enabled. False for disabled.
+ * @hide
+ */
+ public boolean isEnhancedMacRandomizationEnabled() {
+ return mIsEnhancedMacRandomizationEnabled;
+ }
+
+ /**
* Constructor for creating PasspointConfiguration with default values.
*/
public PasspointConfiguration() {}
@@ -574,6 +606,7 @@
mCarrierId = source.mCarrierId;
mIsAutojoinEnabled = source.mIsAutojoinEnabled;
mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled;
+ mIsEnhancedMacRandomizationEnabled = source.mIsEnhancedMacRandomizationEnabled;
mMeteredOverride = source.mMeteredOverride;
}
@@ -606,6 +639,7 @@
dest.writeInt(mCarrierId);
dest.writeBoolean(mIsAutojoinEnabled);
dest.writeBoolean(mIsMacRandomizationEnabled);
+ dest.writeBoolean(mIsEnhancedMacRandomizationEnabled);
dest.writeInt(mMeteredOverride);
}
@@ -639,6 +673,7 @@
&& mCarrierId == that.mCarrierId
&& mIsAutojoinEnabled == that.mIsAutojoinEnabled
&& mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled
+ && mIsEnhancedMacRandomizationEnabled == that.mIsEnhancedMacRandomizationEnabled
&& mMeteredOverride == that.mMeteredOverride
&& (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null
: mServiceFriendlyNames.equals(that.mServiceFriendlyNames));
@@ -651,7 +686,7 @@
mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes,
mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes,
mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled,
- mMeteredOverride);
+ mIsEnhancedMacRandomizationEnabled, mMeteredOverride);
}
@Override
@@ -707,6 +742,7 @@
builder.append("CarrierId:" + mCarrierId);
builder.append("IsAutojoinEnabled:" + mIsAutojoinEnabled);
builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled);
+ builder.append("mIsEnhancedMacRandomizationEnabled:" + mIsEnhancedMacRandomizationEnabled);
builder.append("mMeteredOverride:" + mMeteredOverride);
return builder.toString();
}
@@ -815,6 +851,7 @@
config.mCarrierId = in.readInt();
config.mIsAutojoinEnabled = in.readBoolean();
config.mIsMacRandomizationEnabled = in.readBoolean();
+ config.mIsEnhancedMacRandomizationEnabled = in.readBoolean();
config.mMeteredOverride = in.readInt();
return config;
}
diff --git a/wifi/java/android/net/wifi/nl80211/NativeScanResult.java b/wifi/java/android/net/wifi/nl80211/NativeScanResult.java
index a8e9999..35cf45f 100644
--- a/wifi/java/android/net/wifi/nl80211/NativeScanResult.java
+++ b/wifi/java/android/net/wifi/nl80211/NativeScanResult.java
@@ -225,6 +225,15 @@
* BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Immediate Block Ack.
*/
public static final int BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK = 0x1 << 15;
+ /**
+ * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DMG ESS.
+ * In DMG bits 0 and 1 are parsed together, where ESS=0x3 and IBSS=0x1
+ */
+ public static final int BSS_CAPABILITY_DMG_ESS = 0x3;
+ /**
+ * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DMG IBSS.
+ */
+ public static final int BSS_CAPABILITY_DMG_IBSS = 0x1;
/**
* Returns the capabilities of the AP repseresented by this scan result as advertised in the
diff --git a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java
index 4116234..fb58d3f 100644
--- a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java
+++ b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -223,7 +223,11 @@
/**
* Callbacks for SoftAp interface registered using
* {@link #registerApCallback(String, Executor, SoftApCallback)}.
+ *
+ * @deprecated The usage is replaced by vendor HAL
+ * {@code android.hardware.wifi.hostapd.V1_3.IHostapdCallback}.
*/
+ @Deprecated
public interface SoftApCallback {
/**
* Invoked when there is a fatal failure and the SoftAp is shutdown.
@@ -1044,6 +1048,7 @@
* {@link WifiScanner#WIFI_BAND_5_GHZ},
* {@link WifiScanner#WIFI_BAND_5_GHZ_DFS_ONLY},
* {@link WifiScanner#WIFI_BAND_6_GHZ}
+ * {@link WifiScanner.WIFI_BAND_60_GHZ}
* @return frequencies vector of valid frequencies (MHz), or an empty array for error.
* @throws IllegalArgumentException if band is not recognized.
*/
@@ -1067,6 +1072,9 @@
case WifiScanner.WIFI_BAND_6_GHZ:
result = mWificond.getAvailable6gChannels();
break;
+ case WifiScanner.WIFI_BAND_60_GHZ:
+ result = mWificond.getAvailable60gChannels();
+ break;
default:
throw new IllegalArgumentException("unsupported band " + band);
}
@@ -1121,7 +1129,11 @@
* @param callback Callback for AP events.
* @return true on success, false on failure (e.g. when called on an interface which has not
* been set up).
+ *
+ * @deprecated The usage is replaced by vendor HAL
+ * {@code android.hardware.wifi.hostapd.V1_3.IHostapdCallback}.
*/
+ @Deprecated
public boolean registerApCallback(@NonNull String ifaceName,
@NonNull @CallbackExecutor Executor executor,
@NonNull SoftApCallback callback) {
diff --git a/wifi/java/android/net/wifi/util/SdkLevelUtil.java b/wifi/java/android/net/wifi/util/SdkLevelUtil.java
new file mode 100644
index 0000000..042634c7
--- /dev/null
+++ b/wifi/java/android/net/wifi/util/SdkLevelUtil.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 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.net.wifi.util;
+
+import android.os.Build;
+
+/**
+ * Utility to check the SDK version of the device that the code is running on.
+ *
+ * This can be used to disable new Wifi APIs added in Mainline updates on older SDK versions.
+ *
+ * @hide
+ */
+public class SdkLevelUtil {
+
+ /** This class is instantiable to allow easy mocking. */
+ public SdkLevelUtil() { }
+
+ /** See {@link #isAtLeastS()}. This version is non-static to allow easy mocking. */
+ public boolean isAtLeastSMockable() {
+ return isAtLeastS();
+ }
+
+ /** Returns true if the Android platform SDK is at least "S", false otherwise. */
+ public static boolean isAtLeastS() {
+ // TODO(b/167575586): after S SDK finalization, this method should just be
+ // `return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;`
+
+ // at least S: return true
+ // this condition only evaluates to true after S SDK finalization when VERSION_CODES.S
+ // is set to something like "31", before SDK finalization the value is "10000"
+ // Note that Build.VERSION_CODES.S is inlined at compile time. If it's inlined to 10000,
+ // this condition never evaluates to true.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ return true;
+ }
+
+ // Assume for now that S = R + 1
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ return true;
+ }
+
+ // R: check CODENAME
+ // Before S SDK finalization, SDK_INT = R = 30 i.e. remains on the previous version
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
+ // CODENAME = "REL" on R release builds
+ // CODENAME = "S" on S development builds
+ return "S".equals(Build.VERSION.CODENAME);
+ }
+
+ // older than R: return false
+ return false;
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java
index 641b891..8aa6add 100644
--- a/wifi/tests/src/android/net/wifi/FakeKeys.java
+++ b/wifi/tests/src/android/net/wifi/FakeKeys.java
@@ -212,7 +212,57 @@
(byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
(byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
};
- public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1);
+ public static final PrivateKey RSA_KEY1 = loadPrivateKey("RSA", FAKE_RSA_KEY_1);
+
+ private static final String CA_SUITE_B_RSA3072_CERT_STRING =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIEnTCCAwWgAwIBAgIUD87Y8fFLzLr1HQ/64aEnjNq2R/4wDQYJKoZIhvcNAQEM\n"
+ + "BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAO\n"
+ + "BgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0\n"
+ + "Q0EwHhcNMjAwNzIxMDIxNzU0WhcNMzAwNTMwMDIxNzU0WjBeMQswCQYDVQQGEwJV\n"
+ + "UzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEO\n"
+ + "MAwGA1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTCCAaIwDQYJKoZIhvcN\n"
+ + "AQEBBQADggGPADCCAYoCggGBAMtrsT0otlxh0QS079KpRRbU1PQjCihSoltXnrxF\n"
+ + "sTWZs2weVEeYVyYU5LaauCDDgISCMtjtfbfylMBeYjpWB5hYzYQOiTzo0anWhMyb\n"
+ + "Ngb7gpMVZuIl6lwMYRyVRKwHWnTo2EUg1ZzW5rGe5fs/KHj6//hoNFm+3Oju0TQd\n"
+ + "nraQULpoERPF5B7p85Cssk8uNbviBfZXvtCuJ4N6w7PNceOY/9bbwc1mC+pPZmzV\n"
+ + "SOAg0vvbIQRzChm63C3jBC3xmxSOOZVrKN4zKDG2s8P0oCNGt0NlgRMrgbPRekzg\n"
+ + "4avkbA0vTuc2AyriTEYkdea/Mt4EpRg9XuOb43U/GJ/d/vQv2/9fsxhXmsZrn8kr\n"
+ + "Qo5MMHJFUd96GgHmvYSU3Mf/5r8gF626lvqHioGuTAuHUSnr02ri1WUxZ15LDRgY\n"
+ + "quMjDCFZfucjJPDAdtiHcFSej/4SLJlN39z8oKKNPn3aL9Gv49oAKs9S8tfDVzMk\n"
+ + "fDLROQFHFuW715GnnMgEAoOpRwIDAQABo1MwUTAdBgNVHQ4EFgQUeVuGmSVN4ARs\n"
+ + "mesUMWSJ2qWLbxUwHwYDVR0jBBgwFoAUeVuGmSVN4ARsmesUMWSJ2qWLbxUwDwYD\n"
+ + "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAYEAit1Lo/hegZpPuT9dlWZJ\n"
+ + "bC8JvAf95O8lnn6LFb69pgYOHCLgCIlvYXu9rdBUJgZo+V1MzJJljiO6RxWRfKbQ\n"
+ + "8WBYkoqR1EqriR3Kn8q/SjIZCdFSaznTyU1wQMveBQ6RJWXSUhYVfE9RjyFTp7B4\n"
+ + "UyH2uCluR/0T06HQNGfH5XpIYQqCk1Zgng5lmEmheLDPoJpa92lKeQFJMC6eYz9g\n"
+ + "lF1GHxPxkPfbMJ6ZDp5X6Yopu6Q6uEXhVKM/iQVcgzRkx9rid+xTYl+nOKyK/XfC\n"
+ + "z8P0/TFIoPTW02DLge5wKagdoCpy1B7HdrAXyUjoH4B8MsUkq3kYPFSjPzScuTtV\n"
+ + "kUuDw5ipCNeXCRnhbYqRDk6PX5GUu2cmN9jtaH3tbgm3fKNOsd/BO1fLIl7qjXlR\n"
+ + "27HHbC0JXjNvlm2DLp23v4NTxS7WZGYsxyUj5DZrxBxqCsTXu/01w1BrQKWKh9FM\n"
+ + "aVrlA8omfVODK2CSuw+KhEMHepRv/AUgsLl4L4+RMoa+\n"
+ + "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CA_SUITE_B_RSA3072_CERT =
+ loadCertificate(CA_SUITE_B_RSA3072_CERT_STRING);
+
+ private static final String CA_SUITE_B_ECDSA_CERT_STRING =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIICTzCCAdSgAwIBAgIUdnLttwNPnQzFufplGOr9bTrGCqMwCgYIKoZIzj0EAwMw\n"
+ + "XjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNV\n"
+ + "BAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0Q0Ew\n"
+ + "HhcNMjAwNzIxMDIyNDA1WhcNMzAwNTMwMDIyNDA1WjBeMQswCQYDVQQGEwJVUzEL\n"
+ + "MAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEOMAwG\n"
+ + "A1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTB2MBAGByqGSM49AgEGBSuB\n"
+ + "BAAiA2IABFmntXwk9icqhDQFUP1xy04WyEpaGW4q6Q+8pujlSl/X3iotPZ++GZfp\n"
+ + "Mfv3YDHDBl6sELPQ2BEjyPXmpsKjOUdiUe69e88oGEdeqT2xXiQ6uzpTfJD4170i\n"
+ + "O/TwLrQGKKNTMFEwHQYDVR0OBBYEFCjptsX3g4g5W0L4oEP6N3gfyiZXMB8GA1Ud\n"
+ + "IwQYMBaAFCjptsX3g4g5W0L4oEP6N3gfyiZXMA8GA1UdEwEB/wQFMAMBAf8wCgYI\n"
+ + "KoZIzj0EAwMDaQAwZgIxAK61brUYRbLmQKiaEboZgrHtnPAcGo7Yzx3MwHecx3Dm\n"
+ + "5soIeLVYc8bPYN1pbhXW1gIxALdEe2sh03nBHyQH4adYoZungoCwt8mp/7sJFxou\n"
+ + "9UnRegyBgGzf74ROWdpZHzh+Pg==\n"
+ + "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CA_SUITE_B_ECDSA_CERT =
+ loadCertificate(CA_SUITE_B_ECDSA_CERT_STRING);
private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING =
"-----BEGIN CERTIFICATE-----\n"
@@ -243,6 +293,363 @@
public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT =
loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING);
+ private static final byte[] CLIENT_SUITE_B_RSA3072_KEY_DATA = new byte[]{
+ (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xfe, (byte) 0x02, (byte) 0x01,
+ (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
+ (byte) 0x06, (byte) 0xe8, (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xe4,
+ (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x82, (byte) 0x01,
+ (byte) 0x81, (byte) 0x00, (byte) 0xc1, (byte) 0x22, (byte) 0xb7, (byte) 0x0b,
+ (byte) 0x92, (byte) 0xb9, (byte) 0xb9, (byte) 0xdb, (byte) 0x42, (byte) 0x29,
+ (byte) 0x39, (byte) 0xc4, (byte) 0xd7, (byte) 0x87, (byte) 0xbc, (byte) 0xcf,
+ (byte) 0x67, (byte) 0x19, (byte) 0xbf, (byte) 0x09, (byte) 0x81, (byte) 0xe1,
+ (byte) 0x77, (byte) 0xbe, (byte) 0x6b, (byte) 0xcf, (byte) 0xbb, (byte) 0x40,
+ (byte) 0xbb, (byte) 0x9d, (byte) 0x1e, (byte) 0x8a, (byte) 0x1c, (byte) 0xfe,
+ (byte) 0x54, (byte) 0x33, (byte) 0x0a, (byte) 0x58, (byte) 0x0a, (byte) 0xe0,
+ (byte) 0xc6, (byte) 0xd5, (byte) 0x50, (byte) 0x2d, (byte) 0x03, (byte) 0xdc,
+ (byte) 0x51, (byte) 0x3e, (byte) 0x53, (byte) 0x7d, (byte) 0x82, (byte) 0xef,
+ (byte) 0xc4, (byte) 0xb1, (byte) 0x2a, (byte) 0x84, (byte) 0xda, (byte) 0x45,
+ (byte) 0x6b, (byte) 0x6f, (byte) 0x3e, (byte) 0x63, (byte) 0x66, (byte) 0xf9,
+ (byte) 0x46, (byte) 0x85, (byte) 0x4f, (byte) 0xc2, (byte) 0xa4, (byte) 0xc3,
+ (byte) 0x25, (byte) 0x27, (byte) 0xa3, (byte) 0xf7, (byte) 0x6f, (byte) 0xfb,
+ (byte) 0x65, (byte) 0xc3, (byte) 0xa5, (byte) 0xdf, (byte) 0xf3, (byte) 0x01,
+ (byte) 0x14, (byte) 0x3e, (byte) 0xdc, (byte) 0x5c, (byte) 0x00, (byte) 0x7d,
+ (byte) 0x6a, (byte) 0x29, (byte) 0x02, (byte) 0x11, (byte) 0x32, (byte) 0x09,
+ (byte) 0x54, (byte) 0xb1, (byte) 0xc2, (byte) 0xc0, (byte) 0x9a, (byte) 0xfa,
+ (byte) 0xc9, (byte) 0x50, (byte) 0xe2, (byte) 0x3b, (byte) 0x91, (byte) 0x20,
+ (byte) 0xc2, (byte) 0x2e, (byte) 0x50, (byte) 0x2d, (byte) 0x4c, (byte) 0x9b,
+ (byte) 0x43, (byte) 0x5a, (byte) 0xa6, (byte) 0xd6, (byte) 0x72, (byte) 0x33,
+ (byte) 0x74, (byte) 0xe3, (byte) 0xfc, (byte) 0x80, (byte) 0x90, (byte) 0x11,
+ (byte) 0xfa, (byte) 0x64, (byte) 0xa3, (byte) 0xda, (byte) 0x95, (byte) 0x21,
+ (byte) 0xb8, (byte) 0x8a, (byte) 0xe9, (byte) 0xea, (byte) 0x09, (byte) 0x31,
+ (byte) 0x39, (byte) 0x18, (byte) 0xf0, (byte) 0x45, (byte) 0x9f, (byte) 0x02,
+ (byte) 0x7e, (byte) 0xd1, (byte) 0x4c, (byte) 0x57, (byte) 0x5f, (byte) 0x47,
+ (byte) 0x53, (byte) 0x8b, (byte) 0xb8, (byte) 0xed, (byte) 0x26, (byte) 0x54,
+ (byte) 0xe8, (byte) 0xe0, (byte) 0x2d, (byte) 0x6f, (byte) 0x7f, (byte) 0xfa,
+ (byte) 0xea, (byte) 0x58, (byte) 0xbf, (byte) 0xa8, (byte) 0x59, (byte) 0xd7,
+ (byte) 0xd9, (byte) 0xc0, (byte) 0x30, (byte) 0x0c, (byte) 0x70, (byte) 0xe1,
+ (byte) 0x04, (byte) 0xc9, (byte) 0xc7, (byte) 0xb9, (byte) 0x4b, (byte) 0xc0,
+ (byte) 0x02, (byte) 0xd7, (byte) 0xec, (byte) 0x1f, (byte) 0xad, (byte) 0x0d,
+ (byte) 0x83, (byte) 0x44, (byte) 0x64, (byte) 0x70, (byte) 0xea, (byte) 0x60,
+ (byte) 0xbd, (byte) 0xb3, (byte) 0xca, (byte) 0xf4, (byte) 0x16, (byte) 0x02,
+ (byte) 0x3d, (byte) 0x87, (byte) 0x0a, (byte) 0x57, (byte) 0xab, (byte) 0x7b,
+ (byte) 0xc4, (byte) 0x18, (byte) 0x20, (byte) 0xbc, (byte) 0x64, (byte) 0xbe,
+ (byte) 0x4b, (byte) 0x60, (byte) 0x06, (byte) 0x0d, (byte) 0x9c, (byte) 0xac,
+ (byte) 0x42, (byte) 0x49, (byte) 0x7b, (byte) 0x85, (byte) 0xdb, (byte) 0x0c,
+ (byte) 0x7e, (byte) 0xcb, (byte) 0x03, (byte) 0x7a, (byte) 0xeb, (byte) 0x5e,
+ (byte) 0x6b, (byte) 0x22, (byte) 0xa9, (byte) 0xfd, (byte) 0x59, (byte) 0x6d,
+ (byte) 0xf1, (byte) 0x45, (byte) 0x13, (byte) 0x32, (byte) 0xbd, (byte) 0x34,
+ (byte) 0x5a, (byte) 0xa8, (byte) 0xbc, (byte) 0xbf, (byte) 0xaa, (byte) 0x1a,
+ (byte) 0x1f, (byte) 0xb3, (byte) 0x20, (byte) 0xff, (byte) 0xb9, (byte) 0xf3,
+ (byte) 0xc4, (byte) 0xa1, (byte) 0x24, (byte) 0x53, (byte) 0xbd, (byte) 0x1f,
+ (byte) 0xf4, (byte) 0x43, (byte) 0x9c, (byte) 0x3a, (byte) 0x62, (byte) 0x4e,
+ (byte) 0x70, (byte) 0x05, (byte) 0x4d, (byte) 0x65, (byte) 0xd0, (byte) 0x75,
+ (byte) 0x3c, (byte) 0x20, (byte) 0xb3, (byte) 0x34, (byte) 0x92, (byte) 0xd1,
+ (byte) 0x5c, (byte) 0x36, (byte) 0x3c, (byte) 0x1f, (byte) 0x89, (byte) 0xa8,
+ (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0xaf, (byte) 0x43, (byte) 0x78,
+ (byte) 0xcb, (byte) 0xd7, (byte) 0x4f, (byte) 0x53, (byte) 0xb2, (byte) 0xf8,
+ (byte) 0xd6, (byte) 0x37, (byte) 0x22, (byte) 0xd3, (byte) 0xc7, (byte) 0xcb,
+ (byte) 0x2e, (byte) 0xb7, (byte) 0x9d, (byte) 0x06, (byte) 0x55, (byte) 0x23,
+ (byte) 0x6a, (byte) 0xd7, (byte) 0x00, (byte) 0xdc, (byte) 0x38, (byte) 0x36,
+ (byte) 0x1c, (byte) 0x12, (byte) 0xd1, (byte) 0x9e, (byte) 0x83, (byte) 0x17,
+ (byte) 0xe4, (byte) 0x2c, (byte) 0x4c, (byte) 0xda, (byte) 0xe3, (byte) 0xf8,
+ (byte) 0x65, (byte) 0x3b, (byte) 0x7b, (byte) 0x84, (byte) 0x86, (byte) 0xfc,
+ (byte) 0x41, (byte) 0x91, (byte) 0xf1, (byte) 0x2b, (byte) 0xe5, (byte) 0x76,
+ (byte) 0x36, (byte) 0x1f, (byte) 0x41, (byte) 0x35, (byte) 0x85, (byte) 0x2e,
+ (byte) 0x0d, (byte) 0x65, (byte) 0xfd, (byte) 0x44, (byte) 0xf5, (byte) 0x84,
+ (byte) 0xe3, (byte) 0xa4, (byte) 0x41, (byte) 0x9c, (byte) 0x1d, (byte) 0xb1,
+ (byte) 0xa5, (byte) 0xb5, (byte) 0xce, (byte) 0x02, (byte) 0xb2, (byte) 0x7a,
+ (byte) 0xe8, (byte) 0x85, (byte) 0x07, (byte) 0x62, (byte) 0x9d, (byte) 0x32,
+ (byte) 0x66, (byte) 0xc0, (byte) 0x4a, (byte) 0xaf, (byte) 0x94, (byte) 0xc7,
+ (byte) 0x52, (byte) 0xf5, (byte) 0x28, (byte) 0x80, (byte) 0xa8, (byte) 0xd0,
+ (byte) 0x88, (byte) 0x25, (byte) 0xc1, (byte) 0x67, (byte) 0x01, (byte) 0xff,
+ (byte) 0xc9, (byte) 0xe7, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00,
+ (byte) 0x01, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x80, (byte) 0x04,
+ (byte) 0xb1, (byte) 0xcc, (byte) 0x53, (byte) 0x3a, (byte) 0xb0, (byte) 0xcb,
+ (byte) 0x04, (byte) 0xba, (byte) 0x59, (byte) 0xf8, (byte) 0x2e, (byte) 0x81,
+ (byte) 0xb2, (byte) 0xa9, (byte) 0xf3, (byte) 0x3c, (byte) 0xa5, (byte) 0x52,
+ (byte) 0x90, (byte) 0x6f, (byte) 0x98, (byte) 0xc4, (byte) 0x69, (byte) 0x5b,
+ (byte) 0x83, (byte) 0x84, (byte) 0x20, (byte) 0xb1, (byte) 0xae, (byte) 0xc3,
+ (byte) 0x04, (byte) 0x46, (byte) 0x6a, (byte) 0x24, (byte) 0x2f, (byte) 0xcd,
+ (byte) 0x6b, (byte) 0x90, (byte) 0x70, (byte) 0x20, (byte) 0x45, (byte) 0x25,
+ (byte) 0x1a, (byte) 0xc3, (byte) 0x02, (byte) 0x42, (byte) 0xf3, (byte) 0x49,
+ (byte) 0xe2, (byte) 0x3e, (byte) 0x21, (byte) 0x87, (byte) 0xdd, (byte) 0x6a,
+ (byte) 0x94, (byte) 0x2a, (byte) 0x1e, (byte) 0x0f, (byte) 0xdb, (byte) 0x77,
+ (byte) 0x5f, (byte) 0xc1, (byte) 0x2c, (byte) 0x03, (byte) 0xfb, (byte) 0xcf,
+ (byte) 0x91, (byte) 0x82, (byte) 0xa1, (byte) 0xbf, (byte) 0xb0, (byte) 0x73,
+ (byte) 0xfa, (byte) 0xda, (byte) 0xbc, (byte) 0xf8, (byte) 0x9f, (byte) 0x45,
+ (byte) 0xd3, (byte) 0xe8, (byte) 0xbb, (byte) 0x38, (byte) 0xfb, (byte) 0xc2,
+ (byte) 0x2d, (byte) 0x76, (byte) 0x51, (byte) 0x96, (byte) 0x18, (byte) 0x03,
+ (byte) 0x15, (byte) 0xd9, (byte) 0xea, (byte) 0x82, (byte) 0x25, (byte) 0x83,
+ (byte) 0xff, (byte) 0x5c, (byte) 0x85, (byte) 0x06, (byte) 0x09, (byte) 0xb2,
+ (byte) 0x46, (byte) 0x12, (byte) 0x64, (byte) 0x02, (byte) 0x74, (byte) 0x4f,
+ (byte) 0xbc, (byte) 0x9a, (byte) 0x25, (byte) 0x18, (byte) 0x01, (byte) 0x07,
+ (byte) 0x17, (byte) 0x25, (byte) 0x55, (byte) 0x7c, (byte) 0xdc, (byte) 0xe1,
+ (byte) 0xd1, (byte) 0x5a, (byte) 0x2f, (byte) 0x25, (byte) 0xaf, (byte) 0xf6,
+ (byte) 0x8f, (byte) 0xa4, (byte) 0x9a, (byte) 0x5a, (byte) 0x3a, (byte) 0xfe,
+ (byte) 0x2e, (byte) 0x93, (byte) 0x24, (byte) 0xa0, (byte) 0x27, (byte) 0xac,
+ (byte) 0x07, (byte) 0x75, (byte) 0x33, (byte) 0x01, (byte) 0x54, (byte) 0x23,
+ (byte) 0x0f, (byte) 0xe8, (byte) 0x9f, (byte) 0xfa, (byte) 0x36, (byte) 0xe6,
+ (byte) 0x3a, (byte) 0xd5, (byte) 0x78, (byte) 0xb0, (byte) 0xe4, (byte) 0x6a,
+ (byte) 0x16, (byte) 0x50, (byte) 0xbd, (byte) 0x0f, (byte) 0x9f, (byte) 0x32,
+ (byte) 0xa1, (byte) 0x6b, (byte) 0xf5, (byte) 0xa4, (byte) 0x34, (byte) 0x58,
+ (byte) 0xb6, (byte) 0xa4, (byte) 0xb3, (byte) 0xc3, (byte) 0x83, (byte) 0x08,
+ (byte) 0x18, (byte) 0xc7, (byte) 0xef, (byte) 0x95, (byte) 0xe2, (byte) 0x1b,
+ (byte) 0xba, (byte) 0x35, (byte) 0x61, (byte) 0xa3, (byte) 0xb4, (byte) 0x30,
+ (byte) 0xe0, (byte) 0xd1, (byte) 0xc1, (byte) 0xa2, (byte) 0x3a, (byte) 0xc6,
+ (byte) 0xb4, (byte) 0xd2, (byte) 0x80, (byte) 0x5a, (byte) 0xaf, (byte) 0xa4,
+ (byte) 0x54, (byte) 0x3c, (byte) 0x66, (byte) 0x5a, (byte) 0x1c, (byte) 0x4d,
+ (byte) 0xe1, (byte) 0xd9, (byte) 0x98, (byte) 0x44, (byte) 0x01, (byte) 0x1b,
+ (byte) 0x8c, (byte) 0xe9, (byte) 0x80, (byte) 0x54, (byte) 0x83, (byte) 0x3d,
+ (byte) 0x96, (byte) 0x25, (byte) 0x41, (byte) 0x1c, (byte) 0xad, (byte) 0xae,
+ (byte) 0x3b, (byte) 0x7a, (byte) 0xd7, (byte) 0x9d, (byte) 0x10, (byte) 0x7c,
+ (byte) 0xd1, (byte) 0xa7, (byte) 0x96, (byte) 0x39, (byte) 0xa5, (byte) 0x2f,
+ (byte) 0xbe, (byte) 0xc3, (byte) 0x2c, (byte) 0x64, (byte) 0x01, (byte) 0xfe,
+ (byte) 0xa2, (byte) 0xd1, (byte) 0x6a, (byte) 0xcf, (byte) 0x4c, (byte) 0x76,
+ (byte) 0x3b, (byte) 0xc8, (byte) 0x35, (byte) 0x21, (byte) 0xda, (byte) 0x98,
+ (byte) 0xcf, (byte) 0xf9, (byte) 0x29, (byte) 0xff, (byte) 0x30, (byte) 0x59,
+ (byte) 0x36, (byte) 0x53, (byte) 0x0b, (byte) 0xbb, (byte) 0xfa, (byte) 0xba,
+ (byte) 0xc4, (byte) 0x03, (byte) 0x23, (byte) 0xe0, (byte) 0xd3, (byte) 0x33,
+ (byte) 0xff, (byte) 0x32, (byte) 0xdb, (byte) 0x30, (byte) 0x64, (byte) 0xc7,
+ (byte) 0x56, (byte) 0xca, (byte) 0x55, (byte) 0x14, (byte) 0xee, (byte) 0x58,
+ (byte) 0xfe, (byte) 0x96, (byte) 0x7e, (byte) 0x1c, (byte) 0x34, (byte) 0x16,
+ (byte) 0xeb, (byte) 0x76, (byte) 0x26, (byte) 0x48, (byte) 0xe2, (byte) 0xe5,
+ (byte) 0x5c, (byte) 0xd5, (byte) 0x83, (byte) 0x37, (byte) 0xd9, (byte) 0x09,
+ (byte) 0x71, (byte) 0xbc, (byte) 0x54, (byte) 0x25, (byte) 0xca, (byte) 0x2e,
+ (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0xcc, (byte) 0x3a, (byte) 0x81,
+ (byte) 0x95, (byte) 0x9e, (byte) 0xf4, (byte) 0x01, (byte) 0xa7, (byte) 0xc0,
+ (byte) 0x20, (byte) 0xce, (byte) 0x70, (byte) 0x55, (byte) 0x2c, (byte) 0xe0,
+ (byte) 0x93, (byte) 0x72, (byte) 0xa6, (byte) 0x25, (byte) 0xda, (byte) 0x64,
+ (byte) 0x19, (byte) 0x18, (byte) 0xd2, (byte) 0x31, (byte) 0xe2, (byte) 0x7c,
+ (byte) 0xf2, (byte) 0x30, (byte) 0x9e, (byte) 0x8d, (byte) 0xc6, (byte) 0x14,
+ (byte) 0x8a, (byte) 0x38, (byte) 0xf0, (byte) 0x94, (byte) 0xeb, (byte) 0xf4,
+ (byte) 0x64, (byte) 0x92, (byte) 0x3d, (byte) 0x67, (byte) 0xa6, (byte) 0x2c,
+ (byte) 0x52, (byte) 0xfc, (byte) 0x60, (byte) 0xca, (byte) 0x2a, (byte) 0xcf,
+ (byte) 0x24, (byte) 0xd5, (byte) 0x42, (byte) 0x5f, (byte) 0xc7, (byte) 0x9f,
+ (byte) 0xf3, (byte) 0xb4, (byte) 0xdf, (byte) 0x76, (byte) 0x6e, (byte) 0x53,
+ (byte) 0xa1, (byte) 0x7b, (byte) 0xae, (byte) 0xa5, (byte) 0x84, (byte) 0x1f,
+ (byte) 0xfa, (byte) 0xc0, (byte) 0xb4, (byte) 0x6c, (byte) 0xc9, (byte) 0x02,
+ (byte) 0x81, (byte) 0xc1, (byte) 0x00, (byte) 0xf3, (byte) 0x17, (byte) 0xd9,
+ (byte) 0x48, (byte) 0x17, (byte) 0x87, (byte) 0x84, (byte) 0x16, (byte) 0xea,
+ (byte) 0x2d, (byte) 0x31, (byte) 0x1b, (byte) 0xce, (byte) 0xec, (byte) 0xaf,
+ (byte) 0xdc, (byte) 0x6b, (byte) 0xaf, (byte) 0xc8, (byte) 0xf1, (byte) 0x40,
+ (byte) 0xa7, (byte) 0x4f, (byte) 0xef, (byte) 0x48, (byte) 0x08, (byte) 0x5e,
+ (byte) 0x9a, (byte) 0xd1, (byte) 0xc0, (byte) 0xb1, (byte) 0xfe, (byte) 0xe7,
+ (byte) 0x03, (byte) 0xd5, (byte) 0x96, (byte) 0x01, (byte) 0xe8, (byte) 0x40,
+ (byte) 0xca, (byte) 0x78, (byte) 0xcb, (byte) 0xb3, (byte) 0x28, (byte) 0x1a,
+ (byte) 0xf0, (byte) 0xe5, (byte) 0xf6, (byte) 0x46, (byte) 0xef, (byte) 0xcd,
+ (byte) 0x1a, (byte) 0x0f, (byte) 0x13, (byte) 0x2d, (byte) 0x38, (byte) 0xf8,
+ (byte) 0xf7, (byte) 0x88, (byte) 0x21, (byte) 0x15, (byte) 0xce, (byte) 0x48,
+ (byte) 0xf4, (byte) 0x92, (byte) 0x7e, (byte) 0x9b, (byte) 0x2e, (byte) 0x2f,
+ (byte) 0x22, (byte) 0x3e, (byte) 0x5c, (byte) 0x67, (byte) 0xd7, (byte) 0x58,
+ (byte) 0xf6, (byte) 0xef, (byte) 0x1f, (byte) 0xb4, (byte) 0x04, (byte) 0xc7,
+ (byte) 0xfd, (byte) 0x8c, (byte) 0x4e, (byte) 0x27, (byte) 0x9e, (byte) 0xb9,
+ (byte) 0xef, (byte) 0x0f, (byte) 0xf7, (byte) 0x4a, (byte) 0xc2, (byte) 0xf4,
+ (byte) 0x64, (byte) 0x6b, (byte) 0xe0, (byte) 0xfb, (byte) 0xe3, (byte) 0x45,
+ (byte) 0xd5, (byte) 0x37, (byte) 0xa0, (byte) 0x2a, (byte) 0xc6, (byte) 0xf3,
+ (byte) 0xf6, (byte) 0xcc, (byte) 0xb5, (byte) 0x94, (byte) 0xbf, (byte) 0x56,
+ (byte) 0xa0, (byte) 0x61, (byte) 0x36, (byte) 0x88, (byte) 0x35, (byte) 0xd5,
+ (byte) 0xa5, (byte) 0xad, (byte) 0x20, (byte) 0x48, (byte) 0xda, (byte) 0x70,
+ (byte) 0x35, (byte) 0xd9, (byte) 0x75, (byte) 0x66, (byte) 0xa5, (byte) 0xac,
+ (byte) 0x86, (byte) 0x7a, (byte) 0x75, (byte) 0x49, (byte) 0x88, (byte) 0x40,
+ (byte) 0xce, (byte) 0xb0, (byte) 0x6f, (byte) 0x57, (byte) 0x15, (byte) 0x54,
+ (byte) 0xd3, (byte) 0x2f, (byte) 0x11, (byte) 0x9b, (byte) 0xe3, (byte) 0x87,
+ (byte) 0xc8, (byte) 0x8d, (byte) 0x98, (byte) 0xc6, (byte) 0xe0, (byte) 0xbc,
+ (byte) 0x85, (byte) 0xb9, (byte) 0x04, (byte) 0x43, (byte) 0xa9, (byte) 0x41,
+ (byte) 0xce, (byte) 0x42, (byte) 0x1a, (byte) 0x57, (byte) 0x10, (byte) 0xd8,
+ (byte) 0xe4, (byte) 0x6a, (byte) 0x51, (byte) 0x10, (byte) 0x0a, (byte) 0xec,
+ (byte) 0xe4, (byte) 0x57, (byte) 0xc7, (byte) 0xee, (byte) 0xe9, (byte) 0xd6,
+ (byte) 0xcb, (byte) 0x3e, (byte) 0xba, (byte) 0xfa, (byte) 0xe9, (byte) 0x0e,
+ (byte) 0xed, (byte) 0x87, (byte) 0x04, (byte) 0x9a, (byte) 0x48, (byte) 0xba,
+ (byte) 0xaf, (byte) 0x08, (byte) 0xf5, (byte) 0x02, (byte) 0x81, (byte) 0xc1,
+ (byte) 0x00, (byte) 0xcb, (byte) 0x63, (byte) 0xd6, (byte) 0x54, (byte) 0xb6,
+ (byte) 0xf3, (byte) 0xf3, (byte) 0x8c, (byte) 0xf8, (byte) 0xd0, (byte) 0xd2,
+ (byte) 0x84, (byte) 0xc1, (byte) 0xf5, (byte) 0x12, (byte) 0xe0, (byte) 0x02,
+ (byte) 0x80, (byte) 0x42, (byte) 0x92, (byte) 0x4e, (byte) 0xa4, (byte) 0x5c,
+ (byte) 0xa5, (byte) 0x64, (byte) 0xec, (byte) 0xb7, (byte) 0xdc, (byte) 0xe0,
+ (byte) 0x2d, (byte) 0x5d, (byte) 0xac, (byte) 0x0e, (byte) 0x24, (byte) 0x48,
+ (byte) 0x13, (byte) 0x05, (byte) 0xe8, (byte) 0xff, (byte) 0x96, (byte) 0x93,
+ (byte) 0xba, (byte) 0x3c, (byte) 0x88, (byte) 0xcc, (byte) 0x80, (byte) 0xf9,
+ (byte) 0xdb, (byte) 0xa8, (byte) 0x4d, (byte) 0x86, (byte) 0x47, (byte) 0xc8,
+ (byte) 0xbf, (byte) 0x34, (byte) 0x2d, (byte) 0xda, (byte) 0xb6, (byte) 0x28,
+ (byte) 0xf0, (byte) 0x1e, (byte) 0xd2, (byte) 0x46, (byte) 0x0d, (byte) 0x6f,
+ (byte) 0x36, (byte) 0x8e, (byte) 0x84, (byte) 0xd8, (byte) 0xaf, (byte) 0xf7,
+ (byte) 0x69, (byte) 0x23, (byte) 0x77, (byte) 0xfb, (byte) 0xc5, (byte) 0x04,
+ (byte) 0x08, (byte) 0x18, (byte) 0xac, (byte) 0x85, (byte) 0x80, (byte) 0x87,
+ (byte) 0x1c, (byte) 0xfe, (byte) 0x8e, (byte) 0x5d, (byte) 0x00, (byte) 0x7f,
+ (byte) 0x5b, (byte) 0x33, (byte) 0xf5, (byte) 0xdf, (byte) 0x70, (byte) 0x81,
+ (byte) 0xad, (byte) 0x81, (byte) 0xf4, (byte) 0x5a, (byte) 0x37, (byte) 0x8a,
+ (byte) 0x79, (byte) 0x09, (byte) 0xc5, (byte) 0x55, (byte) 0xab, (byte) 0x58,
+ (byte) 0x7c, (byte) 0x47, (byte) 0xca, (byte) 0xa5, (byte) 0x80, (byte) 0x49,
+ (byte) 0x5f, (byte) 0x71, (byte) 0x83, (byte) 0xfb, (byte) 0x3b, (byte) 0x06,
+ (byte) 0xec, (byte) 0x75, (byte) 0x23, (byte) 0xc4, (byte) 0x32, (byte) 0xc7,
+ (byte) 0x18, (byte) 0xf6, (byte) 0x82, (byte) 0x95, (byte) 0x98, (byte) 0x39,
+ (byte) 0xf7, (byte) 0x92, (byte) 0x31, (byte) 0xc0, (byte) 0x89, (byte) 0xba,
+ (byte) 0xd4, (byte) 0xd4, (byte) 0x58, (byte) 0x4e, (byte) 0x38, (byte) 0x35,
+ (byte) 0x10, (byte) 0xb9, (byte) 0xf1, (byte) 0x27, (byte) 0xdc, (byte) 0xff,
+ (byte) 0xc7, (byte) 0xb2, (byte) 0xba, (byte) 0x1f, (byte) 0x27, (byte) 0xaf,
+ (byte) 0x99, (byte) 0xd5, (byte) 0xb0, (byte) 0x39, (byte) 0xe7, (byte) 0x43,
+ (byte) 0x88, (byte) 0xd3, (byte) 0xce, (byte) 0x38, (byte) 0xc2, (byte) 0x99,
+ (byte) 0x43, (byte) 0xfc, (byte) 0x8a, (byte) 0xe3, (byte) 0x60, (byte) 0x0d,
+ (byte) 0x0a, (byte) 0xb8, (byte) 0xc4, (byte) 0x29, (byte) 0xca, (byte) 0x0d,
+ (byte) 0x30, (byte) 0xaf, (byte) 0xca, (byte) 0xd0, (byte) 0xaa, (byte) 0x67,
+ (byte) 0xb1, (byte) 0xdd, (byte) 0xdb, (byte) 0x7a, (byte) 0x11, (byte) 0xad,
+ (byte) 0xeb, (byte) 0x02, (byte) 0x81, (byte) 0xc0, (byte) 0x71, (byte) 0xb8,
+ (byte) 0xcf, (byte) 0x72, (byte) 0x35, (byte) 0x67, (byte) 0xb5, (byte) 0x38,
+ (byte) 0x8f, (byte) 0x16, (byte) 0xd3, (byte) 0x29, (byte) 0x82, (byte) 0x35,
+ (byte) 0x21, (byte) 0xd4, (byte) 0x49, (byte) 0x20, (byte) 0x74, (byte) 0x2d,
+ (byte) 0xc0, (byte) 0xa4, (byte) 0x44, (byte) 0xf5, (byte) 0xd8, (byte) 0xc9,
+ (byte) 0xe9, (byte) 0x90, (byte) 0x1d, (byte) 0xde, (byte) 0x3a, (byte) 0xa6,
+ (byte) 0xd7, (byte) 0xe5, (byte) 0xe8, (byte) 0x4e, (byte) 0x83, (byte) 0xd7,
+ (byte) 0xe6, (byte) 0x2f, (byte) 0x92, (byte) 0x31, (byte) 0x21, (byte) 0x3f,
+ (byte) 0xfa, (byte) 0xd2, (byte) 0x85, (byte) 0x92, (byte) 0x1f, (byte) 0xff,
+ (byte) 0x61, (byte) 0x00, (byte) 0xf6, (byte) 0xda, (byte) 0x6e, (byte) 0xc6,
+ (byte) 0x7f, (byte) 0x5a, (byte) 0x35, (byte) 0x79, (byte) 0xdc, (byte) 0xdc,
+ (byte) 0xa3, (byte) 0x2e, (byte) 0x9f, (byte) 0x35, (byte) 0xd1, (byte) 0x5c,
+ (byte) 0xda, (byte) 0xb9, (byte) 0xf7, (byte) 0x58, (byte) 0x7d, (byte) 0x4f,
+ (byte) 0xb6, (byte) 0x13, (byte) 0xd7, (byte) 0x2c, (byte) 0x0a, (byte) 0xa8,
+ (byte) 0x4d, (byte) 0xf2, (byte) 0xe4, (byte) 0x67, (byte) 0x4f, (byte) 0x8b,
+ (byte) 0xa6, (byte) 0xca, (byte) 0x1a, (byte) 0xbb, (byte) 0x02, (byte) 0x63,
+ (byte) 0x8f, (byte) 0xb7, (byte) 0x46, (byte) 0xec, (byte) 0x7a, (byte) 0x8a,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x45, (byte) 0x3a, (byte) 0x8d, (byte) 0xa8,
+ (byte) 0x83, (byte) 0x4b, (byte) 0x0a, (byte) 0xdb, (byte) 0x4b, (byte) 0x99,
+ (byte) 0xf3, (byte) 0x69, (byte) 0x95, (byte) 0xf0, (byte) 0xcf, (byte) 0xe9,
+ (byte) 0xf7, (byte) 0x67, (byte) 0xc9, (byte) 0x45, (byte) 0x18, (byte) 0x2f,
+ (byte) 0xf0, (byte) 0x5c, (byte) 0x90, (byte) 0xbd, (byte) 0xa6, (byte) 0x66,
+ (byte) 0x8c, (byte) 0xfe, (byte) 0x60, (byte) 0x5d, (byte) 0x6c, (byte) 0x27,
+ (byte) 0xec, (byte) 0xc1, (byte) 0x84, (byte) 0xb2, (byte) 0xa1, (byte) 0x97,
+ (byte) 0x9e, (byte) 0x16, (byte) 0x29, (byte) 0xa7, (byte) 0xe0, (byte) 0x38,
+ (byte) 0xa2, (byte) 0x36, (byte) 0x05, (byte) 0x5f, (byte) 0xda, (byte) 0x72,
+ (byte) 0x1a, (byte) 0x5f, (byte) 0xa8, (byte) 0x7d, (byte) 0x41, (byte) 0x35,
+ (byte) 0xf6, (byte) 0x4e, (byte) 0x0a, (byte) 0x88, (byte) 0x8e, (byte) 0x00,
+ (byte) 0x98, (byte) 0xa6, (byte) 0xca, (byte) 0xc1, (byte) 0xdf, (byte) 0x72,
+ (byte) 0x6c, (byte) 0xfe, (byte) 0x29, (byte) 0xbe, (byte) 0xa3, (byte) 0x9b,
+ (byte) 0x0b, (byte) 0x5c, (byte) 0x0b, (byte) 0x9d, (byte) 0xa7, (byte) 0x71,
+ (byte) 0xce, (byte) 0x04, (byte) 0xfa, (byte) 0xac, (byte) 0x01, (byte) 0x8d,
+ (byte) 0x52, (byte) 0xa0, (byte) 0x3d, (byte) 0xdd, (byte) 0x02, (byte) 0x81,
+ (byte) 0xc1, (byte) 0x00, (byte) 0xc1, (byte) 0xc0, (byte) 0x2e, (byte) 0xa9,
+ (byte) 0xee, (byte) 0xca, (byte) 0xff, (byte) 0xe4, (byte) 0xf8, (byte) 0x15,
+ (byte) 0xfd, (byte) 0xa5, (byte) 0x68, (byte) 0x1b, (byte) 0x2d, (byte) 0x4a,
+ (byte) 0xe6, (byte) 0x37, (byte) 0x06, (byte) 0xb3, (byte) 0xd7, (byte) 0x64,
+ (byte) 0xad, (byte) 0xb9, (byte) 0x05, (byte) 0x26, (byte) 0x97, (byte) 0x94,
+ (byte) 0x3a, (byte) 0x9e, (byte) 0x1c, (byte) 0xd0, (byte) 0xcd, (byte) 0x7b,
+ (byte) 0xf4, (byte) 0x88, (byte) 0xe2, (byte) 0xa5, (byte) 0x6d, (byte) 0xed,
+ (byte) 0x24, (byte) 0x77, (byte) 0x52, (byte) 0x39, (byte) 0x43, (byte) 0x0f,
+ (byte) 0x4e, (byte) 0x75, (byte) 0xd8, (byte) 0xa3, (byte) 0x59, (byte) 0x5a,
+ (byte) 0xc2, (byte) 0xba, (byte) 0x9a, (byte) 0x5b, (byte) 0x60, (byte) 0x31,
+ (byte) 0x0d, (byte) 0x58, (byte) 0x89, (byte) 0x13, (byte) 0xe8, (byte) 0x95,
+ (byte) 0xdd, (byte) 0xae, (byte) 0xcc, (byte) 0x1f, (byte) 0x73, (byte) 0x48,
+ (byte) 0x55, (byte) 0xd8, (byte) 0xfb, (byte) 0x67, (byte) 0xce, (byte) 0x18,
+ (byte) 0x85, (byte) 0x59, (byte) 0xad, (byte) 0x1f, (byte) 0x93, (byte) 0xe1,
+ (byte) 0xb7, (byte) 0x54, (byte) 0x80, (byte) 0x8e, (byte) 0x5f, (byte) 0xbc,
+ (byte) 0x1c, (byte) 0x96, (byte) 0x66, (byte) 0x2e, (byte) 0x40, (byte) 0x17,
+ (byte) 0x2e, (byte) 0x01, (byte) 0x7a, (byte) 0x7d, (byte) 0xaa, (byte) 0xff,
+ (byte) 0xa3, (byte) 0xd2, (byte) 0xdf, (byte) 0xe2, (byte) 0xf3, (byte) 0x54,
+ (byte) 0x51, (byte) 0xeb, (byte) 0xba, (byte) 0x7c, (byte) 0x2a, (byte) 0x22,
+ (byte) 0xc6, (byte) 0x42, (byte) 0xbc, (byte) 0xa1, (byte) 0x6c, (byte) 0xcf,
+ (byte) 0x73, (byte) 0x2e, (byte) 0x07, (byte) 0xfc, (byte) 0xf5, (byte) 0x67,
+ (byte) 0x25, (byte) 0xd0, (byte) 0xfa, (byte) 0xeb, (byte) 0xb4, (byte) 0xd4,
+ (byte) 0x19, (byte) 0xcc, (byte) 0x64, (byte) 0xa1, (byte) 0x2e, (byte) 0x78,
+ (byte) 0x45, (byte) 0xd9, (byte) 0x7f, (byte) 0x1b, (byte) 0x4c, (byte) 0x10,
+ (byte) 0x31, (byte) 0x44, (byte) 0xe8, (byte) 0xcc, (byte) 0xf9, (byte) 0x1b,
+ (byte) 0x87, (byte) 0x31, (byte) 0xd6, (byte) 0x69, (byte) 0x85, (byte) 0x4a,
+ (byte) 0x49, (byte) 0xf6, (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x98,
+ (byte) 0x3c, (byte) 0xf6, (byte) 0x78, (byte) 0x46, (byte) 0xc8, (byte) 0x3d,
+ (byte) 0x60, (byte) 0xc1, (byte) 0xaa, (byte) 0x2f, (byte) 0x28, (byte) 0xa1,
+ (byte) 0x14, (byte) 0x6b, (byte) 0x75, (byte) 0x4d, (byte) 0xb1, (byte) 0x3d,
+ (byte) 0x80, (byte) 0x49, (byte) 0x33, (byte) 0xfd, (byte) 0x71, (byte) 0xc0,
+ (byte) 0x13, (byte) 0x1e, (byte) 0x16, (byte) 0x69, (byte) 0x80, (byte) 0xa4,
+ (byte) 0x9c, (byte) 0xd7, (byte) 0x02, (byte) 0x81, (byte) 0xc1, (byte) 0x00,
+ (byte) 0x8c, (byte) 0x33, (byte) 0x2d, (byte) 0xd9, (byte) 0xf3, (byte) 0x42,
+ (byte) 0x4d, (byte) 0xca, (byte) 0x5e, (byte) 0x60, (byte) 0x14, (byte) 0x10,
+ (byte) 0xf6, (byte) 0xf3, (byte) 0x71, (byte) 0x15, (byte) 0x88, (byte) 0x54,
+ (byte) 0x84, (byte) 0x21, (byte) 0x04, (byte) 0xb1, (byte) 0xaf, (byte) 0x02,
+ (byte) 0x11, (byte) 0x7f, (byte) 0x42, (byte) 0x3e, (byte) 0x86, (byte) 0xcb,
+ (byte) 0x6c, (byte) 0xf5, (byte) 0x57, (byte) 0x78, (byte) 0x4a, (byte) 0x03,
+ (byte) 0x9b, (byte) 0x80, (byte) 0xc2, (byte) 0x04, (byte) 0x3a, (byte) 0x6b,
+ (byte) 0xb3, (byte) 0x30, (byte) 0x31, (byte) 0x7e, (byte) 0xc3, (byte) 0x89,
+ (byte) 0x09, (byte) 0x4e, (byte) 0x86, (byte) 0x59, (byte) 0x41, (byte) 0xb5,
+ (byte) 0xae, (byte) 0xd5, (byte) 0xc6, (byte) 0x38, (byte) 0xbc, (byte) 0xd7,
+ (byte) 0xd7, (byte) 0x8e, (byte) 0xa3, (byte) 0x1a, (byte) 0xde, (byte) 0x32,
+ (byte) 0xad, (byte) 0x8d, (byte) 0x15, (byte) 0x81, (byte) 0xfe, (byte) 0xac,
+ (byte) 0xbd, (byte) 0xd0, (byte) 0xca, (byte) 0xbc, (byte) 0xd8, (byte) 0x6a,
+ (byte) 0xe1, (byte) 0xfe, (byte) 0xda, (byte) 0xc4, (byte) 0xd8, (byte) 0x62,
+ (byte) 0x71, (byte) 0x20, (byte) 0xa3, (byte) 0xd3, (byte) 0x06, (byte) 0x11,
+ (byte) 0xa9, (byte) 0x53, (byte) 0x7a, (byte) 0x44, (byte) 0x89, (byte) 0x3d,
+ (byte) 0x28, (byte) 0x5e, (byte) 0x7d, (byte) 0xf0, (byte) 0x60, (byte) 0xeb,
+ (byte) 0xb5, (byte) 0xdf, (byte) 0xed, (byte) 0x4f, (byte) 0x6d, (byte) 0x05,
+ (byte) 0x59, (byte) 0x06, (byte) 0xb0, (byte) 0x62, (byte) 0x50, (byte) 0x1c,
+ (byte) 0xb7, (byte) 0x2c, (byte) 0x44, (byte) 0xa4, (byte) 0x49, (byte) 0xf8,
+ (byte) 0x4f, (byte) 0x4b, (byte) 0xab, (byte) 0x71, (byte) 0x5b, (byte) 0xcb,
+ (byte) 0x31, (byte) 0x10, (byte) 0x41, (byte) 0xe0, (byte) 0x1a, (byte) 0x15,
+ (byte) 0xdc, (byte) 0x4c, (byte) 0x5d, (byte) 0x4f, (byte) 0x62, (byte) 0x83,
+ (byte) 0xa4, (byte) 0x80, (byte) 0x06, (byte) 0x36, (byte) 0xba, (byte) 0xc9,
+ (byte) 0xe2, (byte) 0xa4, (byte) 0x11, (byte) 0x98, (byte) 0x6b, (byte) 0x4c,
+ (byte) 0xe9, (byte) 0x90, (byte) 0x55, (byte) 0x18, (byte) 0xde, (byte) 0xe1,
+ (byte) 0x42, (byte) 0x38, (byte) 0x28, (byte) 0xa3, (byte) 0x54, (byte) 0x56,
+ (byte) 0x31, (byte) 0xaf, (byte) 0x5a, (byte) 0xd6, (byte) 0xf0, (byte) 0x26,
+ (byte) 0xe0, (byte) 0x7a, (byte) 0xd9, (byte) 0x6c, (byte) 0x64, (byte) 0xca,
+ (byte) 0x5d, (byte) 0x6d, (byte) 0x3d, (byte) 0x9a, (byte) 0xfe, (byte) 0x36,
+ (byte) 0x93, (byte) 0x9e, (byte) 0x62, (byte) 0x94, (byte) 0xc6, (byte) 0x07,
+ (byte) 0x83, (byte) 0x96, (byte) 0xd6, (byte) 0x27, (byte) 0xa6, (byte) 0xd8
+ };
+ public static final PrivateKey CLIENT_SUITE_B_RSA3072_KEY =
+ loadPrivateKey("RSA", CLIENT_SUITE_B_RSA3072_KEY_DATA);
+
+ private static final String CLIENT_SUITE_B_ECDSA_CERT_STRING =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIB9zCCAX4CFDpfSZh3AH07BEfGWuMDa7Ynz6y+MAoGCCqGSM49BAMDMF4xCzAJ\n"
+ + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQKDAdB\n"
+ + "bmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4XDTIw\n"
+ + "MDcyMTAyMjk1MFoXDTMwMDUzMDAyMjk1MFowYjELMAkGA1UEBhMCVVMxCzAJBgNV\n"
+ + "BAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsM\n"
+ + "BVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE\n"
+ + "ACIDYgAEhxhVJ7dcSqrto0X+dgRxtd8BWG8cWmPjBji3MIxDLfpcMDoIB84ae1Ew\n"
+ + "gJn4YUYHrWsUDiVNihv8j7a/Ol1qcIY2ybH7tbezefLmagqA4vXEUXZXoUyL4ZNC\n"
+ + "DWcdw6LrMAoGCCqGSM49BAMDA2cAMGQCMH4aP73HrriRUJRguiuRic+X4Cqj/7YQ\n"
+ + "ueJmP87KF92/thhoQ9OrRo8uJITPmNDswwIwP2Q1AZCSL4BI9dYrqu07Ar+pSkXE\n"
+ + "R7oOqGdZR+d/MvXcFSrbIaLKEoHXmQamIHLe\n"
+ + "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CLIENT_SUITE_B_ECDSA_CERT =
+ loadCertificate(CLIENT_SUITE_B_ECDSA_CERT_STRING);
+
+ private static final byte[] CLIENT_SUITE_B_ECC_KEY_DATA = new byte[]{
+ (byte) 0x30, (byte) 0x81, (byte) 0xb6, (byte) 0x02, (byte) 0x01, (byte) 0x00,
+ (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
+ (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22,
+ (byte) 0x04, (byte) 0x81, (byte) 0x9e, (byte) 0x30, (byte) 0x81, (byte) 0x9b,
+ (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0xea,
+ (byte) 0x6c, (byte) 0x4b, (byte) 0x6d, (byte) 0x43, (byte) 0xf9, (byte) 0x6c,
+ (byte) 0x91, (byte) 0xdc, (byte) 0x2d, (byte) 0x6e, (byte) 0x87, (byte) 0x4f,
+ (byte) 0x0a, (byte) 0x0b, (byte) 0x97, (byte) 0x25, (byte) 0x1c, (byte) 0x79,
+ (byte) 0xa2, (byte) 0x07, (byte) 0xdc, (byte) 0x94, (byte) 0xc2, (byte) 0xee,
+ (byte) 0x64, (byte) 0x51, (byte) 0x6d, (byte) 0x4e, (byte) 0x35, (byte) 0x1c,
+ (byte) 0x22, (byte) 0x2f, (byte) 0xc0, (byte) 0xea, (byte) 0x09, (byte) 0x47,
+ (byte) 0x3e, (byte) 0xb9, (byte) 0xb6, (byte) 0xb8, (byte) 0x83, (byte) 0x9e,
+ (byte) 0xed, (byte) 0x59, (byte) 0xe5, (byte) 0xe7, (byte) 0x0f, (byte) 0xa1,
+ (byte) 0x64, (byte) 0x03, (byte) 0x62, (byte) 0x00, (byte) 0x04, (byte) 0x87,
+ (byte) 0x18, (byte) 0x55, (byte) 0x27, (byte) 0xb7, (byte) 0x5c, (byte) 0x4a,
+ (byte) 0xaa, (byte) 0xed, (byte) 0xa3, (byte) 0x45, (byte) 0xfe, (byte) 0x76,
+ (byte) 0x04, (byte) 0x71, (byte) 0xb5, (byte) 0xdf, (byte) 0x01, (byte) 0x58,
+ (byte) 0x6f, (byte) 0x1c, (byte) 0x5a, (byte) 0x63, (byte) 0xe3, (byte) 0x06,
+ (byte) 0x38, (byte) 0xb7, (byte) 0x30, (byte) 0x8c, (byte) 0x43, (byte) 0x2d,
+ (byte) 0xfa, (byte) 0x5c, (byte) 0x30, (byte) 0x3a, (byte) 0x08, (byte) 0x07,
+ (byte) 0xce, (byte) 0x1a, (byte) 0x7b, (byte) 0x51, (byte) 0x30, (byte) 0x80,
+ (byte) 0x99, (byte) 0xf8, (byte) 0x61, (byte) 0x46, (byte) 0x07, (byte) 0xad,
+ (byte) 0x6b, (byte) 0x14, (byte) 0x0e, (byte) 0x25, (byte) 0x4d, (byte) 0x8a,
+ (byte) 0x1b, (byte) 0xfc, (byte) 0x8f, (byte) 0xb6, (byte) 0xbf, (byte) 0x3a,
+ (byte) 0x5d, (byte) 0x6a, (byte) 0x70, (byte) 0x86, (byte) 0x36, (byte) 0xc9,
+ (byte) 0xb1, (byte) 0xfb, (byte) 0xb5, (byte) 0xb7, (byte) 0xb3, (byte) 0x79,
+ (byte) 0xf2, (byte) 0xe6, (byte) 0x6a, (byte) 0x0a, (byte) 0x80, (byte) 0xe2,
+ (byte) 0xf5, (byte) 0xc4, (byte) 0x51, (byte) 0x76, (byte) 0x57, (byte) 0xa1,
+ (byte) 0x4c, (byte) 0x8b, (byte) 0xe1, (byte) 0x93, (byte) 0x42, (byte) 0x0d,
+ (byte) 0x67, (byte) 0x1d, (byte) 0xc3, (byte) 0xa2, (byte) 0xeb
+ };
+ public static final PrivateKey CLIENT_SUITE_B_ECC_KEY =
+ loadPrivateKey("EC", CLIENT_SUITE_B_ECC_KEY_DATA);
+
private static X509Certificate loadCertificate(String blob) {
try {
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
@@ -255,9 +662,9 @@
}
}
- private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) {
+ private static PrivateKey loadPrivateKey(String algorithm, byte[] fakeKey) {
try {
- KeyFactory kf = KeyFactory.getInstance("RSA");
+ KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
return null;
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index a7b6765..62220a6 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -22,6 +22,7 @@
import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OWE;
import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK;
import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_SAE;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_WAPI_CERT;
import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_WAPI_PSK;
import static org.junit.Assert.assertArrayEquals;
@@ -537,4 +538,52 @@
configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
assertFalse(configuration.needsPreSharedKey());
}
+
+ @Test
+ public void testGetAuthType() throws Exception {
+ WifiConfiguration configuration = new WifiConfiguration();
+
+ configuration.setSecurityParams(SECURITY_TYPE_PSK);
+ assertEquals(KeyMgmt.WPA_PSK, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_SAE);
+ assertEquals(KeyMgmt.SAE, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_WAPI_PSK);
+ assertEquals(KeyMgmt.WAPI_PSK, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_OPEN);
+ assertEquals(KeyMgmt.NONE, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_OWE);
+ assertEquals(KeyMgmt.OWE, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_EAP);
+ assertEquals(KeyMgmt.WPA_EAP, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B);
+ assertEquals(KeyMgmt.SUITE_B_192, configuration.getAuthType());
+
+ configuration.setSecurityParams(SECURITY_TYPE_WAPI_CERT);
+ assertEquals(KeyMgmt.WAPI_CERT, configuration.getAuthType());
+ }
+
+ @Test (expected = IllegalStateException.class)
+ public void testGetAuthTypeFailure1() throws Exception {
+ WifiConfiguration configuration = new WifiConfiguration();
+
+ configuration.setSecurityParams(SECURITY_TYPE_PSK);
+ configuration.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
+ configuration.getAuthType();
+ }
+
+ @Test (expected = IllegalStateException.class)
+ public void testGetAuthTypeFailure2() throws Exception {
+ WifiConfiguration configuration = new WifiConfiguration();
+
+ configuration.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
+ configuration.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
+ configuration.allowedKeyManagement.set(KeyMgmt.SAE);
+ configuration.getAuthType();
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
index fc0ef46..6f47f3d 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
@@ -22,6 +22,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
@@ -35,6 +37,8 @@
import org.junit.Test;
+import java.security.cert.X509Certificate;
+
/**
* Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}.
*/
@@ -45,6 +49,7 @@
private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
private static final String TEST_BSSID = "12:12:12:12:12:12";
private static final String TEST_PRESHARED_KEY = "\"Test123\"";
+ private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
/**
* Validate correctness of WifiNetworkSpecifier object created by
@@ -135,6 +140,106 @@
wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
}
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+
+ NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.IEEE8021X));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_EAP));
+ assertFalse(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
+ assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
+ assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT);
+ enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY,
+ new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT});
+
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+
+ NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.GCMP_256));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers
+ .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
+ assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
+ assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT);
+ enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY,
+ new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT});
+
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+
+ NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.GCMP_256));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers
+ .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf);
+ assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
+ assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig);
+ }
/**
* Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index 7d5a452..668d238 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -32,6 +32,8 @@
import org.junit.Test;
+import java.security.cert.X509Certificate;
+
/**
* Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}.
*/
@@ -212,16 +214,14 @@
assertNull(suggestion.getEnterpriseConfig());
}
-
/**
* Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkSuggestion.Builder#build()} for SuiteB network.
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network.
*/
@Test
public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0);
enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
@@ -232,6 +232,78 @@
assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.IEEE8021X));
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_EAP));
+ assertFalse(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
+ assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(suggestion.wifiConfiguration.requirePmf);
+ assertNull(suggestion.wifiConfiguration.preSharedKey);
+ // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
+ // here.
+ assertTrue(suggestion.isUserAllowedToManuallyConnect);
+ assertTrue(suggestion.isInitialAutoJoinEnabled);
+ assertNotNull(suggestion.getEnterpriseConfig());
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT);
+ enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY,
+ new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT});
+
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
+ assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.GCMP_256));
+ assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
+ .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
+ assertTrue(suggestion.wifiConfiguration.requirePmf);
+ assertNull(suggestion.wifiConfiguration.preSharedKey);
+ // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
+ // here.
+ assertTrue(suggestion.isUserAllowedToManuallyConnect);
+ assertTrue(suggestion.isInitialAutoJoinEnabled);
+ assertNotNull(suggestion.getEnterpriseConfig());
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT);
+ enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY,
+ new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT});
+
+ enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
+
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.SUITE_B_192));
assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.GCMP_256));
@@ -610,15 +682,15 @@
}
/**
- * Verify that the macRandomizationSetting defaults to RANDOMIZATION_ENHANCED and could be set
- * to RANDOMIZATION_PERSISTENT.
+ * Verify that the macRandomizationSetting defaults to RANDOMIZATION_PERSISTENT and could be set
+ * to RANDOMIZATION_ENHANCED.
*/
@Test
public void testWifiNetworkSuggestionBuilderSetMacRandomization() {
WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
.setSsid(TEST_SSID)
.build();
- assertEquals(WifiConfiguration.RANDOMIZATION_ENHANCED,
+ assertEquals(WifiConfiguration.RANDOMIZATION_PERSISTENT,
suggestion.wifiConfiguration.macRandomizationSetting);
suggestion = new WifiNetworkSuggestion.Builder()
@@ -637,6 +709,31 @@
}
/**
+ * Verify that the builder creates the appropriate PasspointConfiguration according to the
+ * enhanced MAC randomization setting.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderSetMacRandomizationPasspoint() {
+ PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setPasspointConfig(passpointConfiguration)
+ .build();
+ assertEquals(false, suggestion.passpointConfiguration.isEnhancedMacRandomizationEnabled());
+
+ suggestion = new WifiNetworkSuggestion.Builder()
+ .setPasspointConfig(passpointConfiguration)
+ .setIsEnhancedMacRandomizationEnabled(false)
+ .build();
+ assertEquals(false, suggestion.passpointConfiguration.isEnhancedMacRandomizationEnabled());
+
+ suggestion = new WifiNetworkSuggestion.Builder()
+ .setPasspointConfig(passpointConfiguration)
+ .setIsEnhancedMacRandomizationEnabled(true)
+ .build();
+ assertEquals(true, suggestion.passpointConfiguration.isEnhancedMacRandomizationEnabled());
+ }
+
+ /**
* Check that parcel marshalling/unmarshalling works
*/
@Test
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 43d728b..5fe0cb4 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -146,6 +146,15 @@
verify(mockAwareService).getCharacteristics();
}
+ /**
+ * Validate pass-through of isDeviceAttached() API.
+ */
+ @Test
+ public void testIsAttached() throws Exception {
+ mDut.isDeviceAttached();
+ verify(mockAwareService).isDeviceAttached();
+ }
+
/*
* WifiAwareEventCallbackProxy Tests
*/
@@ -360,12 +369,18 @@
eq(publishConfig));
inOrder.verify(mockSessionCallback).onSessionConfigFailed();
- // (5) terminate
+ // (5) discovery session is no longer visible
+ sessionProxyCallback.getValue().onMatchExpired(peerHandle.peerId);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback).onServiceLost(peerIdCaptor.capture());
+ assertEquals(peerHandle.peerId, peerIdCaptor.getValue().peerId);
+
+ // (6) terminate
publishSession.getValue().close();
mMockLooper.dispatchAll();
inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
- // (6) try an update (nothing)
+ // (7) try an update (nothing)
publishSession.getValue().updatePublish(publishConfig);
mMockLooper.dispatchAll();
@@ -502,12 +517,18 @@
eq(subscribeConfig));
inOrder.verify(mockSessionCallback).onSessionConfigFailed();
- // (5) terminate
+ // (5) discovery session is no longer visible
+ sessionProxyCallback.getValue().onMatchExpired(peerHandle.peerId);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback).onServiceLost(peerIdCaptor.capture());
+ assertEquals(peerHandle.peerId, peerIdCaptor.getValue().peerId);
+
+ // (6) terminate
subscribeSession.getValue().close();
mMockLooper.dispatchAll();
inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
- // (6) try an update (nothing)
+ // (7) try an update (nothing)
subscribeSession.getValue().updateSubscribe(subscribeConfig);
mMockLooper.dispatchAll();
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 8270d64..badcf52 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -186,6 +186,7 @@
assertFalse(config.validateForR2());
assertTrue(config.isAutojoinEnabled());
assertTrue(config.isMacRandomizationEnabled());
+ assertFalse(config.isEnhancedMacRandomizationEnabled());
assertTrue(config.getMeteredOverride() == METERED_OVERRIDE_NONE);
}