diff options
37 files changed, 571 insertions, 102 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index bdd9ec7614b4..e2690a9a7ebf 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2970,6 +2970,7 @@ package android.view.accessibility { public final class AccessibilityManager { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int); + method public boolean hasAnyDirectConnection(); } public class AccessibilityNodeInfo implements android.os.Parcelable { diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 0d6b19941afe..9abce3a39944 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -146,4 +146,8 @@ interface IAccessibilityServiceConnection { void onDoubleTapAndHold(int displayId); void setAnimationScale(float scale); + + void setInstalledAndEnabledServices(in List<AccessibilityServiceInfo> infos); + + List<AccessibilityServiceInfo> getInstalledAndEnabledServices(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6c61d4bde29e..1e2b241fbb51 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -10497,6 +10497,8 @@ public final class ViewRootImpl implements ViewParent, if (mDirectConnectionId == AccessibilityNodeInfo.UNDEFINED_CONNECTION_ID) { mDirectConnectionId = AccessibilityInteractionClient.addDirectConnection( new AccessibilityInteractionConnection(ViewRootImpl.this)); + // Notify listeners in the app process. + mAccessibilityManager.notifyAccessibilityStateChanged(); } return mDirectConnectionId; } @@ -10505,6 +10507,8 @@ public final class ViewRootImpl implements ViewParent, if (mDirectConnectionId != AccessibilityNodeInfo.UNDEFINED_CONNECTION_ID) { AccessibilityInteractionClient.removeConnection(mDirectConnectionId); mDirectConnectionId = AccessibilityNodeInfo.UNDEFINED_CONNECTION_ID; + // Notify listeners in the app process. + mAccessibilityManager.notifyAccessibilityStateChanged(); } } } diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 227a8ef6fd60..e3ffc9dcbbde 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -117,6 +117,7 @@ public final class AccessibilityInteractionClient // Used to generate connection ids for direct app-process connections. Start sufficiently far // enough from the connection ids generated by AccessibilityManagerService. private static int sDirectConnectionIdCounter = 1 << 30; + private static int sDirectConnectionCount = 0; /** List of timestamps which indicate the latest time an a11y service receives a scroll event from a window, mapping from windowId -> timestamp. */ @@ -272,12 +273,18 @@ public final class AccessibilityInteractionClient DirectAccessibilityConnection directAccessibilityConnection = new DirectAccessibilityConnection(connection); sConnectionCache.put(connectionId, directAccessibilityConnection); + sDirectConnectionCount++; // Do not use AccessibilityCache for this connection, since there is no corresponding // AccessibilityService to handle cache invalidation events. return connectionId; } } + /** Check if any {@link DirectAccessibilityConnection} is currently in the connection cache. */ + public static boolean hasAnyDirectConnection() { + return sDirectConnectionCount > 0; + } + /** * Gets a cached associated with the connection id if available. * @@ -295,6 +302,9 @@ public final class AccessibilityInteractionClient */ public static void removeConnection(int connectionId) { synchronized (sConnectionCache) { + if (getConnection(connectionId) instanceof DirectAccessibilityConnection) { + sDirectConnectionCount--; + } sConnectionCache.remove(connectionId); sCaches.remove(connectionId); } diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 7528e2a66926..5433fa08ac18 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -602,12 +602,21 @@ public final class AccessibilityManager { */ public boolean isEnabled() { synchronized (mLock) { - return mIsEnabled || (mAccessibilityPolicy != null - && mAccessibilityPolicy.isEnabled(mIsEnabled)); + return mIsEnabled || hasAnyDirectConnection() + || (mAccessibilityPolicy != null && mAccessibilityPolicy.isEnabled(mIsEnabled)); } } /** + * @see AccessibilityInteractionClient#hasAnyDirectConnection + * @hide + */ + @TestApi + public boolean hasAnyDirectConnection() { + return AccessibilityInteractionClient.hasAnyDirectConnection(); + } + + /** * Returns if the touch exploration in the system is enabled. * <p> * <b>Note:</b> This query is used for dispatching hover events, such as @@ -1942,8 +1951,13 @@ public final class AccessibilityManager { /** * Notifies the registered {@link AccessibilityStateChangeListener}s. + * + * Note: this method notifies only the listeners of this single instance. + * AccessibilityManagerService is responsible for calling this method on all of + * its AccessibilityManager clients in order to notify all listeners. + * @hide */ - private void notifyAccessibilityStateChanged() { + public void notifyAccessibilityStateChanged() { final boolean isEnabled; final ArrayMap<AccessibilityStateChangeListener, Handler> listeners; synchronized (mLock) { diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index 1e060987b69f..36fdcce4e1f2 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -108,4 +108,10 @@ interface IAccessibilityManager { void setSystemAudioCaptioningUiEnabled(boolean isEnabled, int userId); oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes); + + // Requires Manifest.permission.MANAGE_ACCESSIBILITY + boolean registerProxyForDisplay(IAccessibilityServiceClient proxy, int displayId); + + // Requires Manifest.permission.MANAGE_ACCESSIBILITY + boolean unregisterProxyForDisplay(int displayId); } diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java index fc385a013d00..35d5948bc2af 100644 --- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java +++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java @@ -26,6 +26,7 @@ import android.graphics.Region; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteCallback; +import android.os.RemoteException; import java.util.Collections; import java.util.List; @@ -206,4 +207,14 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon int processId, long threadId, int callingUid, Bundle serializedCallingStackInBundle) {} public void setAnimationScale(float scale) {} + + @Override + public void setInstalledAndEnabledServices(List<AccessibilityServiceInfo> infos) + throws RemoteException { + } + + @Override + public List<AccessibilityServiceInfo> getInstalledAndEnabledServices() throws RemoteException { + return null; + } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index c76f568e117f..0fb6ff878451 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -103,14 +103,23 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { /** * Similar to {@link #addWindowLayoutInfoListener(Activity, Consumer)}, but takes a UI Context * as a parameter. + * + * Jetpack {@link androidx.window.layout.ExtensionWindowLayoutInfoBackend} makes sure all + * consumers related to the same {@link Context} gets updated {@link WindowLayoutInfo} + * together. However only the first registered consumer of a {@link Context} will actually + * invoke {@link #addWindowLayoutInfoListener(Context, Consumer)}. + * Here we enforce that {@link #addWindowLayoutInfoListener(Context, Consumer)} can only be + * called once for each {@link Context}. */ - // TODO(b/204073440): Add @Override to hook the API in WM extensions library. + @Override public void addWindowLayoutInfoListener(@NonNull @UiContext Context context, @NonNull Consumer<WindowLayoutInfo> consumer) { if (mWindowLayoutChangeListeners.containsKey(context) + // In theory this method can be called on the same consumer with different context. || mWindowLayoutChangeListeners.containsValue(consumer)) { - // Early return if the listener or consumer has been registered. - return; + throw new IllegalArgumentException( + "Context or Consumer has already been registered for WindowLayoutInfo" + + " callback."); } if (!context.isUiContext()) { throw new IllegalArgumentException("Context must be a UI Context, which should be" diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar Binary files differindex 2c766d81d611..b0b95f9cc871 100644 --- a/libs/WindowManager/Jetpack/window-extensions-release.aar +++ b/libs/WindowManager/Jetpack/window-extensions-release.aar diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 9d7b01c8d252..49ef330dcc52 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -59,4 +59,5 @@ <dimen name="large_dialog_width">348dp</dimen> <dimen name="qs_panel_padding_top">@dimen/qqs_layout_margin_top</dimen> + <dimen name="qs_panel_padding_top_combined_headers">@dimen/qs_panel_padding_top</dimen> </resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 5dcbeb5c85cf..599bf30a5135 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -68,6 +68,7 @@ <dimen name="qs_security_footer_background_inset">0dp</dimen> <dimen name="qs_panel_padding_top">8dp</dimen> + <dimen name="qs_panel_padding_top_combined_headers">@dimen/qs_panel_padding_top</dimen> <!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) --> <dimen name="large_dialog_width">472dp</dimen> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 8d49283b7826..03040d66ebad 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -559,7 +559,8 @@ <dimen name="qs_dual_tile_padding_horizontal">6dp</dimen> <dimen name="qs_panel_elevation">4dp</dimen> <dimen name="qs_panel_padding_bottom">@dimen/footer_actions_height</dimen> - <dimen name="qs_panel_padding_top">80dp</dimen> + <dimen name="qs_panel_padding_top">48dp</dimen> + <dimen name="qs_panel_padding_top_combined_headers">80dp</dimen> <dimen name="qs_data_usage_text_size">14sp</dimen> <dimen name="qs_data_usage_usage_text_size">36sp</dimen> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java index 453072bc42da..5d86ccd5409e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java @@ -176,6 +176,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { @Override public void startAppearAnimation() { + setAlpha(1f); + setTranslationY(0); if (mAppearAnimator.isRunning()) { mAppearAnimator.cancel(); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 632fcd1bc6c8..353c3698dce4 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -538,7 +538,7 @@ public class KeyguardSecurityContainer extends FrameLayout { } /** - * Runs after a succsssful authentication only + * Runs after a successful authentication only */ public void startDisappearAnimation(SecurityMode securitySelection) { mDisappearAnimRunning = true; @@ -1063,6 +1063,7 @@ public class KeyguardSecurityContainer extends FrameLayout { mPopup.dismiss(); mPopup = null; } + setupUserSwitcher(); } @Override @@ -1101,7 +1102,6 @@ public class KeyguardSecurityContainer extends FrameLayout { return; } - mView.setAlpha(1f); mUserSwitcherViewGroup.setAlpha(0f); ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(mUserSwitcherViewGroup, View.ALPHA, 1f); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 57058b76ce8f..d448f40ed529 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -427,6 +427,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard public void startAppearAnimation() { if (mCurrentSecurityMode != SecurityMode.None) { + mView.setAlpha(1f); mView.startAppearAnimation(mCurrentSecurityMode); getCurrentSecurityController().startAppearAnimation(); } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java index 9cd149b9bfee..5694f6da0ea5 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java @@ -18,7 +18,7 @@ package com.android.systemui.dreams.complication; import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_FADE_IN_DURATION; import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_FADE_OUT_DURATION; -import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN; +import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN_DEFAULT; import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.SCOPED_COMPLICATIONS_LAYOUT; import android.animation.Animator; @@ -67,7 +67,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll private final Parent mParent; @Complication.Category private final int mCategory; - private final int mMargin; + private final int mDefaultMargin; /** * Default constructor. {@link Parent} allows for the {@link ViewEntry}'s surrounding @@ -75,7 +75,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll */ ViewEntry(View view, ComplicationLayoutParams layoutParams, TouchInsetManager.TouchInsetSession touchSession, int category, Parent parent, - int margin) { + int defaultMargin) { mView = view; // Views that are generated programmatically do not have a unique id assigned to them // at construction. A new id is assigned here to enable ConstraintLayout relative @@ -86,7 +86,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll mTouchInsetSession = touchSession; mCategory = category; mParent = parent; - mMargin = margin; + mDefaultMargin = defaultMargin; touchSession.addViewToTracking(mView); } @@ -195,18 +195,19 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll } if (!isRoot) { + final int margin = mLayoutParams.getMargin(mDefaultMargin); switch(direction) { case ComplicationLayoutParams.DIRECTION_DOWN: - params.setMargins(0, mMargin, 0, 0); + params.setMargins(0, margin, 0, 0); break; case ComplicationLayoutParams.DIRECTION_UP: - params.setMargins(0, 0, 0, mMargin); + params.setMargins(0, 0, 0, margin); break; case ComplicationLayoutParams.DIRECTION_END: - params.setMarginStart(mMargin); + params.setMarginStart(margin); break; case ComplicationLayoutParams.DIRECTION_START: - params.setMarginEnd(mMargin); + params.setMarginEnd(margin); break; } } @@ -263,7 +264,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll private final ComplicationLayoutParams mLayoutParams; private final int mCategory; private Parent mParent; - private int mMargin; + private int mDefaultMargin; Builder(View view, TouchInsetManager.TouchInsetSession touchSession, ComplicationLayoutParams lp, @Complication.Category int category) { @@ -302,8 +303,8 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll * Sets the margin that will be applied in the direction the complication is laid out * towards. */ - Builder setMargin(int margin) { - mMargin = margin; + Builder setDefaultMargin(int margin) { + mDefaultMargin = margin; return this; } @@ -312,7 +313,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll */ ViewEntry build() { return new ViewEntry(mView, mLayoutParams, mTouchSession, mCategory, mParent, - mMargin); + mDefaultMargin); } } @@ -472,7 +473,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll } private final ConstraintLayout mLayout; - private final int mMargin; + private final int mDefaultMargin; private final HashMap<ComplicationId, ViewEntry> mEntries = new HashMap<>(); private final HashMap<Integer, PositionGroup> mPositions = new HashMap<>(); private final TouchInsetManager.TouchInsetSession mSession; @@ -483,12 +484,12 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll /** */ @Inject public ComplicationLayoutEngine(@Named(SCOPED_COMPLICATIONS_LAYOUT) ConstraintLayout layout, - @Named(COMPLICATION_MARGIN) int margin, + @Named(COMPLICATION_MARGIN_DEFAULT) int defaultMargin, TouchInsetManager.TouchInsetSession session, @Named(COMPLICATIONS_FADE_IN_DURATION) int fadeInDuration, @Named(COMPLICATIONS_FADE_OUT_DURATION) int fadeOutDuration) { mLayout = layout; - mMargin = margin; + mDefaultMargin = defaultMargin; mSession = session; mFadeInDuration = fadeInDuration; mFadeOutDuration = fadeOutDuration; @@ -537,7 +538,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll } final ViewEntry.Builder entryBuilder = new ViewEntry.Builder(view, mSession, lp, category) - .setMargin(mMargin); + .setDefaultMargin(mDefaultMargin); // Add position group if doesn't already exist final int position = lp.getPosition(); diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java index 8e8cb72d6ad0..a21eb19bd548 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutParams.java @@ -51,6 +51,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { private static final int FIRST_POSITION = POSITION_TOP; private static final int LAST_POSITION = POSITION_END; + private static final int MARGIN_UNSPECIFIED = 0xFFFFFFFF; + @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "DIRECTION_" }, value = { DIRECTION_UP, @@ -77,6 +79,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { private final int mWeight; + private final int mMargin; + private final boolean mSnapToGuide; // Do not allow specifying opposite positions @@ -106,7 +110,24 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { */ public ComplicationLayoutParams(int width, int height, @Position int position, @Direction int direction, int weight) { - this(width, height, position, direction, weight, false); + this(width, height, position, direction, weight, MARGIN_UNSPECIFIED, false); + } + + /** + * Constructs a {@link ComplicationLayoutParams}. + * @param width The width {@link android.view.View.MeasureSpec} for the view. + * @param height The height {@link android.view.View.MeasureSpec} for the view. + * @param position The place within the parent container where the view should be positioned. + * @param direction The direction the view should be laid out from either the parent container + * or preceding view. + * @param weight The weight that should be considered for this view when compared to other + * views. This has an impact on the placement of the view but not the rendering of + * the view. + * @param margin The margin to apply between complications. + */ + public ComplicationLayoutParams(int width, int height, @Position int position, + @Direction int direction, int weight, int margin) { + this(width, height, position, direction, weight, margin, false); } /** @@ -127,6 +148,28 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { */ public ComplicationLayoutParams(int width, int height, @Position int position, @Direction int direction, int weight, boolean snapToGuide) { + this(width, height, position, direction, weight, MARGIN_UNSPECIFIED, snapToGuide); + } + + /** + * Constructs a {@link ComplicationLayoutParams}. + * @param width The width {@link android.view.View.MeasureSpec} for the view. + * @param height The height {@link android.view.View.MeasureSpec} for the view. + * @param position The place within the parent container where the view should be positioned. + * @param direction The direction the view should be laid out from either the parent container + * or preceding view. + * @param weight The weight that should be considered for this view when compared to other + * views. This has an impact on the placement of the view but not the rendering of + * the view. + * @param margin The margin to apply between complications. + * @param snapToGuide When set to {@code true}, the dimension perpendicular to the direction + * will be automatically set to align with a predetermined guide for that + * side. For example, if the complication is aligned to the top end and + * direction is down, then the width of the complication will be set to span + * from the end of the parent to the guide. + */ + public ComplicationLayoutParams(int width, int height, @Position int position, + @Direction int direction, int weight, int margin, boolean snapToGuide) { super(width, height); if (!validatePosition(position)) { @@ -142,6 +185,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { mWeight = weight; + mMargin = margin; + mSnapToGuide = snapToGuide; } @@ -153,6 +198,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { mPosition = source.mPosition; mDirection = source.mDirection; mWeight = source.mWeight; + mMargin = source.mMargin; mSnapToGuide = source.mSnapToGuide; } @@ -215,6 +261,14 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams { } /** + * Returns the margin to apply between complications, or the given default if no margin is + * specified. + */ + public int getMargin(int defaultMargin) { + return mMargin == MARGIN_UNSPECIFIED ? defaultMargin : mMargin; + } + + /** * Returns whether the complication's dimension perpendicular to direction should be * automatically set. */ diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java index 11d89d2dc816..c9fecc96c1b5 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java @@ -37,7 +37,7 @@ import dagger.Provides; @Module public abstract class ComplicationHostViewModule { public static final String SCOPED_COMPLICATIONS_LAYOUT = "scoped_complications_layout"; - public static final String COMPLICATION_MARGIN = "complication_margin"; + public static final String COMPLICATION_MARGIN_DEFAULT = "complication_margin_default"; public static final String COMPLICATIONS_FADE_OUT_DURATION = "complications_fade_out_duration"; public static final String COMPLICATIONS_FADE_IN_DURATION = "complications_fade_in_duration"; public static final String COMPLICATIONS_RESTORE_TIMEOUT = "complication_restore_timeout"; @@ -58,7 +58,7 @@ public abstract class ComplicationHostViewModule { } @Provides - @Named(COMPLICATION_MARGIN) + @Named(COMPLICATION_MARGIN_DEFAULT) @DreamOverlayComponent.DreamOverlayScope static int providesComplicationPadding(@Main Resources resources) { return resources.getDimensionPixelSize(R.dimen.dream_overlay_complication_margin); diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java index 759d6ec3bf21..7d2ce51ffbf6 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java @@ -59,11 +59,11 @@ public interface RegisteredComplicationsModule { @Named(DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS) static ComplicationLayoutParams provideClockTimeLayoutParams() { return new ComplicationLayoutParams(0, - ViewGroup.LayoutParams.WRAP_CONTENT, - ComplicationLayoutParams.POSITION_TOP - | ComplicationLayoutParams.POSITION_START, - ComplicationLayoutParams.DIRECTION_DOWN, - DREAM_CLOCK_TIME_COMPLICATION_WEIGHT); + ViewGroup.LayoutParams.WRAP_CONTENT, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_START, + ComplicationLayoutParams.DIRECTION_DOWN, + DREAM_CLOCK_TIME_COMPLICATION_WEIGHT); } /** @@ -73,12 +73,12 @@ public interface RegisteredComplicationsModule { @Named(DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS) static ComplicationLayoutParams provideHomeControlsChipLayoutParams(@Main Resources res) { return new ComplicationLayoutParams( - res.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width), - res.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height), - ComplicationLayoutParams.POSITION_BOTTOM - | ComplicationLayoutParams.POSITION_START, - ComplicationLayoutParams.DIRECTION_END, - DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT); + res.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width), + res.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height), + ComplicationLayoutParams.POSITION_BOTTOM + | ComplicationLayoutParams.POSITION_START, + ComplicationLayoutParams.DIRECTION_END, + DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT); } /** @@ -103,11 +103,12 @@ public interface RegisteredComplicationsModule { @Named(DREAM_SMARTSPACE_LAYOUT_PARAMS) static ComplicationLayoutParams provideSmartspaceLayoutParams() { return new ComplicationLayoutParams(0, - ViewGroup.LayoutParams.WRAP_CONTENT, - ComplicationLayoutParams.POSITION_TOP - | ComplicationLayoutParams.POSITION_START, - ComplicationLayoutParams.DIRECTION_DOWN, - DREAM_SMARTSPACE_COMPLICATION_WEIGHT, - true /*snapToGuide*/); + ViewGroup.LayoutParams.WRAP_CONTENT, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_START, + ComplicationLayoutParams.DIRECTION_DOWN, + DREAM_SMARTSPACE_COMPLICATION_WEIGHT, + 0, + true /*snapToGuide*/); } } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 3789cbb1fb65..029cf68b243d 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -142,6 +142,9 @@ public class NavigationBarController implements boolean isOldConfigTablet = mIsTablet; mIsTablet = isTablet(mContext); boolean largeScreenChanged = mIsTablet != isOldConfigTablet; + if (mTaskbarDelegate.isInitialized()) { + mTaskbarDelegate.onConfigurationChanged(newConfig); + } // If we folded/unfolded while in 3 button, show navbar in folded state, hide in unfolded if (largeScreenChanged && updateNavbarForTaskbar()) { return; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index 9e0c49641e72..73fc21ef928c 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -40,7 +40,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode import android.app.StatusBarManager; import android.app.StatusBarManager.WindowVisibleState; -import android.content.ComponentCallbacks; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; @@ -87,7 +86,7 @@ import javax.inject.Inject; @SysUISingleton public class TaskbarDelegate implements CommandQueue.Callbacks, OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener, - ComponentCallbacks, Dumpable { + Dumpable { private static final String TAG = TaskbarDelegate.class.getSimpleName(); private final EdgeBackGestureHandler mEdgeBackGestureHandler; @@ -225,7 +224,6 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, // Initialize component callback Display display = mDisplayManager.getDisplay(displayId); mWindowContext = mContext.createWindowContext(display, TYPE_APPLICATION, null); - mWindowContext.registerComponentCallbacks(this); mScreenPinningNotify = new ScreenPinningNotify(mWindowContext); // Set initial state for any listeners updateSysuiFlags(); @@ -233,6 +231,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mLightBarController.setNavigationBar(mLightBarTransitionsController); mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener); mEdgeBackGestureHandler.setBackAnimation(mBackAnimation); + mEdgeBackGestureHandler.onConfigurationChanged(mContext.getResources().getConfiguration()); mInitialized = true; } @@ -247,10 +246,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mNavBarHelper.destroy(); mEdgeBackGestureHandler.onNavBarDetached(); mScreenPinningNotify = null; - if (mWindowContext != null) { - mWindowContext.unregisterComponentCallbacks(this); - mWindowContext = null; - } + mWindowContext = null; mAutoHideController.setNavigationBar(null); mLightBarTransitionsController.destroy(); mLightBarController.setNavigationBar(null); @@ -267,8 +263,9 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, } /** - * Returns {@code true} if this taskBar is {@link #init(int)}. Returns {@code false} if this - * taskbar has not yet been {@link #init(int)} or has been {@link #destroy()}. + * Returns {@code true} if this taskBar is {@link #init(int)}. + * Returns {@code false} if this taskbar has not yet been {@link #init(int)} + * or has been {@link #destroy()}. */ public boolean isInitialized() { return mInitialized; @@ -460,15 +457,11 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, return mBehavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; } - @Override public void onConfigurationChanged(Configuration configuration) { mEdgeBackGestureHandler.onConfigurationChanged(configuration); } @Override - public void onLowMemory() {} - - @Override public void showPinningEnterExitToast(boolean entering) { updateSysuiFlags(); if (mScreenPinningNotify == null) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index b26b42c802f4..a8799c744656 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -19,6 +19,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_ import static com.android.systemui.classifier.Classifier.BACK_GESTURE; +import android.annotation.NonNull; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; @@ -955,7 +956,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker mStartingQuickstepRotation != rotation; } - public void onConfigurationChanged(Configuration newConfig) { + public void onConfigurationChanged(@NonNull Configuration newConfig) { if (mStartingQuickstepRotation > -1) { updateDisabledForQuickstep(newConfig); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 184089f7eef4..6517ff33a49d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -105,6 +105,7 @@ public class QSPanel extends LinearLayout implements Tunable { private final Rect mClippingRect = new Rect(); private ViewGroup mMediaHostView; private boolean mShouldMoveMediaOnExpansion = true; + private boolean mUsingCombinedHeaders = false; public QSPanel(Context context, AttributeSet attrs) { super(context, attrs); @@ -148,6 +149,10 @@ public class QSPanel extends LinearLayout implements Tunable { } } + void setUsingCombinedHeaders(boolean usingCombinedHeaders) { + mUsingCombinedHeaders = usingCombinedHeaders; + } + protected void setHorizontalContentContainerClipping() { mHorizontalContentContainer.setClipChildren(true); mHorizontalContentContainer.setClipToPadding(false); @@ -371,7 +376,9 @@ public class QSPanel extends LinearLayout implements Tunable { protected void updatePadding() { final Resources res = mContext.getResources(); - int paddingTop = res.getDimensionPixelSize(R.dimen.qs_panel_padding_top); + int paddingTop = res.getDimensionPixelSize( + mUsingCombinedHeaders ? R.dimen.qs_panel_padding_top_combined_headers + : R.dimen.qs_panel_padding_top); int paddingBottom = res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom); setPaddingRelative(getPaddingStart(), paddingTop, diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java index 18bd6b7b3c32..f6db775a7749 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java @@ -17,6 +17,7 @@ package com.android.systemui.qs; import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE; +import static com.android.systemui.flags.Flags.COMBINED_QS_HEADERS; import static com.android.systemui.media.dagger.MediaModule.QS_PANEL; import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS; import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER; @@ -27,6 +28,7 @@ import android.view.View; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.systemui.dump.DumpManager; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.media.MediaHierarchyManager; import com.android.systemui.media.MediaHost; import com.android.systemui.media.MediaHostState; @@ -79,7 +81,8 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory, BrightnessSliderController.Factory brightnessSliderFactory, FalsingManager falsingManager, - StatusBarKeyguardViewManager statusBarKeyguardViewManager) { + StatusBarKeyguardViewManager statusBarKeyguardViewManager, + FeatureFlags featureFlags) { super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger, uiEventLogger, qsLogger, dumpManager); mTunerService = tunerService; @@ -93,6 +96,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { mBrightnessController = brightnessControllerFactory.create(mBrightnessSliderController); mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController); mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; + mView.setUsingCombinedHeaders(featureFlags.isEnabled(COMBINED_QS_HEADERS)); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index bc943cf384ea..d4fa1f27c8f6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -407,8 +407,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } else if (mNotificationPanelViewController.isUnlockHintRunning()) { if (mBouncer != null) { mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); + } else { + mBouncerInteractor.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); } - mBouncerInteractor.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) { // Don't expand to the bouncer. Instead transition back to the lock screen (see // CentralSurfaces#showBouncerOrLockScreenIfKeyguard) @@ -416,8 +417,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } else if (bouncerNeedsScrimming()) { if (mBouncer != null) { mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE); + } else { + mBouncerInteractor.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE); } - mBouncerInteractor.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE); } else if (mShowing && !hideBouncerOverDream) { if (!isWakeAndUnlocking() && !(mBiometricUnlockController.getMode() == MODE_DISMISS_BOUNCER) @@ -425,8 +427,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb && !isUnlockCollapsing()) { if (mBouncer != null) { mBouncer.setExpansion(fraction); + } else { + mBouncerInteractor.setExpansion(fraction); } - mBouncerInteractor.setExpansion(fraction); } if (fraction != KeyguardBouncer.EXPANSION_HIDDEN && tracking && !mKeyguardStateController.canDismissLockScreen() @@ -434,16 +437,18 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb && !bouncerIsAnimatingAway()) { if (mBouncer != null) { mBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */); + } else { + mBouncerInteractor.show(/* isScrimmed= */false); } - mBouncerInteractor.show(/* isScrimmed= */false); } } else if (!mShowing && isBouncerInTransit()) { // Keyguard is not visible anymore, but expansion animation was still running. // We need to hide the bouncer, otherwise it will be stuck in transit. if (mBouncer != null) { mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); + } else { + mBouncerInteractor.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); } - mBouncerInteractor.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); } else if (mPulsing && fraction == KeyguardBouncer.EXPANSION_VISIBLE) { // Panel expanded while pulsing but didn't translate the bouncer (because we are // unlocked.) Let's simply wake-up to dismiss the lock screen. @@ -489,8 +494,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mCentralSurfaces.hideKeyguard(); if (mBouncer != null) { mBouncer.show(true /* resetSecuritySelection */); + } else { + mBouncerInteractor.show(true); } - mBouncerInteractor.show(true); } else { mCentralSurfaces.showKeyguard(); if (hideBouncerWhenShowing) { @@ -531,8 +537,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb void hideBouncer(boolean destroyView) { if (mBouncer != null) { mBouncer.hide(destroyView); + } else { + mBouncerInteractor.hide(); } - mBouncerInteractor.hide(); if (mShowing) { // If we were showing the bouncer and then aborting, we need to also clear out any // potential actions unless we actually unlocked. @@ -553,8 +560,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (mShowing && !isBouncerShowing()) { if (mBouncer != null) { mBouncer.show(false /* resetSecuritySelection */, scrimmed); + } else { + mBouncerInteractor.show(scrimmed); } - mBouncerInteractor.show(scrimmed); } updateStates(); } @@ -590,9 +598,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (mBouncer != null) { mBouncer.setDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction); + } else { + mBouncerInteractor.setDismissAction(mAfterKeyguardGoneAction, + mKeyguardGoneCancelAction); } - mBouncerInteractor.setDismissAction(mAfterKeyguardGoneAction, - mKeyguardGoneCancelAction); mAfterKeyguardGoneAction = null; mKeyguardGoneCancelAction = null; } @@ -605,17 +614,21 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (afterKeyguardGone) { // we'll handle the dismiss action after keyguard is gone, so just show the // bouncer - mBouncerInteractor.show(/* isScrimmed= */true); - if (mBouncer != null) mBouncer.show(false /* resetSecuritySelection */); + if (mBouncer != null) { + mBouncer.show(false /* resetSecuritySelection */); + } else { + mBouncerInteractor.show(/* isScrimmed= */true); + } } else { // after authentication success, run dismiss action with the option to defer // hiding the keyguard based on the return value of the OnDismissAction - mBouncerInteractor.setDismissAction( - mAfterKeyguardGoneAction, mKeyguardGoneCancelAction); - mBouncerInteractor.show(/* isScrimmed= */true); if (mBouncer != null) { mBouncer.showWithDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction); + } else { + mBouncerInteractor.setDismissAction( + mAfterKeyguardGoneAction, mKeyguardGoneCancelAction); + mBouncerInteractor.show(/* isScrimmed= */true); } // bouncer will handle the dismiss action, so we no longer need to track it here mAfterKeyguardGoneAction = null; @@ -719,8 +732,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void onFinishedGoingToSleep() { if (mBouncer != null) { mBouncer.onScreenTurnedOff(); + } else { + mBouncerInteractor.onScreenTurnedOff(); } - mBouncerInteractor.onScreenTurnedOff(); } @Override @@ -832,8 +846,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (bouncerIsShowing()) { if (mBouncer != null) { mBouncer.startPreHideAnimation(finishRunnable); + } else { + mBouncerInteractor.startDisappearAnimation(finishRunnable); } - mBouncerInteractor.startDisappearAnimation(finishRunnable); mCentralSurfaces.onBouncerPreHideAnimation(); // We update the state (which will show the keyguard) only if an animation will run on @@ -1106,13 +1121,15 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (bouncerDismissible || !showing || remoteInputActive) { if (mBouncer != null) { mBouncer.setBackButtonEnabled(true); + } else { + mBouncerInteractor.setBackButtonEnabled(true); } - mBouncerInteractor.setBackButtonEnabled(true); } else { if (mBouncer != null) { mBouncer.setBackButtonEnabled(false); + } else { + mBouncerInteractor.setBackButtonEnabled(false); } - mBouncerInteractor.setBackButtonEnabled(false); } } @@ -1278,8 +1295,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void notifyKeyguardAuthenticated(boolean strongAuth) { if (mBouncer != null) { mBouncer.notifyKeyguardAuthenticated(strongAuth); + } else { + mBouncerInteractor.notifyKeyguardAuthenticated(strongAuth); } - mBouncerInteractor.notifyKeyguardAuthenticated(strongAuth); if (mAlternateAuthInterceptor != null && isShowingAlternateAuthOrAnimating()) { resetAlternateAuth(false); @@ -1296,8 +1314,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } else { if (mBouncer != null) { mBouncer.showMessage(message, colorState); + } else { + mBouncerInteractor.showMessage(message, colorState); } - mBouncerInteractor.showMessage(message, colorState); } } @@ -1344,8 +1363,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void updateResources() { if (mBouncer != null) { mBouncer.updateResources(); + } else { + mBouncerInteractor.updateResources(); } - mBouncerInteractor.updateResources(); } public void dump(PrintWriter pw) { @@ -1430,9 +1450,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void updateKeyguardPosition(float x) { if (mBouncer != null) { mBouncer.updateKeyguardPosition(x); + } else { + mBouncerInteractor.setKeyguardPosition(x); } - - mBouncerInteractor.setKeyguardPosition(x); } private static class DismissWithActionRequest { @@ -1474,9 +1494,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public boolean isBouncerInTransit() { if (mBouncer != null) { return mBouncer.inTransit(); + } else { + return mBouncerInteractor.isInTransit(); } - - return mBouncerInteractor.isInTransit(); } /** @@ -1485,9 +1505,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public boolean bouncerIsShowing() { if (mBouncer != null) { return mBouncer.isShowing(); + } else { + return mBouncerInteractor.isFullyShowing(); } - - return mBouncerInteractor.isFullyShowing(); } /** @@ -1496,9 +1516,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public boolean bouncerIsScrimmed() { if (mBouncer != null) { return mBouncer.isScrimmed(); + } else { + return mBouncerInteractor.isScrimmed(); } - - return mBouncerInteractor.isScrimmed(); } /** @@ -1507,9 +1527,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public boolean bouncerIsAnimatingAway() { if (mBouncer != null) { return mBouncer.isAnimatingAway(); + } else { + return mBouncerInteractor.isAnimatingAway(); } - return mBouncerInteractor.isAnimatingAway(); } /** @@ -1518,9 +1539,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public boolean bouncerWillDismissWithAction() { if (mBouncer != null) { return mBouncer.willDismissWithAction(); + } else { + return mBouncerInteractor.willDismissWithAction(); } - - return mBouncerInteractor.willDismissWithAction(); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java index 2448f1a7633d..849ac5ef90d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java @@ -297,10 +297,10 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { } /** - * Ensures margin is applied + * Ensures default margin is applied */ @Test - public void testMargin() { + public void testDefaultMargin() { final int margin = 5; final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, margin, mTouchSession, 0, 0); @@ -373,6 +373,74 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { } /** + * Ensures complication margin is applied + */ + @Test + public void testComplicationMargin() { + final int defaultMargin = 5; + final int complicationMargin = 10; + final ComplicationLayoutEngine engine = + new ComplicationLayoutEngine(mLayout, defaultMargin, mTouchSession, 0, 0); + + final ViewInfo firstViewInfo = new ViewInfo( + new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_END, + ComplicationLayoutParams.DIRECTION_DOWN, + 0, + complicationMargin), + Complication.CATEGORY_STANDARD, + mLayout); + + addComplication(engine, firstViewInfo); + + final ViewInfo secondViewInfo = new ViewInfo( + new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_END, + ComplicationLayoutParams.DIRECTION_START, + 0), + Complication.CATEGORY_SYSTEM, + mLayout); + + addComplication(engine, secondViewInfo); + + firstViewInfo.clearInvocations(); + secondViewInfo.clearInvocations(); + + final ViewInfo thirdViewInfo = new ViewInfo( + new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_END, + ComplicationLayoutParams.DIRECTION_START, + 1), + Complication.CATEGORY_SYSTEM, + mLayout); + + addComplication(engine, thirdViewInfo); + + // The first added view should now be underneath the second view. + verifyChange(firstViewInfo, false, lp -> { + assertThat(lp.topToBottom == thirdViewInfo.view.getId()).isTrue(); + assertThat(lp.endToEnd == ConstraintLayout.LayoutParams.PARENT_ID).isTrue(); + assertThat(lp.topMargin).isEqualTo(complicationMargin); + }); + + // The second view should be in underneath the third view. + verifyChange(secondViewInfo, false, lp -> { + assertThat(lp.endToStart == thirdViewInfo.view.getId()).isTrue(); + assertThat(lp.topToTop == ConstraintLayout.LayoutParams.PARENT_ID).isTrue(); + assertThat(lp.getMarginEnd()).isEqualTo(defaultMargin); + }); + } + + /** * Ensures layout in a particular position updates. */ @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java index 967b30d07e63..cb7e47b28bcd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutParamsTest.java @@ -97,6 +97,35 @@ public class ComplicationLayoutParamsTest extends SysuiTestCase { } /** + * Ensures unspecified margin uses default. + */ + @Test + public void testUnspecifiedMarginUsesDefault() { + final ComplicationLayoutParams params = new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP, + ComplicationLayoutParams.DIRECTION_DOWN, + 3); + assertThat(params.getMargin(10) == 10).isTrue(); + } + + /** + * Ensures specified margin is used instead of default. + */ + @Test + public void testSpecifiedMargin() { + final ComplicationLayoutParams params = new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP, + ComplicationLayoutParams.DIRECTION_DOWN, + 3, + 10); + assertThat(params.getMargin(5) == 10).isTrue(); + } + + /** * Ensures ComplicationLayoutParams is properly duplicated on copy construction. */ @Test @@ -106,12 +135,36 @@ public class ComplicationLayoutParamsTest extends SysuiTestCase { 100, ComplicationLayoutParams.POSITION_TOP, ComplicationLayoutParams.DIRECTION_DOWN, + 3, + 10); + final ComplicationLayoutParams copy = new ComplicationLayoutParams(params); + + assertThat(copy.getDirection() == params.getDirection()).isTrue(); + assertThat(copy.getPosition() == params.getPosition()).isTrue(); + assertThat(copy.getWeight() == params.getWeight()).isTrue(); + assertThat(copy.getMargin(0) == params.getMargin(1)).isTrue(); + assertThat(copy.height == params.height).isTrue(); + assertThat(copy.width == params.width).isTrue(); + } + + /** + * Ensures ComplicationLayoutParams is properly duplicated on copy construction with unspecified + * margin. + */ + @Test + public void testCopyConstructionWithUnspecifiedMargin() { + final ComplicationLayoutParams params = new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP, + ComplicationLayoutParams.DIRECTION_DOWN, 3); final ComplicationLayoutParams copy = new ComplicationLayoutParams(params); assertThat(copy.getDirection() == params.getDirection()).isTrue(); assertThat(copy.getPosition() == params.getPosition()).isTrue(); assertThat(copy.getWeight() == params.getWeight()).isTrue(); + assertThat(copy.getMargin(1) == params.getMargin(1)).isTrue(); assertThat(copy.height == params.height).isTrue(); assertThat(copy.width == params.width).isTrue(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt index 5eb9a9862340..e539705d9ede 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt @@ -6,6 +6,7 @@ import com.android.internal.logging.MetricsLogger import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.FeatureFlags import com.android.systemui.media.MediaHost import com.android.systemui.media.MediaHostState import com.android.systemui.plugins.FalsingManager @@ -52,6 +53,7 @@ class QSPanelControllerTest : SysuiTestCase() { @Mock private lateinit var tile: QSTile @Mock private lateinit var otherTile: QSTile @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager + @Mock private lateinit var featureFlags: FeatureFlags private lateinit var controller: QSPanelController @@ -82,7 +84,8 @@ class QSPanelControllerTest : SysuiTestCase() { brightnessControllerFactory, brightnessSliderFactory, falsingManager, - statusBarKeyguardViewManager + statusBarKeyguardViewManager, + featureFlags ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt index 2db58be15665..7c930b196d68 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt @@ -159,6 +159,32 @@ class QSPanelTest : SysuiTestCase() { } @Test + fun testTopPadding_notCombinedHeaders() { + qsPanel.setUsingCombinedHeaders(false) + val padding = 10 + val paddingCombined = 100 + context.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_top, padding) + context.orCreateTestableResources.addOverride( + R.dimen.qs_panel_padding_top_combined_headers, paddingCombined) + + qsPanel.updatePadding() + assertThat(qsPanel.paddingTop).isEqualTo(padding) + } + + @Test + fun testTopPadding_combinedHeaders() { + qsPanel.setUsingCombinedHeaders(true) + val padding = 10 + val paddingCombined = 100 + context.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_top, padding) + context.orCreateTestableResources.addOverride( + R.dimen.qs_panel_padding_top_combined_headers, paddingCombined) + + qsPanel.updatePadding() + assertThat(qsPanel.paddingTop).isEqualTo(paddingCombined) + } + + @Test fun testSetSquishinessFraction_noCrash() { qsPanel.addView(qsPanel.mTileLayout as View, 0) qsPanel.addView(FrameLayout(context)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitorTest.kt index 1531f888c857..16e2441c556b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitorTest.kt @@ -148,7 +148,7 @@ class NotificationMemoryMonitorTest : SysuiTestCase() { smallIcon = notification.smallIcon.bitmap.allocationByteCount, largeIcon = notification.getLargeIcon().bitmap.allocationByteCount, extras = 4092, - bigPicture = 960000, + bigPicture = bigPicture.bitmap.allocationByteCount, extender = 0, style = "BigPictureStyle", styleIcon = bigPictureIcon.bitmap.allocationByteCount, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 54549789b904..8c18f58ca10d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.flags.Flags.MODERN_BOUNCER; + import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -525,4 +527,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mBouncerExpansionCallback.onVisibilityChanged(false); verify(mCentralSurfaces).setBouncerShowingOverDream(false); } + + @Test + public void flag_off_DoesNotCallBouncerInteractor() { + when(mFeatureFlags.isEnabled(MODERN_BOUNCER)).thenReturn(false); + mStatusBarKeyguardViewManager.hideBouncer(false); + verify(mBouncerInteractor, never()).hide(); + } } diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index 799c759b96d2..1df382fbd76f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -464,6 +464,16 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } @Override + public void setInstalledAndEnabledServices(List<AccessibilityServiceInfo> infos) { + return; + } + + @Override + public List<AccessibilityServiceInfo> getInstalledAndEnabledServices() { + return null; + } + + @Override public void setAttributionTag(String attributionTag) { mAttributionTag = attributionTag; } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 1efbb0a3c171..365068d22171 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -277,6 +277,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final SparseArray<AccessibilityUserState> mUserStates = new SparseArray<>(); private final UiAutomationManager mUiAutomationManager = new UiAutomationManager(mLock); + private final ProxyManager mProxyManager; private final AccessibilityTraceManager mTraceManager; private final CaptioningManagerImpl mCaptioningManagerImpl; @@ -396,7 +397,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityWindowManager a11yWindowManager, AccessibilityDisplayListener a11yDisplayListener, MagnificationController magnificationController, - @Nullable AccessibilityInputFilter inputFilter) { + @Nullable AccessibilityInputFilter inputFilter, + ProxyManager proxyManager) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); @@ -412,6 +414,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMagnificationController = magnificationController; mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); + mProxyManager = proxyManager; if (inputFilter != null) { mInputFilter = inputFilter; mHasInputFilter = true; @@ -445,6 +448,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub new MagnificationScaleProvider(mContext)); mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); + mProxyManager = new ProxyManager(mLock); init(); } @@ -3602,6 +3606,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } @Override + public boolean registerProxyForDisplay(IAccessibilityServiceClient client, int displayId) + throws RemoteException { + mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); + if (client == null) { + return false; + } + if (displayId < 0) { + throw new IllegalArgumentException("The display id " + displayId + " is invalid."); + } + if (displayId == Display.DEFAULT_DISPLAY) { + throw new IllegalArgumentException("The default display cannot be proxy-ed."); + } + if (!isTrackedDisplay(displayId)) { + throw new IllegalArgumentException("The display " + displayId + " does not exist or is" + + " not tracked by accessibility."); + } + + mProxyManager.registerProxy(client, displayId); + return true; + } + + @Override + public boolean unregisterProxyForDisplay(int displayId) throws RemoteException { + mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); + return mProxyManager.unregisterProxy(displayId); + } + + @Override public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; synchronized (mLock) { @@ -3830,6 +3862,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return mA11yDisplayListener.getValidDisplayList(); } + + /** + * Returns {@code true} if the display id is in the list of currently valid logical displays + * being tracked by a11y. + */ + private boolean isTrackedDisplay(int displayId) { + final ArrayList<Display> displays = getValidDisplayList(); + for (Display display : displays) { + if (display.getDisplayId() == displayId) { + return true; + } + } + return false; + } + /** * A Utility class to handle display state. */ diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java new file mode 100644 index 000000000000..fb0b8f3b17b1 --- /dev/null +++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.accessibility; +import android.accessibilityservice.IAccessibilityServiceClient; + +/** + * Manages proxy connections. + * + * Currently this acts similarly to UiAutomationManager as a global manager, though ideally each + * proxy connection will belong to a separate user state. + * + * TODO(241117292): Remove or cut down during simultaneous user refactoring. + */ +public class ProxyManager { + private final Object mLock; + + ProxyManager(Object lock) { + mLock = lock; + } + + /** + * TODO: Create the proxy service connection. + */ + public void registerProxy(IAccessibilityServiceClient client, int displayId) { + } + + /** + * TODO: Unregister the proxy service connection based on display id. + */ + public boolean unregisterProxy(int displayId) { + return true; + } +} diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index 77fb360ffb85..8510bd369a2f 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -14691,7 +14691,7 @@ public class BatteryStatsImpl extends BatteryStats { @GuardedBy("this") private boolean isUsageHistoryEnabled() { - return false; + return mConstants.RECORD_USAGE_HISTORY; } @GuardedBy("this") @@ -14793,6 +14793,8 @@ public class BatteryStatsImpl extends BatteryStats { public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; public static final String KEY_BATTERY_CHARGED_DELAY_MS = "battery_charged_delay_ms"; + public static final String KEY_RECORD_USAGE_HISTORY = + "record_usage_history"; private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; @@ -14805,6 +14807,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ + private static final boolean DEFAULT_RECORD_USAGE_HISTORY = false; public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an @@ -14820,6 +14823,7 @@ public class BatteryStatsImpl extends BatteryStats { public int MAX_HISTORY_FILES; public int MAX_HISTORY_BUFFER; /*Bytes*/ public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; + public boolean RECORD_USAGE_HISTORY = DEFAULT_RECORD_USAGE_HISTORY; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); @@ -14895,6 +14899,9 @@ public class BatteryStatsImpl extends BatteryStats { DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB : DEFAULT_MAX_HISTORY_BUFFER_KB) * 1024; + RECORD_USAGE_HISTORY = mParser.getBoolean( + KEY_RECORD_USAGE_HISTORY, DEFAULT_RECORD_USAGE_HISTORY); + updateBatteryChargedDelayMsLocked(); onChange(); @@ -14960,6 +14967,8 @@ public class BatteryStatsImpl extends BatteryStats { pw.println(MAX_HISTORY_BUFFER/1024); pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); pw.println(BATTERY_CHARGED_DELAY_MS); + pw.print(KEY_RECORD_USAGE_HISTORY); pw.print("="); + pw.println(RECORD_USAGE_HISTORY); } } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 99950a0c185b..cd0096bd9e42 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -602,9 +602,12 @@ public class TrustManagerService extends SystemService { synchronized (mUserTrustState) { wasTrusted = (mUserTrustState.get(userId) == TrustState.TRUSTED); wasTrustable = (mUserTrustState.get(userId) == TrustState.TRUSTABLE); + boolean isAutomotive = getContext().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_AUTOMOTIVE); boolean renewingTrust = wasTrustable && ( (flags & TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0); - boolean canMoveToTrusted = alreadyUnlocked || isFromUnlock || renewingTrust; + boolean canMoveToTrusted = + alreadyUnlocked || isFromUnlock || renewingTrust || isAutomotive; boolean upgradingTrustForCurrentUser = (userId == mCurrentUser); if (trustedByAtLeastOneAgent && wasTrusted) { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index 51d78e1d3a11..0f09252b8ca1 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -132,6 +132,7 @@ public class AccessibilityManagerServiceTest { @Mock private WindowMagnificationManager mMockWindowMagnificationMgr; @Mock private MagnificationController mMockMagnificationController; @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController; + @Mock private ProxyManager mProxyManager; @Rule public final TestableContext mTestableContext = new TestableContext( @@ -184,7 +185,8 @@ public class AccessibilityManagerServiceTest { mMockA11yWindowManager, mMockA11yDisplayListener, mMockMagnificationController, - mInputFilter); + mInputFilter, + mProxyManager); final AccessibilityUserState userState = new AccessibilityUserState( mA11yms.getCurrentUserIdLocked(), mTestableContext, mA11yms); @@ -278,6 +280,49 @@ public class AccessibilityManagerServiceTest { @SmallTest @Test + public void testRegisterProxy() throws Exception { + mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY); + verify(mProxyManager).registerProxy(mMockServiceClient, TEST_DISPLAY); + } + + + @SmallTest + @Test + public void testRegisterProxyWithoutPermission() throws Exception { + doThrow(SecurityException.class).when(mMockSecurityPolicy) + .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); + try { + mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY); + Assert.fail(); + } catch (SecurityException expected) { + } + verify(mProxyManager, never()).registerProxy(mMockServiceClient, TEST_DISPLAY); + } + + @SmallTest + @Test + public void testRegisterProxyForDefaultDisplay() throws Exception { + try { + mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY); + Assert.fail(); + } catch (IllegalArgumentException expected) { + } + verify(mProxyManager, never()).registerProxy(mMockServiceClient, Display.DEFAULT_DISPLAY); + } + + @SmallTest + @Test + public void testRegisterProxyForInvalidDisplay() throws Exception { + try { + mA11yms.registerProxyForDisplay(mMockServiceClient, Display.INVALID_DISPLAY); + Assert.fail(); + } catch (IllegalArgumentException expected) { + } + verify(mProxyManager, never()).registerProxy(mMockServiceClient, Display.INVALID_DISPLAY); + } + + @SmallTest + @Test public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() { final AccessibilityUserState userState = mA11yms.mUserStates.get( mA11yms.getCurrentUserIdLocked()); |