TileServices.java revision c673fbc2c2eb37037dae9a8c55b1588ab398a116
1d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk/* 2d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * Copyright (C) 2015 The Android Open Source Project 3d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * 4d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 5d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * you may not use this file except in compliance with the License. 6d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * You may obtain a copy of the License at 7d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * 8d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * http://www.apache.org/licenses/LICENSE-2.0 9d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * 10d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * Unless required by applicable law or agreed to in writing, software 11d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * distributed under the License is distributed on an "AS IS" BASIS, 12d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * See the License for the specific language governing permissions and 14d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * limitations under the License 15d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk */ 16d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkpackage com.android.systemui.qs.external; 17d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 18fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monkimport android.content.BroadcastReceiver; 19d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.content.ComponentName; 20d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.content.Context; 21fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monkimport android.content.Intent; 22fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monkimport android.content.IntentFilter; 2366c89c15a0baabf001e69498dbc09903f72cc63dJason Monkimport android.content.pm.PackageInfo; 24d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.content.pm.PackageManager; 2566c89c15a0baabf001e69498dbc09903f72cc63dJason Monkimport android.graphics.drawable.Icon; 26d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.os.Binder; 27d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.os.Handler; 28ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monkimport android.os.IBinder; 29d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.os.Looper; 30fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monkimport android.os.RemoteException; 3166c89c15a0baabf001e69498dbc09903f72cc63dJason Monkimport android.os.UserHandle; 32d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.service.quicksettings.IQSService; 33d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.service.quicksettings.Tile; 34fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monkimport android.service.quicksettings.TileService; 35d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport android.util.ArrayMap; 36fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monkimport android.util.Log; 37c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson 3866c89c15a0baabf001e69498dbc09903f72cc63dJason Monkimport com.android.internal.statusbar.StatusBarIcon; 399c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monkimport com.android.systemui.Dependency; 40e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monkimport com.android.systemui.qs.QSTileHost; 4166c89c15a0baabf001e69498dbc09903f72cc63dJason Monkimport com.android.systemui.statusbar.phone.StatusBarIconController; 429429513cc3ea6e58e330865bd621b57cb3477551Jason Monkimport com.android.systemui.statusbar.policy.KeyguardMonitor; 43d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 44d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport java.util.ArrayList; 45d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport java.util.Collections; 46d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkimport java.util.Comparator; 47d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 48d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk/** 49d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk * Runs the day-to-day operations of which tiles should be bound and when. 50d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk */ 51d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monkpublic class TileServices extends IQSService.Stub { 52d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk static final int DEFAULT_MAX_BOUND = 3; 53d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk static final int REDUCED_MAX_BOUND = 1; 54d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 55d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private final ArrayMap<CustomTile, TileServiceManager> mServices = new ArrayMap<>(); 56d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>(); 57ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>(); 58d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private final Context mContext; 59d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private final Handler mHandler; 6066c89c15a0baabf001e69498dbc09903f72cc63dJason Monk private final Handler mMainHandler; 61d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private final QSTileHost mHost; 62d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 63d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private int mMaxBound = DEFAULT_MAX_BOUND; 64d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 65d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public TileServices(QSTileHost host, Looper looper) { 66d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mHost = host; 67d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mContext = mHost.getContext(); 68fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk mContext.registerReceiver(mRequestListeningReceiver, 69fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk new IntentFilter(TileService.ACTION_REQUEST_LISTENING)); 70d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mHandler = new Handler(looper); 7166c89c15a0baabf001e69498dbc09903f72cc63dJason Monk mMainHandler = new Handler(Looper.getMainLooper()); 72d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 73d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 74d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public Context getContext() { 75d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk return mContext; 76d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 77d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 7807f55a2a04f8bfbb1702ca226f394607b5130908Jason Monk public QSTileHost getHost() { 7907f55a2a04f8bfbb1702ca226f394607b5130908Jason Monk return mHost; 8007f55a2a04f8bfbb1702ca226f394607b5130908Jason Monk } 8107f55a2a04f8bfbb1702ca226f394607b5130908Jason Monk 82d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public TileServiceManager getTileWrapper(CustomTile tile) { 83d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk ComponentName component = tile.getComponent(); 84a3453b8bd9af44566c6a31fd0156cc76e6028f6dJason Monk TileServiceManager service = onCreateTileService(component, tile.getQsTile()); 85d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk synchronized (mServices) { 86d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mServices.put(tile, service); 87d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mTiles.put(component, tile); 88ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk mTokenMap.put(service.getToken(), tile); 89d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 90d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk return service; 91d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 92d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 93a3453b8bd9af44566c6a31fd0156cc76e6028f6dJason Monk protected TileServiceManager onCreateTileService(ComponentName component, Tile tile) { 94a3453b8bd9af44566c6a31fd0156cc76e6028f6dJason Monk return new TileServiceManager(this, mHandler, component, tile); 95d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 96d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 97d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public void freeService(CustomTile tile, TileServiceManager service) { 98d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk synchronized (mServices) { 99d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk service.setBindAllowed(false); 10007f55a2a04f8bfbb1702ca226f394607b5130908Jason Monk service.handleDestroy(); 101d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mServices.remove(tile); 102ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk mTokenMap.remove(service.getToken()); 103d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mTiles.remove(tile.getComponent()); 10466c89c15a0baabf001e69498dbc09903f72cc63dJason Monk final String slot = tile.getComponent().getClassName(); 1054cfd8c740dee6cd8fe361a59487acde4e465f31fJason Monk mMainHandler.post(() -> mHost.getIconController().removeIcon(slot)); 106d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 107d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 108d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 109d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public void setMemoryPressure(boolean memoryPressure) { 110d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk mMaxBound = memoryPressure ? REDUCED_MAX_BOUND : DEFAULT_MAX_BOUND; 111d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk recalculateBindAllowance(); 112d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 113d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 114d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public void recalculateBindAllowance() { 115d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk final ArrayList<TileServiceManager> services; 116d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk synchronized (mServices) { 117d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk services = new ArrayList<>(mServices.values()); 118d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 119d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk final int N = services.size(); 120d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk if (N > mMaxBound) { 121d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk long currentTime = System.currentTimeMillis(); 122d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk // Precalculate the priority of services for binding. 123d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk for (int i = 0; i < N; i++) { 124d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk services.get(i).calculateBindPriority(currentTime); 125d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 126d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk // Sort them so we can bind the most important first. 127d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk Collections.sort(services, SERVICE_SORT); 128d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 129d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk int i; 130d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk // Allow mMaxBound items to bind. 131d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk for (i = 0; i < mMaxBound && i < N; i++) { 132d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk services.get(i).setBindAllowed(true); 133d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 134d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk // The rest aren't allowed to bind for now. 135d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk while (i < N) { 136d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk services.get(i).setBindAllowed(false); 137d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk i++; 138d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 139d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 140d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 141ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk private void verifyCaller(CustomTile tile) { 142d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk try { 143ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk String packageName = tile.getComponent().getPackageName(); 144e06b4d1d9f718b9fe02980fea794a36831a16db2Jeff Sharkey int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 145d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk Binder.getCallingUserHandle().getIdentifier()); 146d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk if (Binder.getCallingUid() != uid) { 147d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk throw new SecurityException("Component outside caller's uid"); 148d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 149d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } catch (PackageManager.NameNotFoundException e) { 150d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk throw new SecurityException(e); 151d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 152d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 153d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 154fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk private void requestListening(ComponentName component) { 155fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk synchronized (mServices) { 156fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk CustomTile customTile = getTileForComponent(component); 157fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk if (customTile == null) { 158fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk Log.d("TileServices", "Couldn't find tile for " + component); 159fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk return; 160fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 161fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk TileServiceManager service = mServices.get(customTile); 16297d2272be0bf3e77474e7ff9984217dfe247f4d0Jason Monk if (!service.isActiveTile()) { 163fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk return; 164fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 165fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk service.setBindRequested(true); 166fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk try { 167fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk service.getTileService().onStartListening(); 168fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } catch (RemoteException e) { 169fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 170fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 171fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 172fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk 173fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk @Override 174ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void updateQsTile(Tile tile, IBinder token) { 175ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 176d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk if (customTile != null) { 177016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 178fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk synchronized (mServices) { 1791c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk final TileServiceManager tileServiceManager = mServices.get(customTile); 1801c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk tileServiceManager.clearPendingBind(); 1811c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk tileServiceManager.setLastUpdate(System.currentTimeMillis()); 182fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 183d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk customTile.updateState(tile); 184d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk customTile.refreshState(); 185d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 186d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 187d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 188d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk @Override 189ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void onStartSuccessful(IBinder token) { 190ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 1911c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk if (customTile != null) { 192016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 1931c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk synchronized (mServices) { 1941c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk final TileServiceManager tileServiceManager = mServices.get(customTile); 1951c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk tileServiceManager.clearPendingBind(); 1961c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk } 1971c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk customTile.refreshState(); 1981c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk } 1991c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk } 2001c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk 2011c2fea8df7054d1bc23945c38460a123ce453c4aJason Monk @Override 202ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void onShowDialog(IBinder token) { 203ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 204d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk if (customTile != null) { 205016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 206d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk customTile.onDialogShown(); 207c673fbc2c2eb37037dae9a8c55b1588ab398a116Yoshinori Hirano mHost.forceCollapsePanels(); 20834a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk mServices.get(customTile).setShowingDialog(true); 20934a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk } 21034a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk } 21134a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk 21234a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk @Override 213ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void onDialogHidden(IBinder token) { 214ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 21534a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk if (customTile != null) { 216016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 21734a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk mServices.get(customTile).setShowingDialog(false); 21834a5cef6298cc44fc0614c4747c4b17137cff441Jason Monk customTile.onDialogHidden(); 219d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 220d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 221d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 22266c89c15a0baabf001e69498dbc09903f72cc63dJason Monk @Override 223ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void onStartActivity(IBinder token) { 224ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 2259429513cc3ea6e58e330865bd621b57cb3477551Jason Monk if (customTile != null) { 226016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 227c673fbc2c2eb37037dae9a8c55b1588ab398a116Yoshinori Hirano mHost.forceCollapsePanels(); 2289429513cc3ea6e58e330865bd621b57cb3477551Jason Monk } 2299429513cc3ea6e58e330865bd621b57cb3477551Jason Monk } 2309429513cc3ea6e58e330865bd621b57cb3477551Jason Monk 2319429513cc3ea6e58e330865bd621b57cb3477551Jason Monk @Override 232ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void updateStatusIcon(IBinder token, Icon icon, String contentDescription) { 233ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 23466c89c15a0baabf001e69498dbc09903f72cc63dJason Monk if (customTile != null) { 235016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 23666c89c15a0baabf001e69498dbc09903f72cc63dJason Monk try { 237ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk ComponentName componentName = customTile.getComponent(); 238ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk String packageName = componentName.getPackageName(); 23966c89c15a0baabf001e69498dbc09903f72cc63dJason Monk UserHandle userHandle = getCallingUserHandle(); 24066c89c15a0baabf001e69498dbc09903f72cc63dJason Monk PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, 24166c89c15a0baabf001e69498dbc09903f72cc63dJason Monk userHandle.getIdentifier()); 24266c89c15a0baabf001e69498dbc09903f72cc63dJason Monk if (info.applicationInfo.isSystemApp()) { 24366c89c15a0baabf001e69498dbc09903f72cc63dJason Monk final StatusBarIcon statusIcon = icon != null 24466c89c15a0baabf001e69498dbc09903f72cc63dJason Monk ? new StatusBarIcon(userHandle, packageName, icon, 0, 0, 24566c89c15a0baabf001e69498dbc09903f72cc63dJason Monk contentDescription) 24666c89c15a0baabf001e69498dbc09903f72cc63dJason Monk : null; 24766c89c15a0baabf001e69498dbc09903f72cc63dJason Monk mMainHandler.post(new Runnable() { 24866c89c15a0baabf001e69498dbc09903f72cc63dJason Monk @Override 24966c89c15a0baabf001e69498dbc09903f72cc63dJason Monk public void run() { 25066c89c15a0baabf001e69498dbc09903f72cc63dJason Monk StatusBarIconController iconController = mHost.getIconController(); 25166c89c15a0baabf001e69498dbc09903f72cc63dJason Monk iconController.setIcon(componentName.getClassName(), statusIcon); 25266c89c15a0baabf001e69498dbc09903f72cc63dJason Monk iconController.setExternalIcon(componentName.getClassName()); 25366c89c15a0baabf001e69498dbc09903f72cc63dJason Monk } 25466c89c15a0baabf001e69498dbc09903f72cc63dJason Monk }); 25566c89c15a0baabf001e69498dbc09903f72cc63dJason Monk } 25666c89c15a0baabf001e69498dbc09903f72cc63dJason Monk } catch (PackageManager.NameNotFoundException e) { 25766c89c15a0baabf001e69498dbc09903f72cc63dJason Monk } 25866c89c15a0baabf001e69498dbc09903f72cc63dJason Monk } 25966c89c15a0baabf001e69498dbc09903f72cc63dJason Monk } 26066c89c15a0baabf001e69498dbc09903f72cc63dJason Monk 2619429513cc3ea6e58e330865bd621b57cb3477551Jason Monk @Override 262ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public Tile getTile(IBinder token) { 263ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 2648753e184f967d1db91de34cb66aae0a977259a60Jason Monk if (customTile != null) { 265016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 2668753e184f967d1db91de34cb66aae0a977259a60Jason Monk return customTile.getQsTile(); 2678753e184f967d1db91de34cb66aae0a977259a60Jason Monk } 2688753e184f967d1db91de34cb66aae0a977259a60Jason Monk return null; 2698753e184f967d1db91de34cb66aae0a977259a60Jason Monk } 2708753e184f967d1db91de34cb66aae0a977259a60Jason Monk 2718753e184f967d1db91de34cb66aae0a977259a60Jason Monk @Override 272ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk public void startUnlockAndRun(IBinder token) { 273ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk CustomTile customTile = getTileForToken(token); 2749429513cc3ea6e58e330865bd621b57cb3477551Jason Monk if (customTile != null) { 275016bc90331cd8b7dd3b8ec58b4ea6f64d3953bbaJason Monk verifyCaller(customTile); 2769429513cc3ea6e58e330865bd621b57cb3477551Jason Monk customTile.startUnlockAndRun(); 2779429513cc3ea6e58e330865bd621b57cb3477551Jason Monk } 2789429513cc3ea6e58e330865bd621b57cb3477551Jason Monk } 2799429513cc3ea6e58e330865bd621b57cb3477551Jason Monk 2809429513cc3ea6e58e330865bd621b57cb3477551Jason Monk @Override 2819429513cc3ea6e58e330865bd621b57cb3477551Jason Monk public boolean isLocked() { 2829c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk KeyguardMonitor keyguardMonitor = Dependency.get(KeyguardMonitor.class); 2839429513cc3ea6e58e330865bd621b57cb3477551Jason Monk return keyguardMonitor.isShowing(); 2849429513cc3ea6e58e330865bd621b57cb3477551Jason Monk } 2859429513cc3ea6e58e330865bd621b57cb3477551Jason Monk 2869429513cc3ea6e58e330865bd621b57cb3477551Jason Monk @Override 2879429513cc3ea6e58e330865bd621b57cb3477551Jason Monk public boolean isSecure() { 2889c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk KeyguardMonitor keyguardMonitor = Dependency.get(KeyguardMonitor.class); 2899429513cc3ea6e58e330865bd621b57cb3477551Jason Monk return keyguardMonitor.isSecure() && keyguardMonitor.isShowing(); 2909429513cc3ea6e58e330865bd621b57cb3477551Jason Monk } 2919429513cc3ea6e58e330865bd621b57cb3477551Jason Monk 292ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk private CustomTile getTileForToken(IBinder token) { 293ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk synchronized (mServices) { 294ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk return mTokenMap.get(token); 295ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk } 296ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk } 297ee68fd889c2dfcd895b8e73fc39d7b97826dc3d8Jason Monk 298d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private CustomTile getTileForComponent(ComponentName component) { 299fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk synchronized (mServices) { 300fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk return mTiles.get(component); 301fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 302d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 303d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk 3048852905b0b3837e326127c6dfef6f699124ce715Jason Monk public void destroy() { 305809aadf69e087eb951e94d19e1d4705e029be68cJason Monk synchronized (mServices) { 306809aadf69e087eb951e94d19e1d4705e029be68cJason Monk mServices.values().forEach(service -> service.handleDestroy()); 307809aadf69e087eb951e94d19e1d4705e029be68cJason Monk mContext.unregisterReceiver(mRequestListeningReceiver); 308809aadf69e087eb951e94d19e1d4705e029be68cJason Monk } 3098852905b0b3837e326127c6dfef6f699124ce715Jason Monk } 3108852905b0b3837e326127c6dfef6f699124ce715Jason Monk 311fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk private final BroadcastReceiver mRequestListeningReceiver = new BroadcastReceiver() { 312fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk @Override 313fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk public void onReceive(Context context, Intent intent) { 314fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk if (TileService.ACTION_REQUEST_LISTENING.equals(intent.getAction())) { 315fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk requestListening( 3161a74942fbfa36bf62013b51d8ad9fb4c0e44c6f4Jeff Sharkey (ComponentName) intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME)); 317fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 318fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk } 319fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk }; 320fe8f6826ce3c2beeb1fce54c67978ce69f849407Jason Monk 321d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk private static final Comparator<TileServiceManager> SERVICE_SORT = 322d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk new Comparator<TileServiceManager>() { 323d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk @Override 324d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk public int compare(TileServiceManager left, TileServiceManager right) { 325d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk return -Integer.compare(left.getBindPriority(), right.getBindPriority()); 326d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk } 327d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk }; 328d5a204f16e7c71ffdbc6c8307a4134dcc1efd60dJason Monk} 329