diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java index 5c4fdcc0e5d89..ed54f08b2b3d4 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java +++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java @@ -17,6 +17,10 @@ package com.android.systemui.accessibility.accessibilitymenu; import android.accessibilityservice.AccessibilityService; +import android.content.res.Configuration; +import android.hardware.display.DisplayManager; +import android.os.Handler; +import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; @@ -27,23 +31,99 @@ import com.android.systemui.accessibility.accessibilitymenu.view.A11yMenuOverlay public class AccessibilityMenuService extends AccessibilityService implements View.OnTouchListener { private static final String TAG = "A11yMenuService"; + private static final long BUFFER_MILLISECONDS_TO_PREVENT_UPDATE_FAILURE = 100L; + private A11yMenuOverlayLayout mA11yMenuLayout; + private static boolean sInitialized = false; + + // TODO(b/136716947): Support multi-display once a11y framework side is ready. + private DisplayManager mDisplayManager; + final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { + int mRotation; + + @Override + public void onDisplayAdded(int displayId) {} + + @Override + public void onDisplayRemoved(int displayId) { + // TODO(b/136716947): Need to reset A11yMenuOverlayLayout by display id. + } + + @Override + public void onDisplayChanged(int displayId) { + Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); + if (mRotation != display.getRotation()) { + mRotation = display.getRotation(); + mA11yMenuLayout.updateViewLayout(); + } + } + }; + + // Update layout. + private final Handler mHandler = new Handler(getMainLooper()); + private final Runnable mOnConfigChangedRunnable = new Runnable() { + @Override + public void run() { + if (!sInitialized) { + return; + } + // Re-assign theme to service after onConfigurationChanged + getTheme().applyStyle(R.style.ServiceTheme, true); + // Caches & updates the page index to ViewPager when a11y menu is refreshed. + // Otherwise, the menu page would reset on a UI update. + int cachedPageIndex = mA11yMenuLayout.getPageIndex(); + mA11yMenuLayout.configureLayout(cachedPageIndex); + } + }; + @Override public void onCreate() { super.onCreate(); } + @Override + public void onDestroy() { + if (mHandler.hasCallbacks(mOnConfigChangedRunnable)) { + mHandler.removeCallbacks(mOnConfigChangedRunnable); + } + + super.onDestroy(); + } + @Override protected void onServiceConnected() { mA11yMenuLayout = new A11yMenuOverlayLayout(this); - super.onServiceConnected(); + + // Temporary measure to force visibility mA11yMenuLayout.toggleVisibility(); + + mDisplayManager = getSystemService(DisplayManager.class); + mDisplayManager.registerDisplayListener(mDisplayListener, null); + + sInitialized = true; } @Override public void onAccessibilityEvent(AccessibilityEvent event) {} + /** + * This method would notify service when device configuration, such as display size, + * localization, orientation or theme, is changed. + * + * @param newConfig the new device configuration. + */ + @Override + public void onConfigurationChanged(Configuration newConfig) { + // Prevent update layout failure + // if multiple onConfigurationChanged are called at the same time. + if (mHandler.hasCallbacks(mOnConfigChangedRunnable)) { + mHandler.removeCallbacks(mOnConfigChangedRunnable); + } + mHandler.postDelayed( + mOnConfigChangedRunnable, BUFFER_MILLISECONDS_TO_PREVENT_UPDATE_FAILURE); + } + @Override public void onInterrupt() { }