diff options
33 files changed, 226 insertions, 632 deletions
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index dc17a78a1cd9..9a0053f8add6 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -572,147 +572,6 @@ java_genrule { }, } -// -// Java API defaults and libraries for single tree build -// - -java_defaults { - name: "stub-annotation-defaults", - libs: [ - "stub-annotations", - ], - static_libs: [ - // stub annotations do not contribute to the API surfaces but are statically - // linked in the stubs for API surfaces (see frameworks/base/StubLibraries.bp). - // This is because annotation processors insist on loading the classes for any - // annotations found, thus should exist inside android.jar. - "private-stub-annotations-jar", - ], -} - -// Listing of API domains contribution and dependencies per API surfaces -java_defaults { - name: "android_test_stubs_current_contributions", - api_surface: "test", - api_contributions: [ - "test-api-stubs-docs-non-updatable.api.contribution", - "framework-virtualization.stubs.source.test.api.contribution", - ], -} - -java_defaults { - name: "android_module_lib_stubs_current_contributions", - api_surface: "module-lib", - api_contributions: [ - "api-stubs-docs-non-updatable.api.contribution", - "system-api-stubs-docs-non-updatable.api.contribution", - "module-lib-api-stubs-docs-non-updatable.api.contribution", - "art.module.public.api.stubs.source.api.contribution", - "art.module.public.api.stubs.source.system.api.contribution", - "art.module.public.api.stubs.source.module_lib.api.contribution", - "i18n.module.public.api.stubs.source.api.contribution", - "i18n.module.public.api.stubs.source.system.api.contribution", - "i18n.module.public.api.stubs.source.module_lib.api.contribution", - ], -} - -// Java API library definitions per API surface -java_api_library { - name: "android_stubs_current.from-text", - api_surface: "public", - defaults: [ - // This module is dynamically created at frameworks/base/api/api.go - // instead of being written out, in order to minimize edits in the codebase - // when there is a change in the list of modules. - // that contributes to an api surface. - "android_stubs_current_contributions", - "stub-annotation-defaults", - ], - api_contributions: [ - "api-stubs-docs-non-updatable.api.contribution", - ], - visibility: ["//visibility:public"], -} - -java_api_library { - name: "android_system_stubs_current.from-text", - api_surface: "system", - defaults: [ - "android_stubs_current_contributions", - "android_system_stubs_current_contributions", - "stub-annotation-defaults", - ], - api_contributions: [ - "api-stubs-docs-non-updatable.api.contribution", - "system-api-stubs-docs-non-updatable.api.contribution", - ], - visibility: ["//visibility:public"], -} - -java_api_library { - name: "android_test_stubs_current.from-text", - api_surface: "test", - defaults: [ - "android_stubs_current_contributions", - "android_system_stubs_current_contributions", - "android_test_stubs_current_contributions", - "stub-annotation-defaults", - ], - api_contributions: [ - "api-stubs-docs-non-updatable.api.contribution", - "system-api-stubs-docs-non-updatable.api.contribution", - ], - visibility: ["//visibility:public"], -} - -java_api_library { - name: "android_module_lib_stubs_current_full.from-text", - api_surface: "module-lib", - defaults: [ - "android_stubs_current_contributions", - "android_system_stubs_current_contributions", - "android_module_lib_stubs_current_contributions_full", - ], - libs: [ - "stub-annotations", - ], - api_contributions: [ - "api-stubs-docs-non-updatable.api.contribution", - "system-api-stubs-docs-non-updatable.api.contribution", - "module-lib-api-stubs-docs-non-updatable.api.contribution", - ], - visibility: ["//visibility:public"], -} - -java_api_library { - name: "android_module_lib_stubs_current.from-text", - api_surface: "module-lib", - defaults: [ - "android_module_lib_stubs_current_contributions", - ], - libs: [ - "android_module_lib_stubs_current_full.from-text", - "stub-annotations", - ], - visibility: ["//visibility:public"], -} - -java_api_library { - name: "android_system_server_stubs_current.from-text", - api_surface: "system-server", - api_contributions: [ - "services-non-updatable-stubs.api.contribution", - ], - libs: [ - "android_module_lib_stubs_current.from-text", - "stub-annotations", - ], - static_libs: [ - "android_module_lib_stubs_current.from-text", - ], - visibility: ["//visibility:public"], -} - //////////////////////////////////////////////////////////////////////// // api-versions.xml generation, for public and system. This API database // also contains the android.test.* APIs. diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 67060913f8f9..53e0a05b27b1 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -21,8 +21,6 @@ import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIO import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; -import static android.content.Intent.FLAG_RECEIVER_FOREGROUND; import static android.view.Display.INVALID_DISPLAY; import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; @@ -1758,9 +1756,7 @@ public class ActivityOptions extends ComponentOptions { * @hide */ public int getPendingIntentLaunchFlags() { - // b/243794108: Ignore all flags except the new task flag, to be reconsidered in b/254490217 - return mPendingIntentLaunchFlags & - (FLAG_ACTIVITY_NEW_TASK | FLAG_RECEIVER_FOREGROUND); + return mPendingIntentLaunchFlags; } /** diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index a4a3fdbc57db..90e3e9d1a9c3 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2857,17 +2857,6 @@ public class Notification implements Parcelable if (person != null) { visitor.accept(person.getIconUri()); } - - final RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[]) - extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); - if (history != null) { - for (int i = 0; i < history.length; i++) { - RemoteInputHistoryItem item = history[i]; - if (item.getUri() != null) { - visitor.accept(item.getUri()); - } - } - } } if (isStyle(MessagingStyle.class) && extras != null) { @@ -2898,14 +2887,6 @@ public class Notification implements Parcelable } } - if (isStyle(CallStyle.class) & extras != null) { - Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON); - if (callPerson != null) { - visitor.accept(callPerson.getIconUri()); - } - visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON)); - } - if (mBubbleMetadata != null) { visitIconUri(visitor, mBubbleMetadata.getIcon()); } diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index b85ea36ae6a1..295df5cc42d0 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -285,12 +285,6 @@ public final class ShortcutInfo implements Parcelable { */ public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103; - /** - * The maximum length of Shortcut ID. IDs will be truncated at this limit. - * @hide - */ - public static final int MAX_ID_LENGTH = 1000; - /** @hide */ @IntDef(prefix = { "DISABLED_REASON_" }, value = { DISABLED_REASON_NOT_DISABLED, @@ -483,7 +477,8 @@ public final class ShortcutInfo implements Parcelable { private ShortcutInfo(Builder b) { mUserId = b.mContext.getUserId(); - mId = getSafeId(Preconditions.checkStringNotEmpty(b.mId, "Shortcut ID must be provided")); + + mId = Preconditions.checkStringNotEmpty(b.mId, "Shortcut ID must be provided"); // Note we can't do other null checks here because SM.updateShortcuts() takes partial // information. @@ -589,14 +584,6 @@ public final class ShortcutInfo implements Parcelable { return ret; } - @NonNull - private static String getSafeId(@NonNull String id) { - if (id.length() > MAX_ID_LENGTH) { - return id.substring(0, MAX_ID_LENGTH); - } - return id; - } - /** * Throws if any of the mandatory fields is not set. * @@ -2355,8 +2342,7 @@ public final class ShortcutInfo implements Parcelable { final ClassLoader cl = getClass().getClassLoader(); mUserId = source.readInt(); - mId = getSafeId(Preconditions.checkStringNotEmpty(source.readString8(), - "Shortcut ID must be provided")); + mId = source.readString8(); mPackageName = source.readString8(); mActivity = source.readParcelable(cl, android.content.ComponentName.class); mFlags = source.readInt(); diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl index 45dad9861406..6a93b354f4da 100644 --- a/core/java/android/permission/IPermissionManager.aidl +++ b/core/java/android/permission/IPermissionManager.aidl @@ -77,7 +77,8 @@ interface IPermissionManager { List<SplitPermissionInfoParcelable> getSplitPermissions(); void startOneTimePermissionSession(String packageName, int userId, long timeout, - long revokeAfterKilledDelay); + long revokeAfterKilledDelay, int importanceToResetTimer, + int importanceToKeepSessionAlive); void stopOneTimePermissionSession(String packageName, int userId); diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 67699543131a..6b540d72bba0 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -1371,7 +1371,8 @@ public final class PermissionManager { @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) { try { mPermissionManager.startOneTimePermissionSession(packageName, mContext.getUserId(), - timeoutMillis, revokeAfterKilledDelayMillis); + timeoutMillis, revokeAfterKilledDelayMillis, importanceToResetTimer, + importanceToKeepSessionAlive); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index d67a476a428d..033f7263bfc6 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -877,7 +877,7 @@ public interface WindowManager extends ViewManager { * <application> * <property * android:name= - * "android.window.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED" + * "android.window.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED" * android:value="false"/> * </application> * </pre> @@ -885,8 +885,8 @@ public interface WindowManager extends ViewManager { * @hide */ // TODO(b/274924641): Make this public API. - String PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED = - "android.window.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED"; + String PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED = + "android.window.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED"; /** * Application level {@link android.content.pm.PackageManager.Property PackageManager diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index c985ae82307c..a33906267736 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -726,12 +726,6 @@ public class RemoteViews implements Parcelable, Filter { mActions.get(i).visitUris(visitor); } } - if (mLandscape != null) { - mLandscape.visitUris(visitor); - } - if (mPortrait != null) { - mPortrait.visitUris(visitor); - } } private static void visitIconUri(Icon icon, @NonNull Consumer<Uri> visitor) { diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java index ed2a32b3d4c7..bbf9f3c99402 100644 --- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java +++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java @@ -24,10 +24,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import android.app.ActivityOptions; import android.app.PendingIntent; @@ -37,8 +33,6 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; -import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.Looper; @@ -64,7 +58,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Map; import java.util.concurrent.CountDownLatch; -import java.util.function.Consumer; /** * Tests for RemoteViews. @@ -700,61 +693,4 @@ public class RemoteViewsTest { return null; } } - - @Test - public void visitUris() { - RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); - - final Uri imageUri = Uri.parse("content://media/image"); - final Icon icon1 = Icon.createWithContentUri("content://media/icon1"); - final Icon icon2 = Icon.createWithContentUri("content://media/icon2"); - final Icon icon3 = Icon.createWithContentUri("content://media/icon3"); - final Icon icon4 = Icon.createWithContentUri("content://media/icon4"); - views.setImageViewUri(R.id.image, imageUri); - views.setTextViewCompoundDrawables(R.id.text, icon1, icon2, icon3, icon4); - - Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class); - views.visitUris(visitor); - verify(visitor, times(1)).accept(eq(imageUri)); - verify(visitor, times(1)).accept(eq(icon1.getUri())); - verify(visitor, times(1)).accept(eq(icon2.getUri())); - verify(visitor, times(1)).accept(eq(icon3.getUri())); - verify(visitor, times(1)).accept(eq(icon4.getUri())); - } - - @Test - public void visitUris_separateOrientation() { - final RemoteViews landscape = new RemoteViews(mPackage, R.layout.remote_views_test); - final Uri imageUriL = Uri.parse("content://landscape/image"); - final Icon icon1L = Icon.createWithContentUri("content://landscape/icon1"); - final Icon icon2L = Icon.createWithContentUri("content://landscape/icon2"); - final Icon icon3L = Icon.createWithContentUri("content://landscape/icon3"); - final Icon icon4L = Icon.createWithContentUri("content://landscape/icon4"); - landscape.setImageViewUri(R.id.image, imageUriL); - landscape.setTextViewCompoundDrawables(R.id.text, icon1L, icon2L, icon3L, icon4L); - - final RemoteViews portrait = new RemoteViews(mPackage, 33); - final Uri imageUriP = Uri.parse("content://portrait/image"); - final Icon icon1P = Icon.createWithContentUri("content://portrait/icon1"); - final Icon icon2P = Icon.createWithContentUri("content://portrait/icon2"); - final Icon icon3P = Icon.createWithContentUri("content://portrait/icon3"); - final Icon icon4P = Icon.createWithContentUri("content://portrait/icon4"); - portrait.setImageViewUri(R.id.image, imageUriP); - portrait.setTextViewCompoundDrawables(R.id.text, icon1P, icon2P, icon3P, icon4P); - - RemoteViews views = new RemoteViews(landscape, portrait); - - Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class); - views.visitUris(visitor); - verify(visitor, times(1)).accept(eq(imageUriL)); - verify(visitor, times(1)).accept(eq(icon1L.getUri())); - verify(visitor, times(1)).accept(eq(icon2L.getUri())); - verify(visitor, times(1)).accept(eq(icon3L.getUri())); - verify(visitor, times(1)).accept(eq(icon4L.getUri())); - verify(visitor, times(1)).accept(eq(imageUriP)); - verify(visitor, times(1)).accept(eq(icon1P.getUri())); - verify(visitor, times(1)).accept(eq(icon2P.getUri())); - verify(visitor, times(1)).accept(eq(icon3P.getUri())); - verify(visitor, times(1)).accept(eq(icon4P.getUri())); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index 4c2e0dafe698..bdf0ac2ed30c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -164,10 +164,6 @@ public class SplitDecorManager extends WindowlessWindowManager { t.remove(mGapBackgroundLeash); mGapBackgroundLeash = null; } - if (mScreenshot != null) { - t.remove(mScreenshot); - mScreenshot = null; - } mHostLeash = null; mIcon = null; mResizingIconView = null; @@ -327,8 +323,6 @@ public class SplitDecorManager extends WindowlessWindowManager { if (!mShown && mIsResizing && !mOldBounds.equals(mResizingBounds)) { if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) { mScreenshotAnimator.cancel(); - } else if (mScreenshot != null) { - t.remove(mScreenshot); } mTempRect.set(mOldBounds); @@ -345,8 +339,6 @@ public class SplitDecorManager extends WindowlessWindowManager { if (!mShown && mIsResizing && !mOldBounds.equals(mResizingBounds)) { if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) { mScreenshotAnimator.cancel(); - } else if (mScreenshot != null) { - t.remove(mScreenshot); } mScreenshot = screenshot; 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 7da750211b7e..c4b5470f461a 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 @@ -73,6 +73,7 @@ import android.window.TaskOrganizer; import android.window.TaskSnapshot; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; +import android.window.WindowContainerTransactionCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; @@ -144,6 +145,23 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, protected final ShellTaskOrganizer mTaskOrganizer; protected final ShellExecutor mMainExecutor; + // the runnable to execute after WindowContainerTransactions is applied to finish resizing pip + private Runnable mPipFinishResizeWCTRunnable; + + private final WindowContainerTransactionCallback mPipFinishResizeWCTCallback = + new WindowContainerTransactionCallback() { + @Override + public void onTransactionReady(int id, SurfaceControl.Transaction t) { + t.apply(); + + // execute the runnable if non-null after WCT is applied to finish resizing pip + if (mPipFinishResizeWCTRunnable != null) { + mPipFinishResizeWCTRunnable.run(); + mPipFinishResizeWCTRunnable = null; + } + } + }; + // These callbacks are called on the update thread private final PipAnimationController.PipAnimationCallback mPipAnimationCallback = new PipAnimationController.PipAnimationCallback() { @@ -1260,8 +1278,23 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, /** * Animates resizing of the pinned stack given the duration and start bounds. * This is used when the starting bounds is not the current PiP bounds. + * + * @param pipFinishResizeWCTRunnable callback to run after window updates are complete */ public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration, + float startingAngle, Consumer<Rect> updateBoundsCallback, + Runnable pipFinishResizeWCTRunnable) { + mPipFinishResizeWCTRunnable = pipFinishResizeWCTRunnable; + if (mPipFinishResizeWCTRunnable != null) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "mPipFinishResizeWCTRunnable is set to be called once window updates"); + } + + scheduleAnimateResizePip(fromBounds, toBounds, duration, startingAngle, + updateBoundsCallback); + } + + private void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration, float startingAngle, Consumer<Rect> updateBoundsCallback) { if (mWaitForFixedRotation) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, @@ -1566,7 +1599,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mSplitScreenOptional.ifPresent(splitScreenController -> splitScreenController.enterSplitScreen(mTaskInfo.taskId, wasPipTopLeft, wct)); } else { - mTaskOrganizer.applyTransaction(wct); + mTaskOrganizer.applySyncTransaction(wct, mPipFinishResizeWCTCallback); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java index 41ff0b35a035..3e83c5fcf9a0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java @@ -580,8 +580,16 @@ public class PipResizeGestureHandler { final float snapFraction = mPipBoundsAlgorithm.getSnapFraction( mLastResizeBounds, movementBounds); mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds, snapFraction); + + // disable the pinch resizing until the final bounds are updated + final boolean prevEnablePinchResize = mEnablePinchResize; + mEnablePinchResize = false; + mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds, - PINCH_RESIZE_SNAP_DURATION, mAngle, mUpdateResizeBoundsCallback); + PINCH_RESIZE_SNAP_DURATION, mAngle, mUpdateResizeBoundsCallback, () -> { + // reset the pinch resizing to its default state + mEnablePinchResize = prevEnablePinchResize; + }); } else { mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, PipAnimationController.TRANSITION_DIRECTION_USER_RESIZE, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java index c7b9eb3d1074..5f356c93d0a4 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java @@ -155,7 +155,7 @@ public class PipResizeGestureHandlerTest extends ShellTestCase { mPipResizeGestureHandler.onPinchResize(upEvent); verify(mPipTaskOrganizer, times(1)) - .scheduleAnimateResizePip(any(), any(), anyInt(), anyFloat(), any()); + .scheduleAnimateResizePip(any(), any(), anyInt(), anyFloat(), any(), any()); assertTrue("The new size should be bigger than the original PiP size.", mPipResizeGestureHandler.getLastResizeBounds().width() @@ -194,7 +194,7 @@ public class PipResizeGestureHandlerTest extends ShellTestCase { mPipResizeGestureHandler.onPinchResize(upEvent); verify(mPipTaskOrganizer, times(1)) - .scheduleAnimateResizePip(any(), any(), anyInt(), anyFloat(), any()); + .scheduleAnimateResizePip(any(), any(), anyInt(), anyFloat(), any(), any()); assertTrue("The new size should be smaller than the original PiP size.", mPipResizeGestureHandler.getLastResizeBounds().width() diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt index 83e44b69812b..f0a82113c3a3 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt @@ -18,10 +18,8 @@ package com.android.systemui.animation import android.graphics.fonts.Font import android.graphics.fonts.FontVariationAxis -import android.util.LruCache import android.util.MathUtils import android.util.MathUtils.abs -import androidx.annotation.VisibleForTesting import java.lang.Float.max import java.lang.Float.min @@ -36,10 +34,6 @@ private const val FONT_ITALIC_MIN = 0f private const val FONT_ITALIC_ANIMATION_STEP = 0.1f private const val FONT_ITALIC_DEFAULT_VALUE = 0f -// Benchmarked via Perfetto, difference between 10 and 50 entries is about 0.3ms in -// frame draw time on a Pixel 6. -@VisibleForTesting const val FONT_CACHE_MAX_ENTRIES = 10 - /** Provide interpolation of two fonts by adjusting font variation settings. */ class FontInterpolator { @@ -87,8 +81,8 @@ class FontInterpolator { // Font interpolator has two level caches: one for input and one for font with different // variation settings. No synchronization is needed since FontInterpolator is not designed to be // thread-safe and can be used only on UI thread. - private val interpCache = LruCache<InterpKey, Font>(FONT_CACHE_MAX_ENTRIES) - private val verFontCache = LruCache<VarFontKey, Font>(FONT_CACHE_MAX_ENTRIES) + private val interpCache = hashMapOf<InterpKey, Font>() + private val verFontCache = hashMapOf<VarFontKey, Font>() // Mutable keys for recycling. private val tmpInterpKey = InterpKey(null, null, 0f) @@ -158,7 +152,7 @@ class FontInterpolator { tmpVarFontKey.set(start, newAxes) val axesCachedFont = verFontCache[tmpVarFontKey] if (axesCachedFont != null) { - interpCache.put(InterpKey(start, end, progress), axesCachedFont) + interpCache[InterpKey(start, end, progress)] = axesCachedFont return axesCachedFont } @@ -166,8 +160,8 @@ class FontInterpolator { // Font.Builder#build won't throw IOException since creating fonts from existing fonts will // not do any IO work. val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build() - interpCache.put(InterpKey(start, end, progress), newFont) - verFontCache.put(VarFontKey(start, newAxes), newFont) + interpCache[InterpKey(start, end, progress)] = newFont + verFontCache[VarFontKey(start, newAxes)] = newFont return newFont } diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt index 3ee97be360f0..9e9929e79d47 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt @@ -24,10 +24,8 @@ import android.graphics.Canvas import android.graphics.Typeface import android.graphics.fonts.Font import android.text.Layout -import android.util.LruCache private const val DEFAULT_ANIMATION_DURATION: Long = 300 -private const val TYPEFACE_CACHE_MAX_ENTRIES = 5 typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit /** @@ -116,7 +114,7 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { private val fontVariationUtils = FontVariationUtils() - private val typefaceCache = LruCache<String, Typeface>(TYPEFACE_CACHE_MAX_ENTRIES) + private val typefaceCache = HashMap<String, Typeface?>() fun updateLayout(layout: Layout) { textInterpolator.layout = layout @@ -220,12 +218,12 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { } if (!fvar.isNullOrBlank()) { - textInterpolator.targetPaint.typeface = typefaceCache.get(fvar) ?: run { - textInterpolator.targetPaint.fontVariationSettings = fvar - textInterpolator.targetPaint.typeface?.also { + textInterpolator.targetPaint.typeface = + typefaceCache.getOrElse(fvar) { + textInterpolator.targetPaint.fontVariationSettings = fvar typefaceCache.put(fvar, textInterpolator.targetPaint.typeface) + textInterpolator.targetPaint.typeface } - } } if (color != null) { diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index adc4c555dfac..3faacf2882ad 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -396,7 +396,7 @@ <dimen name="navigation_key_width">70dp</dimen> <!-- The width/height of the icon of a navigation button --> - <dimen name="navigation_icon_size">24dp</dimen> + <dimen name="navigation_icon_size">32dp</dimen> <!-- The padding on the side of the navigation bar. Must be greater than or equal to navigation_extra_key_width --> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 16299c7aff7b..061bab8a7006 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -752,7 +752,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard case SimPuk: // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); - if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled( + if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser())) { finish = true; eventSubtype = BOUNCER_DISMISS_SIM; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java index a2872e3c639b..a47565390d6b 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java @@ -182,10 +182,6 @@ public class DreamOverlayStateController implements * Returns collection of present {@link Complication}. */ public Collection<Complication> getComplications(boolean filterByAvailability) { - if (isLowLightActive()) { - // Don't show complications on low light. - return Collections.emptyList(); - } return Collections.unmodifiableCollection(filterByAvailability ? mComplications .stream() @@ -197,8 +193,7 @@ public class DreamOverlayStateController implements if (mShouldShowComplications) { return (requiredTypes & getAvailableComplicationTypes()) == requiredTypes; } - final int typesToAlwaysShow = mSupportedTypes & getAvailableComplicationTypes(); - return (requiredTypes & typesToAlwaysShow) == requiredTypes; + return (requiredTypes & mSupportedTypes) == requiredTypes; }) .collect(Collectors.toCollection(HashSet::new)) : mComplications); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt index ddce516a0fb2..5770f3ee8876 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt @@ -47,7 +47,6 @@ constructor( duration = TO_LOCKSCREEN_DURATION, onStep = { value -> -translatePx + value * translatePx }, interpolator = EMPHASIZED_DECELERATE, - onCancel = { 0f }, ) } diff --git a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java index ef0fa012d56d..a4f1ef4fa756 100644 --- a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java +++ b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java @@ -90,9 +90,6 @@ public class TouchInsetManager { final Region cumulativeRegion = Region.obtain(); mTrackedViews.stream().forEach(view -> { - if (!view.isAttachedToWindow()) { - return; - } final Rect boundaries = new Rect(); view.getDrawingRect(boundaries); ((ViewGroup) view.getRootView()).offsetDescendantRectToMyCoords(view, boundaries); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index 3b3df239b8ea..d49275862757 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -163,6 +163,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<KeyguardSecurityContainer.SwipeListener> mSwipeListenerArgumentCaptor; + private Configuration mConfiguration; + private KeyguardSecurityContainerController mKeyguardSecurityContainerController; private KeyguardPasswordViewController mKeyguardPasswordViewController; private KeyguardPasswordView mKeyguardPasswordView; @@ -170,12 +172,12 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Before public void setup() { + mConfiguration = new Configuration(); + mConfiguration.setToDefaults(); // Defaults to ORIENTATION_UNDEFINED. mTestableResources = mContext.getOrCreateTestableResources(); - mTestableResources.getResources().getConfiguration().orientation = - Configuration.ORIENTATION_UNDEFINED; when(mView.getContext()).thenReturn(mContext); - when(mView.getResources()).thenReturn(mTestableResources.getResources()); + when(mView.getResources()).thenReturn(mContext.getResources()); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* width= */ 0, /* height= */ 0); lp.gravity = 0; @@ -252,8 +254,6 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Test public void onResourcesUpdate_callsThroughOnRotationChange() { - clearInvocations(mView); - // Rotation is the same, shouldn't cause an update mKeyguardSecurityContainerController.updateResources(); verify(mView, never()).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager), @@ -579,12 +579,12 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { // Set initial gravity mTestableResources.addOverride(R.integer.keyguard_host_view_gravity, Gravity.CENTER); - mTestableResources.addOverride( - R.bool.can_use_one_handed_bouncer, false); // Kick off the initial pass... mKeyguardSecurityContainerController.onInit(); - verify(mView).setLayoutParams(any()); + verify(mView).setLayoutParams(argThat( + (ArgumentMatcher<FrameLayout.LayoutParams>) argument -> + argument.gravity == Gravity.CENTER)); clearInvocations(mView); // Now simulate a config change @@ -592,7 +592,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); mKeyguardSecurityContainerController.updateResources(); - verify(mView).setLayoutParams(any()); + verify(mView).setLayoutParams(argThat( + (ArgumentMatcher<FrameLayout.LayoutParams>) argument -> + argument.gravity == (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM))); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt index 57a355f4e127..8a5c5b58d058 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt @@ -106,29 +106,4 @@ class FontInterpolatorTest : SysuiTestCase() { val reversedFont = interp.lerp(endFont, startFont, 0.5f) assertThat(resultFont).isSameInstanceAs(reversedFont) } - - @Test - fun testCacheMaxSize() { - val interp = FontInterpolator() - - val startFont = Font.Builder(sFont) - .setFontVariationSettings("'wght' 100") - .build() - val endFont = Font.Builder(sFont) - .setFontVariationSettings("'wght' 1") - .build() - val resultFont = interp.lerp(startFont, endFont, 0.5f) - for (i in 0..FONT_CACHE_MAX_ENTRIES + 1) { - val f1 = Font.Builder(sFont) - .setFontVariationSettings("'wght' ${i * 100}") - .build() - val f2 = Font.Builder(sFont) - .setFontVariationSettings("'wght' $i") - .build() - interp.lerp(f1, f2, 0.5f) - } - - val cachedFont = interp.lerp(startFont, endFont, 0.5f) - assertThat(resultFont).isNotSameInstanceAs(cachedFont) - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java index d0c1c4db62d4..34fa76fd5d46 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java @@ -235,23 +235,6 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase { } @Test - public void testComplicationsNotShownForLowLight() { - final Complication complication = Mockito.mock(Complication.class); - final DreamOverlayStateController stateController = getDreamOverlayStateController(true); - - // Add a complication and verify it's returned in getComplications. - stateController.addComplication(complication); - mExecutor.runAllReady(); - assertThat(stateController.getComplications().contains(complication)) - .isTrue(); - - stateController.setLowLightActive(true); - mExecutor.runAllReady(); - - assertThat(stateController.getComplications()).isEmpty(); - } - - @Test public void testNotifyLowLightChanged() { final DreamOverlayStateController stateController = getDreamOverlayStateController(true); @@ -353,34 +336,6 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase { } } - @Test - public void testHomeControlsDoNotShowIfNotAvailable_featureEnabled() { - when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true); - - final DreamOverlayStateController stateController = getDreamOverlayStateController(true); - stateController.setShouldShowComplications(true); - - final Complication homeControlsComplication = Mockito.mock(Complication.class); - when(homeControlsComplication.getRequiredTypeAvailability()) - .thenReturn(Complication.COMPLICATION_TYPE_HOME_CONTROLS); - - stateController.addComplication(homeControlsComplication); - - final DreamOverlayStateController.Callback callback = - Mockito.mock(DreamOverlayStateController.Callback.class); - - stateController.addCallback(callback); - mExecutor.runAllReady(); - - // No home controls since it is not available. - assertThat(stateController.getComplications()).doesNotContain(homeControlsComplication); - - stateController.setAvailableComplicationTypes(Complication.COMPLICATION_TYPE_HOME_CONTROLS - | Complication.COMPLICATION_TYPE_WEATHER); - mExecutor.runAllReady(); - assertThat(stateController.getComplications()).contains(homeControlsComplication); - } - private DreamOverlayStateController getDreamOverlayStateController(boolean overlayEnabled) { return new DreamOverlayStateController(mExecutor, overlayEnabled, mFeatureFlags); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt index efa5f0c966e3..0c4e84521a36 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt @@ -92,21 +92,6 @@ class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() { job.cancel() } - @Test - fun lockscreenTranslationYResettedAfterJobCancelled() = - runTest(UnconfinedTestDispatcher()) { - val values = mutableListOf<Float>() - - val pixels = 100 - val job = - underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this) - repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED)) - - assertThat(values.last()).isEqualTo(0f) - - job.cancel() - } - private fun step( value: Float, state: TransitionState = TransitionState.RUNNING diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 4c234a0839e2..89a55e1a3331 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2254,8 +2254,8 @@ public class AudioService extends IAudioService.Stub synchronized (VolumeStreamState.class) { mStreamStates[AudioSystem.STREAM_DTMF] .setAllIndexes(mStreamStates[dtmfStreamAlias], caller); - mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName( - System.VOLUME_SETTINGS_INT[a11yStreamAlias]); + mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName = + System.VOLUME_SETTINGS_INT[a11yStreamAlias]; mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes( mStreamStates[a11yStreamAlias], caller); } @@ -7518,7 +7518,7 @@ public class AudioService extends IAudioService.Stub private int mPublicStreamType = AudioSystem.STREAM_MUSIC; private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes(); private boolean mIsMuted = false; - private String mSettingName; + private final String mSettingName; // No API in AudioSystem to get a device from strategy or from attributes. // Need a valid public stream type to use current API getDeviceForStream @@ -7847,19 +7847,15 @@ public class AudioService extends IAudioService.Stub } private void persistVolumeGroup(int device) { - // No need to persist the index if the volume group is backed up - // by a public stream type as this is redundant - if (mUseFixedVolume || mHasValidStreamType) { + if (mUseFixedVolume) { return; } if (DEBUG_VOL) { Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group " + mAudioVolumeGroup.name() + ", device " + AudioSystem.getOutputDeviceName(device) - + " and User=" + getCurrentUserId() - + " mSettingName: " + mSettingName); + + " and User=" + getCurrentUserId()); } - boolean success = mSettings.putSystemIntForUser(mContentResolver, getSettingNameForDevice(device), getIndex(device), @@ -7922,14 +7918,6 @@ public class AudioService extends IAudioService.Stub return mSettingName + "_" + AudioSystem.getOutputDeviceName(device); } - void setSettingName(String settingName) { - mSettingName = settingName; - } - - String getSettingName() { - return mSettingName; - } - private void dump(PrintWriter pw) { pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); pw.print(" Muted: "); @@ -8054,9 +8042,6 @@ public class AudioService extends IAudioService.Stub */ public void setVolumeGroupState(VolumeGroupState volumeGroupState) { mVolumeGroupState = volumeGroupState; - if (mVolumeGroupState != null) { - mVolumeGroupState.setSettingName(mVolumeIndexSettingName); - } } /** * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission @@ -8127,17 +8112,6 @@ public class AudioService extends IAudioService.Stub return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); } - void setSettingName(String settingName) { - mVolumeIndexSettingName = settingName; - if (mVolumeGroupState != null) { - mVolumeGroupState.setSettingName(mVolumeIndexSettingName); - } - } - - String getSettingName() { - return mVolumeIndexSettingName; - } - public void readSettings() { synchronized (mSettingsLock) { synchronized (VolumeStreamState.class) { @@ -8786,7 +8760,7 @@ public class AudioService extends IAudioService.Stub if (streamState.hasValidSettingsName()) { mSettings.putSystemIntForUser(mContentResolver, streamState.getSettingNameForDevice(device), - (streamState.getIndex(device) + 5) / 10, + (streamState.getIndex(device) + 5)/ 10, UserHandle.USER_CURRENT); } } diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 703ae11ae99b..fa115a5345c2 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -2095,25 +2095,9 @@ final class InstallPackageHelper { // The caller explicitly specified INSTALL_ALL_USERS flag. // Thus, updating the settings to install the app for all users. for (int currentUserId : allUsers) { - // If the app is already installed for the currentUser, - // keep it as installed as we might be updating the app at this place. - // If not currently installed, check if the currentUser is restricted by - // DISALLOW_INSTALL_APPS or DISALLOW_DEBUGGING_FEATURES device policy. - // Install / update the app if the user isn't restricted. Skip otherwise. - final boolean installedForCurrentUser = ArrayUtils.contains( - installedForUsers, currentUserId); - final boolean restrictedByPolicy = - mPm.isUserRestricted(currentUserId, - UserManager.DISALLOW_INSTALL_APPS) - || mPm.isUserRestricted(currentUserId, - UserManager.DISALLOW_DEBUGGING_FEATURES); - if (installedForCurrentUser || !restrictedByPolicy) { - ps.setInstalled(true, currentUserId); - ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId, - installerPackageName); - } else { - ps.setInstalled(false, currentUserId); - } + ps.setInstalled(true, currentUserId); + ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, + installerPackageName); } } diff --git a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java index d28048ce74c7..881f8707fdd8 100644 --- a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java +++ b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java @@ -16,26 +16,23 @@ package com.android.server.pm.permission; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED; + import android.annotation.NonNull; import android.app.ActivityManager; -import android.app.ActivityManagerInternal; import android.app.AlarmManager; -import android.app.IActivityManager; -import android.app.IUidObserver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Handler; -import android.os.RemoteException; import android.permission.PermissionControllerManager; import android.provider.DeviceConfig; import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; -import com.android.server.LocalServices; /** * Class that handles one-time permissions for a user @@ -50,8 +47,7 @@ public class OneTimePermissionUserManager { "one_time_permissions_killed_delay_millis"; private final @NonNull Context mContext; - private final @NonNull IActivityManager mIActivityManager; - private final @NonNull ActivityManagerInternal mActivityManagerInternal; + private final @NonNull ActivityManager mActivityManager; private final @NonNull AlarmManager mAlarmManager; private final @NonNull PermissionControllerManager mPermissionControllerManager; @@ -81,15 +77,49 @@ public class OneTimePermissionUserManager { OneTimePermissionUserManager(@NonNull Context context) { mContext = context; - mIActivityManager = ActivityManager.getService(); - mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); + mActivityManager = context.getSystemService(ActivityManager.class); mAlarmManager = context.getSystemService(AlarmManager.class); mPermissionControllerManager = context.getSystemService(PermissionControllerManager.class); mHandler = context.getMainThreadHandler(); } + /** + * Starts a one-time permission session for a given package. A one-time permission session is + * ended if app becomes inactive. Inactivity is defined as the package's uid importance level + * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid + * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start + * until going > importanceToResetTimer. + * <p> + * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive + * then the session is extended until either the importance goes above + * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which + * will continue the session and reset the timer. + * </p> + * <p> + * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}. + * </p> + * <p> + * Once the session ends PermissionControllerService#onNotifyOneTimePermissionSessionTimeout + * is invoked. + * </p> + * <p> + * Note that if there is currently an active session for a package a new one isn't created and + * the existing one isn't changed. + * </p> + * @param packageName The package to start a one-time permission session for + * @param timeoutMillis Number of milliseconds for an app to be in an inactive state + * @param revokeAfterKilledDelayMillis Number of milliseconds to wait after the process dies + * before ending the session. Set to -1 to use default value + * for the device. + * @param importanceToResetTimer The least important level to uid must be to reset the timer + * @param importanceToKeepSessionAlive The least important level the uid must be to keep the + * session alive + * + * @hide + */ void startPackageOneTimeSession(@NonNull String packageName, long timeoutMillis, - long revokeAfterKilledDelayMillis) { + long revokeAfterKilledDelayMillis, int importanceToResetTimer, + int importanceToKeepSessionAlive) { int uid; try { uid = mContext.getPackageManager().getPackageUid(packageName, 0); @@ -101,11 +131,13 @@ public class OneTimePermissionUserManager { synchronized (mLock) { PackageInactivityListener listener = mListeners.get(uid); if (listener != null) { - listener.updateSessionParameters(timeoutMillis, revokeAfterKilledDelayMillis); + listener.updateSessionParameters(timeoutMillis, revokeAfterKilledDelayMillis, + importanceToResetTimer, importanceToKeepSessionAlive); return; } listener = new PackageInactivityListener(uid, packageName, timeoutMillis, - revokeAfterKilledDelayMillis); + revokeAfterKilledDelayMillis, importanceToResetTimer, + importanceToKeepSessionAlive); mListeners.put(uid, listener); } } @@ -150,58 +182,34 @@ public class OneTimePermissionUserManager { private static final long TIMER_INACTIVE = -1; - private static final int STATE_GONE = 0; - private static final int STATE_TIMER = 1; - private static final int STATE_ACTIVE = 2; - private final int mUid; private final @NonNull String mPackageName; private long mTimeout; private long mRevokeAfterKilledDelay; + private int mImportanceToResetTimer; + private int mImportanceToKeepSessionAlive; private boolean mIsAlarmSet; private boolean mIsFinished; private long mTimerStart = TIMER_INACTIVE; + private final ActivityManager.OnUidImportanceListener mStartTimerListener; + private final ActivityManager.OnUidImportanceListener mSessionKillableListener; + private final ActivityManager.OnUidImportanceListener mGoneListener; + private final Object mInnerLock = new Object(); private final Object mToken = new Object(); - private final IUidObserver.Stub mObserver = new IUidObserver.Stub() { - @Override - public void onUidGone(int uid, boolean disabled) { - if (uid == mUid) { - PackageInactivityListener.this.updateUidState(STATE_GONE); - } - } - - @Override - public void onUidStateChanged(int uid, int procState, long procStateSeq, - int capability) { - if (uid == mUid) { - if (procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - && procState != ActivityManager.PROCESS_STATE_NONEXISTENT) { - PackageInactivityListener.this.updateUidState(STATE_TIMER); - } else { - PackageInactivityListener.this.updateUidState(STATE_ACTIVE); - } - } - } - - public void onUidActive(int uid) { - } - public void onUidIdle(int uid, boolean disabled) { - } - public void onUidProcAdjChanged(int uid) { - } - public void onUidCachedChanged(int uid, boolean cached) { - } - }; private PackageInactivityListener(int uid, @NonNull String packageName, long timeout, - long revokeAfterkilledDelay) { + long revokeAfterkilledDelay, int importanceToResetTimer, + int importanceToKeepSessionAlive) { + Log.i(LOG_TAG, "Start tracking " + packageName + ". uid=" + uid + " timeout=" + timeout - + " killedDelay=" + revokeAfterkilledDelay); + + " killedDelay=" + revokeAfterkilledDelay + + " importanceToResetTimer=" + importanceToResetTimer + + " importanceToKeepSessionAlive=" + importanceToKeepSessionAlive); mUid = uid; mPackageName = packageName; @@ -211,24 +219,27 @@ public class OneTimePermissionUserManager { DeviceConfig.NAMESPACE_PERMISSIONS, PROPERTY_KILLED_DELAY_CONFIG_KEY, DEFAULT_KILLED_DELAY_MILLIS) : revokeAfterkilledDelay; - - try { - mIActivityManager.registerUidObserver(mObserver, - ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE, - ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, - null); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Couldn't check uid proc state", e); - // Can't register uid observer, just revoke immediately - synchronized (mInnerLock) { - onPackageInactiveLocked(); - } - } - - updateUidState(); + mImportanceToResetTimer = importanceToResetTimer; + mImportanceToKeepSessionAlive = importanceToKeepSessionAlive; + + mStartTimerListener = + (changingUid, importance) -> onImportanceChanged(changingUid, importance); + mSessionKillableListener = + (changingUid, importance) -> onImportanceChanged(changingUid, importance); + mGoneListener = + (changingUid, importance) -> onImportanceChanged(changingUid, importance); + + mActivityManager.addOnUidImportanceListener(mStartTimerListener, + importanceToResetTimer); + mActivityManager.addOnUidImportanceListener(mSessionKillableListener, + importanceToKeepSessionAlive); + mActivityManager.addOnUidImportanceListener(mGoneListener, IMPORTANCE_CACHED); + + onImportanceChanged(mUid, mActivityManager.getPackageImportance(packageName)); } - public void updateSessionParameters(long timeoutMillis, long revokeAfterKilledDelayMillis) { + public void updateSessionParameters(long timeoutMillis, long revokeAfterKilledDelayMillis, + int importanceToResetTimer, int importanceToKeepSessionAlive) { synchronized (mInnerLock) { mTimeout = Math.min(mTimeout, timeoutMillis); mRevokeAfterKilledDelay = Math.min(mRevokeAfterKilledDelay, @@ -237,74 +248,63 @@ public class OneTimePermissionUserManager { DeviceConfig.NAMESPACE_PERMISSIONS, PROPERTY_KILLED_DELAY_CONFIG_KEY, DEFAULT_KILLED_DELAY_MILLIS) : revokeAfterKilledDelayMillis); + mImportanceToResetTimer = Math.min(importanceToResetTimer, mImportanceToResetTimer); + mImportanceToKeepSessionAlive = Math.min(importanceToKeepSessionAlive, + mImportanceToKeepSessionAlive); Log.v(LOG_TAG, "Updated params for " + mPackageName + ". timeout=" + mTimeout - + " killedDelay=" + mRevokeAfterKilledDelay); - updateUidState(); + + " killedDelay=" + mRevokeAfterKilledDelay + + " importanceToResetTimer=" + mImportanceToResetTimer + + " importanceToKeepSessionAlive=" + mImportanceToKeepSessionAlive); + onImportanceChanged(mUid, mActivityManager.getPackageImportance(mPackageName)); } } - private int getCurrentState() { - return getStateFromProcState(mActivityManagerInternal.getUidProcessState(mUid)); - } - - private int getStateFromProcState(int procState) { - if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { - return STATE_GONE; - } else { - if (procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - return STATE_TIMER; - } else { - return STATE_ACTIVE; - } + private void onImportanceChanged(int uid, int importance) { + if (uid != mUid) { + return; } - } - private void updateUidState() { - updateUidState(getCurrentState()); - } - - private void updateUidState(int state) { - Log.v(LOG_TAG, "Updating state for " + mPackageName + " (" + mUid + ")." - + " state=" + state); + Log.v(LOG_TAG, "Importance changed for " + mPackageName + " (" + mUid + ")." + + " importance=" + importance); synchronized (mInnerLock) { // Remove any pending inactivity callback mHandler.removeCallbacksAndMessages(mToken); - if (state == STATE_GONE) { + if (importance > IMPORTANCE_CACHED) { if (mRevokeAfterKilledDelay == 0) { onPackageInactiveLocked(); return; } // Delay revocation in case app is restarting mHandler.postDelayed(() -> { - int currentState; - synchronized (mInnerLock) { - currentState = getCurrentState(); - if (currentState == STATE_GONE) { - onPackageInactiveLocked(); - return; + int imp = mActivityManager.getUidImportance(mUid); + if (imp > IMPORTANCE_CACHED) { + onPackageInactiveLocked(); + } else { + if (DEBUG) { + Log.d(LOG_TAG, "No longer gone after delayed revocation. " + + "Rechecking for " + mPackageName + " (" + mUid + ")."); } + onImportanceChanged(mUid, imp); } - if (DEBUG) { - Log.d(LOG_TAG, "No longer gone after delayed revocation. " - + "Rechecking for " + mPackageName + " (" + mUid - + ")."); - } - updateUidState(currentState); }, mToken, mRevokeAfterKilledDelay); return; - } else if (state == STATE_TIMER) { + } + if (importance > mImportanceToResetTimer) { if (mTimerStart == TIMER_INACTIVE) { if (DEBUG) { Log.d(LOG_TAG, "Start the timer for " + mPackageName + " (" + mUid + ")."); } mTimerStart = System.currentTimeMillis(); - setAlarmLocked(); } - } else if (state == STATE_ACTIVE) { + } else { mTimerStart = TIMER_INACTIVE; + } + if (importance > mImportanceToKeepSessionAlive) { + setAlarmLocked(); + } else { cancelAlarmLocked(); } } @@ -318,9 +318,19 @@ public class OneTimePermissionUserManager { mIsFinished = true; cancelAlarmLocked(); try { - mIActivityManager.unregisterUidObserver(mObserver); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Unable to unregister uid observer.", e); + mActivityManager.removeOnUidImportanceListener(mStartTimerListener); + } catch (IllegalArgumentException e) { + Log.e(LOG_TAG, "Could not remove start timer listener", e); + } + try { + mActivityManager.removeOnUidImportanceListener(mSessionKillableListener); + } catch (IllegalArgumentException e) { + Log.e(LOG_TAG, "Could not remove session killable listener", e); + } + try { + mActivityManager.removeOnUidImportanceListener(mGoneListener); + } catch (IllegalArgumentException e) { + Log.e(LOG_TAG, "Could not remove gone listener", e); } } } @@ -384,11 +394,9 @@ public class OneTimePermissionUserManager { mPermissionControllerManager.notifyOneTimePermissionSessionTimeout( mPackageName); }); - try { - mIActivityManager.unregisterUidObserver(mObserver); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Unable to unregister uid observer.", e); - } + mActivityManager.removeOnUidImportanceListener(mStartTimerListener); + mActivityManager.removeOnUidImportanceListener(mSessionKillableListener); + mActivityManager.removeOnUidImportanceListener(mGoneListener); synchronized (mLock) { mListeners.remove(mUid); } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 9ebe6b4470a0..1c2603c796c8 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -386,7 +386,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { @Override public void startOneTimePermissionSession(String packageName, @UserIdInt int userId, - long timeoutMillis, long revokeAfterKilledDelayMillis) { + long timeoutMillis, long revokeAfterKilledDelayMillis, int importanceToResetTimer, + int importanceToKeepSessionAlive) { mContext.enforceCallingOrSelfPermission( Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS, "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS @@ -396,7 +397,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { final long token = Binder.clearCallingIdentity(); try { getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName, - timeoutMillis, revokeAfterKilledDelayMillis); + timeoutMillis, revokeAfterKilledDelayMillis, importanceToResetTimer, + importanceToKeepSessionAlive); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 684e787ec4cf..4b2cb7db56cb 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -48,9 +48,9 @@ import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTA import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH; import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE; import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE; -import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE; import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS; +import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION; import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM; @@ -241,7 +241,7 @@ final class LetterboxUiController { private final Boolean mBooleanPropertyIgnoreRequestedOrientation; @Nullable - private final Boolean mBooleanPropertyAllowIgnoringOrientationRequestWhenLoopDetected; + private final Boolean mBooleanPropertyIgnoreOrientationRequestWhenLoopDetected; @Nullable private final Boolean mBooleanPropertyFakeFocus; @@ -264,10 +264,10 @@ final class LetterboxUiController { readComponentProperty(packageManager, mActivityRecord.packageName, mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled, PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION); - mBooleanPropertyAllowIgnoringOrientationRequestWhenLoopDetected = + mBooleanPropertyIgnoreOrientationRequestWhenLoopDetected = readComponentProperty(packageManager, mActivityRecord.packageName, mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled, - PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED); + PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED); mBooleanPropertyFakeFocus = readComponentProperty(packageManager, mActivityRecord.packageName, mLetterboxConfiguration::isCompatFakeFocusEnabled, @@ -453,7 +453,7 @@ final class LetterboxUiController { /* gatingCondition */ mLetterboxConfiguration ::isPolicyForIgnoringRequestedOrientationEnabled, mIsOverrideEnableCompatIgnoreOrientationRequestWhenLoopDetectedEnabled, - mBooleanPropertyAllowIgnoringOrientationRequestWhenLoopDetected)) { + mBooleanPropertyIgnoreOrientationRequestWhenLoopDetected)) { return false; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 95fea0ee22f5..2d21e710bca8 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2053,16 +2053,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP /** * Like isOnScreen(), but we don't return true if the window is part - * of a transition that has not yet been started. + * of a transition but has not yet started animating. */ boolean isReadyForDisplay() { - if (mToken.waitingToShow && getDisplayContent().mAppTransition.isTransitionSet()) { + if (!mHasSurface || mDestroying || !isVisibleByPolicy()) { + return false; + } + if (mToken.waitingToShow && getDisplayContent().mAppTransition.isTransitionSet() + && !isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION)) { return false; } final boolean parentAndClientVisible = !isParentWindowHidden() && mViewVisibility == View.VISIBLE && mToken.isVisible(); - return mHasSurface && isVisibleByPolicy() && !mDestroying - && (parentAndClientVisible || isAnimating(TRANSITION | PARENTS)); + return parentAndClientVisible || isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_ALL); } boolean isFullyTransparent() { diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java index 86d4655e9d3a..c78678431dac 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java @@ -228,15 +228,6 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest { }); } - public void testShortcutIdTruncated() { - ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), - "s".repeat(Short.MAX_VALUE)).build(); - - assertTrue( - "id must be truncated to MAX_ID_LENGTH", - si.getId().length() <= ShortcutInfo.MAX_ID_LENGTH); - } - public void testShortcutInfoParcel() { setCaller(CALLING_PACKAGE_1, USER_10); ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext) diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 8f8b1c50891a..874846d333cf 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -128,7 +128,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Person; import android.app.RemoteInput; -import android.app.RemoteInputHistoryItem; import android.app.StatsManager; import android.app.admin.DevicePolicyManagerInternal; import android.app.usage.UsageStatsManagerInternal; @@ -5374,36 +5373,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testVisitUris() throws Exception { final Uri audioContents = Uri.parse("content://com.example/audio"); final Uri backgroundImage = Uri.parse("content://com.example/background"); - final Icon personIcon1 = Icon.createWithContentUri("content://media/person1"); - final Icon personIcon2 = Icon.createWithContentUri("content://media/person2"); - final Icon personIcon3 = Icon.createWithContentUri("content://media/person3"); - final Person person1 = new Person.Builder() - .setName("Messaging Person") - .setIcon(personIcon1) - .build(); - final Person person2 = new Person.Builder() - .setName("People List Person 1") - .setIcon(personIcon2) - .build(); - final Person person3 = new Person.Builder() - .setName("People List Person 2") - .setIcon(personIcon3) - .build(); - final Uri historyUri1 = Uri.parse("content://com.example/history1"); - final Uri historyUri2 = Uri.parse("content://com.example/history2"); - final RemoteInputHistoryItem historyItem1 = new RemoteInputHistoryItem(null, historyUri1, - "a"); - final RemoteInputHistoryItem historyItem2 = new RemoteInputHistoryItem(null, historyUri2, - "b"); Bundle extras = new Bundle(); extras.putParcelable(Notification.EXTRA_AUDIO_CONTENTS_URI, audioContents); extras.putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, backgroundImage.toString()); - extras.putParcelable(Notification.EXTRA_MESSAGING_PERSON, person1); - extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, - new ArrayList<>(Arrays.asList(person2, person3))); - extras.putParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, - new RemoteInputHistoryItem[]{historyItem1, historyItem2}); Notification n = new Notification.Builder(mContext, "a") .setContentTitle("notification with uris") @@ -5415,34 +5388,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { n.visitUris(visitor); verify(visitor, times(1)).accept(eq(audioContents)); verify(visitor, times(1)).accept(eq(backgroundImage)); - verify(visitor, times(1)).accept(eq(personIcon1.getUri())); - verify(visitor, times(1)).accept(eq(personIcon2.getUri())); - verify(visitor, times(1)).accept(eq(personIcon3.getUri())); - verify(visitor, times(1)).accept(eq(historyUri1)); - verify(visitor, times(1)).accept(eq(historyUri2)); - } - - @Test - public void testVisitUris_callStyle() { - Icon personIcon = Icon.createWithContentUri("content://media/person"); - Icon verificationIcon = Icon.createWithContentUri("content://media/verification"); - Person callingPerson = new Person.Builder().setName("Someone") - .setIcon(personIcon) - .build(); - PendingIntent hangUpIntent = PendingIntent.getActivity(mContext, 0, new Intent(), - PendingIntent.FLAG_IMMUTABLE); - Notification n = new Notification.Builder(mContext, "a") - .setStyle(Notification.CallStyle.forOngoingCall(callingPerson, hangUpIntent) - .setVerificationIcon(verificationIcon)) - .setContentTitle("Calling...") - .setSmallIcon(android.R.drawable.sym_def_app_icon) - .build(); - - Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class); - n.visitUris(visitor); - - verify(visitor, times(1)).accept(eq(personIcon.getUri())); - verify(visitor, times(1)).accept(eq(verificationIcon.getUri())); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java index 4ffd18a99d58..b277283134e2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java @@ -39,9 +39,9 @@ import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTA import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH; import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE; import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE; -import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE; import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS; +import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED; import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -206,7 +206,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase { throws Exception { doReturn(true).when(mLetterboxConfiguration) .isPolicyForIgnoringRequestedOrientationEnabled(); - mockThatProperty(PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED, + mockThatProperty(PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED, /* value */ false); doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio(); |