1015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver/*
2015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** Copyright 2017, The Android Open Source Project
3015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver **
4015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** Licensed under the Apache License, Version 2.0 (the "License");
5015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** you may not use this file except in compliance with the License.
6015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** You may obtain a copy of the License at
7015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver **
8015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver **     http://www.apache.org/licenses/LICENSE-2.0
9015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver **
10015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** Unless required by applicable law or agreed to in writing, software
11015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** distributed under the License is distributed on an "AS IS" BASIS,
12015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** See the License for the specific language governing permissions and
14015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver ** limitations under the License.
15015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver */
16015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
17015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverpackage com.android.server.accessibility;
18015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
19c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaverimport static junit.framework.Assert.assertFalse;
20c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaverimport static junit.framework.Assert.assertTrue;
21c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver
22015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport static org.mockito.ArgumentMatchers.any;
23015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport static org.mockito.ArgumentMatchers.anyInt;
24015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport static org.mockito.ArgumentMatchers.eq;
25015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport static org.mockito.Mockito.mock;
26015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport static org.mockito.Mockito.verify;
27015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport static org.mockito.Mockito.when;
28015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
29015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.accessibilityservice.AccessibilityServiceInfo;
30015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.content.ComponentName;
31015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.content.Context;
32015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.content.Intent;
33015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.content.pm.ApplicationInfo;
34015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.content.pm.ResolveInfo;
35015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.content.pm.ServiceInfo;
36015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.os.Handler;
37015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.os.IBinder;
38015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.os.Looper;
39015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.os.RemoteException;
40015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport android.os.UserHandle;
41e99bc0501a288735d337f2ff64f8fa47f766a59bAdrian Roos
42e99bc0501a288735d337f2ff64f8fa47f766a59bAdrian Roosimport com.android.server.wm.WindowManagerInternal;
43015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
44015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport org.junit.Before;
45015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport org.junit.BeforeClass;
46015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport org.junit.Test;
47015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport org.mockito.Mock;
48015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport org.mockito.MockitoAnnotations;
49015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
50015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport java.util.Arrays;
51015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverimport java.util.HashSet;
52015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
53015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
54015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver/**
55015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver * Tests for AccessibilityServiceConnection
56015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver */
57015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaverpublic class AccessibilityServiceConnectionTest {
58015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    static final ComponentName COMPONENT_NAME = new ComponentName(
59015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver            "com.android.server.accessibility", "AccessibilityServiceConnectionTest");
60015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    static final int SERVICE_ID = 42;
61015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
62015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    AccessibilityServiceConnection mConnection;
63c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver
64015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock AccessibilityManagerService.UserState mMockUserState;
65015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock Context mMockContext;
66015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock AccessibilityServiceInfo mMockServiceInfo;
67015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock ResolveInfo mMockResolveInfo;
68015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock AccessibilityManagerService.SecurityPolicy mMockSecurityPolicy;
694b7c919e725bc87bea82ab2c2370f094a049b8cfEugene Susla    @Mock AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport;
70015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock WindowManagerInternal mMockWindowManagerInternal;
71015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock GlobalActionPerformer mMockGlobalActionPerformer;
72015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Mock KeyEventDispatcher mMockKeyEventDispatcher;
73c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    @Mock MagnificationController mMockMagnificationController;
74015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
75c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
76015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
77015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @BeforeClass
78015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    public static void oneTimeInitialization() {
79015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        if (Looper.myLooper() == null) {
80015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver            Looper.prepare();
81015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        }
82015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    }
83015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
84015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Before
85015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    public void setup() {
86015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        MockitoAnnotations.initMocks(this);
87015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mMockKeyEventDispatcher);
88c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        when(mMockSystemSupport.getMagnificationController())
89c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver                .thenReturn(mMockMagnificationController);
90c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver
91015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
92015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mMockResolveInfo.serviceInfo = mock(ServiceInfo.class);
93015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
94015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
95015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mConnection = new AccessibilityServiceConnection(mMockUserState, mMockContext,
96c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver                COMPONENT_NAME, mMockServiceInfo, SERVICE_ID, mHandler, new Object(),
97015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver                mMockSecurityPolicy, mMockSystemSupport, mMockWindowManagerInternal,
98015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver                mMockGlobalActionPerformer);
99015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    }
100015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
101015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Test
102015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    public void bind_requestsContextToBindService() {
103015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mConnection.bindLocked();
104015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        verify(mMockContext).bindServiceAsUser(any(Intent.class), eq(mConnection),
105015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
106015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver                any(UserHandle.class));
107015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    }
108015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
109015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Test
110015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    public void unbind_requestsContextToUnbindService() {
111015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mConnection.unbindLocked();
112015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        verify(mMockContext).unbindService(mConnection);
113015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    }
114015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver
115015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    @Test
116015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    public void bindConnectUnbind_linksAndUnlinksToServiceDeath() throws RemoteException {
117015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        IBinder mockBinder = mock(IBinder.class);
118c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        setServiceBinding(COMPONENT_NAME);
119015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mConnection.bindLocked();
120015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
121015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        verify(mockBinder).linkToDeath(eq(mConnection), anyInt());
122015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        mConnection.unbindLocked();
123015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver        verify(mockBinder).unlinkToDeath(eq(mConnection), anyInt());
124015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver    }
125c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver
126c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    @Test
127c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    public void connectedServiceCrashedAndRestarted_crashReportedInServiceInfo() {
128c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        IBinder mockBinder = mock(IBinder.class);
129c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        setServiceBinding(COMPONENT_NAME);
130c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        mConnection.bindLocked();
131c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
132c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        assertFalse(mConnection.getServiceInfo().crashed);
133c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        mConnection.binderDied();
134c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        assertTrue(mConnection.getServiceInfo().crashed);
135c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
136c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        mHandler.sendAllMessages();
137c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        assertFalse(mConnection.getServiceInfo().crashed);
138c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    }
139c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver
140c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    private void setServiceBinding(ComponentName componentName) {
141c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver        when(mMockUserState.getBindingServicesLocked())
142c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver                .thenReturn(new HashSet<>(Arrays.asList(componentName)));
143c09a02198718761e20e351f4bf0ee9e30a716d11Phil Weaver    }
144015847aa4f5ba31d6a4fd6695202ae60aaec926aPhil Weaver}
145