summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PACKAGE_MANAGER_OWNERS3
-rw-r--r--apex/media/framework/java/android/media/BaseMediaParceledListSlice.java2
-rw-r--r--core/api/current.txt18
-rwxr-xr-xcore/api/system-current.txt2
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/app/SystemServiceRegistry.java33
-rw-r--r--core/java/android/app/WallpaperManager.java2
-rw-r--r--core/java/android/bluetooth/BluetoothActivityEnergyInfo.java5
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java5
-rw-r--r--core/java/android/bluetooth/BluetoothManager.java13
-rw-r--r--core/java/android/content/Intent.java11
-rw-r--r--core/java/android/content/OWNERS6
-rw-r--r--core/java/android/content/pm/TEST_MAPPING9
-rw-r--r--core/java/android/hardware/biometrics/BiometricOverlayConstants.java5
-rw-r--r--core/java/android/net/NetworkIdentity.java6
-rw-r--r--core/java/android/view/KeyEvent.java38
-rw-r--r--core/java/android/view/ViewRootImpl.java23
-rw-r--r--core/java/android/view/WindowLayout.java145
-rw-r--r--core/proto/android/server/windowmanagerservice.proto2
-rw-r--r--core/res/res/values/attrs.xml16
-rw-r--r--core/res/res/xml/sms_short_codes.xml5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java23
-rw-r--r--media/java/android/media/MediaCodecInfo.java26
-rw-r--r--media/java/android/media/MediaFormat.java2
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java9
-rw-r--r--packages/PackageInstaller/OWNERS4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS1
-rw-r--r--packages/SettingsProvider/OWNERS4
-rw-r--r--packages/SystemUI/proguard.flags17
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt43
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt64
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt72
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java79
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java51
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java139
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java70
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java2
-rw-r--r--services/core/java/android/content/pm/OWNERS2
-rw-r--r--services/core/java/com/android/server/BatteryService.java41
-rw-r--r--services/core/java/com/android/server/SystemService.java19
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerState.java2
-rwxr-xr-xservices/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java6
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java13
-rw-r--r--services/core/java/com/android/server/media/AudioPlayerStateMonitor.java2
-rw-r--r--services/core/java/com/android/server/pm/OWNERS4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/TEST_MAPPING3
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java38
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java2
-rw-r--r--services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java33
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java53
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java67
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowFrames.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java306
-rw-r--r--services/tests/PackageManager/TEST_MAPPING8
-rw-r--r--services/tests/PackageManagerComponentOverrideTests/TEST_MAPPING8
-rw-r--r--services/tests/PackageManagerServiceTests/OWNERS4
-rw-r--r--services/tests/PackageManagerServiceTests/TEST_MAPPING18
-rw-r--r--services/tests/servicestests/src/com/android/server/BatteryServiceTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java39
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java37
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationScaleProviderTest.java100
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java325
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java158
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java2
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java8
91 files changed, 1369 insertions, 1131 deletions
diff --git a/PACKAGE_MANAGER_OWNERS b/PACKAGE_MANAGER_OWNERS
new file mode 100644
index 000000000000..e4549b4de164
--- /dev/null
+++ b/PACKAGE_MANAGER_OWNERS
@@ -0,0 +1,3 @@
+chiuwinson@google.com
+patb@google.com
+schfan@google.com \ No newline at end of file
diff --git a/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java b/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java
index fb666098301a..915f3f6a3fb0 100644
--- a/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java
+++ b/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java
@@ -43,7 +43,7 @@ import java.util.List;
*/
abstract class BaseMediaParceledListSlice<T> implements Parcelable {
private static String TAG = "BaseMediaParceledListSlice";
- private static boolean DEBUG = false;
+ private static final boolean DEBUG = false;
/*
* TODO get this number from somewhere else. For now set it to a quarter of
diff --git a/core/api/current.txt b/core/api/current.txt
index f989d0621843..52e0daff0ec4 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -22672,7 +22672,7 @@ package android.media {
field public static final String KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
field public static final String KEY_MAX_HEIGHT = "max-height";
field public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
- field public static final String KEY_MAX_OUTPUT_CHANNEL_COUNT = "max-output-channel_count";
+ field public static final String KEY_MAX_OUTPUT_CHANNEL_COUNT = "max-output-channel-count";
field public static final String KEY_MAX_PTS_GAP_TO_ENCODER = "max-pts-gap-to-encoder";
field public static final String KEY_MAX_WIDTH = "max-width";
field public static final String KEY_MIME = "mime";
@@ -47696,6 +47696,10 @@ package android.view {
field public static final int KEYCODE_CUT = 277; // 0x115
field public static final int KEYCODE_D = 32; // 0x20
field public static final int KEYCODE_DEL = 67; // 0x43
+ field public static final int KEYCODE_DEMO_APP_1 = 301; // 0x12d
+ field public static final int KEYCODE_DEMO_APP_2 = 302; // 0x12e
+ field public static final int KEYCODE_DEMO_APP_3 = 303; // 0x12f
+ field public static final int KEYCODE_DEMO_APP_4 = 304; // 0x130
field public static final int KEYCODE_DPAD_CENTER = 23; // 0x17
field public static final int KEYCODE_DPAD_DOWN = 20; // 0x14
field public static final int KEYCODE_DPAD_DOWN_LEFT = 269; // 0x10d
@@ -47727,6 +47731,10 @@ package android.view {
field public static final int KEYCODE_F7 = 137; // 0x89
field public static final int KEYCODE_F8 = 138; // 0x8a
field public static final int KEYCODE_F9 = 139; // 0x8b
+ field public static final int KEYCODE_FEATURED_APP_1 = 297; // 0x129
+ field public static final int KEYCODE_FEATURED_APP_2 = 298; // 0x12a
+ field public static final int KEYCODE_FEATURED_APP_3 = 299; // 0x12b
+ field public static final int KEYCODE_FEATURED_APP_4 = 300; // 0x12c
field public static final int KEYCODE_FOCUS = 80; // 0x50
field public static final int KEYCODE_FORWARD = 125; // 0x7d
field public static final int KEYCODE_FORWARD_DEL = 112; // 0x70
@@ -47892,6 +47900,14 @@ package android.view {
field public static final int KEYCODE_U = 49; // 0x31
field public static final int KEYCODE_UNKNOWN = 0; // 0x0
field public static final int KEYCODE_V = 50; // 0x32
+ field public static final int KEYCODE_VIDEO_APP_1 = 289; // 0x121
+ field public static final int KEYCODE_VIDEO_APP_2 = 290; // 0x122
+ field public static final int KEYCODE_VIDEO_APP_3 = 291; // 0x123
+ field public static final int KEYCODE_VIDEO_APP_4 = 292; // 0x124
+ field public static final int KEYCODE_VIDEO_APP_5 = 293; // 0x125
+ field public static final int KEYCODE_VIDEO_APP_6 = 294; // 0x126
+ field public static final int KEYCODE_VIDEO_APP_7 = 295; // 0x127
+ field public static final int KEYCODE_VIDEO_APP_8 = 296; // 0x128
field public static final int KEYCODE_VOICE_ASSIST = 231; // 0xe7
field public static final int KEYCODE_VOLUME_DOWN = 25; // 0x19
field public static final int KEYCODE_VOLUME_MUTE = 164; // 0xa4
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f92c36d488ad..a0f2d2393443 100755
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1954,7 +1954,7 @@ package android.bluetooth {
method public long getControllerIdleTimeMillis();
method public long getControllerRxTimeMillis();
method public long getControllerTxTimeMillis();
- method public long getTimeStamp();
+ method public long getTimestampMillis();
method @NonNull public java.util.List<android.bluetooth.UidTraffic> getUidTraffic();
method public boolean isValid();
field public static final int BT_STACK_STATE_INVALID = 0; // 0x0
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index e707b038e1b6..71ed8348d397 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2785,7 +2785,7 @@ package android.view {
method public static String actionToString(int);
method public final void setDisplayId(int);
field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
- field public static final int LAST_KEYCODE = 288; // 0x120
+ field public static final int LAST_KEYCODE = 304; // 0x130
}
public final class KeyboardShortcutGroup implements android.os.Parcelable {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 8ea1f8315b89..40c19788ae5d 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1925,39 +1925,6 @@ public final class SystemServiceRegistry {
public abstract T createService() throws ServiceNotFoundException;
}
- /**
- * Like StaticServiceFetcher, creates only one instance of the service per application, but when
- * creating the service for the first time, passes it the application context of the creating
- * application.
- *
- * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the
- * case where multiple application components each have their own ConnectivityManager object.
- */
- static abstract class StaticApplicationContextServiceFetcher<T> implements ServiceFetcher<T> {
- private T mCachedInstance;
-
- @Override
- public final T getService(ContextImpl ctx) {
- synchronized (StaticApplicationContextServiceFetcher.this) {
- if (mCachedInstance == null) {
- Context appContext = ctx.getApplicationContext();
- // If the application context is null, we're either in the system process or
- // it's the application context very early in app initialization. In both these
- // cases, the passed-in ContextImpl will not be freed, so it's safe to pass it
- // to the service. http://b/27532714 .
- try {
- mCachedInstance = createService(appContext != null ? appContext : ctx);
- } catch (ServiceNotFoundException e) {
- onServiceNotFound(e);
- }
- }
- return mCachedInstance;
- }
- }
-
- public abstract T createService(Context applicationContext) throws ServiceNotFoundException;
- }
-
/** @hide */
public static void onServiceNotFound(ServiceNotFoundException e) {
// We're mostly interested in tracking down long-lived core system
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a53ef1badca7..b3fad21f2e44 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -108,7 +108,7 @@ import java.util.concurrent.TimeUnit;
@SystemService(Context.WALLPAPER_SERVICE)
public class WallpaperManager {
private static String TAG = "WallpaperManager";
- private static boolean DEBUG = false;
+ private static final boolean DEBUG = false;
private float mWallpaperXStep = -1;
private float mWallpaperYStep = -1;
private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
index f371c6d78221..c17a7b4b3dfd 100644
--- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.ElapsedRealtimeLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
@@ -167,7 +168,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
/**
* @return timestamp (real time elapsed in milliseconds since boot) of record creation
*/
- public long getTimeStamp() {
+ public @ElapsedRealtimeLong long getTimestampMillis() {
return mTimestamp;
}
@@ -189,7 +190,7 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
}
/**
- * @return true if the record is valid
+ * @return true if the record Tx time, Rx time, and Idle time are more than 0.
*/
public boolean isValid() {
return ((mControllerTxTimeMs >= 0) && (mControllerRxTimeMs >= 0)
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index e968052ff5cf..6e918bd6243d 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1186,6 +1186,11 @@ public final class BluetoothDevice implements Parcelable, Attributable {
mAttributionSource = attributionSource;
}
+ /** {@hide} */
+ public void prepareToEnterProcess(@NonNull AttributionSource attributionSource) {
+ setAttributionSource(attributionSource);
+ }
+
@Override
public boolean equals(@Nullable Object o) {
if (o instanceof BluetoothDevice) {
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index b5df4db2460d..20152f3d2471 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -62,15 +62,15 @@ public final class BluetoothManager {
private static final String TAG = "BluetoothManager";
private static final boolean DBG = false;
- private static AttributionSource sAttributionSource = null;
+ private final AttributionSource mAttributionSource;
private final BluetoothAdapter mAdapter;
/**
* @hide
*/
public BluetoothManager(Context context) {
- sAttributionSource = resolveAttributionSource(context);
- mAdapter = BluetoothAdapter.createAdapter(sAttributionSource);
+ mAttributionSource = resolveAttributionSource(context);
+ mAdapter = BluetoothAdapter.createAdapter(mAttributionSource);
}
/** {@hide} */
@@ -79,9 +79,6 @@ public final class BluetoothManager {
if (context != null) {
res = context.getAttributionSource();
}
- else if (sAttributionSource != null) {
- return sAttributionSource;
- }
if (res == null) {
res = ActivityThread.currentAttributionSource();
}
@@ -201,8 +198,8 @@ public final class BluetoothManager {
IBluetoothGatt iGatt = managerService.getBluetoothGatt();
if (iGatt == null) return devices;
devices = Attributable.setAttributionSource(
- iGatt.getDevicesMatchingConnectionStates(states, sAttributionSource),
- sAttributionSource);
+ iGatt.getDevicesMatchingConnectionStates(states, mAttributionSource),
+ mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6446b44153ec..e838d93c6cdc 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -32,6 +32,7 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.app.AppGlobals;
+import android.bluetooth.BluetoothDevice;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -11688,6 +11689,16 @@ public class Intent implements Parcelable, Cloneable {
if (fromProtectedComponent) {
mLocalFlags |= LOCAL_FLAG_FROM_PROTECTED_COMPONENT;
}
+
+ // Special attribution fix-up logic for any BluetoothDevice extras
+ // passed via Bluetooth intents
+ if (mAction != null && mAction.startsWith("android.bluetooth.")
+ && hasExtra(BluetoothDevice.EXTRA_DEVICE)) {
+ final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ if (device != null) {
+ device.prepareToEnterProcess(source);
+ }
+ }
}
/** @hide */
diff --git a/core/java/android/content/OWNERS b/core/java/android/content/OWNERS
index c7f92c9714f0..660368aeca14 100644
--- a/core/java/android/content/OWNERS
+++ b/core/java/android/content/OWNERS
@@ -2,11 +2,9 @@
per-file Context.java = *
per-file ContextWrapper.java = *
per-file Content* = file:/services/core/java/com/android/server/am/OWNERS
-per-file IntentFilter.java = toddke@google.com
-per-file IntentFilter.java = patb@google.com
+per-file IntentFilter.java = file:/PACKAGE_MANAGER_OWNERS
per-file IntentFilter.java = file:/services/core/java/com/android/server/am/OWNERS
-per-file Intent.java = toddke@google.com
-per-file Intent.java = patb@google.com
+per-file Intent.java = file:/PACKAGE_MANAGER_OWNERS
per-file Intent.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file Intent.java = file:/services/core/java/com/android/server/am/OWNERS
per-file AutofillOptions* = file:/core/java/android/service/autofill/OWNERS
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 0d8fdcc4138f..cc4782ad4a79 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -1,6 +1,15 @@
{
"imports": [
{
+ "path": "frameworks/base/services/tests/PackageManagerServiceTests"
+ },
+ {
+ "path": "frameworks/base/services/tests/PackageManager"
+ },
+ {
+ "path": "frameworks/base/services/tests/PackageManagerComponentOverrideTests"
+ },
+ {
"path": "cts/tests/tests/packageinstaller"
},
{
diff --git a/core/java/android/hardware/biometrics/BiometricOverlayConstants.java b/core/java/android/hardware/biometrics/BiometricOverlayConstants.java
index 603b06ddabaa..065ae64a92ad 100644
--- a/core/java/android/hardware/biometrics/BiometricOverlayConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricOverlayConstants.java
@@ -38,13 +38,16 @@ public interface BiometricOverlayConstants {
int REASON_AUTH_KEYGUARD = 4;
/** Non-specific usage (from FingerprintManager). */
int REASON_AUTH_OTHER = 5;
+ /** Usage from Settings. */
+ int REASON_AUTH_SETTINGS = 6;
@IntDef({REASON_UNKNOWN,
REASON_ENROLL_FIND_SENSOR,
REASON_ENROLL_ENROLLING,
REASON_AUTH_BP,
REASON_AUTH_KEYGUARD,
- REASON_AUTH_OTHER})
+ REASON_AUTH_OTHER,
+ REASON_AUTH_SETTINGS})
@Retention(RetentionPolicy.SOURCE)
@interface ShowReason {}
}
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 1d07a0330bc5..eb8f43e3d073 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -220,8 +220,10 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
String networkId = null;
boolean roaming = !snapshot.getNetworkCapabilities().hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
- boolean metered = !snapshot.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ boolean metered = !(snapshot.getNetworkCapabilities().hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+ || snapshot.getNetworkCapabilities().hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities());
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index d12ed8f1595e..1460cb251c72 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -832,13 +832,45 @@ public class KeyEvent extends InputEvent implements Parcelable {
* consuming content. May be consumed by system to set account globally.
*/
public static final int KEYCODE_PROFILE_SWITCH = 288;
-
- /**
+ /** Key code constant: Video Application key #1. */
+ public static final int KEYCODE_VIDEO_APP_1 = 289;
+ /** Key code constant: Video Application key #2. */
+ public static final int KEYCODE_VIDEO_APP_2 = 290;
+ /** Key code constant: Video Application key #3. */
+ public static final int KEYCODE_VIDEO_APP_3 = 291;
+ /** Key code constant: Video Application key #4. */
+ public static final int KEYCODE_VIDEO_APP_4 = 292;
+ /** Key code constant: Video Application key #5. */
+ public static final int KEYCODE_VIDEO_APP_5 = 293;
+ /** Key code constant: Video Application key #6. */
+ public static final int KEYCODE_VIDEO_APP_6 = 294;
+ /** Key code constant: Video Application key #7. */
+ public static final int KEYCODE_VIDEO_APP_7 = 295;
+ /** Key code constant: Video Application key #8. */
+ public static final int KEYCODE_VIDEO_APP_8 = 296;
+ /** Key code constant: Featured Application key #1. */
+ public static final int KEYCODE_FEATURED_APP_1 = 297;
+ /** Key code constant: Featured Application key #2. */
+ public static final int KEYCODE_FEATURED_APP_2 = 298;
+ /** Key code constant: Featured Application key #3. */
+ public static final int KEYCODE_FEATURED_APP_3 = 299;
+ /** Key code constant: Featured Application key #4. */
+ public static final int KEYCODE_FEATURED_APP_4 = 300;
+ /** Key code constant: Demo Application key #1. */
+ public static final int KEYCODE_DEMO_APP_1 = 301;
+ /** Key code constant: Demo Application key #2. */
+ public static final int KEYCODE_DEMO_APP_2 = 302;
+ /** Key code constant: Demo Application key #3. */
+ public static final int KEYCODE_DEMO_APP_3 = 303;
+ /** Key code constant: Demo Application key #4. */
+ public static final int KEYCODE_DEMO_APP_4 = 304;
+
+ /**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
*/
@TestApi
- public static final int LAST_KEYCODE = KEYCODE_PROFILE_SWITCH;
+ public static final int LAST_KEYCODE = KEYCODE_DEMO_APP_4;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6b5cc97d875f..4879206d6190 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -57,12 +57,15 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
@@ -72,6 +75,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_V
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_APPLICATION_ATTACHED_DIALOG;
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;
@@ -90,6 +94,7 @@ import android.annotation.UiContext;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ResourcesManager;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ClipData;
import android.content.ClipDescription;
@@ -515,6 +520,8 @@ public final class ViewRootImpl implements ViewParent,
private final WindowLayout mWindowLayout = new WindowLayout();
+ private ViewRootImpl mParentViewRoot;
+
// This is used to reduce the race between window focus changes being dispatched from
// the window manager and input events coming through the input system.
@GuardedBy("this")
@@ -1053,6 +1060,7 @@ public final class ViewRootImpl implements ViewParent,
if (panelParentView != null) {
mAttachInfo.mPanelParentWindowToken
= panelParentView.getApplicationWindowToken();
+ mParentViewRoot = panelParentView.getViewRootImpl();
}
mAdded = true;
int res; /* = WindowManagerImpl.ADD_OKAY; */
@@ -1113,10 +1121,13 @@ public final class ViewRootImpl implements ViewParent,
final InsetsState state = mInsetsController.getState();
final Rect displayCutoutSafe = mTempRect;
state.getDisplayCutoutSafe(displayCutoutSafe);
+ final WindowConfiguration winConfig = getConfiguration().windowConfiguration;
mWindowLayout.computeWindowFrames(mWindowAttributes, state,
- displayCutoutSafe, getConfiguration().windowConfiguration.getBounds(),
+ displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(),
+ UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH,
mInsetsController.getRequestedVisibilities(),
- null /* attachedWindowFrame */, mTmpFrames.frame, mTempRect2);
+ getAttachedWindowFrame(), 1f /* compactScale */,
+ mTmpFrames.displayFrame, mTempRect2, mTmpFrames.frame);
setFrame(mTmpFrames.frame);
if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow);
if (res < WindowManagerGlobal.ADD_OKAY) {
@@ -1227,6 +1238,14 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ private Rect getAttachedWindowFrame() {
+ final int type = mWindowAttributes.type;
+ final boolean layoutAttached = (mParentViewRoot != null
+ && type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW
+ && type != TYPE_APPLICATION_ATTACHED_DIALOG);
+ return layoutAttached ? mParentViewRoot.mWinFrame : null;
+ }
+
/**
* Register any kind of listeners if setView was success.
*/
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index cdc1977eaad6..7dfc95ef0302 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -19,29 +19,44 @@ package android.view;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
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_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
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_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
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_SYSTEM_ERROR;
+import android.app.WindowConfiguration;
+import android.app.WindowConfiguration.WindowingMode;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.util.Log;
/**
* Computes window frames.
* @hide
*/
public class WindowLayout {
+ private static final String TAG = WindowLayout.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ public static final int UNSPECIFIED_LENGTH = -1;
+
private final Rect mTempDisplayCutoutSafeExceptMaybeBarsRect = new Rect();
private final Rect mTempRect = new Rect();
public boolean computeWindowFrames(WindowManager.LayoutParams attrs, InsetsState state,
- Rect displayCutoutSafe, Rect windowBounds, InsetsVisibilities requestedVisibilities,
- Rect attachedWindowFrame, Rect outDisplayFrame, Rect outParentFrame) {
+ Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode,
+ int requestedWidth, int requestedHeight, InsetsVisibilities requestedVisibilities,
+ Rect attachedWindowFrame, float compatScale, Rect outDisplayFrame, Rect outParentFrame,
+ Rect outFrame) {
final int type = attrs.type;
final int fl = attrs.flags;
final int pfl = attrs.privateFlags;
@@ -72,18 +87,14 @@ public class WindowLayout {
}
// Compute bounds restricted by display cutout
+ final int cutoutMode = attrs.layoutInDisplayCutoutMode;
final DisplayCutout cutout = state.getDisplayCutout();
- if (cutout.isEmpty()) {
- return false;
- }
- boolean clippedByDisplayCutout = false;
final Rect displayCutoutSafeExceptMaybeBars = mTempDisplayCutoutSafeExceptMaybeBarsRect;
displayCutoutSafeExceptMaybeBars.set(displayCutoutSafe);
-
- // Ensure that windows with a non-ALWAYS display cutout mode are laid out in
- // the cutout safe zone.
- final int cutoutMode = attrs.layoutInDisplayCutoutMode;
- if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
+ boolean clippedByDisplayCutout = false;
+ if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS && !cutout.isEmpty()) {
+ // Ensure that windows with a non-ALWAYS display cutout mode are laid out in
+ // the cutout safe zone.
final Rect displayFrame = state.getDisplayFrame();
final InsetsSource statusBarSource = state.peekSource(ITYPE_STATUS_BAR);
if (statusBarSource != null && displayCutoutSafe.top > displayFrame.top) {
@@ -147,6 +158,118 @@ public class WindowLayout {
}
outDisplayFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
}
+
+ final boolean noLimits = (attrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0;
+ final boolean inMultiWindowMode = WindowConfiguration.inMultiWindowMode(windowingMode);
+
+ // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
+ // Also, we don't allow windows in multi-window mode to extend out of the screen.
+ if (noLimits && type != TYPE_SYSTEM_ERROR && !inMultiWindowMode) {
+ outDisplayFrame.left = outDisplayFrame.top = -10000;
+ outDisplayFrame.right = outDisplayFrame.bottom = 10000;
+ }
+
+ final boolean hasCompatScale = compatScale != 1f;
+ final int pw = outParentFrame.width();
+ final int ph = outParentFrame.height();
+ int rw = requestedWidth;
+ int rh = requestedHeight;
+ float x, y;
+ int w, h;
+
+ // If the view hierarchy hasn't been measured, the requested width and height would be
+ // UNSPECIFIED_LENGTH. This can happen in the first layout of a window or in the simulated
+ // layout.
+ if (rw == UNSPECIFIED_LENGTH) {
+ rw = attrs.width >= 0 ? attrs.width : pw;
+ }
+ if (rh == UNSPECIFIED_LENGTH) {
+ rh = attrs.height >= 0 ? attrs.height : ph;
+ }
+
+ if ((attrs.flags & FLAG_SCALED) != 0) {
+ if (attrs.width < 0) {
+ w = pw;
+ } else if (hasCompatScale) {
+ w = (int) (attrs.width * compatScale + .5f);
+ } else {
+ w = attrs.width;
+ }
+ if (attrs.height < 0) {
+ h = ph;
+ } else if (hasCompatScale) {
+ h = (int) (attrs.height * compatScale + .5f);
+ } else {
+ h = attrs.height;
+ }
+ } else {
+ if (attrs.width == MATCH_PARENT) {
+ w = pw;
+ } else if (hasCompatScale) {
+ w = (int) (rw * compatScale + .5f);
+ } else {
+ w = rw;
+ }
+ if (attrs.height == MATCH_PARENT) {
+ h = ph;
+ } else if (hasCompatScale) {
+ h = (int) (rh * compatScale + .5f);
+ } else {
+ h = rh;
+ }
+ }
+
+ if (hasCompatScale) {
+ x = attrs.x * compatScale;
+ y = attrs.y * compatScale;
+ } else {
+ x = attrs.x;
+ y = attrs.y;
+ }
+
+ if (inMultiWindowMode
+ && (attrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) == 0) {
+ // Make sure window fits in parent frame since it is in a non-fullscreen task as
+ // required by {@link Gravity#apply} call.
+ w = Math.min(w, pw);
+ h = Math.min(h, ph);
+ }
+
+ // We need to fit it to the display if either
+ // a) The window is in a fullscreen container, or we don't have a task (we assume fullscreen
+ // for the taskless windows)
+ // b) If it's a secondary app window, we also need to fit it to the display unless
+ // FLAG_LAYOUT_NO_LIMITS is set. This is so we place Popups, dialogs, and similar windows on
+ // screen, but SurfaceViews want to be always at a specific location so we don't fit it to
+ // the display.
+ final boolean fitToDisplay = !inMultiWindowMode
+ || ((attrs.type != TYPE_BASE_APPLICATION) && !noLimits);
+
+ // Set mFrame
+ Gravity.apply(attrs.gravity, w, h, outParentFrame,
+ (int) (x + attrs.horizontalMargin * pw),
+ (int) (y + attrs.verticalMargin * ph), outFrame);
+ // Now make sure the window fits in the overall display frame.
+ if (fitToDisplay) {
+ Gravity.applyDisplay(attrs.gravity, outDisplayFrame, outFrame);
+ }
+
+ if (DEBUG) Log.d(TAG, "computeWindowFrames " + attrs.getTitle()
+ + " outFrame=" + outFrame.toShortString()
+ + " outParentFrame=" + outParentFrame.toShortString()
+ + " outDisplayFrame=" + outDisplayFrame.toShortString()
+ + " attachedWindowFrame=" + (attachedWindowFrame != null
+ ? attachedWindowFrame.toShortString()
+ : "null")
+ + " requestedWidth=" + requestedWidth
+ + " requestedHeight=" + requestedHeight
+ + " compatScale=" + compatScale
+ + " windowingMode=" + WindowConfiguration.windowingModeToString(windowingMode)
+ + " displayCutoutSafe=" + displayCutoutSafe
+ + " attrs=" + attrs
+ + " state=" + state
+ + " requestedVisibilities=" + requestedVisibilities);
+
return clippedByDisplayCutout;
}
}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 5ad0055dae78..3248cf513c84 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -529,7 +529,7 @@ message ConfigurationContainerProto {
message WindowFramesProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
- optional .android.graphics.RectProto containing_frame = 1;
+ optional .android.graphics.RectProto containing_frame = 1 [deprecated=true];
optional .android.graphics.RectProto content_frame = 2 [deprecated=true];
optional .android.graphics.RectProto decor_frame = 3 [deprecated=true];
optional .android.graphics.RectProto display_frame = 4;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 765495aea546..06333e19ce5e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1984,6 +1984,22 @@
<enum name="KEYCODE_THUMBS_UP" value="286" />
<enum name="KEYCODE_THUMBS_DOWN" value="287" />
<enum name="KEYCODE_PROFILE_SWITCH" value="288" />
+ <enum name="KEYCODE_VIDEO_APP_1" value="289" />
+ <enum name="KEYCODE_VIDEO_APP_2" value="290" />
+ <enum name="KEYCODE_VIDEO_APP_3" value="291" />
+ <enum name="KEYCODE_VIDEO_APP_4" value="292" />
+ <enum name="KEYCODE_VIDEO_APP_5" value="293" />
+ <enum name="KEYCODE_VIDEO_APP_6" value="294" />
+ <enum name="KEYCODE_VIDEO_APP_7" value="295" />
+ <enum name="KEYCODE_VIDEO_APP_8" value="296" />
+ <enum name="KEYCODE_FEATURED_APP_1" value="297" />
+ <enum name="KEYCODE_FEATURED_APP_2" value="298" />
+ <enum name="KEYCODE_FEATURED_APP_3" value="299" />
+ <enum name="KEYCODE_FEATURED_APP_4" value="300" />
+ <enum name="KEYCODE_DEMO_APP_1" value="301" />
+ <enum name="KEYCODE_DEMO_APP_2" value="302" />
+ <enum name="KEYCODE_DEMO_APP_3" value="303" />
+ <enum name="KEYCODE_DEMO_APP_4" value="304" />
</attr>
<!-- ***************************************************************** -->
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index a65de9128be9..205c517d2b84 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -105,6 +105,9 @@
http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
<shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}|95034" />
+ <!-- Egypt: 4 digits, known codes listed -->
+ <shortcode country="eg" pattern="\\d{4}" free="1499" />
+
<!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
<shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}|22791|222145|22189" />
@@ -196,7 +199,7 @@
<shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" />
<!-- Nigeria -->
- <shortcode country="ng" pattern="\\d{1,5}" free="2441|55019" />
+ <shortcode country="ng" pattern="\\d{1,5}" free="2441|55020" />
<!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
<shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 5b3ce2dbaeb9..b1b0382b401c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -565,11 +565,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mDismissingDimValue = 0;
int totalDismissingDistance = 0;
- if (position <= mDividerSnapAlgorithm.getFirstSplitTarget().position) {
+ if (position < mDividerSnapAlgorithm.getFirstSplitTarget().position) {
mDismissingSide = isLandscape ? DOCKED_LEFT : DOCKED_TOP;
totalDismissingDistance = mDividerSnapAlgorithm.getDismissStartTarget().position
- mDividerSnapAlgorithm.getFirstSplitTarget().position;
- } else if (position >= mDividerSnapAlgorithm.getLastSplitTarget().position) {
+ } else if (position > mDividerSnapAlgorithm.getLastSplitTarget().position) {
mDismissingSide = isLandscape ? DOCKED_RIGHT : DOCKED_BOTTOM;
totalDismissingDistance = mDividerSnapAlgorithm.getLastSplitTarget().position
- mDividerSnapAlgorithm.getDismissEndTarget().position;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 291cbb3676dc..b6e5804a64dd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1292,13 +1292,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
Rect baseBounds = direction == TRANSITION_DIRECTION_SNAP_AFTER_RESIZE
? mPipBoundsState.getBounds() : currentBounds;
+ final boolean existingAnimatorRunning = mPipAnimationController.getCurrentAnimator() != null
+ && mPipAnimationController.getCurrentAnimator().isRunning();
final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController
.getAnimator(mTaskInfo, mLeash, baseBounds, currentBounds, destinationBounds,
sourceHintRect, direction, startingAngle, rotationDelta);
animator.setTransitionDirection(direction)
- .setPipAnimationCallback(mPipAnimationCallback)
.setPipTransactionHandler(mPipTransactionHandler)
.setDuration(durationMs);
+ if (!existingAnimatorRunning) {
+ animator.setPipAnimationCallback(mPipAnimationCallback);
+ }
if (isInPipDirection(direction)) {
// Similar to auto-enter-pip transition, we use content overlay when there is no
// source rect hint to enter PiP use bounds animation.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 328f3ed73f2e..b31e6e0750ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -116,6 +116,12 @@ public class PipTransition extends PipTransitionController {
if (mExitTransition == transition || info.getType() == TRANSIT_EXIT_PIP) {
mExitTransition = null;
if (info.getChanges().size() == 1) {
+ if (mFinishCallback != null) {
+ mFinishCallback.onTransitionFinished(null, null);
+ mFinishCallback = null;
+ throw new RuntimeException("Previous callback not called, aborting exit PIP.");
+ }
+
final TransitionInfo.Change change = info.getChanges().get(0);
mFinishCallback = finishCallback;
startTransaction.apply();
@@ -129,6 +135,12 @@ public class PipTransition extends PipTransitionController {
}
if (info.getType() == TRANSIT_REMOVE_PIP) {
+ if (mFinishCallback != null) {
+ mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
+ mFinishCallback = null;
+ throw new RuntimeException("Previous callback not called, aborting remove PIP.");
+ }
+
startTransaction.apply();
finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
mPipBoundsState.getDisplayBounds());
@@ -159,6 +171,12 @@ public class PipTransition extends PipTransitionController {
return false;
}
+ if (mFinishCallback != null) {
+ mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
+ mFinishCallback = null;
+ throw new RuntimeException("Previous callback not called, aborting entering PIP.");
+ }
+
// Show the wallpaper if there is a wallpaper change.
if (wallpaper != null) {
startTransaction.show(wallpaper.getLeash());
@@ -231,7 +249,7 @@ public class PipTransition extends PipTransitionController {
if (tx != null) {
wct.setBoundsChangeTransaction(taskInfo.token, tx);
}
- mFinishCallback.onTransitionFinished(wct, null /* wctCallback */);
+ mFinishCallback.onTransitionFinished(wct, null /* callback */);
mFinishCallback = null;
}
finishResizeForMenu(destinationBounds);
@@ -240,7 +258,7 @@ public class PipTransition extends PipTransitionController {
@Override
public void forceFinishTransition() {
if (mFinishCallback == null) return;
- mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCallback */);
+ mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
mFinishCallback = null;
}
@@ -286,7 +304,6 @@ public class PipTransition extends PipTransitionController {
mPipBoundsState.setBounds(destinationBounds);
onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */);
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
- mFinishCallback = null;
mPipTransitionState.setInSwipePipToHomeTransition(false);
return true;
}
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 49477b94cbe0..374cc7592faf 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -182,10 +182,15 @@ public final class MediaCodecInfo {
public String mName;
public int mValue;
public boolean mDefault;
+ public boolean mInternal;
public Feature(String name, int value, boolean def) {
+ this(name, value, def, false /* internal */);
+ }
+ public Feature(String name, int value, boolean def, boolean internal) {
mName = name;
mValue = value;
mDefault = def;
+ mInternal = internal;
}
}
@@ -579,6 +584,11 @@ public final class MediaCodecInfo {
public static final String FEATURE_LowLatency = "low-latency";
/**
+ * Do not include in REGULAR_CODECS list in MediaCodecList.
+ */
+ private static final String FEATURE_SpecialCodec = "special-codec";
+
+ /**
* <b>video encoder only</b>: codec supports quantization parameter bounds.
* @see MediaFormat#KEY_VIDEO_QP_MAX
* @see MediaFormat#KEY_VIDEO_QP_MIN
@@ -616,6 +626,8 @@ public final class MediaCodecInfo {
new Feature(FEATURE_MultipleFrames, (1 << 5), false),
new Feature(FEATURE_DynamicTimestamp, (1 << 6), false),
new Feature(FEATURE_LowLatency, (1 << 7), true),
+ // feature to exclude codec from REGULAR codec list
+ new Feature(FEATURE_SpecialCodec, (1 << 30), false, true),
};
private static final Feature[] encoderFeatures = {
@@ -623,6 +635,8 @@ public final class MediaCodecInfo {
new Feature(FEATURE_MultipleFrames, (1 << 1), false),
new Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
new Feature(FEATURE_QpBounds, (1 << 3), false),
+ // feature to exclude codec from REGULAR codec list
+ new Feature(FEATURE_SpecialCodec, (1 << 30), false, true),
};
/** @hide */
@@ -630,7 +644,9 @@ public final class MediaCodecInfo {
Feature[] features = getValidFeatures();
String[] res = new String[features.length];
for (int i = 0; i < res.length; i++) {
- res[i] = features[i].mName;
+ if (!features[i].mInternal) {
+ res[i] = features[i].mName;
+ }
}
return res;
}
@@ -778,6 +794,10 @@ public final class MediaCodecInfo {
// check feature support
for (Feature feat: getValidFeatures()) {
+ if (feat.mInternal) {
+ continue;
+ }
+
Integer yesNo = (Integer)map.get(MediaFormat.KEY_FEATURE_ + feat.mName);
if (yesNo == null) {
continue;
@@ -1091,7 +1111,9 @@ public final class MediaCodecInfo {
mFlagsRequired |= feat.mValue;
}
mFlagsSupported |= feat.mValue;
- mDefaultFormat.setInteger(key, 1);
+ if (!feat.mInternal) {
+ mDefaultFormat.setInteger(key, 1);
+ }
// TODO restrict features by mFlagsVerified once all codecs reliably verify them
}
}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 08a648a83daa..4891d74f868f 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -754,7 +754,7 @@ public final class MediaFormat {
* <p>This key is only used during decoding.
*/
public static final String KEY_MAX_OUTPUT_CHANNEL_COUNT =
- "max-output-channel_count";
+ "max-output-channel-count";
/**
* A key describing the number of frames to trim from the start of the decoded audio stream.
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 9dc4949799cd..405f9eedab14 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -751,8 +751,13 @@ public class Tuner implements AutoCloseable {
*/
@Result
public int tune(@NonNull FrontendSettings settings) {
- Log.d(TAG, "Tune to " + settings.getFrequency());
- mFrontendType = settings.getType();
+ final int type = settings.getType();
+ if (mFrontendHandle != null && type != mFrontendType) {
+ Log.e(TAG, "Frontend was opened with type " + mFrontendType + ", new type is " + type);
+ return RESULT_INVALID_STATE;
+ }
+ Log.d(TAG, "Tune to " + settings.getFrequencyLong());
+ mFrontendType = type;
if (mFrontendType == FrontendSettings.TYPE_DTMB) {
if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1, "Tuner with DTMB Frontend")) {
diff --git a/packages/PackageInstaller/OWNERS b/packages/PackageInstaller/OWNERS
index c6331133367a..27368705c6b0 100644
--- a/packages/PackageInstaller/OWNERS
+++ b/packages/PackageInstaller/OWNERS
@@ -1,7 +1,5 @@
svetoslavganov@google.com
-toddke@google.com
-patb@google.com
-suprabh@google.com
+include /PACKAGE_MANAGER_OWNERS
# For automotive related changes
rogerxue@google.com
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS b/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS
index a0e28baee3f6..5b2e1e3b50d3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS
@@ -1,5 +1,6 @@
# Default reviewers for this and subdirectories.
takaoka@google.com
yukawa@google.com
+wilsonwu@google.com
# Emergency approvers in case the above are not available \ No newline at end of file
diff --git a/packages/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS
index 6c61d4b91d36..5ade9716c8cb 100644
--- a/packages/SettingsProvider/OWNERS
+++ b/packages/SettingsProvider/OWNERS
@@ -2,6 +2,4 @@ hackbod@android.com
hackbod@google.com
narayan@google.com
svetoslavganov@google.com
-schfan@google.com
-toddke@google.com
-patb@google.com
+include /PACKAGE_MANAGER_OWNERS
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 61147281da6f..a110413700b2 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,20 +1,3 @@
--keep class com.android.systemui.navigationbar.buttons.KeyButtonView {
- public float getDrawingAlpha();
- public void setDrawingAlpha(float);
-}
-
--keep class com.android.systemui.navigationbar.buttons.KeyButtonRipple {
- public float getGlowAlpha();
- public float getGlowScale();
- public void setGlowAlpha(float);
- public void setGlowScale(float);
-}
-
--keep class com.android.systemui.settings.brightness.BrightnessSliderView {
- public float getSliderScaleY();
- public void setSliderScaleY(float);
-}
-
-keep class com.android.systemui.recents.OverviewProxyRecentsImpl
-keep class com.android.systemui.statusbar.car.CarStatusBar
-keep class com.android.systemui.statusbar.phone.StatusBar
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index cac90ea60e97..8c7ede26e2e6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -49,7 +49,7 @@ import dagger.Lazy;
public class KeyguardDisplayManager {
protected static final String TAG = "KeyguardDisplayManager";
- private static boolean DEBUG = KeyguardConstants.DEBUG;
+ private static final boolean DEBUG = KeyguardConstants.DEBUG;
private MediaRouter mMediaRouter = null;
private final DisplayManager mDisplayService;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
index b7398d86c16e..e2a2d07bdf35 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
@@ -22,6 +22,7 @@ import android.graphics.PorterDuffColorFilter
import android.graphics.Rect
import android.hardware.biometrics.BiometricOverlayConstants
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
import android.hardware.display.DisplayManager
import android.hardware.fingerprint.FingerprintManager
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
@@ -181,6 +182,7 @@ class SidefpsController @Inject constructor(
@BiometricOverlayConstants.ShowReason
private fun Int.isReasonToShow(): Boolean = when (this) {
REASON_AUTH_KEYGUARD -> false
+ REASON_AUTH_SETTINGS -> false
else -> true
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
index e3e2367aeef8..2ea706c16b7e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
@@ -34,6 +34,8 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
+import androidx.annotation.Keep;
+
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
@@ -184,19 +186,27 @@ public class KeyButtonRipple extends Drawable {
}
}
+ /** Gets the glow alpha, used by {@link android.animation.ObjectAnimator} via reflection. */
+ @Keep
public float getGlowAlpha() {
return mGlowAlpha;
}
+ /** Sets the glow alpha, used by {@link android.animation.ObjectAnimator} via reflection. */
+ @Keep
public void setGlowAlpha(float x) {
mGlowAlpha = x;
invalidateSelf();
}
+ /** Gets the glow scale, used by {@link android.animation.ObjectAnimator} via reflection. */
+ @Keep
public float getGlowScale() {
return mGlowScale;
}
+ /** Sets the glow scale, used by {@link android.animation.ObjectAnimator} via reflection. */
+ @Keep
public void setGlowScale(float x) {
mGlowScale = x;
invalidateSelf();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index bc21b2d0fba7..80ec0adc21a9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -112,20 +112,9 @@ class DeviceControlsTile @Inject constructor(
}
mUiHandler.post {
- if (keyguardStateController.isUnlocked) {
- mActivityStarter.startActivity(
- intent, true /* dismissShade */, animationController)
- } else {
- if (state.state == Tile.STATE_ACTIVE) {
- mHost.collapsePanels()
- // With an active tile, don't use ActivityStarter so that the activity is
- // started without prompting keyguard unlock.
- mContext.startActivity(intent)
- } else {
- mActivityStarter.postStartActivityDismissingKeyguard(
- intent, 0 /* delay */, animationController)
- }
- }
+ val showOverLockscreenWhenLocked = state.state == Tile.STATE_ACTIVE
+ mActivityStarter.startActivity(
+ intent, true /* dismissShade */, animationController, showOverLockscreenWhenLocked)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 15b78e7cb08a..58e899285e3b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -331,7 +331,7 @@ public class InternetDialog extends SystemUIDialog implements
showProgressBar();
final boolean isDeviceLocked = mInternetDialogController.isDeviceLocked();
final boolean isWifiEnabled = mWifiManager.isWifiEnabled();
- final boolean isWifiScanEnabled = mWifiManager.isScanAlwaysAvailable();
+ final boolean isWifiScanEnabled = mInternetDialogController.isWifiScanEnabled();
updateWifiToggle(isWifiEnabled, isDeviceLocked);
updateConnectedWifi(isWifiEnabled, isDeviceLocked);
updateWifiScanNotify(isWifiEnabled, isWifiScanEnabled, isDeviceLocked);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index 1ade5ce39c27..40590a76536e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -78,6 +78,7 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.NetworkController.AccessPointController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.toast.SystemUIToast;
import com.android.systemui.toast.ToastFactory;
import com.android.systemui.util.CarrierConfigTracker;
@@ -150,6 +151,7 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
private WindowManager mWindowManager;
private ToastFactory mToastFactory;
private SignalDrawable mSignalDrawable;
+ private LocationController mLocationController;
@VisibleForTesting
static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
@@ -199,7 +201,8 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
GlobalSettings globalSettings, KeyguardStateController keyguardStateController,
WindowManager windowManager, ToastFactory toastFactory,
@Background Handler workerHandler,
- CarrierConfigTracker carrierConfigTracker) {
+ CarrierConfigTracker carrierConfigTracker,
+ LocationController locationController) {
if (DEBUG) {
Log.d(TAG, "Init InternetDialogController");
}
@@ -227,6 +230,7 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
mWindowManager = windowManager;
mToastFactory = toastFactory;
mSignalDrawable = new SignalDrawable(mContext);
+ mLocationController = locationController;
}
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
@@ -788,6 +792,14 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback,
return false;
}
+ @WorkerThread
+ boolean isWifiScanEnabled() {
+ if (!mLocationController.isLocationEnabled()) {
+ return false;
+ }
+ return mWifiManager.isScanAlwaysAvailable();
+ }
+
static class WifiEntryConnectCallback implements WifiEntry.ConnectCallback {
final ActivityStarter mActivityStarter;
final WifiEntry mWifiEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
index 15aa2b730adf..a4e1537bd831 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
@@ -27,6 +27,7 @@ import android.view.View;
import android.widget.FrameLayout;
import android.widget.SeekBar.OnSeekBarChangeListener;
+import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -183,6 +184,7 @@ public class BrightnessSliderView extends FrameLayout {
*
* Used in {@link com.android.systemui.qs.QSAnimator}.
*/
+ @Keep
public void setSliderScaleY(float scale) {
if (scale != mScale) {
mScale = scale;
@@ -199,6 +201,7 @@ public class BrightnessSliderView extends FrameLayout {
}
}
+ @Keep
public float getSliderScaleY() {
return mScale;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index c639eecf037c..e26f75f7ce40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -1078,10 +1078,14 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(ControlsUiController.EXTRA_ANIMATE, true);
+ ActivityLaunchAnimator.Controller controller =
+ v != null ? ActivityLaunchAnimator.Controller.fromView(v, null /* cujType */)
+ : null;
if (mControlsComponent.getVisibility() == AVAILABLE) {
- mContext.startActivity(intent);
+ mActivityStarter.startActivity(intent, true /* dismissShade */, controller,
+ true /* showOverLockscreenWhenLocked */);
} else {
- mActivityStarter.postStartActivityDismissingKeyguard(intent, 0 /* delay */);
+ mActivityStarter.postStartActivityDismissingKeyguard(intent, 0 /* delay */, controller);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
index 16d7f983d0f3..6ae8331dfde5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
@@ -156,18 +156,21 @@ class StatusBarContentInsetsProvider @Inject constructor(
val isRtl = rotatedResources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
val roundedCornerPadding = rotatedResources
.getDimensionPixelSize(R.dimen.rounded_corner_content_padding)
- val minDotWidth = if (isPrivacyDotEnabled)
+ val minDotPadding = if (isPrivacyDotEnabled)
rotatedResources.getDimensionPixelSize(R.dimen.ongoing_appops_dot_min_padding)
else 0
+ val dotWidth = if (isPrivacyDotEnabled)
+ rotatedResources.getDimensionPixelSize(R.dimen.ongoing_appops_dot_diameter)
+ else 0
val minLeft: Int
val minRight: Int
if (isRtl) {
- minLeft = max(minDotWidth, roundedCornerPadding)
+ minLeft = max(minDotPadding, roundedCornerPadding)
minRight = roundedCornerPadding
} else {
minLeft = roundedCornerPadding
- minRight = max(minDotWidth, roundedCornerPadding)
+ minRight = max(minDotPadding, roundedCornerPadding)
}
return calculateInsetsForRotationWithRotatedResources(
@@ -177,7 +180,9 @@ class StatusBarContentInsetsProvider @Inject constructor(
context.resources.configuration.windowConfiguration.maxBounds,
SystemBarUtils.getStatusBarHeight(context),
minLeft,
- minRight)
+ minRight,
+ isRtl,
+ dotWidth)
}
fun getStatusBarPaddingTop(@Rotation rotation: Int? = null): Int {
@@ -246,10 +251,13 @@ fun getPrivacyChipBoundingRectForInsets(
*
* @param currentRotation current device rotation
* @param targetRotation rotation for which to calculate the status bar content rect
- * @param displayCutout [DisplayCutout] for the curren display. possibly null
+ * @param displayCutout [DisplayCutout] for the current display. possibly null
* @param windowMetrics [WindowMetrics] for the current window
* @param statusBarHeight height of the status bar for the target rotation
- * @param roundedCornerPadding from rounded_corner_content_padding
+ * @param minLeft the minimum padding to enforce on the left
+ * @param minRight the minimum padding to enforce on the right
+ * @param isRtl current layout direction is Right-To-Left or not
+ * @param dotWidth privacy dot image width (0 if privacy dot is disabled)
*
* @see [RotationUtils#getResourcesForRotation]
*/
@@ -260,7 +268,9 @@ fun calculateInsetsForRotationWithRotatedResources(
maxBounds: Rect,
statusBarHeight: Int,
minLeft: Int,
- minRight: Int
+ minRight: Int,
+ isRtl: Boolean,
+ dotWidth: Int
): Rect {
/*
TODO: Check if this is ever used for devices with no rounded corners
@@ -279,6 +289,8 @@ fun calculateInsetsForRotationWithRotatedResources(
maxBounds.height(),
minLeft,
minRight,
+ isRtl,
+ dotWidth,
targetRotation,
currentRotation)
@@ -296,6 +308,8 @@ fun calculateInsetsForRotationWithRotatedResources(
* @param cHeight display height in our current rotation
* @param minLeft the minimum padding to enforce on the left
* @param minRight the minimum padding to enforce on the right
+ * @param isRtl current layout direction is Right-To-Left or not
+ * @param dotWidth privacy dot image width (0 if privacy dot is disabled)
* @param targetRotation the rotation for which to calculate margins
* @param currentRotation the rotation from which the display cutout was generated
*
@@ -311,6 +325,8 @@ private fun getStatusBarLeftRight(
cHeight: Int,
minLeft: Int,
minRight: Int,
+ isRtl: Boolean,
+ dotWidth: Int,
@Rotation targetRotation: Int,
@Rotation currentRotation: Int
): Rect {
@@ -345,13 +361,16 @@ private fun getStatusBarLeftRight(
}
if (cutoutRect.touchesLeftEdge(relativeRotation, cWidth, cHeight)) {
-
- val l = max(minLeft, cutoutRect.logicalWidth(relativeRotation))
- leftMargin = max(l, leftMargin)
+ var logicalWidth = cutoutRect.logicalWidth(relativeRotation)
+ if (isRtl) logicalWidth += dotWidth
+ leftMargin = max(logicalWidth, leftMargin)
} else if (cutoutRect.touchesRightEdge(relativeRotation, cWidth, cHeight)) {
- val logicalWidth = cutoutRect.logicalWidth(relativeRotation)
- rightMargin = max(minRight, logicalWidth)
+ var logicalWidth = cutoutRect.logicalWidth(relativeRotation)
+ if (!isRtl) logicalWidth += dotWidth
+ rightMargin = max(rightMargin, logicalWidth)
}
+ // TODO(b/203626889): Fix the scenario when config_mainBuiltInDisplayCutoutRectApproximation
+ // is very close to but not directly touch edges.
}
return Rect(leftMargin, 0, logicalDisplayWidth - rightMargin, sbHeight)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
index 5fee7fbf8705..ca7d506dcc78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
@@ -18,6 +18,7 @@ package com.android.systemui.biometrics
import android.graphics.Rect
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN
import android.hardware.biometrics.SensorProperties
import android.hardware.display.DisplayManager
@@ -182,7 +183,16 @@ class SidefpsControllerTest : SysuiTestCase() {
@Test
fun testIgnoredForKeyguard() {
- overlayController.show(SENSOR_ID, REASON_AUTH_KEYGUARD)
+ testIgnoredFor(REASON_AUTH_KEYGUARD)
+ }
+
+ @Test
+ fun testIgnoredForSettings() {
+ testIgnoredFor(REASON_AUTH_SETTINGS)
+ }
+
+ private fun testIgnoredFor(reason: Int) {
+ overlayController.show(SENSOR_ID, reason)
executor.runAllReady()
verify(windowManager, never()).addView(any(), any())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 94af10a485fd..98c7274aeba6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -52,13 +52,11 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.doNothing
-import org.mockito.Mockito.never
import org.mockito.Mockito.nullable
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
@@ -272,28 +270,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
- fun handleClick_availableAndLocked_activityStarted() {
- verify(controlsListingController).observe(
- any(LifecycleOwner::class.java),
- capture(listingCallbackCaptor)
- )
- `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
- `when`(keyguardStateController.isUnlocked).thenReturn(false)
-
- listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
- testableLooper.processAllMessages()
-
- tile.click(null /* view */)
- testableLooper.processAllMessages()
-
- // The activity should be started right away and not require a keyguard dismiss.
- verifyZeroInteractions(activityStarter)
- verify(spiedContext).startActivity(intentCaptor.capture())
- assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME)
- }
-
- @Test
- fun handleClick_availableAndUnlocked_activityStarted() {
+ fun handleClick_available_shownOverLockscreenWhenLocked() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),
capture(listingCallbackCaptor)
@@ -307,16 +284,16 @@ class DeviceControlsTileTest : SysuiTestCase() {
tile.click(null /* view */)
testableLooper.processAllMessages()
- verify(activityStarter, never()).postStartActivityDismissingKeyguard(any(), anyInt())
verify(activityStarter).startActivity(
intentCaptor.capture(),
eq(true) /* dismissShade */,
- nullable(ActivityLaunchAnimator.Controller::class.java))
+ nullable(ActivityLaunchAnimator.Controller::class.java),
+ eq(true) /* showOverLockscreenWhenLocked */)
assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME)
}
@Test
- fun handleClick_availableAfterUnlockAndIsLocked_keyguardDismissRequired() {
+ fun handleClick_availableAfterUnlock_notShownOverLockscreenWhenLocked() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),
capture(listingCallbackCaptor)
@@ -331,38 +308,11 @@ class DeviceControlsTileTest : SysuiTestCase() {
tile.click(null /* view */)
testableLooper.processAllMessages()
- verify(activityStarter, never()).startActivity(
- any(),
- anyBoolean() /* dismissShade */,
- nullable(ActivityLaunchAnimator.Controller::class.java))
- verify(activityStarter).postStartActivityDismissingKeyguard(
- intentCaptor.capture(),
- anyInt(),
- nullable(ActivityLaunchAnimator.Controller::class.java))
- assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME)
- }
-
- @Test
- fun handleClick_availableAfterUnlockAndIsUnlocked_activityStarted() {
- verify(controlsListingController).observe(
- any(LifecycleOwner::class.java),
- capture(listingCallbackCaptor)
- )
- `when`(controlsComponent.getVisibility())
- .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)
- `when`(keyguardStateController.isUnlocked).thenReturn(true)
-
- listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
- testableLooper.processAllMessages()
-
- tile.click(null /* view */)
- testableLooper.processAllMessages()
-
- verify(activityStarter, never()).postStartActivityDismissingKeyguard(any(), anyInt())
verify(activityStarter).startActivity(
intentCaptor.capture(),
- eq(true) /* dismissShade */,
- nullable(ActivityLaunchAnimator.Controller::class.java))
+ anyBoolean() /* dismissShade */,
+ nullable(ActivityLaunchAnimator.Controller::class.java),
+ eq(false) /* showOverLockscreenWhenLocked */)
assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index fe328395b89f..5cea7632192b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -51,6 +51,7 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.NetworkController.AccessPointController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.toast.SystemUIToast;
import com.android.systemui.toast.ToastFactory;
import com.android.systemui.util.CarrierConfigTracker;
@@ -135,6 +136,8 @@ public class InternetDialogControllerTest extends SysuiTestCase {
private Animator mAnimator;
@Mock
private CarrierConfigTracker mCarrierConfigTracker;
+ @Mock
+ private LocationController mLocationController;
private TestableResources mTestableResources;
private MockInternetDialogController mInternetDialogController;
@@ -170,7 +173,8 @@ public class InternetDialogControllerTest extends SysuiTestCase {
mSubscriptionManager, mTelephonyManager, mWifiManager,
mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
- mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker);
+ mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
+ mLocationController);
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
mInternetDialogController.mOnSubscriptionsChangedListener);
mInternetDialogController.onStart(mInternetDialogCallback, true);
@@ -602,6 +606,30 @@ public class InternetDialogControllerTest extends SysuiTestCase {
verify(mMergedCarrierEntry).setEnabled(false);
}
+ @Test
+ public void isWifiScanEnabled_locationOff_returnFalse() {
+ when(mLocationController.isLocationEnabled()).thenReturn(false);
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+ }
+
+ @Test
+ public void isWifiScanEnabled_locationOn_returnIsScanAlwaysAvailable() {
+ when(mLocationController.isLocationEnabled()).thenReturn(true);
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+
+ when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+
+ assertThat(mInternetDialogController.isWifiScanEnabled()).isTrue();
+ }
+
private String getResourcesString(String name) {
return mContext.getResources().getString(getResourcesId(name));
}
@@ -625,12 +653,13 @@ public class InternetDialogControllerTest extends SysuiTestCase {
KeyguardUpdateMonitor keyguardUpdateMonitor, GlobalSettings globalSettings,
KeyguardStateController keyguardStateController, WindowManager windowManager,
ToastFactory toastFactory, Handler workerHandler,
- CarrierConfigTracker carrierConfigTracker) {
+ CarrierConfigTracker carrierConfigTracker,
+ LocationController locationController) {
super(context, uiEventLogger, starter, accessPointController, subscriptionManager,
telephonyManager, wifiManager, connectivityManager, handler, mainExecutor,
broadcastDispatcher, keyguardUpdateMonitor, globalSettings,
keyguardStateController, windowManager, toastFactory, workerHandler,
- carrierConfigTracker);
+ carrierConfigTracker, locationController);
mGlobalSettings = globalSettings;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
index 66889607482f..5e1fea512d55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
@@ -282,7 +282,7 @@ public class InternetDialogTest extends SysuiTestCase {
@Test
public void updateDialog_wifiOffAndWifiScanOff_hideWifiScanNotify() {
when(mWifiManager.isWifiEnabled()).thenReturn(false);
- when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
+ when(mInternetDialogController.isWifiScanEnabled()).thenReturn(false);
mInternetDialog.updateDialog(false);
@@ -292,7 +292,7 @@ public class InternetDialogTest extends SysuiTestCase {
@Test
public void updateDialog_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() {
when(mWifiManager.isWifiEnabled()).thenReturn(false);
- when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+ when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
mInternetDialog.updateDialog(false);
@@ -303,7 +303,7 @@ public class InternetDialogTest extends SysuiTestCase {
@Test
public void updateDialog_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() {
when(mWifiManager.isWifiEnabled()).thenReturn(false);
- when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
+ when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
when(mInternetDialogController.isDeviceLocked()).thenReturn(false);
mInternetDialog.updateDialog(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
index 1503af82545c..e5158e74759c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
@@ -86,7 +86,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
var chipBounds = getPrivacyChipBoundingRectForInsets(bounds, dotWidth, chipWidth, isRtl)
/* 1080 - 20 (rounded corner) - 30 (chip),
@@ -115,7 +117,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
chipBounds = getPrivacyChipBoundingRectForInsets(bounds, dotWidth, chipWidth, isRtl)
/* 2160 - 20 (rounded corner) - 30 (chip),
@@ -146,6 +150,8 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
val sbHeightPortrait = 100
val sbHeightLandscape = 60
val currentRotation = ROTATION_NONE
+ val isRtl = false
+ val dotWidth = 10
`when`(dc.boundingRects).thenReturn(listOf(dcBounds))
@@ -164,7 +170,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
@@ -181,7 +189,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
@@ -200,7 +210,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
@@ -208,7 +220,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
targetRotation = ROTATION_SEASCAPE
expectedBounds = Rect(minLeftPadding,
0,
- screenBounds.height() - dcBounds.height(),
+ screenBounds.height() - dcBounds.height() - dotWidth,
sbHeightLandscape)
bounds = calculateInsetsForRotationWithRotatedResources(
@@ -218,7 +230,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
}
@@ -237,6 +251,8 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
val sbHeightPortrait = 100
val sbHeightLandscape = 60
val currentRotation = ROTATION_NONE
+ val isRtl = false
+ val dotWidth = 10
`when`(dc.boundingRects).thenReturn(listOf(dcBounds))
@@ -255,7 +271,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
@@ -272,7 +290,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
@@ -289,14 +309,16 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
targetRotation = ROTATION_SEASCAPE
expectedBounds = Rect(minLeftPadding,
0,
- screenBounds.height() - dcBounds.height(),
+ screenBounds.height() - dcBounds.height() - dotWidth,
sbHeightLandscape)
bounds = calculateInsetsForRotationWithRotatedResources(
@@ -306,7 +328,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
}
@@ -320,6 +344,8 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
val minRightPadding = 20
val sbHeightPortrait = 100
val sbHeightLandscape = 60
+ val isRtl = false
+ val dotWidth = 10
// THEN content insets should only use rounded corner padding
var targetRotation = ROTATION_NONE
@@ -335,7 +361,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
targetRotation = ROTATION_LANDSCAPE
@@ -351,7 +379,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
targetRotation = ROTATION_UPSIDE_DOWN
@@ -367,7 +397,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
targetRotation = ROTATION_LANDSCAPE
@@ -383,7 +415,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightLandscape,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
}
@@ -397,6 +431,8 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
val sbHeightPortrait = 100
val sbHeightLandscape = 60
val currentRotation = ROTATION_NONE
+ val isRtl = false
+ val dotWidth = 10
`when`(dc.boundingRects).thenReturn(listOf(dcBounds))
@@ -414,7 +450,9 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds,
sbHeightPortrait,
minLeftPadding,
- minRightPadding)
+ minRightPadding,
+ isRtl,
+ dotWidth)
assertRects(expectedBounds, bounds, currentRotation, targetRotation)
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 8205d3579b3b..e6f91a25f168 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -128,6 +128,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationProcessor;
+import com.android.server.accessibility.magnification.MagnificationScaleProvider;
import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -338,7 +339,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler,
mWindowManagerService, this, mSecurityPolicy, this, mTraceManager);
mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler);
- mMagnificationController = new MagnificationController(this, mLock, mContext);
+ mMagnificationController = new MagnificationController(this, mLock, mContext,
+ new MagnificationScaleProvider(mContext));
mMagnificationProcessor = new MagnificationProcessor(mMagnificationController);
init();
}
@@ -1364,6 +1366,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
private void switchUser(int userId) {
+ mMagnificationController.updateUserIdIfNeeded(userId);
synchronized (mLock) {
if (mCurrentUserId == userId && mInitialized) {
return;
@@ -1386,8 +1389,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
// The user changed.
mCurrentUserId = userId;
-
- mMagnificationController.updateUserIdIfNeeded(mCurrentUserId);
AccessibilityUserState userState = getCurrentUserStateLocked();
readConfigurationForUserStateLocked(userState);
@@ -1444,6 +1445,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
synchronized (mLock) {
mUserStates.remove(userId);
}
+ getMagnificationController().onUserRemoved(userId);
}
// Called only during settings restore; currently supports only the owner user
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 8f30aa9acc79..c62473db948c 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -28,10 +28,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.graphics.Region;
-import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
-import android.provider.Settings;
import android.text.TextUtils;
import android.util.MathUtils;
import android.util.Slog;
@@ -59,7 +57,8 @@ import java.util.Locale;
* holding the current state of magnification and animation, and it handles
* communication between the accessibility manager and window manager.
*
- * Magnification is limited to the range [MIN_SCALE, MAX_SCALE], and can only occur inside the
+ * Magnification is limited to the range controlled by
+ * {@link MagnificationScaleProvider#constrainScale(float)}, and can only occur inside the
* magnification region. If a value is out of bounds, it will be adjusted to guarantee these
* constraints.
*/
@@ -69,13 +68,9 @@ public class FullScreenMagnificationController {
private static final MagnificationAnimationCallback STUB_ANIMATION_CALLBACK = success -> {
};
- public static final float MIN_SCALE = 1.0f;
- public static final float MAX_SCALE = 8.0f;
private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
- private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
-
private final Object mLock;
private final ControllerContext mControllerCtx;
@@ -84,7 +79,7 @@ public class FullScreenMagnificationController {
private final MagnificationInfoChangedCallback mMagnificationInfoChangedCallback;
- private int mUserId;
+ private final MagnificationScaleProvider mScaleProvider;
private final long mMainThreadId;
@@ -489,7 +484,7 @@ public class FullScreenMagnificationController {
return false;
}
// Constrain scale immediately for use in the pivot calculations.
- scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ scale = MagnificationScaleProvider.constrainScale(scale);
final Rect viewport = mTempRect;
mMagnificationRegion.getBounds(viewport);
@@ -557,7 +552,7 @@ public class FullScreenMagnificationController {
// Compute changes.
boolean changed = false;
- final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ final float normScale = MagnificationScaleProvider.constrainScale(scale);
if (Float.compare(mCurrentMagnificationSpec.scale, normScale) != 0) {
mCurrentMagnificationSpec.scale = normScale;
changed = true;
@@ -658,12 +653,13 @@ public class FullScreenMagnificationController {
*/
public FullScreenMagnificationController(@NonNull Context context,
@NonNull AccessibilityManagerService ams, @NonNull Object lock,
- @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback) {
+ @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback,
+ @NonNull MagnificationScaleProvider scaleProvider) {
this(new ControllerContext(context, ams,
LocalServices.getService(WindowManagerInternal.class),
new Handler(context.getMainLooper()),
context.getResources().getInteger(R.integer.config_longAnimTime)), lock,
- magnificationInfoChangedCallback);
+ magnificationInfoChangedCallback, scaleProvider);
}
/**
@@ -672,12 +668,14 @@ public class FullScreenMagnificationController {
@VisibleForTesting
public FullScreenMagnificationController(@NonNull ControllerContext ctx,
@NonNull Object lock,
- @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback) {
+ @NonNull MagnificationInfoChangedCallback magnificationInfoChangedCallback,
+ @NonNull MagnificationScaleProvider scaleProvider) {
mControllerCtx = ctx;
mLock = lock;
mMainThreadId = mControllerCtx.getContext().getMainLooper().getThread().getId();
mScreenStateObserver = new ScreenStateObserver(mControllerCtx.getContext(), this);
mMagnificationInfoChangedCallback = magnificationInfoChangedCallback;
+ mScaleProvider = scaleProvider;
}
/**
@@ -1096,18 +1094,9 @@ public class FullScreenMagnificationController {
/**
* Persists the default display magnification scale to the current user's settings.
*/
- public void persistScale() {
- // TODO: b/123047354, Need support multi-display?
+ public void persistScale(int displayId) {
final float scale = getScale(Display.DEFAULT_DISPLAY);
- final int userId = mUserId;
-
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- mControllerCtx.putMagnificationScale(scale, userId);
- return null;
- }
- }.execute();
+ mScaleProvider.putScale(scale, displayId);
}
/**
@@ -1117,21 +1106,8 @@ public class FullScreenMagnificationController {
* @return the previously persisted magnification scale, or the default
* scale if none is available
*/
- public float getPersistedScale() {
- return mControllerCtx.getMagnificationScale(mUserId);
- }
-
- /**
- * Sets the currently active user ID.
- *
- * @param userId the currently active user ID
- */
- public void setUserId(int userId) {
- if (mUserId == userId) {
- return;
- }
- mUserId = userId;
- resetAllIfNeeded(false);
+ public float getPersistedScale(int displayId) {
+ return mScaleProvider.getScale(displayId);
}
/**
@@ -1225,7 +1201,11 @@ public class FullScreenMagnificationController {
mControllerCtx.getHandler().sendMessage(m);
}
- private void resetAllIfNeeded(boolean animate) {
+ /**
+ * Resets magnification on all displays.
+ * @param animate reset the magnification with animation
+ */
+ void resetAllIfNeeded(boolean animate) {
synchronized (mLock) {
for (int i = 0; i < mDisplays.size(); i++) {
resetIfNeeded(mDisplays.keyAt(i), animate);
@@ -1288,8 +1268,8 @@ public class FullScreenMagnificationController {
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("MagnificationController[");
- builder.append("mUserId=").append(mUserId);
builder.append(", mDisplays=").append(mDisplays);
+ builder.append(", mScaleProvider=").append(mScaleProvider);
builder.append("]");
return builder.toString();
}
@@ -1570,23 +1550,6 @@ public class FullScreenMagnificationController {
}
/**
- * Write Settings of magnification scale.
- */
- public void putMagnificationScale(float value, int userId) {
- Settings.Secure.putFloatForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, value, userId);
- }
-
- /**
- * Get Settings of magnification scale.
- */
- public float getMagnificationScale(int userId) {
- return Settings.Secure.getFloatForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
- DEFAULT_MAGNIFICATION_SCALE, userId);
- }
-
- /**
* @return Configuration of animation duration.
*/
public long getAnimationDuration() {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 8f4a5cb4dad0..935df9934dcb 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -119,11 +119,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private static final boolean DEBUG_DETECTING = false | DEBUG_ALL;
private static final boolean DEBUG_PANNING_SCALING = false | DEBUG_ALL;
- // The MIN_SCALE is different from MagnificationController.MIN_SCALE due
+ // The MIN_SCALE is different from MagnificationScaleProvider.MIN_SCALE due
// to AccessibilityService.MagnificationController#setScale() has
// different scale range
private static final float MIN_SCALE = 2.0f;
- private static final float MAX_SCALE = FullScreenMagnificationController.MAX_SCALE;
+ private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE;
@VisibleForTesting final FullScreenMagnificationController mFullScreenMagnificationController;
@@ -341,7 +341,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
public void persistScaleAndTransitionTo(State state) {
- mFullScreenMagnificationController.persistScale();
+ mFullScreenMagnificationController.persistScale(mDisplayId);
clear();
transitionTo(state);
}
@@ -945,7 +945,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
if (DEBUG_DETECTING) Slog.i(mLogTag, "zoomOn(" + centerX + ", " + centerY + ")");
final float scale = MathUtils.constrain(
- mFullScreenMagnificationController.getPersistedScale(),
+ mFullScreenMagnificationController.getPersistedScale(mDisplayId),
MIN_SCALE, MAX_SCALE);
mFullScreenMagnificationController.setScaleAndCenter(mDisplayId,
scale, centerX, centerY,
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 5a6836c2d771..3708c7a422a0 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -23,11 +23,13 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import android.util.SparseArray;
@@ -75,12 +77,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private final SparseArray<DisableMagnificationCallback>
mMagnificationEndRunnableSparseArray = new SparseArray();
+ private final MagnificationScaleProvider mScaleProvider;
private FullScreenMagnificationController mFullScreenMagnificationController;
private WindowMagnificationManager mWindowMagnificationMgr;
private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
@GuardedBy("mLock")
private int mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+ // Track the active user to reset the magnification and get the associated user settings.
+ private @UserIdInt int mUserId = UserHandle.USER_SYSTEM;
@GuardedBy("mLock")
private boolean mImeWindowVisible = false;
private long mWindowModeEnabledTime = 0;
@@ -98,17 +103,19 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
public MagnificationController(AccessibilityManagerService ams, Object lock,
- Context context) {
+ Context context, MagnificationScaleProvider scaleProvider) {
mAms = ams;
mLock = lock;
mContext = context;
+ mScaleProvider = scaleProvider;
}
@VisibleForTesting
public MagnificationController(AccessibilityManagerService ams, Object lock,
Context context, FullScreenMagnificationController fullScreenMagnificationController,
- WindowMagnificationManager windowMagnificationManager) {
- this(ams, lock, context);
+ WindowMagnificationManager windowMagnificationManager,
+ MagnificationScaleProvider scaleProvider) {
+ this(ams, lock, context, scaleProvider);
mFullScreenMagnificationController = fullScreenMagnificationController;
mWindowMagnificationMgr = windowMagnificationManager;
}
@@ -194,7 +201,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
final FullScreenMagnificationController screenMagnificationController =
getFullScreenMagnificationController();
final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
- final float scale = windowMagnificationMgr.getPersistedScale();
+ final float scale = mScaleProvider.getScale(displayId);
final DisableMagnificationCallback animationEndCallback =
new DisableMagnificationCallback(transitionCallBack, displayId, targetMode,
scale, magnificationCenter);
@@ -313,13 +320,23 @@ public class MagnificationController implements WindowMagnificationManager.Callb
* @param userId the currently active user ID
*/
public void updateUserIdIfNeeded(int userId) {
+ if (mUserId == userId) {
+ return;
+ }
+ mUserId = userId;
+ final FullScreenMagnificationController fullMagnificationController;
+ final WindowMagnificationManager windowMagnificationManager;
synchronized (mLock) {
- if (mFullScreenMagnificationController != null) {
- mFullScreenMagnificationController.setUserId(userId);
- }
- if (mWindowMagnificationMgr != null) {
- mWindowMagnificationMgr.setUserId(userId);
- }
+ fullMagnificationController = mFullScreenMagnificationController;
+ windowMagnificationManager = mWindowMagnificationMgr;
+ }
+
+ mScaleProvider.onUserChanged(userId);
+ if (fullMagnificationController != null) {
+ fullMagnificationController.resetAllIfNeeded(false);
+ }
+ if (windowMagnificationManager != null) {
+ windowMagnificationManager.disableAllWindowMagnifiers();
}
}
@@ -337,6 +354,14 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mWindowMagnificationMgr.onDisplayRemoved(displayId);
}
}
+ mScaleProvider.onDisplayRemoved(displayId);
+ }
+
+ /**
+ * Called when the given user is removed.
+ */
+ public void onUserRemoved(int userId) {
+ mScaleProvider.onUserRemoved(userId);
}
public void setMagnificationCapabilities(int capabilities) {
@@ -378,8 +403,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
if (mFullScreenMagnificationController == null) {
mFullScreenMagnificationController = new FullScreenMagnificationController(mContext,
- mAms, mLock, this);
- mFullScreenMagnificationController.setUserId(mAms.getCurrentUserIdLocked());
+ mAms, mLock, this, mScaleProvider);
}
}
return mFullScreenMagnificationController;
@@ -404,7 +428,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
synchronized (mLock) {
if (mWindowMagnificationMgr == null) {
mWindowMagnificationMgr = new WindowMagnificationManager(mContext,
- mAms.getCurrentUserIdLocked(), this, mAms.getTraceManager());
+ mUserId, this, mAms.getTraceManager(),
+ mScaleProvider);
}
return mWindowMagnificationMgr;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java
new file mode 100644
index 000000000000..8e1aa38be9e8
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2021 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.accessibility.magnification;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.MathUtils;
+import android.util.SparseArray;
+import android.view.Display;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+
+/**
+ * Supplies setter/getter of the magnification scale for the given display. Only the value of the
+ * default play is persisted. It also constraints the range of applied magnification scale between
+ * [MIN_SCALE, MAX_SCALE] which is consistent with the range provided by
+ * {@code AccessibilityService.MagnificationController#setScale()}.
+ */
+public class MagnificationScaleProvider {
+
+ @VisibleForTesting
+ protected static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
+ public static final float MIN_SCALE = 1.0f;
+ public static final float MAX_SCALE = 8.0f;
+
+ private final Context mContext;
+ // Stores the scale for non-default displays.
+ @GuardedBy("mLock")
+ private final SparseArray<SparseArray<Float>> mUsersScales = new SparseArray();
+ private int mCurrentUserId = UserHandle.USER_SYSTEM;
+ private final Object mLock = new Object();
+
+ public MagnificationScaleProvider(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Stores the user settings scale associated to the given display. Only the scale of the
+ * default display is persistent.
+ *
+ * @param scale the magnification scale
+ * @param displayId the id of the display
+ */
+ void putScale(float scale, int displayId) {
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ BackgroundThread.getHandler().post(
+ () -> Settings.Secure.putFloatForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale,
+ mCurrentUserId));
+ } else {
+ synchronized (mLock) {
+ getScalesWithCurrentUser().put(displayId, scale);
+ }
+ }
+ }
+
+ /**
+ * Gets the user settings scale with the given display.
+ *
+ * @param displayId the id of the display
+ * @return the magnification scale.
+ */
+ float getScale(int displayId) {
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ return Settings.Secure.getFloatForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ DEFAULT_MAGNIFICATION_SCALE, mCurrentUserId);
+ } else {
+ synchronized (mLock) {
+ return getScalesWithCurrentUser().get(displayId, DEFAULT_MAGNIFICATION_SCALE);
+ }
+ }
+ }
+
+
+ @GuardedBy("mLock")
+ private SparseArray<Float> getScalesWithCurrentUser() {
+ SparseArray<Float> scales = mUsersScales.get(mCurrentUserId);
+ if (scales == null) {
+ scales = new SparseArray<>();
+ mUsersScales.put(mCurrentUserId, scales);
+ }
+
+ return scales;
+ }
+
+ void onUserChanged(int userId) {
+ synchronized (mLock) {
+ mCurrentUserId = userId;
+ }
+ }
+
+ void onUserRemoved(int userId) {
+ synchronized (mLock) {
+ mUsersScales.remove(userId);
+ }
+ }
+
+ void onDisplayRemoved(int displayId) {
+ synchronized (mLock) {
+ final int userCounts = mUsersScales.size();
+ for (int i = userCounts - 1; i >= 0; i--) {
+ mUsersScales.get(i).remove(displayId);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ synchronized (mLock) {
+ return "MagnificationScaleProvider{"
+ + "mCurrentUserId=" + mCurrentUserId
+ + "Scale on the default display=" + getScale(Display.DEFAULT_DISPLAY)
+ + "Scales on non-default displays=" + getScalesWithCurrentUser()
+ + '}';
+ }
+ }
+
+ static float constrainScale(float scale) {
+ return MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index bc61284f6084..7d8f545b65c3 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -69,7 +69,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
//Ensure the range has consistency with FullScreenMagnificationGestureHandler.
private static final float MIN_SCALE = 2.0f;
- private static final float MAX_SCALE = WindowMagnificationManager.MAX_SCALE;
+ private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE;
private final WindowMagnificationManager mWindowMagnificationMgr;
@VisibleForTesting
@@ -177,8 +177,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
}
final float scale = MathUtils.constrain(
- mWindowMagnificationMgr.getPersistedScale(),
- MIN_SCALE, MAX_SCALE);
+ mWindowMagnificationMgr.getPersistedScale(mDisplayId), MIN_SCALE, MAX_SCALE);
mWindowMagnificationMgr.enableWindowMagnification(mDisplayId, scale, centerX, centerY);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index 7a111d80b42e..ce7ba7568b6e 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -29,8 +29,6 @@ import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
-import android.provider.Settings;
-import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.view.MotionEvent;
@@ -40,7 +38,6 @@ import android.view.accessibility.MagnificationAnimationCallback;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -49,6 +46,8 @@ import com.android.server.statusbar.StatusBarManagerInternal;
* A class to manipulate window magnification through {@link WindowMagnificationConnectionWrapper}
* create by {@link #setConnection(IWindowMagnificationConnection)}. To set the connection with
* SysUI, call {@code StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)}.
+ * The applied magnification scale is constrained by
+ * {@link MagnificationScaleProvider#constrainScale(float)}
*/
public class WindowMagnificationManager implements
PanningScalingHandler.MagnificationDelegate {
@@ -57,10 +56,6 @@ public class WindowMagnificationManager implements
private static final String TAG = "WindowMagnificationMgr";
- //Ensure the range has consistency with full screen.
- static final float MAX_SCALE = FullScreenMagnificationController.MAX_SCALE;
- static final float MIN_SCALE = FullScreenMagnificationController.MIN_SCALE;
-
private final Object mLock = new Object();
private final Context mContext;
@VisibleForTesting
@@ -71,7 +66,6 @@ public class WindowMagnificationManager implements
private ConnectionCallback mConnectionCallback;
@GuardedBy("mLock")
private SparseArray<WindowMagnifier> mWindowMagnifiers = new SparseArray<>();
- private int mUserId;
private boolean mReceiverRegistered = false;
@VisibleForTesting
@@ -116,13 +110,14 @@ public class WindowMagnificationManager implements
private final Callback mCallback;
private final AccessibilityTraceManager mTrace;
+ private final MagnificationScaleProvider mScaleProvider;
public WindowMagnificationManager(Context context, int userId, @NonNull Callback callback,
- AccessibilityTraceManager trace) {
+ AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) {
mContext = context;
- mUserId = userId;
mCallback = callback;
mTrace = trace;
+ mScaleProvider = scaleProvider;
}
/**
@@ -159,15 +154,6 @@ public class WindowMagnificationManager implements
}
/**
- * Sets the currently active user ID.
- *
- * @param userId the currently active user ID
- */
- public void setUserId(int userId) {
- mUserId = userId;
- }
-
- /**
* @return {@code true} if {@link IWindowMagnificationConnection} is available
*/
public boolean isConnected() {
@@ -219,13 +205,18 @@ public class WindowMagnificationManager implements
return true;
}
- @GuardedBy("mLock")
- private void disableAllWindowMagnifiers() {
- for (int i = 0; i < mWindowMagnifiers.size(); i++) {
- final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i);
- magnifier.disableWindowMagnificationInternal(null);
+ /**
+ * Disables window magnifier on all displays without animation.
+ */
+ void disableAllWindowMagnifiers() {
+ synchronized (mLock) {
+ for (int i = 0; i < mWindowMagnifiers.size(); i++) {
+ final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i);
+ magnifier.disableWindowMagnificationInternal(null);
+ }
+ mWindowMagnifiers.clear();
}
- mWindowMagnifiers.clear();
+
}
private void resetWindowMagnifiers() {
@@ -378,29 +369,24 @@ public class WindowMagnificationManager implements
}
/**
- * Retrieves a previously persisted magnification scale from the current
- * user's settings.
+ * Retrieves a previously magnification scale from the current
+ * user's settings. Only the value of the default display is persisted.
*
- * @return the previously persisted magnification scale, or the default
+ * @return the previously magnification scale, or the default
* scale if none is available
*/
- float getPersistedScale() {
- return Settings.Secure.getFloatForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
- MIN_SCALE, mUserId);
+ float getPersistedScale(int displayId) {
+ return mScaleProvider.getScale(displayId);
}
/**
- * Persists the default display magnification scale to the current user's settings.
+ * Persists the default display magnification scale to the current user's settings. Only the
+ * value of the default display is persisted in user's settings.
*/
void persistScale(int displayId) {
-
float scale = getScale(displayId);
if (scale != 1.0f) {
- BackgroundThread.getHandler().post(() -> {
- Settings.Secure.putFloatForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale, mUserId);
- });
+ mScaleProvider.putScale(scale, displayId);
}
}
@@ -511,7 +497,7 @@ public class WindowMagnificationManager implements
*
* @param displayId The logical display id.
*/
- void onDisplayRemoved(int displayId) {
+ public void onDisplayRemoved(int displayId) {
disableWindowMagnification(displayId, true);
}
@@ -613,7 +599,7 @@ public class WindowMagnificationManager implements
private static class WindowMagnifier {
private final int mDisplayId;
- private float mScale = MIN_SCALE;
+ private float mScale = MagnificationScaleProvider.MIN_SCALE;
private boolean mEnabled;
private final WindowMagnificationManager mWindowMagnificationManager;
@@ -633,7 +619,7 @@ public class WindowMagnificationManager implements
if (mEnabled) {
return false;
}
- final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ final float normScale = MagnificationScaleProvider.constrainScale(scale);
if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale,
centerX, centerY, animationCallback)) {
mScale = normScale;
@@ -664,7 +650,7 @@ public class WindowMagnificationManager implements
if (!mEnabled) {
return;
}
- final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ final float normScale = MagnificationScaleProvider.constrainScale(scale);
if (Float.compare(mScale, normScale) != 0
&& mWindowMagnificationManager.setScaleInternal(mDisplayId, scale)) {
mScale = normScale;
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index c32543ae5c13..78d9095853f7 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -147,7 +147,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
OnCrossProfileWidgetProvidersChangeListener {
private static final String TAG = "AppWidgetServiceImpl";
- private static boolean DEBUG = false;
+ private static final boolean DEBUG = false;
private static final String OLD_KEYGUARD_HOST_PACKAGE = "android";
private static final String NEW_KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
diff --git a/services/core/java/android/content/pm/OWNERS b/services/core/java/android/content/pm/OWNERS
index 5eed0b509688..39931407ec1f 100644
--- a/services/core/java/android/content/pm/OWNERS
+++ b/services/core/java/android/content/pm/OWNERS
@@ -1 +1 @@
-include /core/java/android/content/pm/OWNERS \ No newline at end of file
+include /PACKAGE_MANAGER_OWNERS \ No newline at end of file
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 1e608f5c1240..0146aa82a217 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -81,8 +81,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
@@ -1435,11 +1433,7 @@ public final class BatteryService extends SystemService {
*/
public static final class HealthServiceWrapper {
private static final String TAG = "HealthServiceWrapper";
- public static final String INSTANCE_HEALTHD = "backup";
public static final String INSTANCE_VENDOR = "default";
- // All interesting instances, sorted by priority high -> low.
- private static final List<String> sAllInstances =
- Arrays.asList(INSTANCE_VENDOR, INSTANCE_HEALTHD);
private final IServiceNotification mNotification = new Notification();
private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceHwbinder");
@@ -1471,8 +1465,8 @@ public final class BatteryService extends SystemService {
}
/**
- * Start monitoring registration of new IHealth services. Only instances that are in
- * {@code sAllInstances} and in device / framework manifest are used. This function should
+ * Start monitoring registration of new IHealth services. Only instance
+ * {@link #INSTANCE_VENDOR} and in device / framework manifest are used. This function should
* only be called once.
*
* mCallback.onRegistration() is called synchronously (aka in init thread) before
@@ -1481,7 +1475,7 @@ public final class BatteryService extends SystemService {
* @throws RemoteException transaction error when talking to IServiceManager
* @throws NoSuchElementException if one of the following cases:
* - No service manager;
- * - none of {@code sAllInstances} are in manifests (i.e. not
+ * - {@link #INSTANCE_VENDOR} is not in manifests (i.e. not
* available on this device), or none of these instances are available to current
* process.
* @throws NullPointerException when supplier is null
@@ -1499,26 +1493,23 @@ public final class BatteryService extends SystemService {
// Initialize mLastService and call callback for the first time (in init thread)
IHealth newService = null;
- for (String name : sAllInstances) {
- traceBegin("HealthInitGetService_" + name);
- try {
- newService = healthSupplier.get(name);
- } catch (NoSuchElementException ex) {
- /* ignored, handled below */
- } finally {
- traceEnd();
- }
- if (newService != null) {
- mInstanceName = name;
- mLastService.set(newService);
- break;
- }
+ traceBegin("HealthInitGetService_" + INSTANCE_VENDOR);
+ try {
+ newService = healthSupplier.get(INSTANCE_VENDOR);
+ } catch (NoSuchElementException ex) {
+ /* ignored, handled below */
+ } finally {
+ traceEnd();
+ }
+ if (newService != null) {
+ mInstanceName = INSTANCE_VENDOR;
+ mLastService.set(newService);
}
if (mInstanceName == null || newService == null) {
throw new NoSuchElementException(String.format(
- "No IHealth service instance among %s is available. Perhaps no permission?",
- sAllInstances.toString()));
+ "IHealth service instance %s isn't available. Perhaps no permission?",
+ INSTANCE_VENDOR));
}
if (callback != null) {
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 39321bfe6435..99232746cea1 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -301,17 +301,20 @@ public abstract class SystemService {
protected void dumpSupportedUsers(@NonNull PrintWriter pw, @NonNull String prefix) {
final List<UserInfo> allUsers = UserManager.get(mContext).getUsers();
final List<Integer> supportedUsers = new ArrayList<>(allUsers.size());
- for (UserInfo user : allUsers) {
- supportedUsers.add(user.id);
+ for (int i = 0; i < allUsers.size(); i++) {
+ final UserInfo user = allUsers.get(i);
+ if (isUserSupported(new TargetUser(user))) {
+ supportedUsers.add(user.id);
+ }
}
- if (allUsers.isEmpty()) {
+ if (supportedUsers.isEmpty()) {
pw.print(prefix); pw.println("No supported users");
- } else {
- final int size = supportedUsers.size();
- pw.print(prefix); pw.print(size); pw.print(" supported user");
- if (size > 1) pw.print("s");
- pw.print(": "); pw.println(supportedUsers);
+ return;
}
+ final int size = supportedUsers.size();
+ pw.print(prefix); pw.print(size); pw.print(" supported user");
+ if (size > 1) pw.print("s");
+ pw.print(": "); pw.println(supportedUsers);
}
/**
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 031f6eeeca5f..61b8ded60db7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -168,6 +168,10 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
return Utils.isKeyguard(getContext(), getOwnerString());
}
+ private boolean isSettings() {
+ return Utils.isSettings(getContext(), getOwnerString());
+ }
+
@Override
protected boolean isCryptoOperation() {
return mOperationId != 0;
@@ -499,6 +503,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
protected int getShowOverlayReason() {
if (isKeyguard()) {
return BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
+ } else if (isSettings()) {
+ return BiometricOverlayConstants.REASON_AUTH_SETTINGS;
} else if (isBiometricPrompt()) {
return BiometricOverlayConstants.REASON_AUTH_BP;
} else {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index ca051e9e9bf4..e4d5fba3a471 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -229,6 +229,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
@Override
public void onLockoutTimed(long durationMillis) {
+ super.onLockoutTimed(durationMillis);
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
// Lockout metrics are logged as an error code.
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
@@ -246,6 +247,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
@Override
public void onLockoutPermanent() {
+ super.onLockoutPermanent();
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
// Lockout metrics are logged as an error code.
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index 147050cd271f..2f22d33f552a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -48,7 +48,7 @@ import java.io.PrintWriter;
final class DisplayPowerState {
private static final String TAG = "DisplayPowerState";
- private static boolean DEBUG = false;
+ private static final boolean DEBUG = false;
private static String COUNTER_COLOR_FADE = "ColorFadeLevel";
private final Handler mHandler;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index f356c36f7468..3aa2f420d11f 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -208,6 +208,12 @@ abstract class HdmiCecLocalDevice {
void init() {
assertRunOnServiceThread();
mPreferredAddress = getPreferredAddress();
+ if (mHandler.hasMessages(MSG_DISABLE_DEVICE_TIMEOUT)) {
+ // Remove and trigger the queued message for clearing all actions when going to standby.
+ // This is necessary because the device may wake up before the message is triggered.
+ mHandler.removeMessages(MSG_DISABLE_DEVICE_TIMEOUT);
+ handleDisableDeviceTimeout();
+ }
mPendingActionClearedCallback = null;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b5bb8bd3ae1a..69f7af23fe4c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -3166,7 +3166,7 @@ public class HdmiControlService extends SystemService {
Slog.v(TAG, "On standby-action cleared:" + device.mDeviceType);
devices.remove(device);
if (devices.isEmpty()) {
- onStandbyCompleted(standbyAction);
+ onPendingActionsCleared(standbyAction);
// We will not clear local devices here, since some OEM/SOC will keep passing
// the received packets until the application processor enters to the sleep
// actually.
@@ -3227,10 +3227,17 @@ public class HdmiControlService extends SystemService {
mHdmiCecNetwork.clearLocalDevices();
}
+ /**
+ * Normally called after all devices have cleared their pending actions, to execute the final
+ * phase of the standby flow.
+ *
+ * This can also be called during wakeup, when pending actions are cleared after failing to be
+ * cleared during standby. In this case, it does not execute the standby flow.
+ */
@ServiceThreadOnly
- private void onStandbyCompleted(int standbyAction) {
+ private void onPendingActionsCleared(int standbyAction) {
assertRunOnServiceThread();
- Slog.v(TAG, "onStandbyCompleted");
+ Slog.v(TAG, "onPendingActionsCleared");
if (!mPowerStatusController.isPowerStatusTransientToStandby()) {
return;
diff --git a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
index d285c437a3df..487346763f0f 100644
--- a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
+++ b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
@@ -40,7 +40,7 @@ import java.util.Set;
* Monitors the state changes of audio players.
*/
class AudioPlayerStateMonitor {
- private static boolean DEBUG = MediaSessionService.DEBUG;
+ private static final boolean DEBUG = MediaSessionService.DEBUG;
private static String TAG = "AudioPlayerStateMonitor";
private static AudioPlayerStateMonitor sInstance;
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 3233819b543f..babe21c87a86 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -3,11 +3,9 @@ hackbod@google.com
jsharkey@android.com
jsharkey@google.com
narayan@google.com
-patb@google.com
svetoslavganov@android.com
svetoslavganov@google.com
-toddke@android.com
-toddke@google.com
+include /PACKAGE_MANAGER_OWNERS
# apex support
per-file ApexManager.java = dariofreni@google.com, ioffe@google.com, olilan@google.com
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c953166ba814..89e47b9cbe04 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8916,7 +8916,8 @@ public class PackageManagerService extends IPackageManager.Stub
* return {@code true} if any one application belongs to the shared user ID meets the criteria.
*/
boolean canQueryPackage(int callingUid, @Nullable String targetPackageName) {
- if (targetPackageName == null) {
+ // Since getSettingLPr returns null for ROOT_UID, add an extra check for it here.
+ if (callingUid == Process.ROOT_UID || targetPackageName == null) {
return true;
}
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index c8deffbf257a..d54acb7d6bd6 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -21,9 +21,6 @@
"name": "CtsAppEnumerationTestCases"
},
{
- "name": "AppEnumerationInternalTests"
- },
- {
"name": "CtsMatchFlagTestCases"
},
{
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 2cb9d76b6846..0590e22f012d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2937,6 +2937,24 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in"
+ " interceptKeyBeforeQueueing");
return key_consumed;
+ case KeyEvent.KEYCODE_VIDEO_APP_1:
+ case KeyEvent.KEYCODE_VIDEO_APP_2:
+ case KeyEvent.KEYCODE_VIDEO_APP_3:
+ case KeyEvent.KEYCODE_VIDEO_APP_4:
+ case KeyEvent.KEYCODE_VIDEO_APP_5:
+ case KeyEvent.KEYCODE_VIDEO_APP_6:
+ case KeyEvent.KEYCODE_VIDEO_APP_7:
+ case KeyEvent.KEYCODE_VIDEO_APP_8:
+ case KeyEvent.KEYCODE_FEATURED_APP_1:
+ case KeyEvent.KEYCODE_FEATURED_APP_2:
+ case KeyEvent.KEYCODE_FEATURED_APP_3:
+ case KeyEvent.KEYCODE_FEATURED_APP_4:
+ case KeyEvent.KEYCODE_DEMO_APP_1:
+ case KeyEvent.KEYCODE_DEMO_APP_2:
+ case KeyEvent.KEYCODE_DEMO_APP_3:
+ case KeyEvent.KEYCODE_DEMO_APP_4:
+ Slog.wtf(TAG, "KEYCODE_APP_X should be handled in interceptKeyBeforeQueueing");
+ return key_consumed;
case KeyEvent.KEYCODE_SYSRQ:
if (down && repeatCount == 0) {
mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
@@ -4040,6 +4058,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
break;
}
+ case KeyEvent.KEYCODE_VIDEO_APP_1:
+ case KeyEvent.KEYCODE_VIDEO_APP_2:
+ case KeyEvent.KEYCODE_VIDEO_APP_3:
+ case KeyEvent.KEYCODE_VIDEO_APP_4:
+ case KeyEvent.KEYCODE_VIDEO_APP_5:
+ case KeyEvent.KEYCODE_VIDEO_APP_6:
+ case KeyEvent.KEYCODE_VIDEO_APP_7:
+ case KeyEvent.KEYCODE_VIDEO_APP_8:
+ case KeyEvent.KEYCODE_FEATURED_APP_1:
+ case KeyEvent.KEYCODE_FEATURED_APP_2:
+ case KeyEvent.KEYCODE_FEATURED_APP_3:
+ case KeyEvent.KEYCODE_FEATURED_APP_4:
+ case KeyEvent.KEYCODE_DEMO_APP_1:
+ case KeyEvent.KEYCODE_DEMO_APP_2:
+ case KeyEvent.KEYCODE_DEMO_APP_3:
+ case KeyEvent.KEYCODE_DEMO_APP_4: {
+ // Just drop if keys are not intercepted for direct key.
+ result &= ~ACTION_PASS_TO_USER;
+ break;
+ }
}
// Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
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 0fcf458ba535..0c7849468b96 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -2069,7 +2069,7 @@ public class StatsPullAtomService extends SystemService {
if (info == null) {
return StatsManager.PULL_SKIP;
}
- pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, info.getTimeStamp(),
+ pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, info.getTimestampMillis(),
info.getBluetoothStackState(), info.getControllerTxTimeMillis(),
info.getControllerRxTimeMillis(), info.getControllerIdleTimeMillis(),
info.getControllerEnergyUsed()));
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 0f37450c24c9..e98fa28634a4 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -86,6 +86,9 @@ public final class TextClassificationManagerService extends ITextClassifierServi
private static final String LOG_TAG = "TextClassificationManagerService";
+ // TODO: consider using device config to control it.
+ private static final boolean DEBUG = false;
+
private static final ITextClassifierCallback NO_OP_CALLBACK = new ITextClassifierCallback() {
@Override
public void onSuccess(Bundle result) {}
@@ -175,8 +178,6 @@ public final class TextClassificationManagerService extends ITextClassifierServi
private final String mDefaultTextClassifierPackage;
@Nullable
private final String mSystemTextClassifierPackage;
- // TODO: consider using device config to control it.
- private boolean DEBUG = false;
private TextClassificationManagerService(Context context) {
mContext = Objects.requireNonNull(context);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 50f3d8b25c92..3de4cdc930e5 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4109,19 +4109,40 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* conditions a) above.
* Multi-windowing mode will be exited if {@code true} is returned.
*/
- boolean canShowWhenLocked() {
- if (!inPinnedWindowingMode() && (mShowWhenLocked || containsShowWhenLockedWindow())) {
+ private static boolean canShowWhenLocked(ActivityRecord r) {
+ if (r == null || r.getTaskFragment() == null) {
+ return false;
+ }
+ if (!r.inPinnedWindowingMode() && (r.mShowWhenLocked || r.containsShowWhenLockedWindow())) {
return true;
- } else if (mInheritShownWhenLocked) {
- final ActivityRecord r = task.getActivityBelow(this);
- return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
- || r.containsShowWhenLockedWindow());
+ } else if (r.mInheritShownWhenLocked) {
+ final ActivityRecord activity = r.getTaskFragment().getActivityBelow(r);
+ return activity != null && !activity.inPinnedWindowingMode()
+ && (activity.mShowWhenLocked || activity.containsShowWhenLockedWindow());
} else {
return false;
}
}
/**
+ * Determines if the activity can show while lock-screen is displayed. System displays
+ * activities while lock-screen is displayed only if all activities
+ * {@link #canShowWhenLocked(ActivityRecord)}.
+ * @see #canShowWhenLocked(ActivityRecord)
+ */
+ boolean canShowWhenLocked() {
+ final TaskFragment taskFragment = getTaskFragment();
+ if (taskFragment != null && taskFragment.getAdjacentTaskFragment() != null
+ && taskFragment.isEmbedded()) {
+ final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
+ final ActivityRecord r = adjacentTaskFragment.getTopNonFinishingActivity();
+ return canShowWhenLocked(this) && canShowWhenLocked(r);
+ } else {
+ return canShowWhenLocked(this);
+ }
+ }
+
+ /**
* @return Whether we are allowed to show non-starting windows at the moment. We disallow
* showing windows during transitions in case we have windows that have wide-color-gamut
* color mode set to avoid jank in the middle of the transition.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 25a5708f3b4b..52546affa51e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -804,13 +804,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
};
private final Consumer<WindowState> mPerformLayout = w -> {
+ if (w.mLayoutAttached || w.skipLayout()) {
+ return;
+ }
+
// Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
// wasting time and funky changes while a window is animating away.
final boolean gone = w.isGoneForLayout();
- if (DEBUG_LAYOUT && !w.mLayoutAttached) {
+ if (DEBUG_LAYOUT) {
Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame
- + " mLayoutAttached=" + w.mLayoutAttached
+ " config reported=" + w.isLastConfigReportedToClient());
final ActivityRecord activity = w.mActivityRecord;
if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility
@@ -826,7 +829,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// If this view is GONE, then skip it -- keep the current frame, and let the caller know
// so they can ignore it if they want. (We do the normal layout for INVISIBLE windows,
// since that means "perform layout as normal, just don't display").
- if ((!gone || !w.mHaveFrame || w.mLayoutNeeded) && !w.mLayoutAttached) {
+ if (!gone || !w.mHaveFrame || w.mLayoutNeeded) {
if (mTmpInitial) {
w.resetContentChanged();
}
@@ -853,34 +856,34 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrame()
- + " mContainingFrame=" + w.getContainingFrame()
+ + " mParentFrame=" + w.getParentFrame()
+ " mDisplayFrame=" + w.getDisplayFrame());
}
};
private final Consumer<WindowState> mPerformLayoutAttached = w -> {
- if (w.mLayoutAttached) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
- + " mViewVisibility=" + w.mViewVisibility
- + " mRelayoutCalled=" + w.mRelayoutCalled);
- // If this view is GONE, then skip it -- keep the current frame, and let the caller
- // know so they can ignore it if they want. (We do the normal layout for INVISIBLE
- // windows, since that means "perform layout as normal, just don't display").
- if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame
- || w.mLayoutNeeded) {
- if (mTmpInitial) {
- //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
- w.resetContentChanged();
- }
- w.mSurfacePlacementNeeded = true;
- w.mLayoutNeeded = false;
- w.prelayout();
- getDisplayPolicy().layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
- w.mLayoutSeq = mLayoutSeq;
- if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrame()
- + " mContainingFrame=" + w.getContainingFrame()
- + " mDisplayFrame=" + w.getDisplayFrame());
+ if (!w.mLayoutAttached || w.skipLayout()) {
+ return;
+ }
+ if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
+ + " mViewVisibility=" + w.mViewVisibility
+ + " mRelayoutCalled=" + w.mRelayoutCalled);
+ // If this view is GONE, then skip it -- keep the current frame, and let the caller
+ // know so they can ignore it if they want. (We do the normal layout for INVISIBLE
+ // windows, since that means "perform layout as normal, just don't display").
+ if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame
+ || w.mLayoutNeeded) {
+ if (mTmpInitial) {
+ w.resetContentChanged();
}
+ w.mSurfacePlacementNeeded = true;
+ w.mLayoutNeeded = false;
+ w.prelayout();
+ getDisplayPolicy().layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
+ w.mLayoutSeq = mLayoutSeq;
+ if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrame()
+ + " mParentFrame=" + w.getParentFrame()
+ + " mDisplayFrame=" + w.getDisplayFrame());
}
};
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 253b3a529f67..750c890ec066 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -43,12 +43,12 @@ import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_B
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
+import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -65,7 +65,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
@@ -115,6 +114,7 @@ import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
+import android.gui.DropInputMode;
import android.hardware.power.Boost;
import android.os.Handler;
import android.os.IBinder;
@@ -962,6 +962,20 @@ public class DisplayPolicy {
}
/**
+ * Add additional policy if needed to ensure the window or its children should not receive any
+ * input.
+ */
+ public void setDropInputModePolicy(WindowState win, LayoutParams attrs) {
+ if (attrs.type == TYPE_TOAST
+ && (attrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) == 0) {
+ // Toasts should not receive input. These windows should not have any children, so
+ // force this hierarchy of windows to drop all input.
+ mService.mTransactionFactory.get()
+ .setDropInputMode(win.getSurfaceControl(), DropInputMode.ALL).apply();
+ }
+ }
+
+ /**
* Check if a window can be added to the system.
*
* Currently enforces that two window types are singletons per display:
@@ -1704,10 +1718,6 @@ public class DisplayPolicy {
layoutStatusBar(displayFrames, mBarContentFrames.get(TYPE_STATUS_BAR));
return;
}
- if (win.mActivityRecord != null && win.mActivityRecord.mWaitForEnteringPinnedMode) {
- // Skip layout of the window when in transition to pip mode.
- return;
- }
final WindowManager.LayoutParams attrs = win.getLayoutingAttrs(displayFrames.mRotation);
final int type = attrs.type;
@@ -1719,37 +1729,50 @@ public class DisplayPolicy {
final Rect pf = windowFrames.mParentFrame;
final Rect df = windowFrames.mDisplayFrame;
+ final Rect f = windowFrames.mFrame;
final Rect attachedWindowFrame = attached != null ? attached.getFrame() : null;
sTmpLastParentFrame.set(pf);
- // Override the bounds in window token has many side effects. Directly use the display
- // frame set for the simulated layout for this case.
- final Rect winBounds = windowFrames.mIsSimulatingDecorWindow ? df : win.getBounds();
+ final Rect winBounds;
+ final int requestedWidth;
+ final int requestedHeight;
+ if (windowFrames.mIsSimulatingDecorWindow) {
+ // Override the bounds in window token has many side effects. Directly use the display
+ // frame set for the simulated layout.
+ winBounds = df;
+
+ // The view hierarchy has not been measured in the simulated layout. Use
+ // UNSPECIFIED_LENGTH as the requested width and height so that WindowLayout will choose
+ // the proper values in this case.
+ requestedWidth = UNSPECIFIED_LENGTH;
+ requestedHeight = UNSPECIFIED_LENGTH;
+ } else {
+ winBounds = win.getBounds();
+ requestedWidth = win.mRequestedWidth;
+ requestedHeight = win.mRequestedHeight;
+ }
final boolean clippedByDisplayCutout = mWindowLayout.computeWindowFrames(attrs,
- win.getInsetsState(), displayFrames.mDisplayCutoutSafe, winBounds,
- win.getRequestedVisibilities(), attachedWindowFrame, df, pf);
+ win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
+ winBounds, win.getWindowingMode(), requestedWidth, requestedHeight,
+ win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
+ df, pf, f);
windowFrames.setParentFrameWasClippedByDisplayCutout(clippedByDisplayCutout);
- // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
- // Also, we don't allow windows in multi-window mode to extend out of the screen.
- if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && type != TYPE_SYSTEM_ERROR
- && !win.inMultiWindowMode()) {
- df.left = df.top = -10000;
- df.right = df.bottom = 10000;
- }
-
if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
+ ": sim=#" + Integer.toHexString(sim)
+ " attach=" + attached + " type=" + type
- + String.format(" flags=0x%08x", fl)
- + " pf=" + pf.toShortString() + " df=" + df.toShortString());
+ + " flags=" + ViewDebug.flagsToString(LayoutParams.class, "flags", fl)
+ + " pf=" + pf.toShortString() + " df=" + df.toShortString()
+ + " f=" + f.toShortString());
if (!sTmpLastParentFrame.equals(pf)) {
windowFrames.setContentChanged(true);
}
- win.computeFrameAndUpdateSourceFrame(displayFrames);
+ if (!windowFrames.mIsSimulatingDecorWindow) {
+ win.setFrame();
+ }
}
WindowState getTopFullscreenOpaqueWindow() {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 96c935af9d5a..63246aca2587 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -392,7 +392,7 @@ class TaskSnapshotController {
final WindowState imeWindow = task.getDisplayContent().mInputMethodWindow;
SurfaceControl.ScreenshotHardwareBuffer imeBuffer = null;
if (imeWindow != null && imeWindow.isWinVisibleLw()) {
- final Rect bounds = imeWindow.getContainingFrame();
+ final Rect bounds = imeWindow.getParentFrame();
bounds.offsetTo(0, 0);
imeBuffer = SurfaceControl.captureLayersExcluding(imeWindow.getSurfaceControl(),
bounds, 1.0f, pixelFormat, null);
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index baea85439582..c3d3c8225055 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import static com.android.server.wm.WindowFramesProto.COMPAT_FRAME;
-import static com.android.server.wm.WindowFramesProto.CONTAINING_FRAME;
import static com.android.server.wm.WindowFramesProto.DISPLAY_FRAME;
import static com.android.server.wm.WindowFramesProto.FRAME;
import static com.android.server.wm.WindowFramesProto.PARENT_FRAME;
@@ -37,32 +36,16 @@ public class WindowFrames {
private static final StringBuilder sTmpSB = new StringBuilder();
/**
- * In most cases, this is the area of the entire screen.
- *
- * TODO(b/111611553): The name is unclear and most likely should be swapped with
- * {@link #mDisplayFrame}
- * TODO(b/111611553): In some cases, it also includes top insets, like for IME. Determine
- * whether this is still necessary to do.
+ * The frame to be referenced while applying gravity and MATCH_PARENT.
*/
public final Rect mParentFrame = new Rect();
/**
- * The entire screen area of the {@link Task} this window is in. Usually equal to the
- * screen area of the device.
- *
- * TODO(b/111611553): The name is unclear and most likely should be swapped with
- * {@link #mParentFrame}
+ * The bounds that the window should fit.
*/
public final Rect mDisplayFrame = new Rect();
/**
- * Similar to {@link #mDisplayFrame}
- *
- * TODO: Why is this different than mDisplayFrame
- */
- final Rect mContainingFrame = new Rect();
-
- /**
* "Real" frame that the application sees, in display coordinate space.
*/
final Rect mFrame = new Rect();
@@ -124,10 +107,6 @@ public class WindowFrames {
return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height());
}
- void offsetFrames(int layoutXDiff, int layoutYDiff) {
- mFrame.offset(layoutXDiff, layoutYDiff);
- }
-
/**
* Updates info about whether the size of the window has changed since last reported.
*
@@ -188,16 +167,13 @@ public class WindowFrames {
final long token = proto.start(fieldId);
mParentFrame.dumpDebug(proto, PARENT_FRAME);
mDisplayFrame.dumpDebug(proto, DISPLAY_FRAME);
- mContainingFrame.dumpDebug(proto, CONTAINING_FRAME);
mFrame.dumpDebug(proto, FRAME);
mCompatFrame.dumpDebug(proto, COMPAT_FRAME);
proto.end(token);
}
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "Frames: containing="
- + mContainingFrame.toShortString(sTmpSB)
- + " parent=" + mParentFrame.toShortString(sTmpSB)
+ pw.println(prefix + "Frames: parent=" + mParentFrame.toShortString(sTmpSB)
+ " display=" + mDisplayFrame.toShortString(sTmpSB));
pw.println(prefix + "mFrame=" + mFrame.toShortString(sTmpSB)
+ " last=" + mLastFrame.toShortString(sTmpSB));
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c4a518395eea..5d916eaa4bf7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1783,6 +1783,7 @@ public class WindowManagerService extends IWindowManager.Stub
win.mToken.addWindow(win);
displayPolicy.addWindowLw(win, attrs);
+ displayPolicy.setDropInputModePolicy(win, win.mAttrs);
if (type == TYPE_APPLICATION_STARTING && activity != null) {
activity.attachStartingWindow(win);
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a5f812f15ad5..65389f0385d5 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -38,10 +38,9 @@ import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE;
-import static android.view.WindowInsets.Type.displayCutout;
-import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
@@ -49,7 +48,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
@@ -224,7 +222,6 @@ import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayInfo;
-import android.view.Gravity;
import android.view.IWindow;
import android.view.IWindowFocusObserver;
import android.view.IWindowId;
@@ -473,9 +470,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
/** The frames used to compute a temporal layout appearance. */
private WindowFrames mSimulatedWindowFrames;
- /** Usually the same as {@link #getBounds()}. */
- private final Rect mInsetFrame = new Rect();
-
/**
* List of rects where system gestures should be ignored.
*
@@ -1138,10 +1132,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWinAnimator = new WindowStateAnimator(this);
mWinAnimator.mAlpha = a.alpha;
- mRequestedWidth = 0;
- mRequestedHeight = 0;
- mLastRequestedWidth = 0;
- mLastRequestedHeight = 0;
+ mRequestedWidth = UNSPECIFIED_LENGTH;
+ mRequestedHeight = UNSPECIFIED_LENGTH;
+ mLastRequestedWidth = UNSPECIFIED_LENGTH;
+ mLastRequestedHeight = UNSPECIFIED_LENGTH;
mLayer = 0;
mOverrideScale = mWmService.mAtmService.mCompatModePackages.getCompatScale(
mAttrs.packageName, s.mUid);
@@ -1244,136 +1238,26 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mSession.mCanAcquireSleepToken;
}
- /**
- * Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame}
- * from {@param frame}. In other words, it applies the insets that would result if
- * {@param frame} would be shifted to {@param layoutFrame} and then applying the insets from
- * {@param insetFrame}. Also it respects {@param displayFrame} in case window has minimum
- * width/height applied and insets should be overridden.
- */
- private void subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame, Rect displayFrame) {
- final int left = Math.max(0, insetFrame.left - Math.max(layoutFrame.left, displayFrame.left));
- final int top = Math.max(0, insetFrame.top - Math.max(layoutFrame.top, displayFrame.top));
- final int right = Math.max(0, Math.min(layoutFrame.right, displayFrame.right) - insetFrame.right);
- final int bottom = Math.max(0, Math.min(layoutFrame.bottom, displayFrame.bottom) - insetFrame.bottom);
- frame.inset(left, top, right, bottom);
- }
-
- void computeFrameAndUpdateSourceFrame(DisplayFrames displayFrames) {
- computeFrame(displayFrames);
- // Update the source frame to provide insets to other windows during layout. If the
- // simulated frames exist, then this is not computing a stable result so just skip.
- if (mControllableInsetProvider != null && mSimulatedWindowFrames == null) {
- mControllableInsetProvider.updateSourceFrame();
- }
- }
-
- /**
- * Perform standard frame computation. The result can be obtained with getFrame() if so desired.
- */
- void computeFrame(DisplayFrames displayFrames) {
+ boolean skipLayout() {
if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
// This window is being replaced and either already got information that it's being
// removed or we are still waiting for some information. Because of this we don't
// want to apply any more changes to it, so it remains in this state until new window
// appears.
- return;
+ return true;
}
- mHaveFrame = true;
-
- final Task task = getTask();
- final boolean isFullscreenAndFillsArea = !inMultiWindowMode() && matchesDisplayAreaBounds();
- final boolean windowsAreFloating = task != null && task.isFloating();
- final DisplayContent dc = getDisplayContent();
- final DisplayInfo displayInfo = getDisplayInfo();
- final WindowFrames windowFrames = getLayoutingWindowFrames();
-
- mInsetFrame.set(getBounds());
-
- // Denotes the actual frame used to calculate the insets and to perform the layout. When
- // resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the
- // insets temporarily. By the notion of a task having a different layout frame, we can
- // achieve that while still moving the task around.
- final Rect layoutContainingFrame;
- final Rect layoutDisplayFrame;
-
- // The offset from the layout containing frame to the actual containing frame.
- final int layoutXDiff;
- final int layoutYDiff;
- final WindowState imeWin = mWmService.mRoot.getCurrentInputMethodWindow();
- final InsetsControlTarget imeTarget = dc.getImeTarget(IME_TARGET_LAYERING);
- final boolean isInputMethodAdjustTarget = windowsAreFloating
- ? imeTarget != null && task == imeTarget.getWindow().getTask()
- : isImeLayeringTarget();
- final boolean isImeTarget =
- imeWin != null && imeWin.isVisibleNow() && isInputMethodAdjustTarget;
- if (isFullscreenAndFillsArea || layoutInParentFrame()) {
- // We use the parent frame as the containing frame for fullscreen and child windows
- windowFrames.mContainingFrame.set(windowFrames.mParentFrame);
- layoutDisplayFrame = windowFrames.mDisplayFrame;
- layoutContainingFrame = windowFrames.mParentFrame;
- layoutXDiff = 0;
- layoutYDiff = 0;
- } else {
- windowFrames.mContainingFrame.set(getBounds());
- // IME is up and obscuring this window. Adjust the window position so it is visible.
- if (isImeTarget) {
- if (inFreeformWindowingMode()) {
- // Push the freeform window up to make room for the IME. However, don't push
- // it up past the bottom of the top bar.
- final InsetsState state = dc.getInsetsStateController().getRawInsetsState();
- final Rect visibleFrame = mTmpRect;
- visibleFrame.set(state.getDisplayFrame());
- visibleFrame.inset(state.calculateInsets(visibleFrame,
- systemBars() | ime() | displayCutout(), false /* ignoreVisibility */));
- final int bottomOverlap =
- windowFrames.mContainingFrame.bottom - visibleFrame.bottom;
- if (bottomOverlap > 0) {
- final int distanceToTop = Math.max(windowFrames.mContainingFrame.top
- - visibleFrame.top, 0);
- int offs = Math.min(bottomOverlap, distanceToTop);
- windowFrames.mContainingFrame.offset(0, -offs);
- mInsetFrame.offset(0, -offs);
- }
- } else if (!inPinnedWindowingMode() && windowFrames.mContainingFrame.bottom
- > windowFrames.mParentFrame.bottom) {
- // But in docked we want to behave like fullscreen and behave as if the task
- // were given smaller bounds for the purposes of layout. Skip adjustments for
- // the root pinned task, they are handled separately in the
- // PinnedTaskController.
- windowFrames.mContainingFrame.bottom = windowFrames.mParentFrame.bottom;
- }
- }
+ // Skip layout of the window when in transition to pip mode.
+ return mActivityRecord != null && mActivityRecord.mWaitForEnteringPinnedMode;
+ }
- if (windowsAreFloating) {
- // In floating modes (e.g. freeform, pinned) we have only to set the rectangle
- // if it wasn't set already. No need to intersect it with the (visible)
- // "content frame" since it is allowed to be outside the visible desktop.
- if (windowFrames.mContainingFrame.isEmpty()) {
- windowFrames.mContainingFrame.set(windowFrames.mDisplayFrame);
- }
- }
+ // TODO(b/161810301): Make the frame be passed from the client side.
+ void setFrame() {
+ // TODO(b/161810301): Set the window frame here. We don't have to do it now because
+ // DisplayPolicy has already done it for the window.
- layoutDisplayFrame = mTmpRect2;
- layoutDisplayFrame.set(windowFrames.mDisplayFrame);
- windowFrames.mDisplayFrame.set(windowFrames.mContainingFrame);
- layoutXDiff = mInsetFrame.left - windowFrames.mContainingFrame.left;
- layoutYDiff = mInsetFrame.top - windowFrames.mContainingFrame.top;
- layoutContainingFrame = mInsetFrame;
- mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
- subtractInsets(windowFrames.mDisplayFrame, layoutContainingFrame, layoutDisplayFrame,
- mTmpRect);
- if (!layoutInParentFrame()) {
- subtractInsets(windowFrames.mContainingFrame, layoutContainingFrame,
- windowFrames.mParentFrame, mTmpRect);
- subtractInsets(mInsetFrame, layoutContainingFrame, windowFrames.mParentFrame,
- mTmpRect);
- }
- layoutDisplayFrame.intersect(layoutContainingFrame);
- }
+ mHaveFrame = true;
- final int pw = windowFrames.mContainingFrame.width();
- final int ph = windowFrames.mContainingFrame.height();
+ final WindowFrames windowFrames = mWindowFrames;
if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
mLastRequestedWidth = mRequestedWidth;
@@ -1381,21 +1265,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
windowFrames.setContentChanged(true);
}
- final int fw = windowFrames.mFrame.width();
- final int fh = windowFrames.mFrame.height();
-
- applyGravityAndUpdateFrame(windowFrames, layoutContainingFrame, layoutDisplayFrame,
- displayFrames);
-
- if (mAttrs.type == TYPE_DOCK_DIVIDER) {
- if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {
- mMovedByResize = true;
- }
- }
-
- // Offset the actual frame by the amount layout frame is off.
- windowFrames.offsetFrames(-layoutXDiff, -layoutYDiff);
-
windowFrames.mCompatFrame.set(windowFrames.mFrame);
if (hasCompatScale()) {
// Also the scaled frame that we report to the app needs to be
@@ -1403,14 +1272,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
windowFrames.mCompatFrame.scale(mInvGlobalScale);
}
- if (mIsWallpaper && (fw != windowFrames.mFrame.width()
- || fh != windowFrames.mFrame.height())) {
- dc.mWallpaperController.updateWallpaperOffset(this, false /* sync */);
- }
-
// Calculate relative frame
windowFrames.mRelFrame.set(windowFrames.mFrame);
- WindowContainer parent = getParent();
+ WindowContainer<?> parent = getParent();
int parentLeft = 0;
int parentTop = 0;
if (mIsChildWindow) {
@@ -1425,14 +1289,39 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
windowFrames.mFrame.top - parentTop);
if (DEBUG_LAYOUT || DEBUG) {
+ final int pw = windowFrames.mParentFrame.width();
+ final int ph = windowFrames.mParentFrame.height();
Slog.v(TAG, "Resolving (mRequestedWidth="
- + mRequestedWidth + ", mRequestedheight="
- + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
- + "): frame=" + windowFrames.mFrame.toShortString()
- + " " + mAttrs.getTitle());
+ + mRequestedWidth + ", mRequestedheight="
+ + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
+ + "): frame=" + windowFrames.mFrame.toShortString()
+ + " " + mAttrs.getTitle());
+ }
+
+ if (mAttrs.type == TYPE_DOCK_DIVIDER) {
+ if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {
+ mMovedByResize = true;
+ }
+ }
+
+ if (mIsWallpaper) {
+ final Rect lastFrame = windowFrames.mLastFrame;
+ final Rect frame = windowFrames.mFrame;
+ if (lastFrame.width() != frame.width() || lastFrame.height() != frame.height()) {
+ mDisplayContent.mWallpaperController.updateWallpaperOffset(this, false /* sync */);
+ }
+ }
+
+ // Update the source frame to provide insets to other windows during layout.
+ if (mControllableInsetProvider != null) {
+ mControllableInsetProvider.updateSourceFrame();
}
}
+ // TODO(b/161810301): Remove this after INSETS_LAYOUT_GENERALIZATION is removed.
+ void computeFrameAndUpdateSourceFrame(DisplayFrames displayFrames) {
+ }
+
@Override
public Rect getBounds() {
// The window bounds are used for layout in screen coordinates. If the token has bounds for
@@ -1463,10 +1352,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mWindowFrames.mParentFrame;
}
- Rect getContainingFrame() {
- return mWindowFrames.mContainingFrame;
- }
-
void getCompatFrameSize(Rect outFrame) {
outFrame.set(0, 0, mWindowFrames.mCompatFrame.width(), mWindowFrames.mCompatFrame.height());
}
@@ -4023,11 +3908,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return getDisplayContent().mCurrentFocus == this;
}
- /** Is this window in a container that takes up the entire screen space? */
- private boolean inAppWindowThatMatchesParentBounds() {
- return mActivityRecord == null || (mActivityRecord.matchParentBounds() && !inMultiWindowMode());
- }
-
/**
* @return true if activity bounds are letterboxed or letterboxed for diplay cutout.
*
@@ -4402,98 +4282,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mStringNameCache;
}
- private void applyGravityAndUpdateFrame(WindowFrames windowFrames, Rect containingFrame,
- Rect displayFrame, DisplayFrames displayFrames) {
- final int pw = containingFrame.width();
- final int ph = containingFrame.height();
- final Task task = getTask();
- final boolean inNonFullscreenContainer = !inAppWindowThatMatchesParentBounds();
- final WindowManager.LayoutParams attrs = getLayoutingAttrs(displayFrames.mRotation);
- final boolean noLimits = (attrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0;
-
- // We need to fit it to the display if either
- // a) The window is in a fullscreen container, or we don't have a task (we assume fullscreen
- // for the taskless windows)
- // b) If it's a secondary app window, we also need to fit it to the display unless
- // FLAG_LAYOUT_NO_LIMITS is set. This is so we place Popups, dialogs, and similar windows on
- // screen, but SurfaceViews want to be always at a specific location so we don't fit it to
- // the display.
- final boolean fitToDisplay = (task == null || !inNonFullscreenContainer)
- || ((attrs.type != TYPE_BASE_APPLICATION) && !noLimits);
- float x, y;
- int w,h;
-
- final boolean hasCompatScale = hasCompatScale();
- if ((attrs.flags & FLAG_SCALED) != 0 || mAttrs != attrs) {
- // For the window with different layout attrs for different rotations, we need to avoid
- // using requested size. Otherwise, when finishing a simulated rotation, the information
- // coming from WindowManagerServices to the ViewRootImpl may not contain the correct
- // value for the new rotation, and there will be a quick flash of wrong layout when the
- // simulated activity faded out.
- if (attrs.width < 0) {
- w = pw;
- } else if (hasCompatScale) {
- w = (int) (attrs.width * mGlobalScale + .5f);
- } else {
- w = attrs.width;
- }
- if (attrs.height < 0) {
- h = ph;
- } else if (hasCompatScale) {
- h = (int) (attrs.height * mGlobalScale + .5f);
- } else {
- h = attrs.height;
- }
- } else {
- if (attrs.width == MATCH_PARENT) {
- w = pw;
- } else if (hasCompatScale) {
- w = (int) (mRequestedWidth * mGlobalScale + .5f);
- } else {
- w = mRequestedWidth;
- }
- if (attrs.height == MATCH_PARENT) {
- h = ph;
- } else if (hasCompatScale) {
- h = (int) (mRequestedHeight * mGlobalScale + .5f);
- } else {
- h = mRequestedHeight;
- }
- }
-
- if (hasCompatScale) {
- x = attrs.x * mGlobalScale;
- y = attrs.y * mGlobalScale;
- } else {
- x = attrs.x;
- y = attrs.y;
- }
-
- if (inNonFullscreenContainer && !layoutInParentFrame()) {
- // Make sure window fits in containing frame since it is in a non-fullscreen task as
- // required by {@link Gravity#apply} call.
- w = Math.min(w, pw);
- h = Math.min(h, ph);
- }
-
- // Set mFrame
- Gravity.apply(attrs.gravity, w, h, containingFrame,
- (int) (x + attrs.horizontalMargin * pw),
- (int) (y + attrs.verticalMargin * ph), windowFrames.mFrame);
- // Now make sure the window fits in the overall display frame.
- if (fitToDisplay) {
- Gravity.applyDisplay(attrs.gravity, displayFrame, windowFrames.mFrame);
- }
-
- // We need to make sure we update the CompatFrame as it is used for
- // cropping decisions, etc, on systems where we lack a decor layer.
- windowFrames.mCompatFrame.set(windowFrames.mFrame);
- if (hasCompatScale) {
- // See comparable block in computeFrameLw.
- windowFrames.mCompatFrame.scale(mInvGlobalScale);
- }
- }
-
boolean isChildWindow() {
return mIsChildWindow;
}
@@ -5884,7 +5672,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// animation target (which will be different than the task bounds)
outFrame.set(getTask().getParent().getBounds());
} else {
- outFrame.set(getContainingFrame());
+ outFrame.set(getParentFrame());
}
outSurfaceInsets.set(getAttrs().surfaceInsets);
final InsetsState state = getInsetsStateWithVisibilityOverride();
diff --git a/services/tests/PackageManager/TEST_MAPPING b/services/tests/PackageManager/TEST_MAPPING
new file mode 100644
index 000000000000..72d4c828c452
--- /dev/null
+++ b/services/tests/PackageManager/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+ "presubmit": [
+ {
+ "name": "PackageInstallerTests"
+ }
+ ]
+}
+
diff --git a/services/tests/PackageManagerComponentOverrideTests/TEST_MAPPING b/services/tests/PackageManagerComponentOverrideTests/TEST_MAPPING
new file mode 100644
index 000000000000..528c949f36de
--- /dev/null
+++ b/services/tests/PackageManagerComponentOverrideTests/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+ "presubmit": [
+ {
+ "name": "PackageManagerComponentOverrideTests"
+ }
+ ]
+}
+
diff --git a/services/tests/PackageManagerServiceTests/OWNERS b/services/tests/PackageManagerServiceTests/OWNERS
index 182dfe8fca9e..86ae5818e91c 100644
--- a/services/tests/PackageManagerServiceTests/OWNERS
+++ b/services/tests/PackageManagerServiceTests/OWNERS
@@ -1,3 +1 @@
-chiuwinson@google.com
-patb@google.com
-toddke@google.com
+include /PACKAGE_MANAGER_OWNERS
diff --git a/services/tests/PackageManagerServiceTests/TEST_MAPPING b/services/tests/PackageManagerServiceTests/TEST_MAPPING
new file mode 100644
index 000000000000..af0008c29aaf
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+ "presubmit": [
+ {
+ "name": "AppEnumerationInternalTests"
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "PackageManagerServiceHostTests"
+ }
+ ],
+ "imports": [
+ {
+ "path": "frameworks/base/services/tests/PackageManagerServiceTests/unit"
+ }
+ ]
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java b/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
index cb12ba7d7679..a2ecbc30ec64 100644
--- a/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
@@ -47,7 +47,6 @@ public class BatteryServiceTest extends AndroidTestCase {
@Mock BatteryService.HealthServiceWrapper.IHealthSupplier mHealthServiceSupplier;
BatteryService.HealthServiceWrapper mWrapper;
- private static final String HEALTHD = BatteryService.HealthServiceWrapper.INSTANCE_HEALTHD;
private static final String VENDOR = BatteryService.HealthServiceWrapper.INSTANCE_VENDOR;
@Override
@@ -117,7 +116,7 @@ public class BatteryServiceTest extends AndroidTestCase {
@SmallTest
public void testWrapPreferVendor() throws Exception {
- initForInstances(VENDOR, HEALTHD);
+ initForInstances(VENDOR);
mWrapper.init(mCallback, mManagerSupplier, mHealthServiceSupplier);
waitHandlerThreadFinish();
verify(mCallback, times(1)).onRegistration(same(null), same(mMockedHal), eq(VENDOR));
@@ -126,16 +125,6 @@ public class BatteryServiceTest extends AndroidTestCase {
}
@SmallTest
- public void testUseHealthd() throws Exception {
- initForInstances(HEALTHD);
- mWrapper.init(mCallback, mManagerSupplier, mHealthServiceSupplier);
- waitHandlerThreadFinish();
- verify(mCallback, times(1)).onRegistration(same(null), same(mMockedHal), eq(HEALTHD));
- verify(mCallback, never()).onRegistration(same(mMockedHal), same(mMockedHal), anyString());
- verify(mCallback, times(1)).onRegistration(same(mMockedHal), same(mMockedHal2), eq(HEALTHD));
- }
-
- @SmallTest
public void testNoService() throws Exception {
initForInstances("unrelated");
try {
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 fb5c557c8d4b..96af61737bff 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
@@ -100,7 +100,11 @@ public class FullScreenMagnificationControllerTest {
MagnificationAnimationCallback.class);
private final MagnificationInfoChangedCallback mRequestObserver = mock(
MagnificationInfoChangedCallback.class);
- final MessageCapturingHandler mMessageCapturingHandler = new MessageCapturingHandler(null);
+ private final MessageCapturingHandler mMessageCapturingHandler = new MessageCapturingHandler(
+ null);
+ private final MagnificationScaleProvider mScaleProvider = mock(
+ MagnificationScaleProvider.class);
+
ValueAnimator mMockValueAnimator;
ValueAnimator.AnimatorUpdateListener mTargetAnimationListener;
@@ -123,7 +127,7 @@ public class FullScreenMagnificationControllerTest {
initMockWindowManager();
mFullScreenMagnificationController = new FullScreenMagnificationController(
- mMockControllerCtx, new Object(), mRequestObserver);
+ mMockControllerCtx, new Object(), mRequestObserver, mScaleProvider);
}
@After
@@ -412,12 +416,12 @@ public class FullScreenMagnificationControllerTest {
MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter,
- FullScreenMagnificationController.MAX_SCALE);
+ MagnificationScaleProvider.MAX_SCALE);
MagnificationSpec endSpec = getMagnificationSpec(
- FullScreenMagnificationController.MAX_SCALE, offsets);
+ MagnificationScaleProvider.MAX_SCALE, offsets);
assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
- FullScreenMagnificationController.MAX_SCALE + 1.0f,
+ MagnificationScaleProvider.MAX_SCALE + 1.0f,
newCenter.x, newCenter.y, false, SERVICE_ID_1));
mMessageCapturingHandler.sendAllMessages();
@@ -632,31 +636,6 @@ public class FullScreenMagnificationControllerTest {
}
@Test
- public void testSetUserId_resetsOnlyIfIdChanges() {
- for (int i = 0; i < DISPLAY_COUNT; i++) {
- testSetUserId_resetsOnlyIfIdChanges(i);
- resetMockWindowManager();
- }
- }
-
- private void testSetUserId_resetsOnlyIfIdChanges(int displayId) {
- final int userId1 = 1;
- final int userId2 = 2;
-
- register(displayId);
- mFullScreenMagnificationController.setUserId(userId1);
- PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
- float scale = 2.0f;
- mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
- false, SERVICE_ID_1);
-
- mFullScreenMagnificationController.setUserId(userId1);
- assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
- mFullScreenMagnificationController.setUserId(userId2);
- assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
- }
-
- @Test
public void testResetIfNeeded_doesWhatItSays() {
for (int i = 0; i < DISPLAY_COUNT; i++) {
testResetIfNeeded_doesWhatItSays(i);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 6c32f7e8bacb..2060223f6f98 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -22,6 +22,8 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static com.android.server.testutils.TestUtils.strictMock;
import static org.junit.Assert.assertFalse;
@@ -38,16 +40,15 @@ import static org.mockito.Mockito.when;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
-import android.content.Context;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
+import android.testing.TestableContext;
import android.util.DebugUtils;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
-import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.accessibility.AccessibilityManagerService;
@@ -60,6 +61,7 @@ import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -121,7 +123,6 @@ public class FullScreenMagnificationGestureHandlerTest {
private static final int DISPLAY_0 = 0;
- private Context mContext;
FullScreenMagnificationController mFullScreenMagnificationController;
@Mock
MagnificationGestureHandler.Callback mMockCallback;
@@ -134,6 +135,9 @@ public class FullScreenMagnificationGestureHandlerTest {
@Mock
AccessibilityTraceManager mMockTraceManager;
+ @Rule
+ public final TestableContext mContext = new TestableContext(getInstrumentation().getContext());
+
private OffsettableClock mClock;
private FullScreenMagnificationGestureHandler mMgh;
private TestHandler mHandler;
@@ -143,7 +147,6 @@ public class FullScreenMagnificationGestureHandlerTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = InstrumentationRegistry.getContext();
final FullScreenMagnificationController.ControllerContext mockController =
mock(FullScreenMagnificationController.ControllerContext.class);
final WindowManagerInternal mockWindowManager = mock(WindowManagerInternal.class);
@@ -157,14 +160,16 @@ public class FullScreenMagnificationGestureHandlerTest {
when(mockController.getAnimationDuration()).thenReturn(1000L);
when(mockWindowManager.setMagnificationCallbacks(eq(DISPLAY_0), any())).thenReturn(true);
mFullScreenMagnificationController = new FullScreenMagnificationController(mockController,
- new Object(), mMagnificationInfoChangedCallback) {
+ new Object(), mMagnificationInfoChangedCallback,
+ new MagnificationScaleProvider(mContext)) {
@Override
public boolean magnificationRegionContains(int displayId, float x, float y) {
return true;
}
@Override
- void setForceShowMagnifiableBounds(int displayId, boolean show) {}
+ void setForceShowMagnifiableBounds(int displayId, boolean show) {
+ }
};
mFullScreenMagnificationController.register(DISPLAY_0);
mClock = new OffsettableClock.Stopped();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index 2cb3d27229bc..69061c14c70e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -46,6 +46,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
+import android.testing.DexmakerShareClassLoaderRule;
import android.view.Display;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.MagnificationAnimationCallback;
@@ -58,6 +59,7 @@ import com.android.server.accessibility.AccessibilityTraceManager;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -79,7 +81,8 @@ public class MagnificationControllerTest {
private static final float MAGNIFIED_CENTER_X = 100;
private static final float MAGNIFIED_CENTER_Y = 200;
private static final float DEFAULT_SCALE = 3f;
- private static final int CURRENT_USER_ID = UserHandle.USER_CURRENT;
+ private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
+ private static final int SECOND_USER_ID = CURRENT_USER_ID + 1;
private static final int MODE_WINDOW = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
private static final int MODE_FULLSCREEN =
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
@@ -94,6 +97,7 @@ public class MagnificationControllerTest {
private Context mContext;
@Mock
private FullScreenMagnificationController mScreenMagnificationController;
+ private MagnificationScaleProvider mScaleProvider;
@Captor
private ArgumentCaptor<MagnificationAnimationCallback> mCallbackArgumentCaptor;
@@ -103,6 +107,11 @@ public class MagnificationControllerTest {
private MagnificationController mMagnificationController;
private FullScreenMagnificationControllerStubber mScreenMagnificationControllerStubber;
+ // To mock package-private class
+ @Rule
+ public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+ new DexmakerShareClassLoaderRule();
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -113,15 +122,17 @@ public class MagnificationControllerTest {
Settings.Secure.putFloatForUser(mMockResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, DEFAULT_SCALE,
CURRENT_USER_ID);
+ mScaleProvider = spy(new MagnificationScaleProvider(mContext));
mWindowMagnificationManager = Mockito.spy(
new WindowMagnificationManager(mContext, CURRENT_USER_ID,
- mock(WindowMagnificationManager.Callback.class), mTraceManager));
+ mock(WindowMagnificationManager.Callback.class), mTraceManager,
+ mScaleProvider));
mMockConnection = new MockWindowMagnificationConnection(true);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mScreenMagnificationControllerStubber = new FullScreenMagnificationControllerStubber(
mScreenMagnificationController);
mMagnificationController = spy(new MagnificationController(mService, new Object(), mContext,
- mScreenMagnificationController, mWindowMagnificationManager));
+ mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider));
mMagnificationController.setMagnificationCapabilities(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
@@ -283,14 +294,16 @@ public class MagnificationControllerTest {
verify(mScreenMagnificationController).onDisplayRemoved(TEST_DISPLAY);
verify(mWindowMagnificationManager).onDisplayRemoved(TEST_DISPLAY);
+ verify(mScaleProvider).onDisplayRemoved(TEST_DISPLAY);
}
@Test
- public void updateUserIdIfNeeded_AllModulesAvailable_setUserId() {
- mMagnificationController.updateUserIdIfNeeded(CURRENT_USER_ID);
+ public void updateUserIdIfNeeded_AllModulesAvailable_disableMagnificationAndChangeUserId() {
+ mMagnificationController.updateUserIdIfNeeded(SECOND_USER_ID);
- verify(mScreenMagnificationController).setUserId(CURRENT_USER_ID);
- verify(mWindowMagnificationManager).setUserId(CURRENT_USER_ID);
+ verify(mScreenMagnificationController).resetAllIfNeeded(false);
+ verify(mWindowMagnificationManager).disableAllWindowMagnifiers();
+ verify(mScaleProvider).onUserChanged(SECOND_USER_ID);
}
@Test
@@ -575,6 +588,13 @@ public class MagnificationControllerTest {
verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
}
+ @Test
+ public void onUserRemoved_notifyScaleProvider() {
+ mMagnificationController.onUserRemoved(SECOND_USER_ID);
+
+ verify(mScaleProvider).onUserRemoved(SECOND_USER_ID);
+ }
+
private void setMagnificationEnabled(int mode) throws RemoteException {
setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
}
@@ -627,7 +647,8 @@ public class MagnificationControllerTest {
TEST_DISPLAY);
doAnswer(invocation -> mIsMagnifying).when(
mScreenMagnificationController).isForceShowMagnifiableBounds(TEST_DISPLAY);
- doAnswer(invocation -> mScale).when(mScreenMagnificationController).getPersistedScale();
+ doAnswer(invocation -> mScale).when(mScreenMagnificationController).getPersistedScale(
+ TEST_DISPLAY);
doAnswer(invocation -> mScale).when(mScreenMagnificationController).getScale(
TEST_DISPLAY);
doAnswer(invocation -> mCenterX).when(mScreenMagnificationController).getCenterX(
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationScaleProviderTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationScaleProviderTest.java
new file mode 100644
index 000000000000..9b392b200821
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationScaleProviderTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 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.accessibility.magnification;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.UserHandle;
+import android.testing.TestableContext;
+import android.view.Display;
+
+import com.android.compatibility.common.util.TestUtils;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+/**
+ * Tests for {@link MagnificationScaleProvider}.
+ */
+public class MagnificationScaleProviderTest {
+
+ private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY + 1;
+ private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
+ private static final int SECOND_USER_ID = CURRENT_USER_ID + 1;
+
+ private static final float TEST_SCALE = 3;
+ private static final float DEFAULT_SCALE =
+ MagnificationScaleProvider.DEFAULT_MAGNIFICATION_SCALE;
+
+ @Rule
+ public final TestableContext mContext = new TestableContext(getInstrumentation().getContext());
+
+ private MagnificationScaleProvider mScaleProvider;
+
+ @Before
+ public void setUp() {
+ mScaleProvider = new MagnificationScaleProvider(mContext);
+ }
+
+ @Test
+ public void putScaleOnDefaultDisplay_getExpectedValue() throws Exception {
+ mScaleProvider.putScale(TEST_SCALE, Display.DEFAULT_DISPLAY);
+
+ TestUtils.waitUntil("settings value is not changed",
+ () -> Float.compare(mScaleProvider.getScale(Display.DEFAULT_DISPLAY),
+ TEST_SCALE) == 0);
+ }
+
+ @Test
+ public void putScaleOnTestDisplay_getExpectedValue() {
+ mScaleProvider.putScale(TEST_SCALE, TEST_DISPLAY);
+
+ assertEquals(TEST_SCALE, mScaleProvider.getScale(TEST_DISPLAY), 0);
+ }
+
+ @Test
+ public void onUserChanged_putScale_fallbackToDefaultScale() {
+ mScaleProvider.putScale(TEST_SCALE, TEST_DISPLAY);
+
+ mScaleProvider.onUserChanged(SECOND_USER_ID);
+ assertEquals(DEFAULT_SCALE, mScaleProvider.getScale(TEST_DISPLAY), 0);
+ }
+
+ @Test
+ public void onUserRemoved_setScaleOnSecondUser_fallbackToDefaultScale() {
+ mScaleProvider.onUserChanged(SECOND_USER_ID);
+ mScaleProvider.putScale(TEST_SCALE, TEST_DISPLAY);
+ mScaleProvider.onUserChanged(CURRENT_USER_ID);
+
+ mScaleProvider.onUserRemoved(SECOND_USER_ID);
+ // Assume the second user is created with the same id
+ mScaleProvider.onUserChanged(SECOND_USER_ID);
+
+ assertEquals(DEFAULT_SCALE, mScaleProvider.getScale(TEST_DISPLAY), 0);
+ }
+
+ @Test
+ public void onTestDisplayRemoved_setScaleOnTestDisplay_fallbackToDefaultScale() {
+ mScaleProvider.putScale(TEST_SCALE, TEST_DISPLAY);
+
+ mScaleProvider.onDisplayRemoved(TEST_DISPLAY);
+
+ assertEquals(DEFAULT_SCALE, mScaleProvider.getScale(TEST_DISPLAY), 0);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
index 95f43275376e..1b8aff50d2e2 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
@@ -21,10 +21,10 @@ import static com.android.server.testutils.TestUtils.strictMock;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
-import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.RemoteException;
+import android.testing.TestableContext;
import android.util.DebugUtils;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -39,6 +39,7 @@ import com.android.server.accessibility.utils.TouchEventGenerator;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -67,7 +68,10 @@ public class WindowMagnificationGestureHandlerTest {
public static final float DEFAULT_TAP_Y = 299;
private static final int DISPLAY_0 = MockWindowMagnificationConnection.TEST_DISPLAY;
- private Context mContext;
+ @Rule
+ public final TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getContext());
+
private WindowMagnificationManager mWindowMagnificationManager;
private MockWindowMagnificationConnection mMockConnection;
private WindowMagnificationGestureHandler mWindowMagnificationGestureHandler;
@@ -79,9 +83,9 @@ public class WindowMagnificationGestureHandlerTest {
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
- mContext = InstrumentationRegistry.getInstrumentation().getContext();
mWindowMagnificationManager = new WindowMagnificationManager(mContext, 0,
- mock(WindowMagnificationManager.Callback.class), mMockTrace);
+ mock(WindowMagnificationManager.Callback.class), mMockTrace,
+ new MagnificationScaleProvider(mContext));
mMockConnection = new MockWindowMagnificationConnection();
mWindowMagnificationGestureHandler = new WindowMagnificationGestureHandler(
mContext, mWindowMagnificationManager, mMockTrace, mMockCallback,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index af6d40f2fdf2..da881c4e6494 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -67,7 +67,7 @@ import org.mockito.invocation.InvocationOnMock;
public class WindowMagnificationManagerTest {
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
- private static final int CURRENT_USER_ID = UserHandle.USER_CURRENT;
+ private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
private MockWindowMagnificationConnection mMockConnection;
@Mock
@@ -91,7 +91,7 @@ public class WindowMagnificationManagerTest {
mResolver = new MockContentResolver();
mMockConnection = new MockWindowMagnificationConnection();
mWindowMagnificationManager = new WindowMagnificationManager(mContext, CURRENT_USER_ID,
- mMockCallback, mMockTrace);
+ mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext));
when(mContext.getContentResolver()).thenReturn(mResolver);
doAnswer((InvocationOnMock invocation) -> {
@@ -230,7 +230,7 @@ public class WindowMagnificationManagerTest {
public void getPersistedScale() {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- assertEquals(mWindowMagnificationManager.getPersistedScale(), 2.5f);
+ assertEquals(mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY), 2.5f);
}
@Test
@@ -264,7 +264,7 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.setScale(TEST_DISPLAY, 10.0f);
assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY),
- WindowMagnificationManager.MAX_SCALE);
+ MagnificationScaleProvider.MAX_SCALE);
}
@Test
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 4957ab96ace1..03132c428077 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -50,7 +50,6 @@ import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
@@ -107,9 +106,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Before
public void setUp() throws Exception {
mWindow = spy(createWindow(null, TYPE_APPLICATION, "window"));
- // We only test window frames set by DisplayPolicy, so here prevents computeFrameLw from
- // changing those frames.
- doNothing().when(mWindow).computeFrame(any());
spyOn(mStatusBarWindow);
spyOn(mNavBarWindow);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
deleted file mode 100644
index 316309c8440e..000000000000
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-
-import static org.junit.Assert.assertEquals;
-
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-import android.view.DisplayInfo;
-import android.view.Gravity;
-import android.view.InsetsSource;
-import android.view.InsetsState;
-import android.view.InsetsVisibilities;
-import android.view.WindowManager;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-/**
- * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
- *
- * Build/Install/Run:
- * atest WmTests:WindowFrameTests
- */
-@SmallTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class WindowFrameTests extends WindowTestsBase {
-
- private DisplayContent mTestDisplayContent;
- private DisplayFrames mTestDisplayFrames;
-
- @Before
- public void setUp() throws Exception {
- DisplayInfo testDisplayInfo = new DisplayInfo(mDisplayInfo);
- testDisplayInfo.displayCutout = null;
- mTestDisplayContent = createNewDisplay(testDisplayInfo);
- mTestDisplayFrames = mTestDisplayContent.mDisplayFrames;
- }
-
- // Do not use this function directly in the tests below. Instead, use more explicit function
- // such as assertFlame().
- private void assertRect(Rect rect, int left, int top, int right, int bottom) {
- assertEquals(left, rect.left);
- assertEquals(top, rect.top);
- assertEquals(right, rect.right);
- assertEquals(bottom, rect.bottom);
- }
-
- private void assertFrame(WindowState w, Rect frame) {
- assertEquals(w.getFrame(), frame);
- }
-
- private void assertFrame(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getFrame(), left, top, right, bottom);
- }
-
- private void assertRelFrame(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getRelativeFrame(), left, top, right, bottom);
- }
-
- @Test
- public void testLayoutInFullscreenTask() {
- // fullscreen task doesn't use bounds for computeFrame
- WindowState w = createWindow();
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
-
- // With no insets or system decor all the frames incoming from PhoneWindowManager
- // are identical.
- final Rect pf = new Rect(0, 0, 1000, 1000);
-
- // Here the window has FILL_PARENT, FILL_PARENT
- // so we expect it to fill the entire available frame.
- w.getWindowFrames().setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 0, 0, 1000, 1000);
- assertRelFrame(w, 0, 0, 1000, 1000);
-
- // It can select various widths and heights within the bounds.
- // Strangely the window attribute width is ignored for normal windows
- // and we use mRequestedWidth/mRequestedHeight
- w.mAttrs.width = 300;
- w.mAttrs.height = 300;
- w.computeFrame(mTestDisplayFrames);
- // Explicit width and height without requested width/height
- // gets us nothing.
- assertFrame(w, 0, 0, 0, 0);
-
- w.mRequestedWidth = 300;
- w.mRequestedHeight = 300;
- w.computeFrame(mTestDisplayFrames);
- // With requestedWidth/Height we can freely choose our size within the
- // parent bounds.
- assertFrame(w, 0, 0, 300, 300);
-
- // With FLAG_SCALED though, requestedWidth/height is used to control
- // the unscaled surface size, and mAttrs.width/height becomes the
- // layout controller.
- w.mAttrs.flags = WindowManager.LayoutParams.FLAG_SCALED;
- w.mRequestedHeight = -1;
- w.mRequestedWidth = -1;
- w.mAttrs.width = 100;
- w.mAttrs.height = 100;
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 0, 0, 100, 100);
- w.mAttrs.flags = 0;
-
- // But sizes too large will be clipped to the containing frame
- w.mRequestedWidth = 1200;
- w.mRequestedHeight = 1200;
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 0, 0, 1000, 1000);
-
- // Before they are clipped though windows will be shifted
- w.mAttrs.x = 300;
- w.mAttrs.y = 300;
- w.mRequestedWidth = 1000;
- w.mRequestedHeight = 1000;
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 0, 0, 1000, 1000);
-
- // If there is room to move around in the parent frame the window will be shifted according
- // to gravity.
- w.mAttrs.x = 0;
- w.mAttrs.y = 0;
- w.mRequestedWidth = 300;
- w.mRequestedHeight = 300;
- w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 700, 0, 1000, 300);
- assertRelFrame(w, 700, 0, 1000, 300);
- w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 700, 700, 1000, 1000);
- assertRelFrame(w, 700, 700, 1000, 1000);
- // Window specified x and y are interpreted as offsets in the opposite
- // direction of gravity
- w.mAttrs.x = 100;
- w.mAttrs.y = 100;
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, 600, 600, 900, 900);
- assertRelFrame(w, 600, 600, 900, 900);
- }
-
- @Test
- public void testLayoutNonfullscreenTask() {
- removeGlobalMinSizeRestriction();
- final DisplayInfo displayInfo = mWm.getDefaultDisplayContentLocked().getDisplayInfo();
- final int logicalWidth = displayInfo.logicalWidth;
- final int logicalHeight = displayInfo.logicalHeight;
-
- final Rect taskBounds = new Rect(
- logicalWidth / 4, logicalHeight / 4, logicalWidth / 4 * 3, logicalHeight / 4 * 3);
- WindowState w = createWindow();
- final Task task = w.getTask();
- // Use split-screen because it is non-fullscreen, but also not floating
- task.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- task.setBounds(taskBounds);
- // The bounds we are requesting might be different from what the system resolved based on
- // other factors.
- final Rect resolvedTaskBounds = task.getBounds();
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
-
- final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
- final WindowFrames windowFrames = w.getWindowFrames();
- windowFrames.setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- // For non fullscreen tasks the containing frame is based off the
- // task bounds not the parent frame.
- assertEquals(resolvedTaskBounds, w.getFrame());
- assertEquals(0, w.getRelativeFrame().left);
- assertEquals(0, w.getRelativeFrame().top);
-
- pf.set(0, 0, logicalWidth, logicalHeight);
- // We still produce insets against the containing frame the same way.
- final int cfRight = logicalWidth / 2;
- final int cfBottom = logicalHeight / 2;
- final Rect cf = new Rect(0, 0, cfRight, cfBottom);
- windowFrames.setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertEquals(resolvedTaskBounds, w.getFrame());
- assertEquals(0, w.getRelativeFrame().left);
- assertEquals(0, w.getRelativeFrame().top);
- }
-
- @Test
- @FlakyTest(bugId = 137879065)
- public void testLayoutLetterboxedWindow() {
- // First verify task behavior in multi-window mode.
- final DisplayInfo displayInfo = mTestDisplayContent.getDisplayInfo();
- final int logicalWidth = displayInfo.logicalWidth;
- final int logicalHeight = displayInfo.logicalHeight;
-
- final int taskLeft = logicalWidth / 5;
- final int taskTop = logicalHeight / 5;
- final int taskRight = logicalWidth / 4 * 3;
- final int taskBottom = logicalHeight / 4 * 3;
- final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
- WindowState w = createWindow();
- final Task task = w.getTask();
- // Use split-screen because it is non-fullscreen, but also not floating
- task.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- task.setBounds(taskBounds);
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
-
- final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
- final WindowFrames windowFrames = w.getWindowFrames();
- windowFrames.setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- // For non fullscreen tasks the containing frame is based off the
- // task bounds not the parent frame.
- assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
-
- // Now simulate switch to fullscreen for letterboxed app.
- final int xInset = logicalWidth / 10;
- final Rect cf = new Rect(xInset, 0, logicalWidth - xInset, logicalHeight);
- Configuration config = new Configuration(w.mActivityRecord.getRequestedOverrideConfiguration());
- config.windowConfiguration.setBounds(cf);
- config.windowConfiguration.setAppBounds(cf);
- w.mActivityRecord.onRequestedOverrideConfigurationChanged(config);
- pf.set(0, 0, logicalWidth, logicalHeight);
- task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- task.setBounds(null);
- windowFrames.setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, cf);
- }
-
- @Test
- public void testFreeformContentInsets() {
- removeGlobalMinSizeRestriction();
- // fullscreen task doesn't use bounds for computeFrame
- WindowState w = createWindow();
- final Task task = w.getTask();
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
- task.setWindowingMode(WINDOWING_MODE_FREEFORM);
-
- // Make IME attach to the window and can produce insets.
- final DisplayContent dc = mTestDisplayContent;
- dc.setImeLayeringTarget(w);
- WindowState mockIme = mock(WindowState.class);
- Mockito.doReturn(true).when(mockIme).isVisibleNow();
- dc.mInputMethodWindow = mockIme;
- final InsetsState state = dc.getInsetsStateController().getRawInsetsState();
- final InsetsSource imeSource = state.getSource(ITYPE_IME);
- final Rect imeFrame = new Rect(state.getDisplayFrame());
- imeFrame.top = 400;
- imeSource.setFrame(imeFrame);
- imeSource.setVisible(true);
- final InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
- requestedVisibilities.setVisibility(ITYPE_IME, true);
- w.setRequestedVisibilities(requestedVisibilities);
- w.mAboveInsetsState.addSource(imeSource);
-
- // With no insets or system decor all the frames incoming from PhoneWindowManager
- // are identical.
- final Rect pf = new Rect(0, 0, 1000, 800);
-
- // First check that it only gets moved up enough to show window.
- final Rect winRect = new Rect(200, 200, 300, 500);
- task.setBounds(winRect);
- w.getWindowFrames().setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, winRect.left, imeFrame.top - winRect.height(), winRect.right, imeFrame.top);
-
- // Now check that it won't get moved beyond the top
- winRect.bottom = 650;
- task.setBounds(winRect);
- w.setBounds(winRect);
- w.getWindowFrames().setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, winRect.left, 0, winRect.right, winRect.height());
-
- // Now we have status bar. Check that it won't go into the status bar area.
- final Rect statusBarFrame = new Rect(state.getDisplayFrame());
- statusBarFrame.bottom = 60;
- state.getSource(ITYPE_STATUS_BAR).setFrame(statusBarFrame);
- w.getWindowFrames().setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertFrame(w, winRect.left, statusBarFrame.bottom, winRect.right,
- statusBarFrame.bottom + winRect.height());
-
- // Check that it's moved back without ime insets
- state.removeSource(ITYPE_IME);
- w.getWindowFrames().setFrames(pf, pf);
- w.computeFrame(mTestDisplayFrames);
- assertEquals(winRect, w.getFrame());
- }
-
- private WindowState createWindow() {
- final WindowState ws = createWindow(null, TYPE_APPLICATION, mTestDisplayContent, "WindowFrameTests");
- spyOn(ws);
- return ws;
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
new file mode 100644
index 000000000000..117f2ff96922
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2021 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;
+
+import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.WindowConfiguration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.view.Gravity;
+import android.view.InsetsState;
+import android.view.InsetsVisibilities;
+import android.view.WindowLayout;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link WindowLayout#computeWindowFrames}.
+ *
+ * Build/Install/Run:
+ * atest WmTests:WindowLayoutTests
+ */
+@SmallTest
+@Presubmit
+public class WindowLayoutTests {
+ private static final int DISPLAY_WIDTH = 500;
+ private static final int DISPLAY_HEIGHT = 1000;
+ private static final int STATUS_BAR_HEIGHT = 10;
+ private static final int NAVIGATION_BAR_HEIGHT = 15;
+
+ private final WindowLayout mWindowLayout = new WindowLayout();
+ private final Rect mDisplayFrame = new Rect();
+ private final Rect mParentFrame = new Rect();
+ private final Rect mFrame = new Rect();
+
+ private WindowManager.LayoutParams mAttrs;
+ private InsetsState mState;
+ private final Rect mDisplayCutoutSafe = new Rect();
+ private Rect mWindowBounds;
+ private int mWindowingMode;
+ private int mRequestedWidth;
+ private int mRequestedHeight;
+ private InsetsVisibilities mRequestedVisibilities;
+ private Rect mAttachedWindowFrame;
+ private float mCompatScale;
+
+ @Before
+ public void setUp() {
+ mAttrs = new WindowManager.LayoutParams();
+ mState = new InsetsState();
+ mState.setDisplayFrame(new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
+ mState.getSource(InsetsState.ITYPE_STATUS_BAR).setFrame(
+ 0, 0, DISPLAY_WIDTH, STATUS_BAR_HEIGHT);
+ mState.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setFrame(
+ 0, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+ mState.getDisplayCutoutSafe(mDisplayCutoutSafe);
+ mWindowBounds = new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+ mWindowingMode = WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+ mRequestedWidth = DISPLAY_WIDTH;
+ mRequestedHeight = DISPLAY_HEIGHT;
+ mRequestedVisibilities = new InsetsVisibilities();
+ mAttachedWindowFrame = null;
+ mCompatScale = 1f;
+ }
+
+ @Test
+ public void testDefaultLayoutParams() {
+ computeWindowFrames();
+
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mDisplayFrame);
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mParentFrame);
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mFrame);
+ }
+
+ @Test
+ public void testUnmeasured() {
+ mRequestedWidth = UNSPECIFIED_LENGTH;
+ mRequestedHeight = UNSPECIFIED_LENGTH;
+ computeWindowFrames();
+
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mDisplayFrame);
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mParentFrame);
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mFrame);
+ }
+
+ @Test
+ public void testUnmeasuredWithSizeSpecifiedInLayoutParams() {
+ final int width = DISPLAY_WIDTH / 2;
+ final int height = DISPLAY_HEIGHT / 2;
+ mRequestedWidth = UNSPECIFIED_LENGTH;
+ mRequestedHeight = UNSPECIFIED_LENGTH;
+ mAttrs.width = width;
+ mAttrs.height = height;
+ mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+ computeWindowFrames();
+
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mDisplayFrame);
+ assertRect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mParentFrame);
+ assertRect(0, STATUS_BAR_HEIGHT, width, STATUS_BAR_HEIGHT + height,
+ mFrame);
+ }
+
+ @Test
+ public void testNonFullscreenWindowBounds() {
+ final int top = Math.max(DISPLAY_HEIGHT / 2, STATUS_BAR_HEIGHT);
+ mWindowBounds.set(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+ mRequestedWidth = UNSPECIFIED_LENGTH;
+ mRequestedHeight = UNSPECIFIED_LENGTH;
+ computeWindowFrames();
+
+ assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mDisplayFrame);
+ assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mParentFrame);
+ assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
+ mFrame);
+ }
+
+ // TODO(b/161810301): Move tests here from DisplayPolicyLayoutTests and add more tests.
+
+ private void computeWindowFrames() {
+ mWindowLayout.computeWindowFrames(mAttrs, mState, mDisplayCutoutSafe, mWindowBounds,
+ mWindowingMode, mRequestedWidth, mRequestedHeight, mRequestedVisibilities,
+ mAttachedWindowFrame, mCompatScale, mDisplayFrame, mParentFrame, mFrame);
+ }
+
+ private void assertRect(int left, int top, int right, int bottom, Rect actual) {
+ assertEquals(new Rect(left, top, right, bottom), actual);
+ }
+}
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 ac61bb15ab06..056a07a77068 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -285,8 +285,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
mStatusBarWindow.mAttrs.gravity = Gravity.TOP;
mStatusBarWindow.mAttrs.layoutInDisplayCutoutMode =
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- mStatusBarWindow.setRequestedSize(WindowManager.LayoutParams.MATCH_PARENT,
- STATUS_BAR_HEIGHT);
}
}
if (addAll || ArrayUtils.contains(requestedWindows, W_NOTIFICATION_SHADE)) {
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 7a424c87d1d6..10fba60d4c95 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -650,7 +650,13 @@ public final class TelephonyPermissions {
private static boolean checkCarrierPrivilegeForAnySubId(Context context, int uid) {
SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- int[] activeSubIds = sm.getCompleteActiveSubscriptionIdList();
+ int[] activeSubIds;
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ activeSubIds = sm.getCompleteActiveSubscriptionIdList();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
for (int activeSubId : activeSubIds) {
if (getCarrierPrivilegeStatus(context, activeSubId, uid)
== TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {