Merge "Store tiles by component name and user" into udc-dev

This commit is contained in:
Fabian Kozynski
2023-03-30 13:43:51 +00:00
committed by Android (Google) Code Review
2 changed files with 51 additions and 7 deletions

View File

@@ -30,6 +30,7 @@ import android.service.quicksettings.IQSService;
import android.service.quicksettings.Tile;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArrayMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -64,7 +65,7 @@ public class TileServices extends IQSService.Stub {
private static final String TAG = "TileServices";
private final ArrayMap<CustomTile, TileServiceManager> mServices = new ArrayMap<>();
private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
private final SparseArrayMap<ComponentName, CustomTile> mTiles = new SparseArrayMap<>();
private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
private final Context mContext;
private final Handler mMainHandler;
@@ -112,10 +113,11 @@ public class TileServices extends IQSService.Stub {
public TileServiceManager getTileWrapper(CustomTile tile) {
ComponentName component = tile.getComponent();
int userId = tile.getUser();
TileServiceManager service = onCreateTileService(component, mBroadcastDispatcher);
synchronized (mServices) {
mServices.put(tile, service);
mTiles.put(component, tile);
mTiles.add(userId, component, tile);
mTokenMap.put(service.getToken(), tile);
}
// Makes sure binding only happens after the maps have been populated
@@ -135,7 +137,7 @@ public class TileServices extends IQSService.Stub {
service.handleDestroy();
mServices.remove(tile);
mTokenMap.remove(service.getToken());
mTiles.remove(tile.getComponent());
mTiles.delete(tile.getUser(), tile.getComponent());
final String slot = getStatusBarIconSlotName(tile.getComponent());
mMainHandler.post(() -> mStatusBarIconController.removeIconForTile(slot));
}
@@ -188,9 +190,10 @@ public class TileServices extends IQSService.Stub {
private void requestListening(ComponentName component) {
synchronized (mServices) {
CustomTile customTile = getTileForComponent(component);
int userId = mUserTracker.getUserId();
CustomTile customTile = getTileForUserAndComponent(userId, component);
if (customTile == null) {
Log.d("TileServices", "Couldn't find tile for " + component);
Log.d(TAG, "Couldn't find tile for " + component + "(" + userId + ")");
return;
}
TileServiceManager service = mServices.get(customTile);
@@ -362,9 +365,9 @@ public class TileServices extends IQSService.Stub {
}
@Nullable
private CustomTile getTileForComponent(ComponentName component) {
private CustomTile getTileForUserAndComponent(int userId, ComponentName component) {
synchronized (mServices) {
return mTiles.get(component);
return mTiles.get(userId, component);
}
}
@@ -395,4 +398,5 @@ public class TileServices extends IQSService.Stub {
return -Integer.compare(left.getBindPriority(), right.getBindPriority());
}
};
}

View File

@@ -54,6 +54,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -95,6 +96,8 @@ public class TileServicesTest extends SysuiTestCase {
private QSHost mQSHost;
@Mock
private PanelInteractor mPanelInteractor;
@Captor
private ArgumentCaptor<CommandQueue.Callbacks> mCallbacksArgumentCaptor;
@Before
public void setUp() throws Exception {
@@ -251,6 +254,41 @@ public class TileServicesTest extends SysuiTestCase {
verify(mPanelInteractor).forceCollapsePanels();
}
@Test
public void tileFreedForCorrectUser() throws RemoteException {
verify(mCommandQueue).addCallback(mCallbacksArgumentCaptor.capture());
ComponentName componentName = new ComponentName("pkg", "cls");
CustomTile tileUser0 = mock(CustomTile.class);
CustomTile tileUser1 = mock(CustomTile.class);
when(tileUser0.getComponent()).thenReturn(componentName);
when(tileUser1.getComponent()).thenReturn(componentName);
when(tileUser0.getUser()).thenReturn(0);
when(tileUser1.getUser()).thenReturn(1);
// Create a tile for user 0
TileServiceManager manager0 = mTileService.getTileWrapper(tileUser0);
when(manager0.isActiveTile()).thenReturn(true);
// Then create a tile for user 1
TileServiceManager manager1 = mTileService.getTileWrapper(tileUser1);
when(manager1.isActiveTile()).thenReturn(true);
// When the tile for user 0 gets freed
mTileService.freeService(tileUser0, manager0);
// and the user is 1
when(mUserTracker.getUserId()).thenReturn(1);
// a call to requestListeningState
mCallbacksArgumentCaptor.getValue().requestTileServiceListeningState(componentName);
mTestableLooper.processAllMessages();
// will call in the correct tile
verify(manager1).setBindRequested(true);
// and set it to listening
verify(manager1.getTileService()).onStartListening();
}
private class TestTileServices extends TileServices {
TestTileServices(QSHost host, Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
@@ -268,6 +306,8 @@ public class TileServicesTest extends SysuiTestCase {
when(manager.isLifecycleStarted()).thenReturn(true);
Binder b = new Binder();
when(manager.getToken()).thenReturn(b);
IQSTileService service = mock(IQSTileService.class);
when(manager.getTileService()).thenReturn(service);
return manager;
}
}