1 /* 2 ** Copyright 2017, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 package com.android.server.accessibility; 18 19 import static junit.framework.Assert.assertFalse; 20 import static junit.framework.Assert.assertTrue; 21 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.eq; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.accessibilityservice.AccessibilityServiceInfo; 30 import android.content.ComponentName; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.pm.ApplicationInfo; 34 import android.content.pm.ResolveInfo; 35 import android.content.pm.ServiceInfo; 36 import android.os.Handler; 37 import android.os.IBinder; 38 import android.os.Looper; 39 import android.os.RemoteException; 40 import android.os.UserHandle; 41 42 import com.android.server.wm.WindowManagerInternal; 43 44 import org.junit.Before; 45 import org.junit.BeforeClass; 46 import org.junit.Test; 47 import org.mockito.Mock; 48 import org.mockito.MockitoAnnotations; 49 50 import java.util.Arrays; 51 import java.util.HashSet; 52 53 54 /** 55 * Tests for AccessibilityServiceConnection 56 */ 57 public class AccessibilityServiceConnectionTest { 58 static final ComponentName COMPONENT_NAME = new ComponentName( 59 "com.android.server.accessibility", "AccessibilityServiceConnectionTest"); 60 static final int SERVICE_ID = 42; 61 62 AccessibilityServiceConnection mConnection; 63 64 @Mock AccessibilityManagerService.UserState mMockUserState; 65 @Mock Context mMockContext; 66 @Mock AccessibilityServiceInfo mMockServiceInfo; 67 @Mock ResolveInfo mMockResolveInfo; 68 @Mock AccessibilityManagerService.SecurityPolicy mMockSecurityPolicy; 69 @Mock AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport; 70 @Mock WindowManagerInternal mMockWindowManagerInternal; 71 @Mock GlobalActionPerformer mMockGlobalActionPerformer; 72 @Mock KeyEventDispatcher mMockKeyEventDispatcher; 73 @Mock MagnificationController mMockMagnificationController; 74 75 MessageCapturingHandler mHandler = new MessageCapturingHandler(null); 76 77 @BeforeClass 78 public static void oneTimeInitialization() { 79 if (Looper.myLooper() == null) { 80 Looper.prepare(); 81 } 82 } 83 84 @Before 85 public void setup() { 86 MockitoAnnotations.initMocks(this); 87 when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mMockKeyEventDispatcher); 88 when(mMockSystemSupport.getMagnificationController()) 89 .thenReturn(mMockMagnificationController); 90 91 when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo); 92 mMockResolveInfo.serviceInfo = mock(ServiceInfo.class); 93 mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class); 94 95 mConnection = new AccessibilityServiceConnection(mMockUserState, mMockContext, 96 COMPONENT_NAME, mMockServiceInfo, SERVICE_ID, mHandler, new Object(), 97 mMockSecurityPolicy, mMockSystemSupport, mMockWindowManagerInternal, 98 mMockGlobalActionPerformer); 99 } 100 101 @Test 102 public void bind_requestsContextToBindService() { 103 mConnection.bindLocked(); 104 verify(mMockContext).bindServiceAsUser(any(Intent.class), eq(mConnection), 105 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE), 106 any(UserHandle.class)); 107 } 108 109 @Test 110 public void unbind_requestsContextToUnbindService() { 111 mConnection.unbindLocked(); 112 verify(mMockContext).unbindService(mConnection); 113 } 114 115 @Test 116 public void bindConnectUnbind_linksAndUnlinksToServiceDeath() throws RemoteException { 117 IBinder mockBinder = mock(IBinder.class); 118 setServiceBinding(COMPONENT_NAME); 119 mConnection.bindLocked(); 120 mConnection.onServiceConnected(COMPONENT_NAME, mockBinder); 121 verify(mockBinder).linkToDeath(eq(mConnection), anyInt()); 122 mConnection.unbindLocked(); 123 verify(mockBinder).unlinkToDeath(eq(mConnection), anyInt()); 124 } 125 126 @Test 127 public void connectedServiceCrashedAndRestarted_crashReportedInServiceInfo() { 128 IBinder mockBinder = mock(IBinder.class); 129 setServiceBinding(COMPONENT_NAME); 130 mConnection.bindLocked(); 131 mConnection.onServiceConnected(COMPONENT_NAME, mockBinder); 132 assertFalse(mConnection.getServiceInfo().crashed); 133 mConnection.binderDied(); 134 assertTrue(mConnection.getServiceInfo().crashed); 135 mConnection.onServiceConnected(COMPONENT_NAME, mockBinder); 136 mHandler.sendAllMessages(); 137 assertFalse(mConnection.getServiceInfo().crashed); 138 } 139 140 private void setServiceBinding(ComponentName componentName) { 141 when(mMockUserState.getBindingServicesLocked()) 142 .thenReturn(new HashSet<>(Arrays.asList(componentName))); 143 } 144 } 145