diff options
| -rw-r--r-- | core/java/android/widget/ToastPresenter.java | 30 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java | 9 |
2 files changed, 26 insertions, 13 deletions
diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java index 0f2a3ca6936b..eccff0692fab 100644 --- a/core/java/android/widget/ToastPresenter.java +++ b/core/java/android/widget/ToastPresenter.java @@ -69,7 +69,7 @@ public class ToastPresenter { private final Context mContext; private final Resources mResources; private final WindowManager mWindowManager; - private final AccessibilityManager mAccessibilityManager; + private final IAccessibilityManager mAccessibilityManager; private final INotificationManager mNotificationManager; private final String mPackageName; private final WindowManager.LayoutParams mParams; @@ -83,16 +83,7 @@ public class ToastPresenter { mWindowManager = context.getSystemService(WindowManager.class); mNotificationManager = notificationManager; mPackageName = packageName; - - // We obtain AccessibilityManager manually via its constructor instead of using method - // AccessibilityManager.getInstance() for 2 reasons: - // 1. We want to be able to inject IAccessibilityManager in tests to verify behavior. - // 2. getInstance() caches the instance for the process even if we pass a different - // context to it. This is problematic for multi-user because callers can pass a context - // created via Context.createContextAsUser(). - mAccessibilityManager = new AccessibilityManager(context, accessibilityManager, - context.getUserId()); - + mAccessibilityManager = accessibilityManager; mParams = createLayoutParams(); } @@ -283,7 +274,16 @@ public class ToastPresenter { * enabled. */ public void trySendAccessibilityEvent(View view, String packageName) { - if (!mAccessibilityManager.isEnabled()) { + // We obtain AccessibilityManager manually via its constructor instead of using method + // AccessibilityManager.getInstance() for 2 reasons: + // 1. We want to be able to inject IAccessibilityManager in tests to verify behavior. + // 2. getInstance() caches the instance for the process even if we pass a different + // context to it. This is problematic for multi-user because callers can pass a context + // created via Context.createContextAsUser(). + final AccessibilityManager accessibilityManager = + new AccessibilityManager(mContext, mAccessibilityManager, mContext.getUserId()); + if (!accessibilityManager.isEnabled()) { + accessibilityManager.removeClient(); return; } AccessibilityEvent event = AccessibilityEvent.obtain( @@ -291,7 +291,11 @@ public class ToastPresenter { event.setClassName(Toast.class.getName()); event.setPackageName(packageName); view.dispatchPopulateAccessibilityEvent(event); - mAccessibilityManager.sendAccessibilityEvent(event); + accessibilityManager.sendAccessibilityEvent(event); + // Every new instance of A11yManager registers an IA11yManagerClient object with the + // backing service. This client isn't removed until the calling process is destroyed, + // causing a leak here. We explicitly remove the client. + accessibilityManager.removeClient(); } private void addToastView() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java b/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java index 9b177e1cd0e5..5efe05f6db46 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java @@ -84,6 +84,7 @@ public class ToastUITest extends SysuiTestCase { private static final String PACKAGE_NAME_1 = "com.example1.test"; private static final Binder TOKEN_1 = new Binder(); private static final Binder WINDOW_TOKEN_1 = new Binder(); + private static final int USER_ID = 1; private static final int UID_2 = 10256; private static final String PACKAGE_NAME_2 = "com.example2.test"; @@ -227,6 +228,14 @@ public class ToastUITest extends SysuiTestCase { } @Test + public void testShowToast_accessibilityManagerClientIsRemoved() throws Exception { + when(mContextSpy.getUserId()).thenReturn(USER_ID); + mToastUI.showToast(UID_1, PACKAGE_NAME_1, TOKEN_1, TEXT, WINDOW_TOKEN_1, Toast.LENGTH_LONG, + null); + verify(mAccessibilityManager).removeClient(any(), eq(USER_ID)); + } + + @Test public void testHideToast_removesView() throws Exception { mToastUI.showToast(UID_1, PACKAGE_NAME_1, TOKEN_1, TEXT, WINDOW_TOKEN_1, Toast.LENGTH_LONG, mCallback); |