Unbind TileService onNullBinding

Test: atest TileLifecycleManagerTest
Test: manual: adb shell dumpsys activity service
Test: sts test
Bug: 300903792
Change-Id: Ia8126ac65432b124683960e3ebf47301ba6172a1
Merged-In: Ia8126ac65432b124683960e3ebf47301ba6172a1
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index aa51771..68a83f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -221,6 +221,11 @@
     }
 
     @Override
+    public void onNullBinding(ComponentName name) {
+        setBindService(false);
+    }
+
+    @Override
     public void onServiceDisconnected(ComponentName name) {
         if (DEBUG) Log.d(TAG, "onServiceDisconnected " + name);
         handleDeath();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
index 42fd288..c03b2ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
@@ -22,13 +22,16 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.PackageInfo;
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
@@ -51,7 +54,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
+import org.mockito.ArgumentCaptor;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -59,10 +62,10 @@
     private static final int TEST_FAIL_TIMEOUT = 5000;
 
     private final PackageManagerAdapter mMockPackageManagerAdapter =
-            Mockito.mock(PackageManagerAdapter.class);
+            mock(PackageManagerAdapter.class);
     private final BroadcastDispatcher mMockBroadcastDispatcher =
-            Mockito.mock(BroadcastDispatcher.class);
-    private final IQSTileService.Stub mMockTileService = Mockito.mock(IQSTileService.Stub.class);
+            mock(BroadcastDispatcher.class);
+    private final IQSTileService.Stub mMockTileService = mock(IQSTileService.Stub.class);
     private ComponentName mTileServiceComponentName;
     private Intent mTileServiceIntent;
     private UserHandle mUser;
@@ -87,7 +90,7 @@
         mThread.start();
         mHandler = Handler.createAsync(mThread.getLooper());
         mStateManager = new TileLifecycleManager(mHandler, mContext,
-                Mockito.mock(IQSService.class), new Tile(),
+                mock(IQSService.class), new Tile(),
                 mTileServiceIntent,
                 mUser,
                 mMockPackageManagerAdapter,
@@ -247,4 +250,26 @@
     public void testToggleableTile() throws Exception {
         assertTrue(mStateManager.isToggleableTile());
     }
+
+    @Test
+    public void testNullBindingCallsUnbind() {
+        Context mockContext = mock(Context.class);
+        // Binding has to succeed
+        when(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true);
+        TileLifecycleManager manager = new TileLifecycleManager(mHandler, mockContext,
+                mock(IQSService.class),
+                new Tile(),
+                mTileServiceIntent,
+                mUser,
+                mMockPackageManagerAdapter,
+                mMockBroadcastDispatcher);
+
+        manager.setBindService(true);
+
+        ArgumentCaptor<ServiceConnection> captor = ArgumentCaptor.forClass(ServiceConnection.class);
+        verify(mockContext).bindServiceAsUser(any(), captor.capture(), anyInt(), any());
+
+        captor.getValue().onNullBinding(mTileServiceComponentName);
+        verify(mockContext).unbindService(captor.getValue());
+    }
 }