Merge "QS: Don't use ComponentName to identify tiles" into nyc-mr1-dev
This commit is contained in:
@ -23,16 +23,16 @@ import android.service.quicksettings.Tile;
|
||||
* @hide
|
||||
*/
|
||||
interface IQSService {
|
||||
Tile getTile(in ComponentName component);
|
||||
void updateQsTile(in Tile tile);
|
||||
void updateStatusIcon(in Tile tile, in Icon icon,
|
||||
Tile getTile(in IBinder tile);
|
||||
void updateQsTile(in Tile tile, in IBinder service);
|
||||
void updateStatusIcon(in IBinder tile, in Icon icon,
|
||||
String contentDescription);
|
||||
void onShowDialog(in Tile tile);
|
||||
void onStartActivity(in Tile tile);
|
||||
void onShowDialog(in IBinder tile);
|
||||
void onStartActivity(in IBinder tile);
|
||||
boolean isLocked();
|
||||
boolean isSecure();
|
||||
void startUnlockAndRun(in Tile tile);
|
||||
void startUnlockAndRun(in IBinder tile);
|
||||
|
||||
void onDialogHidden(in Tile tile);
|
||||
void onStartSuccessful(in Tile tile);
|
||||
void onDialogHidden(in IBinder tile);
|
||||
void onStartSuccessful(in IBinder tile);
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
*/
|
||||
package android.service.quicksettings;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
@ -59,7 +59,7 @@ public final class Tile implements Parcelable {
|
||||
*/
|
||||
public static final int STATE_ACTIVE = 2;
|
||||
|
||||
private ComponentName mComponentName;
|
||||
private IBinder mToken;
|
||||
private Icon mIcon;
|
||||
private CharSequence mLabel;
|
||||
private CharSequence mContentDescription;
|
||||
@ -78,29 +78,15 @@ public final class Tile implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public Tile(ComponentName componentName) {
|
||||
mComponentName = componentName;
|
||||
public Tile() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setService(IQSService service) {
|
||||
public void setService(IQSService service, IBinder stub) {
|
||||
mService = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public ComponentName getComponentName() {
|
||||
return mComponentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public IQSService getQsService() {
|
||||
return mService;
|
||||
mToken = stub;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,7 +179,7 @@ public final class Tile implements Parcelable {
|
||||
*/
|
||||
public void updateTile() {
|
||||
try {
|
||||
mService.updateQsTile(this);
|
||||
mService.updateQsTile(this, mToken);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Couldn't update tile");
|
||||
}
|
||||
@ -201,12 +187,6 @@ public final class Tile implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
if (mComponentName != null) {
|
||||
dest.writeByte((byte) 1);
|
||||
mComponentName.writeToParcel(dest, flags);
|
||||
} else {
|
||||
dest.writeByte((byte) 0);
|
||||
}
|
||||
if (mIcon != null) {
|
||||
dest.writeByte((byte) 1);
|
||||
mIcon.writeToParcel(dest, flags);
|
||||
@ -219,11 +199,6 @@ public final class Tile implements Parcelable {
|
||||
}
|
||||
|
||||
private void readFromParcel(Parcel source) {
|
||||
if (source.readByte() != 0) {
|
||||
mComponentName = ComponentName.CREATOR.createFromParcel(source);
|
||||
} else {
|
||||
mComponentName = null;
|
||||
}
|
||||
if (source.readByte() != 0) {
|
||||
mIcon = Icon.CREATOR.createFromParcel(source);
|
||||
} else {
|
||||
|
@ -120,6 +120,11 @@ public class TileService extends Service {
|
||||
*/
|
||||
public static final String EXTRA_SERVICE = "service";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_TOKEN = "token";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@ -132,6 +137,7 @@ public class TileService extends Service {
|
||||
private IBinder mToken;
|
||||
private IQSService mService;
|
||||
private Runnable mUnlockRunnable;
|
||||
private IBinder mTileToken;
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
@ -197,7 +203,7 @@ public class TileService extends Service {
|
||||
public final void setStatusIcon(Icon icon, String contentDescription) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.updateStatusIcon(mTile, icon, contentDescription);
|
||||
mService.updateStatusIcon(mTileToken, icon, contentDescription);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@ -224,14 +230,14 @@ public class TileService extends Service {
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View v) {
|
||||
try {
|
||||
mService.onDialogHidden(getQsTile());
|
||||
mService.onDialogHidden(mTileToken);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
try {
|
||||
mService.onShowDialog(mTile);
|
||||
mService.onShowDialog(mTileToken);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@ -246,7 +252,7 @@ public class TileService extends Service {
|
||||
public final void unlockAndRun(Runnable runnable) {
|
||||
mUnlockRunnable = runnable;
|
||||
try {
|
||||
mService.startUnlockAndRun(mTile);
|
||||
mService.startUnlockAndRun(mTileToken);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@ -292,7 +298,7 @@ public class TileService extends Service {
|
||||
public final void startActivityAndCollapse(Intent intent) {
|
||||
startActivity(intent);
|
||||
try {
|
||||
mService.onStartActivity(mTile);
|
||||
mService.onStartActivity(mTileToken);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
@ -311,14 +317,14 @@ public class TileService extends Service {
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE));
|
||||
mTileToken = intent.getIBinderExtra(EXTRA_TOKEN);
|
||||
try {
|
||||
ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT);
|
||||
mTile = mService.getTile(component);
|
||||
mTile = mService.getTile(mTileToken);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("Unable to reach IQSService", e);
|
||||
}
|
||||
if (mTile != null) {
|
||||
mTile.setService(mService);
|
||||
mTile.setService(mService, mTileToken);
|
||||
mHandler.sendEmptyMessage(H.MSG_START_SUCCESS);
|
||||
}
|
||||
return new IQSTileService.Stub() {
|
||||
@ -403,7 +409,7 @@ public class TileService extends Service {
|
||||
break;
|
||||
case MSG_START_SUCCESS:
|
||||
try {
|
||||
mService.onStartSuccessful(mTile);
|
||||
mService.onStartSuccessful(mTileToken);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
break;
|
||||
|
@ -71,7 +71,7 @@ public class CustomTile extends QSTile<QSTile.State> implements TileChangeListen
|
||||
super(host);
|
||||
mWindowManager = WindowManagerGlobal.getWindowManagerService();
|
||||
mComponent = ComponentName.unflattenFromString(action);
|
||||
mTile = new Tile(mComponent);
|
||||
mTile = new Tile();
|
||||
setTileIcon();
|
||||
mServiceManager = host.getTileServices().getTileWrapper(this);
|
||||
mService = mServiceManager.getTileService();
|
||||
|
@ -94,4 +94,8 @@ public class QSTileServiceWrapper {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IQSTileService getService() {
|
||||
return mService;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@ -37,6 +38,7 @@ import android.service.quicksettings.TileService;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import libcore.util.Objects;
|
||||
|
||||
import java.util.Set;
|
||||
@ -67,6 +69,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
|
||||
private final Handler mHandler;
|
||||
private final Intent mIntent;
|
||||
private final UserHandle mUser;
|
||||
private final IBinder mToken = new Binder();
|
||||
|
||||
private Set<Integer> mQueuedMessages = new ArraySet<>();
|
||||
private QSTileServiceWrapper mWrapper;
|
||||
@ -88,7 +91,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
|
||||
mHandler = handler;
|
||||
mIntent = intent;
|
||||
mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder());
|
||||
mIntent.putExtra(TileService.EXTRA_COMPONENT, intent.getComponent());
|
||||
mIntent.putExtra(TileService.EXTRA_TOKEN, mToken);
|
||||
mUser = user;
|
||||
if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
|
||||
}
|
||||
@ -396,6 +399,10 @@ public class TileLifecycleManager extends BroadcastReceiver implements
|
||||
handleDeath();
|
||||
}
|
||||
|
||||
public IBinder getToken() {
|
||||
return mToken;
|
||||
}
|
||||
|
||||
public interface TileChangeListener {
|
||||
void onTileChanged(ComponentName tile);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.UserHandle;
|
||||
import android.service.quicksettings.IQSTileService;
|
||||
import android.service.quicksettings.Tile;
|
||||
@ -32,6 +33,7 @@ import android.service.quicksettings.TileService;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
|
||||
import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
|
||||
|
||||
import java.util.List;
|
||||
@ -106,6 +108,10 @@ public class TileServiceManager {
|
||||
return mStateManager;
|
||||
}
|
||||
|
||||
public IBinder getToken() {
|
||||
return mStateManager.getToken();
|
||||
}
|
||||
|
||||
public void setBindRequested(boolean bindRequested) {
|
||||
if (mBindRequested == bindRequested) return;
|
||||
mBindRequested = bindRequested;
|
||||
|
@ -25,10 +25,12 @@ import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.service.quicksettings.IQSService;
|
||||
import android.service.quicksettings.IQSTileService;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
import android.util.ArrayMap;
|
||||
@ -52,6 +54,7 @@ public class TileServices extends IQSService.Stub {
|
||||
|
||||
private final ArrayMap<CustomTile, TileServiceManager> mServices = new ArrayMap<>();
|
||||
private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
|
||||
private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final Handler mMainHandler;
|
||||
@ -82,6 +85,7 @@ public class TileServices extends IQSService.Stub {
|
||||
synchronized (mServices) {
|
||||
mServices.put(tile, service);
|
||||
mTiles.put(component, tile);
|
||||
mTokenMap.put(service.getToken(), tile);
|
||||
}
|
||||
return service;
|
||||
}
|
||||
@ -95,6 +99,7 @@ public class TileServices extends IQSService.Stub {
|
||||
service.setBindAllowed(false);
|
||||
service.handleDestroy();
|
||||
mServices.remove(tile);
|
||||
mTokenMap.remove(service.getToken());
|
||||
mTiles.remove(tile.getComponent());
|
||||
final String slot = tile.getComponent().getClassName();
|
||||
mMainHandler.post(new Runnable() {
|
||||
@ -138,8 +143,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyCaller(String packageName) {
|
||||
private void verifyCaller(CustomTile tile) {
|
||||
try {
|
||||
String packageName = tile.getComponent().getPackageName();
|
||||
int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
|
||||
Binder.getCallingUserHandle().getIdentifier());
|
||||
if (Binder.getCallingUid() != uid) {
|
||||
@ -170,10 +176,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateQsTile(Tile tile) {
|
||||
ComponentName componentName = tile.getComponentName();
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void updateQsTile(Tile tile, IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
synchronized (mServices) {
|
||||
final TileServiceManager tileServiceManager = mServices.get(customTile);
|
||||
@ -186,10 +191,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartSuccessful(Tile tile) {
|
||||
ComponentName componentName = tile.getComponentName();
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void onStartSuccessful(IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
synchronized (mServices) {
|
||||
final TileServiceManager tileServiceManager = mServices.get(customTile);
|
||||
@ -200,10 +204,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowDialog(Tile tile) {
|
||||
ComponentName componentName = tile.getComponentName();
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void onShowDialog(IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
customTile.onDialogShown();
|
||||
mHost.collapsePanels();
|
||||
@ -212,10 +215,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogHidden(Tile tile) {
|
||||
ComponentName componentName = tile.getComponentName();
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void onDialogHidden(IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
mServices.get(customTile).setShowingDialog(false);
|
||||
customTile.onDialogHidden();
|
||||
@ -223,23 +225,22 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartActivity(Tile tile) {
|
||||
ComponentName componentName = tile.getComponentName();
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void onStartActivity(IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
mHost.collapsePanels();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatusIcon(Tile tile, Icon icon, String contentDescription) {
|
||||
final ComponentName componentName = tile.getComponentName();
|
||||
String packageName = componentName.getPackageName();
|
||||
verifyCaller(packageName);
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void updateStatusIcon(IBinder token, Icon icon, String contentDescription) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
try {
|
||||
ComponentName componentName = customTile.getComponent();
|
||||
String packageName = componentName.getPackageName();
|
||||
UserHandle userHandle = getCallingUserHandle();
|
||||
PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser(packageName, 0,
|
||||
userHandle.getIdentifier());
|
||||
@ -263,9 +264,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tile getTile(ComponentName componentName) {
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public Tile getTile(IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
return customTile.getQsTile();
|
||||
}
|
||||
@ -273,10 +274,9 @@ public class TileServices extends IQSService.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUnlockAndRun(Tile tile) {
|
||||
ComponentName componentName = tile.getComponentName();
|
||||
verifyCaller(componentName.getPackageName());
|
||||
CustomTile customTile = getTileForComponent(componentName);
|
||||
public void startUnlockAndRun(IBinder token) {
|
||||
CustomTile customTile = getTileForToken(token);
|
||||
verifyCaller(customTile);
|
||||
if (customTile != null) {
|
||||
customTile.startUnlockAndRun();
|
||||
}
|
||||
@ -294,6 +294,12 @@ public class TileServices extends IQSService.Stub {
|
||||
return keyguardMonitor.isSecure() && keyguardMonitor.isShowing();
|
||||
}
|
||||
|
||||
private CustomTile getTileForToken(IBinder token) {
|
||||
synchronized (mServices) {
|
||||
return mTokenMap.get(token);
|
||||
}
|
||||
}
|
||||
|
||||
private CustomTile getTileForComponent(ComponentName component) {
|
||||
synchronized (mServices) {
|
||||
return mTiles.get(component);
|
||||
|
@ -400,7 +400,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
|
||||
ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
|
||||
Intent intent = new Intent().setComponent(component);
|
||||
TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
|
||||
mContext, mServices, new Tile(component), intent,
|
||||
mContext, mServices, new Tile(), intent,
|
||||
new UserHandle(ActivityManager.getCurrentUser()));
|
||||
lifecycleManager.onStopListening();
|
||||
lifecycleManager.onTileRemoved();
|
||||
@ -414,7 +414,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
|
||||
ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
|
||||
Intent intent = new Intent().setComponent(component);
|
||||
TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
|
||||
mContext, mServices, new Tile(component), intent,
|
||||
mContext, mServices, new Tile(), intent,
|
||||
new UserHandle(ActivityManager.getCurrentUser()));
|
||||
lifecycleManager.onTileAdded();
|
||||
lifecycleManager.flushMessagesAndUnbind();
|
||||
|
@ -58,7 +58,7 @@ public class TileLifecycleManagerTests extends AndroidTestCase {
|
||||
mHandler = new Handler(mThread.getLooper());
|
||||
ComponentName component = new ComponentName(mContext, FakeTileService.class);
|
||||
mStateManager = new TileLifecycleManager(mHandler, getContext(),
|
||||
Mockito.mock(IQSService.class), new Tile(component),
|
||||
Mockito.mock(IQSService.class), new Tile(),
|
||||
new Intent().setComponent(component),
|
||||
new UserHandle(UserHandle.myUserId()));
|
||||
mCallbacks.clear();
|
||||
|
Reference in New Issue
Block a user