109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki/* 209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * Copyright (C) 2017 The Android Open Source Project 309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * 409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * you may not use this file except in compliance with the License. 609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * You may obtain a copy of the License at 709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * 809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * 1009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * Unless required by applicable law or agreed to in writing, software 1109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 1209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * See the License for the specific language governing permissions and 1409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki * limitations under the License. 1509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki */ 1609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukipackage com.android.server.am; 1709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 1809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport static org.mockito.ArgumentMatchers.any; 1909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport static org.mockito.ArgumentMatchers.anyInt; 2009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport static org.mockito.ArgumentMatchers.eq; 2109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport static org.mockito.Mockito.mock; 2209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport static org.mockito.Mockito.verify; 2309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport static org.mockito.Mockito.when; 2409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 2509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.app.admin.IDeviceAdminService; 2609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.content.ComponentName; 2709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.content.Context; 2809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.content.Intent; 2909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.content.ServiceConnection; 3009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.os.Handler; 3109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.os.IBinder; 3209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.os.Looper; 3309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.os.UserHandle; 3409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.test.AndroidTestCase; 3509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport android.util.Pair; 3609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 3709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport org.mockito.ArgumentMatchers; 3809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 3909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport java.util.ArrayList; 4009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport java.util.Arrays; 4109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukiimport java.util.Collections; 4209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 4309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onukipublic class PersistentConnectionTest extends AndroidTestCase { 4409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki private static class MyConnection extends PersistentConnection<IDeviceAdminService> { 4509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki public long uptimeMillis = 12345; 4609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 4709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki public ArrayList<Pair<Runnable, Long>> scheduledRunnables = new ArrayList<>(); 4809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 4909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki public MyConnection(String tag, Context context, Handler handler, int userId, 5009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki ComponentName componentName, long rebindBackoffSeconds, 5109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki double rebindBackoffIncrease, long rebindMaxBackoffSeconds) { 5209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki super(tag, context, handler, userId, componentName, 5309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki rebindBackoffSeconds, rebindBackoffIncrease, rebindMaxBackoffSeconds); 5409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 5509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 5609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki @Override 5709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki protected IDeviceAdminService asInterface(IBinder binder) { 5809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki return (IDeviceAdminService) binder; 5909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 6009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 6109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki @Override 6209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki long injectUptimeMillis() { 6309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki return uptimeMillis; 6409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 6509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 6609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki @Override 6709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki void injectPostAtTime(Runnable r, long uptimeMillis) { 6809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki scheduledRunnables.add(Pair.create(r, uptimeMillis)); 6909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 7009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 7109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki @Override 7209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki void injectRemoveCallbacks(Runnable r) { 7309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki for (int i = scheduledRunnables.size() - 1; i >= 0; i--) { 7409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki if (scheduledRunnables.get(i).first.equals(r)) { 7509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki scheduledRunnables.remove(i); 7609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 7709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 7809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 7909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 8009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki void elapse(long milliSeconds) { 8109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki uptimeMillis += milliSeconds; 8209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 8309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Fire the scheduled runnables. 8409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 8509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Note we collect first and then run all, because sometimes a scheduled runnable 8609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // calls removeCallbacks. 8709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final ArrayList<Runnable> list = new ArrayList<>(); 8809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 8909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki for (int i = scheduledRunnables.size() - 1; i >= 0; i--) { 9009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki if (scheduledRunnables.get(i).second <= uptimeMillis) { 9109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki list.add(scheduledRunnables.get(i).first); 9209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki scheduledRunnables.remove(i); 9309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 9409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 9509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 9609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki Collections.reverse(list); 9709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki for (Runnable r : list) { 9809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki r.run(); 9909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 10009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 10109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 10209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 10309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki public void testAll() { 10409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final Context context = mock(Context.class); 10509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final int userId = 11; 10609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def"); 10709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final Handler handler = new Handler(Looper.getMainLooper()); 10809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 10909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final MyConnection conn = new MyConnection("tag", context, handler, userId, cn, 11009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki /* rebindBackoffSeconds= */ 5, 11109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki /* rebindBackoffIncrease= */ 1.5, 11209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki /* rebindMaxBackoffSeconds= */ 11); 11309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 11409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 11509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 11609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 11709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 11809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 11909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 12009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(), 12109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki any(Handler.class), any(UserHandle.class))) 12209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki .thenReturn(true); 12309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 12409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Call bind. 12509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.bind(); 12609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 12709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 12809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 12909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 13009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 13109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 13209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 13309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 13409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 13509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki verify(context).bindServiceAsUser( 13609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki ArgumentMatchers.argThat(intent -> cn.equals(intent.getComponent())), 13709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki eq(conn.getServiceConnectionForTest()), 13809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE), 13909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki eq(handler), eq(UserHandle.of(userId))); 14009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 14109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // AM responds... 14209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onServiceConnected(cn, 14309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki new IDeviceAdminService.Stub() {}); 14409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 14509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 14609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 14709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isConnected()); 14809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNotNull(conn.getServiceBinder()); 14909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 15009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 15109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 15209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 15309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 15409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Now connected. 15509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 15609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Call unbind... 15709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.unbind(); 15809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 15909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.shouldBeBoundForTest()); 16009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 16109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 16209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 16309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 16409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Caller bind again... 16509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.bind(); 16609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 16709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 16809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 16909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 17009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 17109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 17209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 17309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 17409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 17509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 17609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Now connected again. 17709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 17809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // The service got killed... 17909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onServiceDisconnected(cn); 18009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 18109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 18209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 18309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 18409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 18509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 18609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 18709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 18809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 18909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Connected again... 19009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onServiceConnected(cn, 19109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki new IDeviceAdminService.Stub() {}); 19209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 19309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 19409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 19509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isConnected()); 19609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNotNull(conn.getServiceBinder()); 19709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 19809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 19909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 20009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 20109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 20209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Then the binding is "died"... 20309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onBindingDied(cn); 20409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 20509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 20609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 20709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 20809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 20909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isRebindScheduled()); 21009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 21109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(7500, conn.getNextBackoffMsForTest()); 21209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 21309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals( 21409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(), 21509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.uptimeMillis + 5000)), 21609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.scheduledRunnables); 21709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 21809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // 5000 ms later... 21909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.elapse(5000); 22009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 22109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 22209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 22309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 22409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 22509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 22609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 22709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(7500, conn.getNextBackoffMsForTest()); 22809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 22909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Connected. 23009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onServiceConnected(cn, 23109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki new IDeviceAdminService.Stub() {}); 23209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 23309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 23409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 23509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isConnected()); 23609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNotNull(conn.getServiceBinder()); 23709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 23809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 23909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(7500, conn.getNextBackoffMsForTest()); 24009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 24109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Then the binding is "died"... 24209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onBindingDied(cn); 24309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 24409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 24509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 24609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 24709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 24809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isRebindScheduled()); 24909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 25009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(11000, conn.getNextBackoffMsForTest()); 25109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 25209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals( 25309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(), 25409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.uptimeMillis + 7500)), 25509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.scheduledRunnables); 25609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 25709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Later... 25809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.elapse(7500); 25909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 26009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 26109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 26209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 26309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 26409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 26509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 26609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(11000, conn.getNextBackoffMsForTest()); 26709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 26809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 26909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Then the binding is "died"... 27009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onBindingDied(cn); 27109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 27209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 27309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 27409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 27509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 27609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isRebindScheduled()); 27709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 27809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(11000, conn.getNextBackoffMsForTest()); 27909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 28009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals( 28109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(), 28209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.uptimeMillis + 11000)), 28309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.scheduledRunnables); 28409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 28509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Call unbind... 28609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.unbind(); 28709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 28809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.shouldBeBoundForTest()); 28909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 29009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 29109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 29209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 29309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Call bind again... And now the backoff is reset to 5000. 29409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.bind(); 29509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 29609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 29709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 29809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isConnected()); 29909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 30009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertNull(conn.getServiceBinder()); 30109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 30209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(5000, conn.getNextBackoffMsForTest()); 30309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 30409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 30509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki public void testReconnectFiresAfterUnbind() { 30609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final Context context = mock(Context.class); 30709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final int userId = 11; 30809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def"); 30909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final Handler handler = new Handler(Looper.getMainLooper()); 31009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 31109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki final MyConnection conn = new MyConnection("tag", context, handler, userId, cn, 31209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki /* rebindBackoffSeconds= */ 5, 31309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki /* rebindBackoffIncrease= */ 1.5, 31409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki /* rebindMaxBackoffSeconds= */ 11); 31509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 31609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(), 31709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki any(Handler.class), any(UserHandle.class))) 31809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki .thenReturn(true); 31909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 32009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Bind. 32109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.bind(); 32209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 32309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isBound()); 32409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 32509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isRebindScheduled()); 32609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 32709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.elapse(1000); 32809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 32909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Service crashes. 33009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getServiceConnectionForTest().onBindingDied(cn); 33109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 33209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 33309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.shouldBeBoundForTest()); 33409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertTrue(conn.isRebindScheduled()); 33509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 33609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertEquals(7500, conn.getNextBackoffMsForTest()); 33709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 33809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Call unbind. 33909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.unbind(); 34009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 34109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.shouldBeBoundForTest()); 34209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 34309c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Now, at this point, it's possible that the scheduled runnable had already been fired 34409c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // before during the unbind() call, and waiting on mLock. 34509c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // To simulate it, we just call the runnable here. 34609c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki conn.getBindForBackoffRunnableForTest().run(); 34709c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki 34809c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki // Should still not be bound. 34909c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.isBound()); 35009c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki assertFalse(conn.shouldBeBoundForTest()); 35109c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki } 35209c529a9bc85bfd0d50b65f447472ad064eac16cMakoto Onuki} 353