Loading services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java +20 −7 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ class UiAutomationManager { private int mUiAutomationFlags; private IBinder mUiAutomationServiceOwner; private final DeathRecipient mUiAutomationSerivceOwnerDeathRecipient = private final DeathRecipient mUiAutomationServiceOwnerDeathRecipient = new DeathRecipient() { @Override public void binderDied() { Loading Loading @@ -85,7 +85,7 @@ class UiAutomationManager { } try { owner.linkToDeath(mUiAutomationSerivceOwnerDeathRecipient, 0); owner.linkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0); } catch (RemoteException re) { Slog.e(LOG_TAG, "Couldn't register for the death of a UiTestAutomationService!", re); return; Loading Loading @@ -165,12 +165,14 @@ class UiAutomationManager { mUiAutomationService = null; mUiAutomationFlags = 0; if (mUiAutomationServiceOwner != null) { mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationSerivceOwnerDeathRecipient, 0); mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0); mUiAutomationServiceOwner = null; } } private class UiAutomationService extends AccessibilityClientConnection { private final Handler mMainHandler; UiAutomationService(Context context, AccessibilityServiceInfo accessibilityServiceInfo, int id, Handler mainHandler, Object lock, AccessibilityManagerService.SecurityPolicy securityPolicy, Loading @@ -178,15 +180,26 @@ class UiAutomationManager { GlobalActionPerformer globalActionPerfomer) { super(context, COMPONENT_NAME, accessibilityServiceInfo, id, mainHandler, lock, securityPolicy, systemSupport, windowManagerInternal, globalActionPerfomer); mMainHandler = mainHandler; } void connectServiceUnknownThread() { // This needs to be done on the main thread mEventDispatchHandler.post(() -> { mMainHandler.post(() -> { try { mService = mServiceInterface.asBinder(); mService.linkToDeath(this, 0); mServiceInterface.init(this, mId, mOverlayWindowToken); final IAccessibilityServiceClient serviceInterface; final IBinder service; synchronized (mLock) { serviceInterface = mServiceInterface; mService = (serviceInterface == null) ? null : mServiceInterface.asBinder(); service = mService; } // If the serviceInterface is null, the UiAutomation has been shut down on // another thread. if (serviceInterface != null) { service.linkToDeath(this, 0); serviceInterface.init(this, mId, mOverlayWindowToken); } } catch (RemoteException re) { Slog.w(LOG_TAG, "Error initialized connection", re); destroyUiAutomationService(); Loading services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java +11 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.accessibility; import android.app.Notification; import android.os.Handler; import android.os.Message; import android.util.Pair; Loading Loading @@ -49,7 +50,7 @@ public class MessageCapturingHandler extends Handler { public void sendOneMessage() { Message message = timedMessages.remove(0).first; removeMessages(message.what, message.obj); mCallback.handleMessage(message); dispatchMessage(message); removeStaleMessages(); } Loading @@ -62,7 +63,7 @@ public class MessageCapturingHandler extends Handler { public void sendLastMessage() { Message message = timedMessages.remove(timedMessages.size() - 1).first; removeMessages(message.what, message.obj); mCallback.handleMessage(message); dispatchMessage(message); removeStaleMessages(); } Loading @@ -79,4 +80,12 @@ public class MessageCapturingHandler extends Handler { } } } public void dispatchMessage(Message m) { if (mCallback != null) { mCallback.handleMessage(m); return; } super.dispatchMessage(m); } } services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java +18 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.server.accessibility; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; Loading @@ -29,7 +31,6 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.view.WindowManagerInternal; Loading @@ -38,6 +39,7 @@ import android.view.accessibility.AccessibilityEvent; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading @@ -49,6 +51,8 @@ public class UiAutomationManagerTest { final UiAutomationManager mUiAutomationManager = new UiAutomationManager(); MessageCapturingHandler mMessageCapturingHandler; @Mock AccessibilityManagerService.UserState mMockUserState; @Mock Context mMockContext; @Mock AccessibilityServiceInfo mMockServiceInfo; Loading @@ -68,7 +72,6 @@ public class UiAutomationManagerTest { } } @Before public void setup() { MockitoAnnotations.initMocks(this); Loading @@ -80,6 +83,8 @@ public class UiAutomationManagerTest { mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class); when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder); mMessageCapturingHandler = new MessageCapturingHandler(null); } @Test Loading Loading @@ -146,10 +151,20 @@ public class UiAutomationManagerTest { assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked()); } @Test public void uiAutomationBinderDiesBeforeConnecting_shouldNotCrash() throws Exception { register(0); ArgumentCaptor<IBinder.DeathRecipient> captor = ArgumentCaptor.forClass( IBinder.DeathRecipient.class); verify(mMockOwner).linkToDeath(captor.capture(), anyInt()); captor.getValue().binderDied(); mMessageCapturingHandler.sendAllMessages(); } private void register(int flags) { mUiAutomationManager.registerUiTestAutomationServiceLocked(mMockOwner, mMockAccessibilityServiceClient, mMockContext, mMockServiceInfo, SERVICE_ID, new Handler(), new Object(), mMockSecurityPolicy, mMockSystemSupport, mMessageCapturingHandler, new Object(), mMockSecurityPolicy, mMockSystemSupport, mMockWindowManagerInternal, mMockGlobalActionPerformer, flags); } Loading Loading
services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java +20 −7 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ class UiAutomationManager { private int mUiAutomationFlags; private IBinder mUiAutomationServiceOwner; private final DeathRecipient mUiAutomationSerivceOwnerDeathRecipient = private final DeathRecipient mUiAutomationServiceOwnerDeathRecipient = new DeathRecipient() { @Override public void binderDied() { Loading Loading @@ -85,7 +85,7 @@ class UiAutomationManager { } try { owner.linkToDeath(mUiAutomationSerivceOwnerDeathRecipient, 0); owner.linkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0); } catch (RemoteException re) { Slog.e(LOG_TAG, "Couldn't register for the death of a UiTestAutomationService!", re); return; Loading Loading @@ -165,12 +165,14 @@ class UiAutomationManager { mUiAutomationService = null; mUiAutomationFlags = 0; if (mUiAutomationServiceOwner != null) { mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationSerivceOwnerDeathRecipient, 0); mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0); mUiAutomationServiceOwner = null; } } private class UiAutomationService extends AccessibilityClientConnection { private final Handler mMainHandler; UiAutomationService(Context context, AccessibilityServiceInfo accessibilityServiceInfo, int id, Handler mainHandler, Object lock, AccessibilityManagerService.SecurityPolicy securityPolicy, Loading @@ -178,15 +180,26 @@ class UiAutomationManager { GlobalActionPerformer globalActionPerfomer) { super(context, COMPONENT_NAME, accessibilityServiceInfo, id, mainHandler, lock, securityPolicy, systemSupport, windowManagerInternal, globalActionPerfomer); mMainHandler = mainHandler; } void connectServiceUnknownThread() { // This needs to be done on the main thread mEventDispatchHandler.post(() -> { mMainHandler.post(() -> { try { mService = mServiceInterface.asBinder(); mService.linkToDeath(this, 0); mServiceInterface.init(this, mId, mOverlayWindowToken); final IAccessibilityServiceClient serviceInterface; final IBinder service; synchronized (mLock) { serviceInterface = mServiceInterface; mService = (serviceInterface == null) ? null : mServiceInterface.asBinder(); service = mService; } // If the serviceInterface is null, the UiAutomation has been shut down on // another thread. if (serviceInterface != null) { service.linkToDeath(this, 0); serviceInterface.init(this, mId, mOverlayWindowToken); } } catch (RemoteException re) { Slog.w(LOG_TAG, "Error initialized connection", re); destroyUiAutomationService(); Loading
services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java +11 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.accessibility; import android.app.Notification; import android.os.Handler; import android.os.Message; import android.util.Pair; Loading Loading @@ -49,7 +50,7 @@ public class MessageCapturingHandler extends Handler { public void sendOneMessage() { Message message = timedMessages.remove(0).first; removeMessages(message.what, message.obj); mCallback.handleMessage(message); dispatchMessage(message); removeStaleMessages(); } Loading @@ -62,7 +63,7 @@ public class MessageCapturingHandler extends Handler { public void sendLastMessage() { Message message = timedMessages.remove(timedMessages.size() - 1).first; removeMessages(message.what, message.obj); mCallback.handleMessage(message); dispatchMessage(message); removeStaleMessages(); } Loading @@ -79,4 +80,12 @@ public class MessageCapturingHandler extends Handler { } } } public void dispatchMessage(Message m) { if (mCallback != null) { mCallback.handleMessage(m); return; } super.dispatchMessage(m); } }
services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java +18 −3 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.server.accessibility; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; Loading @@ -29,7 +31,6 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.view.WindowManagerInternal; Loading @@ -38,6 +39,7 @@ import android.view.accessibility.AccessibilityEvent; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading @@ -49,6 +51,8 @@ public class UiAutomationManagerTest { final UiAutomationManager mUiAutomationManager = new UiAutomationManager(); MessageCapturingHandler mMessageCapturingHandler; @Mock AccessibilityManagerService.UserState mMockUserState; @Mock Context mMockContext; @Mock AccessibilityServiceInfo mMockServiceInfo; Loading @@ -68,7 +72,6 @@ public class UiAutomationManagerTest { } } @Before public void setup() { MockitoAnnotations.initMocks(this); Loading @@ -80,6 +83,8 @@ public class UiAutomationManagerTest { mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class); when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder); mMessageCapturingHandler = new MessageCapturingHandler(null); } @Test Loading Loading @@ -146,10 +151,20 @@ public class UiAutomationManagerTest { assertEquals(0, mUiAutomationManager.getRequestedEventMaskLocked()); } @Test public void uiAutomationBinderDiesBeforeConnecting_shouldNotCrash() throws Exception { register(0); ArgumentCaptor<IBinder.DeathRecipient> captor = ArgumentCaptor.forClass( IBinder.DeathRecipient.class); verify(mMockOwner).linkToDeath(captor.capture(), anyInt()); captor.getValue().binderDied(); mMessageCapturingHandler.sendAllMessages(); } private void register(int flags) { mUiAutomationManager.registerUiTestAutomationServiceLocked(mMockOwner, mMockAccessibilityServiceClient, mMockContext, mMockServiceInfo, SERVICE_ID, new Handler(), new Object(), mMockSecurityPolicy, mMockSystemSupport, mMessageCapturingHandler, new Object(), mMockSecurityPolicy, mMockSystemSupport, mMockWindowManagerInternal, mMockGlobalActionPerformer, flags); } Loading