diff options
29 files changed, 414 insertions, 88 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 5c1b3ee0134b..2eb6ca758970 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2840,6 +2840,10 @@ public class Notification implements Parcelable * @hide */ public void visitUris(@NonNull Consumer<Uri> visitor) { + if (publicVersion != null) { + publicVersion.visitUris(visitor); + } + visitor.accept(sound); if (tickerView != null) tickerView.visitUris(visitor); diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java index dacb25ca1628..bb5dd7f0cdfe 100644 --- a/core/java/android/speech/SpeechRecognizer.java +++ b/core/java/android/speech/SpeechRecognizer.java @@ -812,7 +812,7 @@ public class SpeechRecognizer { Intent recognizerIntent, Executor callbackExecutor, RecognitionSupportCallback recognitionSupportCallback) { - if (!maybeInitializeManagerService()) { + if (!maybeInitializeManagerService() || !checkOpenConnection()) { return; } try { @@ -831,7 +831,7 @@ public class SpeechRecognizer { Intent recognizerIntent, @Nullable Executor callbackExecutor, @Nullable ModelDownloadListener modelDownloadListener) { - if (!maybeInitializeManagerService()) { + if (!maybeInitializeManagerService() || !checkOpenConnection()) { return; } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index d8bff1c4cb10..f570c6d15672 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -658,6 +658,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation /** Set of inset types which cannot be controlled by the user animation */ private @InsetsType int mDisabledUserAnimationInsetsTypes; + /** Set of inset types which are existing */ + private @InsetsType int mExistingTypes = 0; + /** Set of inset types which are visible */ private @InsetsType int mVisibleTypes = WindowInsets.Type.defaultVisible(); @@ -906,6 +909,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } mVisibleTypes = visibleTypes; } + if (mExistingTypes != existingTypes) { + if (WindowInsets.Type.hasCompatSystemBars(mExistingTypes ^ existingTypes)) { + mCompatSysUiVisibilityStaled = true; + } + mExistingTypes = existingTypes; + } InsetsState.traverse(mState, newState, mRemoveGoneSources); updateDisabledUserAnimationTypes(disabledUserAnimationTypes); @@ -1662,7 +1671,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mCompatSysUiVisibilityStaled) { mCompatSysUiVisibilityStaled = false; mHost.updateCompatSysUiVisibility( - mVisibleTypes, mRequestedVisibleTypes, mControllableTypes); + // Treat non-existing types as controllable types for compatibility. + mVisibleTypes, mRequestedVisibleTypes, mControllableTypes | ~mExistingTypes); } } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 5525336735b7..dedbf50124f9 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -726,6 +726,11 @@ public class RemoteViews implements Parcelable, Filter { mActions.get(i).visitUris(visitor); } } + if (mSizedRemoteViews != null) { + for (int i = 0; i < mSizedRemoteViews.size(); i++) { + mSizedRemoteViews.get(i).visitUris(visitor); + } + } if (mLandscape != null) { mLandscape.visitUris(visitor); } diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java index 2695b9c7651f..1ac5e1f12bfa 100644 --- a/core/java/com/android/internal/widget/ImageFloatingTextView.java +++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java @@ -82,7 +82,7 @@ public class ImageFloatingTextView extends TextView { .setIncludePad(getIncludeFontPadding()) .setUseLineSpacingFromFallbacks(true) .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY) - .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL); + .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL_FAST); int maxLines; if (mMaxLinesForHeight > 0) { maxLines = mMaxLinesForHeight; diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java index 78798015729f..b42a4bdc352f 100644 --- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java +++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java @@ -58,6 +58,7 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; @@ -774,4 +775,43 @@ public class RemoteViewsTest { verify(visitor, times(1)).accept(eq(icon3P.getUri())); verify(visitor, times(1)).accept(eq(icon4P.getUri())); } + + @Test + public void visitUris_sizedViews() { + final RemoteViews large = new RemoteViews(mPackage, R.layout.remote_views_test); + final Uri imageUriL = Uri.parse("content://large/image"); + final Icon icon1L = Icon.createWithContentUri("content://large/icon1"); + final Icon icon2L = Icon.createWithContentUri("content://large/icon2"); + final Icon icon3L = Icon.createWithContentUri("content://large/icon3"); + final Icon icon4L = Icon.createWithContentUri("content://large/icon4"); + large.setImageViewUri(R.id.image, imageUriL); + large.setTextViewCompoundDrawables(R.id.text, icon1L, icon2L, icon3L, icon4L); + + final RemoteViews small = new RemoteViews(mPackage, 33); + final Uri imageUriS = Uri.parse("content://small/image"); + final Icon icon1S = Icon.createWithContentUri("content://small/icon1"); + final Icon icon2S = Icon.createWithContentUri("content://small/icon2"); + final Icon icon3S = Icon.createWithContentUri("content://small/icon3"); + final Icon icon4S = Icon.createWithContentUri("content://small/icon4"); + small.setImageViewUri(R.id.image, imageUriS); + small.setTextViewCompoundDrawables(R.id.text, icon1S, icon2S, icon3S, icon4S); + + HashMap<SizeF, RemoteViews> sizedViews = new HashMap<>(); + sizedViews.put(new SizeF(300, 300), large); + sizedViews.put(new SizeF(100, 100), small); + RemoteViews views = new RemoteViews(sizedViews); + + 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(imageUriS)); + verify(visitor, times(1)).accept(eq(icon1S.getUri())); + verify(visitor, times(1)).accept(eq(icon2S.getUri())); + verify(visitor, times(1)).accept(eq(icon3S.getUri())); + verify(visitor, times(1)).accept(eq(icon4S.getUri())); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java index 4d8075a9b56c..658359ed31d0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java @@ -121,21 +121,21 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler } boolean hasOpeningOcclude = false; + boolean hasClosingOcclude = false; boolean hasOpeningDream = false; boolean hasClosingApp = false; // Check for occluding/dream/closing apps for (int i = info.getChanges().size() - 1; i >= 0; i--) { final TransitionInfo.Change change = info.getChanges().get(i); - if (isOpeningType(change.getMode())) { - if (change.hasFlags(FLAG_OCCLUDES_KEYGUARD)) { - hasOpeningOcclude = true; - } - if (change.getTaskInfo() != null - && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM) { - hasOpeningDream = true; - } + if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) { + continue; + } else if (isOpeningType(change.getMode())) { + hasOpeningOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD); + hasOpeningDream |= (change.getTaskInfo() != null + && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM); } else if (isClosingType(change.getMode())) { + hasClosingOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD); hasClosingApp = true; } } @@ -147,6 +147,11 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler transition, info, startTransaction, finishTransaction, finishCallback); } if (hasOpeningOcclude || info.getType() == TRANSIT_KEYGUARD_OCCLUDE) { + if (hasClosingOcclude) { + // Transitions between apps on top of the keyguard can use the default handler. + // WM sends a final occlude status update after the transition is finished. + return false; + } if (hasOpeningDream) { return startAnimation(mOccludeByDreamTransition, "occlude-by-dream", diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml new file mode 100644 index 000000000000..2a8092010a37 --- /dev/null +++ b/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<resources> + <!-- Invisibility to use for the date & weather view when it is disabled by a clock --> + <integer name="keyguard_date_weather_view_invisibility">8</integer> +</resources> diff --git a/packages/SystemUI/res-keyguard/values/integers.xml b/packages/SystemUI/res-keyguard/values/integers.xml index c6e90c0fcdec..b08fde339d65 100644 --- a/packages/SystemUI/res-keyguard/values/integers.xml +++ b/packages/SystemUI/res-keyguard/values/integers.xml @@ -27,4 +27,7 @@ 0x50 = bottom, 0x01 = center_horizontal --> <integer name="keyguard_host_view_one_handed_gravity">0x51</integer> + + <!-- Invisibility to use for the date & weather view when it is disabled by a clock --> + <integer name="keyguard_date_weather_view_invisibility">4</integer> </resources> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index d8bf570954df..99e25745dda7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -86,6 +86,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private int mKeyguardSmallClockTopMargin = 0; private int mKeyguardLargeClockTopMargin = 0; + private int mKeyguardDateWeatherViewInvisibility = View.INVISIBLE; private final ClockRegistry.ClockChangeListener mClockChangedListener; private ViewGroup mStatusArea; @@ -201,6 +202,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin); mKeyguardLargeClockTopMargin = mView.getResources().getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin); + mKeyguardDateWeatherViewInvisibility = + mView.getResources().getInteger(R.integer.keyguard_date_weather_view_invisibility); if (mOnlyClock) { View ksv = mView.findViewById(R.id.keyguard_slice_view); @@ -335,7 +338,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin); mKeyguardLargeClockTopMargin = mView.getResources().getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin); + mKeyguardDateWeatherViewInvisibility = + mView.getResources().getInteger(R.integer.keyguard_date_weather_view_invisibility); mView.updateClockTargetRegions(); + setDateWeatherVisibility(); } @@ -497,8 +503,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private void setDateWeatherVisibility() { if (mDateWeatherView != null) { mUiExecutor.execute(() -> { - mDateWeatherView.setVisibility( - clockHasCustomWeatherDataDisplay() ? View.INVISIBLE : View.VISIBLE); + mDateWeatherView.setVisibility(clockHasCustomWeatherDataDisplay() + ? mKeyguardDateWeatherViewInvisibility + : View.VISIBLE); }); } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index a2b159cda284..d6c082928168 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -731,4 +731,9 @@ object Flags { // TODO(b/283084712): Tracking Bug @JvmField val IMPROVED_HUN_ANIMATIONS = unreleasedFlag(283084712, "improved_hun_animations") + + // TODO(b/283447257): Tracking bug + @JvmField + val BIGPICTURE_NOTIFICATION_LAZY_LOADING = + unreleasedFlag(283447257, "bigpicture_notification_lazy_loading") } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index b8d3121518e9..d2526dffcc52 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -141,8 +141,8 @@ public class KeyguardService extends Service { return apps.length == 0 ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER : TRANSIT_OLD_KEYGUARD_GOING_AWAY; } else if (type == TRANSIT_KEYGUARD_OCCLUDE) { - boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo.topActivityType - == WindowConfiguration.ACTIVITY_TYPE_DREAM; + boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo != null + && apps[0].taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_DREAM; if (isOccludeByDream) return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; return TRANSIT_OLD_KEYGUARD_OCCLUDE; } else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 122e25975837..1a158c89dee7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -637,7 +637,9 @@ class KeyguardUnlockAnimationController @Inject constructor( * Unlock to the launcher, using in-window animations, and the smartspace shared element * transition if possible. */ - private fun unlockToLauncherWithInWindowAnimations() { + + @VisibleForTesting + fun unlockToLauncherWithInWindowAnimations() { setSurfaceBehindAppearAmount(1f, wallpapers = false) try { @@ -662,7 +664,9 @@ class KeyguardUnlockAnimationController @Inject constructor( // Now that the Launcher surface (with its smartspace positioned identically to ours) is // visible, hide our smartspace. - lockscreenSmartspace?.visibility = View.INVISIBLE + if (lockscreenSmartspace?.visibility == View.VISIBLE) { + lockscreenSmartspace?.visibility = View.INVISIBLE + } // Start an animation for the wallpaper, which will finish keyguard exit when it completes. fadeInWallpaper() @@ -914,7 +918,9 @@ class KeyguardUnlockAnimationController @Inject constructor( willUnlockWithSmartspaceTransition = false // The lockscreen surface is gone, so it is now safe to re-show the smartspace. - lockscreenSmartspace?.visibility = View.VISIBLE + if (lockscreenSmartspace?.visibility == View.INVISIBLE) { + lockscreenSmartspace?.visibility = View.VISIBLE + } listeners.forEach { it.onUnlockAnimationFinished() } } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt index 1fd11bd61700..77e2847cbe76 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt @@ -607,7 +607,7 @@ class BackPanelController internal constructor( ) } - private var previousPreThresholdWidthInterpolator = params.entryWidthTowardsEdgeInterpolator + private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator private fun preThresholdWidthStretchAmount(progress: Float): Float { val interpolator = run { val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt index 6d881d527ce4..9ddb78ae19ee 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt @@ -147,8 +147,21 @@ data class EdgePanelParams(private var resources: Resources) { val flungCommittedWidthSpring = createSpring(10000f, 1f) val flungCommittedHeightSpring = createSpring(10000f, 1f) - val entryIndicatorAlphaThreshold = .23f - val entryIndicatorAlphaFactor = 1.05f + val commonArrowDimensAlphaThreshold = .165f + val commonArrowDimensAlphaFactor = 1.05f + val commonArrowDimensAlphaSpring = Step( + threshold = commonArrowDimensAlphaThreshold, + factor = commonArrowDimensAlphaFactor, + postThreshold = createSpring(180f, 0.9f), + preThreshold = createSpring(2000f, 0.6f) + ) + val commonArrowDimensAlphaSpringInterpolator = Step( + threshold = commonArrowDimensAlphaThreshold, + factor = commonArrowDimensAlphaFactor, + postThreshold = 1f, + preThreshold = 0f + ) + entryIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin), scale = getDimenFloat(R.dimen.navigation_edge_entry_scale), @@ -162,18 +175,8 @@ data class EdgePanelParams(private var resources: Resources) { alpha = 0f, lengthSpring = createSpring(600f, 0.4f), heightSpring = createSpring(600f, 0.4f), - alphaSpring = Step( - threshold = entryIndicatorAlphaThreshold, - factor = entryIndicatorAlphaFactor, - postThreshold = createSpring(200f, 1f), - preThreshold = createSpring(2000f, 0.6f) - ), - alphaInterpolator = Step( - threshold = entryIndicatorAlphaThreshold, - factor = entryIndicatorAlphaFactor, - postThreshold = 1f, - preThreshold = 0f - ) + alphaSpring = commonArrowDimensAlphaSpring, + alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), backgroundDimens = BackgroundDimens( alpha = 1f, @@ -188,20 +191,6 @@ data class EdgePanelParams(private var resources: Resources) { ) ) - val preThresholdAndActiveIndicatorAlphaThreshold = .355f - val preThresholdAndActiveIndicatorAlphaFactor = 1.05f - val preThresholdAndActiveAlphaSpring = Step( - threshold = preThresholdAndActiveIndicatorAlphaThreshold, - factor = preThresholdAndActiveIndicatorAlphaFactor, - postThreshold = createSpring(180f, 0.9f), - preThreshold = createSpring(2000f, 0.6f) - ) - val preThresholdAndActiveAlphaSpringInterpolator = Step( - threshold = preThresholdAndActiveIndicatorAlphaThreshold, - factor = preThresholdAndActiveIndicatorAlphaFactor, - postThreshold = 1f, - preThreshold = 0f - ) activeIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin), scale = getDimenFloat(R.dimen.navigation_edge_active_scale), @@ -214,8 +203,8 @@ data class EdgePanelParams(private var resources: Resources) { alpha = 1f, lengthSpring = activeCommittedArrowLengthSpring, heightSpring = activeCommittedArrowHeightSpring, - alphaSpring = preThresholdAndActiveAlphaSpring, - alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator + alphaSpring = commonArrowDimensAlphaSpring, + alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), backgroundDimens = BackgroundDimens( alpha = 1f, @@ -242,8 +231,8 @@ data class EdgePanelParams(private var resources: Resources) { alpha = 1f, lengthSpring = createSpring(100f, 0.6f), heightSpring = createSpring(100f, 0.6f), - alphaSpring = preThresholdAndActiveAlphaSpring, - alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator + alphaSpring = commonArrowDimensAlphaSpring, + alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), backgroundDimens = BackgroundDimens( alpha = 1f, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java index fb738454fc71..b21cc6dde815 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -150,6 +150,8 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { .thenReturn(100); when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin)) .thenReturn(-200); + when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility)) + .thenReturn(View.INVISIBLE); when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame); when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java index 68dc6c04bc79..4d3243a2ccf6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java @@ -15,11 +15,13 @@ */ package com.android.keyguard; +import static org.junit.Assume.assumeFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.pm.PackageManager; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; @@ -76,12 +78,20 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase { @Test public void refresh_replacesSliceContentAndNotifiesListener() { + // Skips the test if running on a watch because watches don't have a SliceManager system + // service. + assumeFalse(isWatch()); + mController.refresh(); verify(mView).hideSlice(); } @Test public void onAttachedToWindow_registersListeners() { + // Skips the test if running on a watch because watches don't have a SliceManager system + // service. + assumeFalse(isWatch()); + mController.init(); verify(mTunerService).addTunable(any(TunerService.Tunable.class), anyString()); verify(mConfigurationController).addCallback( @@ -90,6 +100,10 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase { @Test public void onDetachedFromWindow_unregistersListeners() { + // Skips the test if running on a watch because watches don't have a SliceManager system + // service. + assumeFalse(isWatch()); + ArgumentCaptor<View.OnAttachStateChangeListener> attachListenerArgumentCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class); @@ -102,4 +116,9 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase { verify(mConfigurationController).removeCallback( any(ConfigurationController.ConfigurationListener.class)); } + + private boolean isWatch() { + final PackageManager pm = mContext.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_WATCH); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt index 688c2db044e4..477e076669b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt @@ -10,6 +10,7 @@ import android.testing.TestableLooper.RunWithLooper import android.view.RemoteAnimationTarget import android.view.SurfaceControl import android.view.SyncRtSurfaceTransactionApplier +import android.view.View import android.view.ViewRootImpl import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardViewController @@ -32,6 +33,7 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.mock +import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions @@ -374,6 +376,83 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { verifyNoMoreInteractions(surfaceTransactionApplier) } + @Test + fun unlockToLauncherWithInWindowAnimations_ssViewIsVisible() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.VISIBLE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations() + + verify(mockLockscreenSmartspaceView).visibility = View.INVISIBLE + } + + @Test + fun unlockToLauncherWithInWindowAnimations_ssViewIsInvisible() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations() + + verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE + } + + @Test + fun unlockToLauncherWithInWindowAnimations_ssViewIsGone() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations() + + verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE + } + + @Test + fun notifyFinishedKeyguardExitAnimation_ssViewIsInvisibleAndCancelledIsTrue() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true) + + verify(mockLockscreenSmartspaceView).visibility = View.VISIBLE + } + + @Test + fun notifyFinishedKeyguardExitAnimation_ssViewIsGoneAndCancelledIsTrue() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true) + + verify(mockLockscreenSmartspaceView, never()).visibility = View.VISIBLE + } + + @Test + fun notifyFinishedKeyguardExitAnimation_ssViewIsInvisibleAndCancelledIsFalse() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(false) + + verify(mockLockscreenSmartspaceView).visibility = View.VISIBLE + } + + @Test + fun notifyFinishedKeyguardExitAnimation_ssViewIsGoneAndCancelledIsFalse() { + val mockLockscreenSmartspaceView = mock(View::class.java) + whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE) + keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView + + keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(false) + + verify(mockLockscreenSmartspaceView, never()).visibility = View.VISIBLE + } + private class ArgThatCaptor<T> { private var allArgs: MutableList<T> = mutableListOf() diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java new file mode 100644 index 000000000000..7351ef59feca --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 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.autofill; + +import android.annotation.Nullable; +import android.os.Bundle; +import android.os.RemoteCallback; +import android.util.Slog; +import android.view.autofill.AutofillId; +import android.view.inputmethod.InlineSuggestionsRequest; + +import java.lang.ref.WeakReference; +import java.util.function.Consumer; + +final class InlineSuggestionRendorInfoCallbackOnResultListener implements + RemoteCallback.OnResultListener{ + private static final String TAG = "InlineSuggestionRendorInfoCallbackOnResultListener"; + + private final int mRequestIdCopy; + private final AutofillId mFocusedId; + private final WeakReference<Session> mSessionWeakReference; + private final Consumer<InlineSuggestionsRequest> mInlineSuggestionsRequestConsumer; + + InlineSuggestionRendorInfoCallbackOnResultListener(WeakReference<Session> sessionWeakReference, + int requestIdCopy, + Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer, + AutofillId focusedId) { + this.mRequestIdCopy = requestIdCopy; + this.mInlineSuggestionsRequestConsumer = inlineSuggestionsRequestConsumer; + this.mSessionWeakReference = sessionWeakReference; + this.mFocusedId = focusedId; + } + public void onResult(@Nullable Bundle result) { + Session session = this.mSessionWeakReference.get(); + if (session == null) { + Slog.wtf(TAG, "Session is null before trying to call onResult"); + return; + } + synchronized (session.mLock) { + if (session.mDestroyed) { + Slog.wtf(TAG, "Session is destroyed before trying to call onResult"); + return; + } + session.mInlineSessionController.onCreateInlineSuggestionsRequestLocked( + this.mFocusedId, + session.inlineSuggestionsRequestCacheDecorator( + this.mInlineSuggestionsRequestConsumer, this.mRequestIdCopy), + result); + } + } +} diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 0a8f474fd4cc..d2d99b1a0a5e 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -184,6 +184,7 @@ import com.android.server.wm.ActivityTaskManagerInternal; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -321,7 +322,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState * Id of the View currently being displayed. */ @GuardedBy("mLock") - @Nullable private AutofillId mCurrentViewId; + @Nullable AutofillId mCurrentViewId; @GuardedBy("mLock") private IAutoFillManagerClient mClient; @@ -369,7 +370,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState private Bundle mClientState; @GuardedBy("mLock") - private boolean mDestroyed; + boolean mDestroyed; /** * Helper used to handle state of Save UI when it must be hiding to show a custom description @@ -448,7 +449,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState private ArrayList<AutofillId> mAugmentedAutofillableIds; @NonNull - private final AutofillInlineSessionController mInlineSessionController; + final AutofillInlineSessionController mInlineSessionController; /** * Receiver of assist data from the app's {@link Activity}. @@ -1224,24 +1225,30 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState final RemoteInlineSuggestionRenderService remoteRenderService = mService.getRemoteInlineSuggestionRenderServiceLocked(); if (mSessionFlags.mInlineSupportedByService - && remoteRenderService != null - && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) { + && remoteRenderService != null + && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) { + Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer = mAssistReceiver.newAutofillRequestLocked(viewState, /* isInlineRequest= */ true); + if (inlineSuggestionsRequestConsumer != null) { - final AutofillId focusedId = mCurrentViewId; final int requestIdCopy = requestId; + final AutofillId focusedId = mCurrentViewId; + + WeakReference sessionWeakReference = new WeakReference<Session>(this); + InlineSuggestionRendorInfoCallbackOnResultListener + inlineSuggestionRendorInfoCallbackOnResultListener = + new InlineSuggestionRendorInfoCallbackOnResultListener( + sessionWeakReference, + requestIdCopy, + inlineSuggestionsRequestConsumer, + focusedId); + RemoteCallback inlineSuggestionRendorInfoCallback = new RemoteCallback( + inlineSuggestionRendorInfoCallbackOnResultListener, mHandler); + remoteRenderService.getInlineSuggestionsRendererInfo( - new RemoteCallback((extras) -> { - synchronized (mLock) { - mInlineSessionController.onCreateInlineSuggestionsRequestLocked( - focusedId, inlineSuggestionsRequestCacheDecorator( - inlineSuggestionsRequestConsumer, requestIdCopy), - extras); - } - }, mHandler) - ); + inlineSuggestionRendorInfoCallback); viewState.setState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST); } } else { @@ -5151,7 +5158,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } @NonNull - private Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestCacheDecorator( + Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestCacheDecorator( @NonNull Consumer<InlineSuggestionsRequest> consumer, int requestId) { return inlineSuggestionsRequest -> { consumer.accept(inlineSuggestionsRequest); diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index 9bc0ee224ce0..a694e315ac29 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -265,7 +265,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } - notifyWakeLockListener(callback, true); + notifyWakeLockListener(callback, tag, true); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); if (monitorType >= 0) { try { @@ -392,7 +392,7 @@ public class Notifier { + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid + ", workSource=" + workSource); } - notifyWakeLockListener(callback, false); + notifyWakeLockListener(callback, tag, false); final int monitorType = getBatteryStatsWakeLockMonitorType(flags); if (monitorType >= 0) { try { @@ -1011,13 +1011,13 @@ public class Notifier { return enabled && dndOff; } - private void notifyWakeLockListener(IWakeLockCallback callback, boolean isEnabled) { + private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled) { if (callback != null) { mHandler.post(() -> { try { callback.onStateChanged(isEnabled); } catch (RemoteException e) { - throw new IllegalArgumentException("Wakelock.mCallback is already dead.", e); + Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e); } }); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 750ed986f567..89862918744c 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3649,6 +3649,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r); return; } + EventLogTags.writeWmEnterPip(r.mUserId, System.identityHashCode(r), + r.shortComponentName, Boolean.toString(isAutoEnter)); r.setPictureInPictureParams(params); r.mAutoEnteringPip = isAutoEnter; mRootWindowContainer.moveActivityToPinnedRootTask(r, diff --git a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java index e88cfbf6986e..527edc13931a 100644 --- a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java +++ b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java @@ -190,6 +190,11 @@ class BackgroundLaunchProcessController { return false; } List<IBinder> binderTokens = getOriginatingTokensThatAllowBal(); + if (binderTokens.isEmpty()) { + // no tokens to allow anything + return false; + } + // The callback will decide. return mBackgroundActivityStartCallback.isActivityStartAllowed( binderTokens, uid, packageName); diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags index 244656ca68e6..d957591ab7f9 100644 --- a/services/core/java/com/android/server/wm/EventLogTags.logtags +++ b/services/core/java/com/android/server/wm/EventLogTags.logtags @@ -80,3 +80,6 @@ option java_package com.android.server.wm # Request surface flinger to show / hide the wallpaper surface. 33001 wm_wallpaper_surface (Display Id|1|5),(Visible|1),(Target|3) + +# Entering pip called +38000 wm_enter_pip (User|1|5),(Token|1|5),(Component Name|3),(is Auto Enter|3) diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 7e34d15ddcfc..8e85e5bca240 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -960,20 +960,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub errorCallbackToken, organizer); break; } - default: { - // The other operations may change task order so they are skipped while in lock - // task mode. The above operations are still allowed because they don't move - // tasks. And it may be necessary such as clearing launch root after entering - // lock task mode. - if (isInLockTaskMode) { - Slog.w(TAG, "Skip applying hierarchy operation " + hop - + " while in lock task mode"); - return effects; - } - } - } - - switch (type) { case HIERARCHY_OP_TYPE_PENDING_INTENT: { final Bundle launchOpts = hop.getLaunchOptions(); ActivityOptions activityOptions = launchOpts != null @@ -1012,6 +998,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } break; } + default: { + // The other operations may change task order so they are skipped while in lock + // task mode. The above operations are still allowed because they don't move + // tasks. And it may be necessary such as clearing launch root after entering + // lock task mode. + if (isInLockTaskMode) { + Slog.w(TAG, "Skip applying hierarchy operation " + hop + + " while in lock task mode"); + return effects; + } + } + } + + switch (type) { case HIERARCHY_OP_TYPE_START_SHORTCUT: { final Bundle launchOpts = hop.getLaunchOptions(); final String callingPackage = launchOpts.getString( diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c96bfd716297..60207111ed76 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2191,7 +2191,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void suspendAppsForQuietProfiles(boolean toSuspend) { PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); - List<UserInfo> users = mUserManager.getUsers(); + List<UserInfo> users = mUserManagerInternal.getUsers(true /* excludeDying */); for (UserInfo user : users) { if (user.isManagedProfile() && user.isQuietModeEnabled()) { pmi.setPackagesSuspendedForQuietMode(user.id, toSuspend); diff --git a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java index 849aae29aca0..2f039654ca7e 100644 --- a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java +++ b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java @@ -34,7 +34,10 @@ import android.hardware.SensorManager; import android.hardware.display.AmbientDisplayConfiguration; import android.os.BatteryStats; import android.os.Handler; +import android.os.IWakeLockCallback; import android.os.Looper; +import android.os.PowerManager; +import android.os.RemoteException; import android.os.ServiceManager; import android.os.VibrationAttributes; import android.os.Vibrator; @@ -219,6 +222,34 @@ public class NotifierTest { verify(mStatusBarManagerInternal, never()).showChargingAnimation(anyInt()); } + @Test + public void testOnWakeLockListener_RemoteException_NoRethrow() { + createNotifier(); + + IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { + @Override public void onStateChanged(boolean enabled) throws RemoteException { + throw new RemoteException("Just testing"); + } + }; + + final int uid = 1234; + final int pid = 5678; + mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", + "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, + exceptingCallback); + mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", + "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, + exceptingCallback); + mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", + "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, + exceptingCallback, + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", + "my.package.name", uid, pid, /* newWorkSource= */ null, /* newHistoryTag= */ null, + exceptingCallback); + mTestLooper.dispatchAll(); + // If we didn't throw, we're good! + } + private final PowerManagerService.Injector mInjector = new PowerManagerService.Injector() { @Override Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats, 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 6ef81f6c6211..9166b3d75f60 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -5618,6 +5618,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testVisitUris_publicVersion() throws Exception { + final Icon smallIconPublic = Icon.createWithContentUri("content://media/small/icon"); + final Icon largeIconPrivate = Icon.createWithContentUri("content://media/large/icon"); + + Notification publicVersion = new Notification.Builder(mContext, "a") + .setContentTitle("notification with uris") + .setSmallIcon(smallIconPublic) + .build(); + Notification n = new Notification.Builder(mContext, "a") + .setLargeIcon(largeIconPrivate) + .setPublicVersion(publicVersion) + .build(); + + Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class); + n.visitUris(visitor); + verify(visitor, times(1)).accept(eq(smallIconPublic.getUri())); + verify(visitor, times(1)).accept(eq(largeIconPrivate.getUri())); + } + + @Test public void testVisitUris_audioContentsString() throws Exception { final Uri audioContents = Uri.parse("content://com.example/audio"); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java index 0e627b2f0909..4c10ddc76894 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java @@ -87,7 +87,6 @@ public class NotificationVisitUrisTest extends UiServiceTestCase { // This list should be emptied! Items can be removed as bugs are fixed. private static final Multimap<Class<?>, String> KNOWN_BAD = ImmutableMultimap.<Class<?>, String>builder() - .put(Notification.Builder.class, "setPublicVersion") // b/276294099 .put(RemoteViews.class, "setIcon") // b/281018094 .put(Notification.WearableExtender.class, "addAction") // TODO: b/281044385 .put(Person.Builder.class, "setUri") // TODO: b/281044385 |