Merge "QS: Don't use ComponentName to identify tiles" into nyc-mr1-dev

This commit is contained in:
Jason Monk
2016-07-15 16:55:22 +00:00
committed by Android (Google) Code Review
10 changed files with 90 additions and 86 deletions

View File

@@ -23,16 +23,16 @@ import android.service.quicksettings.Tile;
* @hide * @hide
*/ */
interface IQSService { interface IQSService {
Tile getTile(in ComponentName component); Tile getTile(in IBinder tile);
void updateQsTile(in Tile tile); void updateQsTile(in Tile tile, in IBinder service);
void updateStatusIcon(in Tile tile, in Icon icon, void updateStatusIcon(in IBinder tile, in Icon icon,
String contentDescription); String contentDescription);
void onShowDialog(in Tile tile); void onShowDialog(in IBinder tile);
void onStartActivity(in Tile tile); void onStartActivity(in IBinder tile);
boolean isLocked(); boolean isLocked();
boolean isSecure(); boolean isSecure();
void startUnlockAndRun(in Tile tile); void startUnlockAndRun(in IBinder tile);
void onDialogHidden(in Tile tile); void onDialogHidden(in IBinder tile);
void onStartSuccessful(in Tile tile); void onStartSuccessful(in IBinder tile);
} }

View File

@@ -15,8 +15,8 @@
*/ */
package android.service.quicksettings; package android.service.quicksettings;
import android.content.ComponentName;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.RemoteException; import android.os.RemoteException;
@@ -59,7 +59,7 @@ public final class Tile implements Parcelable {
*/ */
public static final int STATE_ACTIVE = 2; public static final int STATE_ACTIVE = 2;
private ComponentName mComponentName; private IBinder mToken;
private Icon mIcon; private Icon mIcon;
private CharSequence mLabel; private CharSequence mLabel;
private CharSequence mContentDescription; private CharSequence mContentDescription;
@@ -78,29 +78,15 @@ public final class Tile implements Parcelable {
/** /**
* @hide * @hide
*/ */
public Tile(ComponentName componentName) { public Tile() {
mComponentName = componentName;
} }
/** /**
* @hide * @hide
*/ */
public void setService(IQSService service) { public void setService(IQSService service, IBinder stub) {
mService = service; mService = service;
} mToken = stub;
/**
* @hide
*/
public ComponentName getComponentName() {
return mComponentName;
}
/**
* @hide
*/
public IQSService getQsService() {
return mService;
} }
/** /**
@@ -193,7 +179,7 @@ public final class Tile implements Parcelable {
*/ */
public void updateTile() { public void updateTile() {
try { try {
mService.updateQsTile(this); mService.updateQsTile(this, mToken);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Couldn't update tile"); Log.e(TAG, "Couldn't update tile");
} }
@@ -201,12 +187,6 @@ public final class Tile implements Parcelable {
@Override @Override
public void writeToParcel(Parcel dest, int flags) { 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) { if (mIcon != null) {
dest.writeByte((byte) 1); dest.writeByte((byte) 1);
mIcon.writeToParcel(dest, flags); mIcon.writeToParcel(dest, flags);
@@ -219,11 +199,6 @@ public final class Tile implements Parcelable {
} }
private void readFromParcel(Parcel source) { private void readFromParcel(Parcel source) {
if (source.readByte() != 0) {
mComponentName = ComponentName.CREATOR.createFromParcel(source);
} else {
mComponentName = null;
}
if (source.readByte() != 0) { if (source.readByte() != 0) {
mIcon = Icon.CREATOR.createFromParcel(source); mIcon = Icon.CREATOR.createFromParcel(source);
} else { } else {

View File

@@ -120,6 +120,11 @@ public class TileService extends Service {
*/ */
public static final String EXTRA_SERVICE = "service"; public static final String EXTRA_SERVICE = "service";
/**
* @hide
*/
public static final String EXTRA_TOKEN = "token";
/** /**
* @hide * @hide
*/ */
@@ -132,6 +137,7 @@ public class TileService extends Service {
private IBinder mToken; private IBinder mToken;
private IQSService mService; private IQSService mService;
private Runnable mUnlockRunnable; private Runnable mUnlockRunnable;
private IBinder mTileToken;
@Override @Override
public void onDestroy() { public void onDestroy() {
@@ -197,7 +203,7 @@ public class TileService extends Service {
public final void setStatusIcon(Icon icon, String contentDescription) { public final void setStatusIcon(Icon icon, String contentDescription) {
if (mService != null) { if (mService != null) {
try { try {
mService.updateStatusIcon(mTile, icon, contentDescription); mService.updateStatusIcon(mTileToken, icon, contentDescription);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
@@ -224,14 +230,14 @@ public class TileService extends Service {
@Override @Override
public void onViewDetachedFromWindow(View v) { public void onViewDetachedFromWindow(View v) {
try { try {
mService.onDialogHidden(getQsTile()); mService.onDialogHidden(mTileToken);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
}); });
dialog.show(); dialog.show();
try { try {
mService.onShowDialog(mTile); mService.onShowDialog(mTileToken);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
@@ -246,7 +252,7 @@ public class TileService extends Service {
public final void unlockAndRun(Runnable runnable) { public final void unlockAndRun(Runnable runnable) {
mUnlockRunnable = runnable; mUnlockRunnable = runnable;
try { try {
mService.startUnlockAndRun(mTile); mService.startUnlockAndRun(mTileToken);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
@@ -292,7 +298,7 @@ public class TileService extends Service {
public final void startActivityAndCollapse(Intent intent) { public final void startActivityAndCollapse(Intent intent) {
startActivity(intent); startActivity(intent);
try { try {
mService.onStartActivity(mTile); mService.onStartActivity(mTileToken);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
@@ -311,14 +317,14 @@ public class TileService extends Service {
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE)); mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE));
mTileToken = intent.getIBinderExtra(EXTRA_TOKEN);
try { try {
ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT); mTile = mService.getTile(mTileToken);
mTile = mService.getTile(component);
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException("Unable to reach IQSService", e); throw new RuntimeException("Unable to reach IQSService", e);
} }
if (mTile != null) { if (mTile != null) {
mTile.setService(mService); mTile.setService(mService, mTileToken);
mHandler.sendEmptyMessage(H.MSG_START_SUCCESS); mHandler.sendEmptyMessage(H.MSG_START_SUCCESS);
} }
return new IQSTileService.Stub() { return new IQSTileService.Stub() {
@@ -403,7 +409,7 @@ public class TileService extends Service {
break; break;
case MSG_START_SUCCESS: case MSG_START_SUCCESS:
try { try {
mService.onStartSuccessful(mTile); mService.onStartSuccessful(mTileToken);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
break; break;

View File

@@ -71,7 +71,7 @@ public class CustomTile extends QSTile<QSTile.State> implements TileChangeListen
super(host); super(host);
mWindowManager = WindowManagerGlobal.getWindowManagerService(); mWindowManager = WindowManagerGlobal.getWindowManagerService();
mComponent = ComponentName.unflattenFromString(action); mComponent = ComponentName.unflattenFromString(action);
mTile = new Tile(mComponent); mTile = new Tile();
setTileIcon(); setTileIcon();
mServiceManager = host.getTileServices().getTileWrapper(this); mServiceManager = host.getTileServices().getTileWrapper(this);
mService = mServiceManager.getTileService(); mService = mServiceManager.getTileService();

View File

@@ -94,4 +94,8 @@ public class QSTileServiceWrapper {
return false; return false;
} }
} }
public IQSTileService getService() {
return mService;
}
} }

View File

@@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
@@ -37,6 +38,7 @@ import android.service.quicksettings.TileService;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Log; import android.util.Log;
import libcore.util.Objects; import libcore.util.Objects;
import java.util.Set; import java.util.Set;
@@ -67,6 +69,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
private final Handler mHandler; private final Handler mHandler;
private final Intent mIntent; private final Intent mIntent;
private final UserHandle mUser; private final UserHandle mUser;
private final IBinder mToken = new Binder();
private Set<Integer> mQueuedMessages = new ArraySet<>(); private Set<Integer> mQueuedMessages = new ArraySet<>();
private QSTileServiceWrapper mWrapper; private QSTileServiceWrapper mWrapper;
@@ -88,7 +91,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
mHandler = handler; mHandler = handler;
mIntent = intent; mIntent = intent;
mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder()); mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder());
mIntent.putExtra(TileService.EXTRA_COMPONENT, intent.getComponent()); mIntent.putExtra(TileService.EXTRA_TOKEN, mToken);
mUser = user; mUser = user;
if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser); if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
} }
@@ -396,6 +399,10 @@ public class TileLifecycleManager extends BroadcastReceiver implements
handleDeath(); handleDeath();
} }
public IBinder getToken() {
return mToken;
}
public interface TileChangeListener { public interface TileChangeListener {
void onTileChanged(ComponentName tile); void onTileChanged(ComponentName tile);
} }

View File

@@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle; import android.os.UserHandle;
import android.service.quicksettings.IQSTileService; import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
@@ -32,6 +33,7 @@ import android.service.quicksettings.TileService;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.util.Log; import android.util.Log;
import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
import java.util.List; import java.util.List;
@@ -106,6 +108,10 @@ public class TileServiceManager {
return mStateManager; return mStateManager;
} }
public IBinder getToken() {
return mStateManager.getToken();
}
public void setBindRequested(boolean bindRequested) { public void setBindRequested(boolean bindRequested) {
if (mBindRequested == bindRequested) return; if (mBindRequested == bindRequested) return;
mBindRequested = bindRequested; mBindRequested = bindRequested;

View File

@@ -25,10 +25,12 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.service.quicksettings.IQSService; import android.service.quicksettings.IQSService;
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile; import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService; import android.service.quicksettings.TileService;
import android.util.ArrayMap; 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<CustomTile, TileServiceManager> mServices = new ArrayMap<>();
private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>(); private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
private final Context mContext; private final Context mContext;
private final Handler mHandler; private final Handler mHandler;
private final Handler mMainHandler; private final Handler mMainHandler;
@@ -82,6 +85,7 @@ public class TileServices extends IQSService.Stub {
synchronized (mServices) { synchronized (mServices) {
mServices.put(tile, service); mServices.put(tile, service);
mTiles.put(component, tile); mTiles.put(component, tile);
mTokenMap.put(service.getToken(), tile);
} }
return service; return service;
} }
@@ -95,6 +99,7 @@ public class TileServices extends IQSService.Stub {
service.setBindAllowed(false); service.setBindAllowed(false);
service.handleDestroy(); service.handleDestroy();
mServices.remove(tile); mServices.remove(tile);
mTokenMap.remove(service.getToken());
mTiles.remove(tile.getComponent()); mTiles.remove(tile.getComponent());
final String slot = tile.getComponent().getClassName(); final String slot = tile.getComponent().getClassName();
mMainHandler.post(new Runnable() { 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 { try {
String packageName = tile.getComponent().getPackageName();
int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
Binder.getCallingUserHandle().getIdentifier()); Binder.getCallingUserHandle().getIdentifier());
if (Binder.getCallingUid() != uid) { if (Binder.getCallingUid() != uid) {
@@ -170,10 +176,9 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public void updateQsTile(Tile tile) { public void updateQsTile(Tile tile, IBinder token) {
ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
verifyCaller(componentName.getPackageName()); verifyCaller(customTile);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
synchronized (mServices) { synchronized (mServices) {
final TileServiceManager tileServiceManager = mServices.get(customTile); final TileServiceManager tileServiceManager = mServices.get(customTile);
@@ -186,10 +191,9 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public void onStartSuccessful(Tile tile) { public void onStartSuccessful(IBinder token) {
ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
verifyCaller(componentName.getPackageName()); verifyCaller(customTile);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
synchronized (mServices) { synchronized (mServices) {
final TileServiceManager tileServiceManager = mServices.get(customTile); final TileServiceManager tileServiceManager = mServices.get(customTile);
@@ -200,10 +204,9 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public void onShowDialog(Tile tile) { public void onShowDialog(IBinder token) {
ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
verifyCaller(componentName.getPackageName()); verifyCaller(customTile);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
customTile.onDialogShown(); customTile.onDialogShown();
mHost.collapsePanels(); mHost.collapsePanels();
@@ -212,10 +215,9 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public void onDialogHidden(Tile tile) { public void onDialogHidden(IBinder token) {
ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
verifyCaller(componentName.getPackageName()); verifyCaller(customTile);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
mServices.get(customTile).setShowingDialog(false); mServices.get(customTile).setShowingDialog(false);
customTile.onDialogHidden(); customTile.onDialogHidden();
@@ -223,23 +225,22 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public void onStartActivity(Tile tile) { public void onStartActivity(IBinder token) {
ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
verifyCaller(componentName.getPackageName()); verifyCaller(customTile);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
mHost.collapsePanels(); mHost.collapsePanels();
} }
} }
@Override @Override
public void updateStatusIcon(Tile tile, Icon icon, String contentDescription) { public void updateStatusIcon(IBinder token, Icon icon, String contentDescription) {
final ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
String packageName = componentName.getPackageName(); verifyCaller(customTile);
verifyCaller(packageName);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
try { try {
ComponentName componentName = customTile.getComponent();
String packageName = componentName.getPackageName();
UserHandle userHandle = getCallingUserHandle(); UserHandle userHandle = getCallingUserHandle();
PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser(packageName, 0,
userHandle.getIdentifier()); userHandle.getIdentifier());
@@ -263,9 +264,9 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public Tile getTile(ComponentName componentName) { public Tile getTile(IBinder token) {
verifyCaller(componentName.getPackageName()); CustomTile customTile = getTileForToken(token);
CustomTile customTile = getTileForComponent(componentName); verifyCaller(customTile);
if (customTile != null) { if (customTile != null) {
return customTile.getQsTile(); return customTile.getQsTile();
} }
@@ -273,10 +274,9 @@ public class TileServices extends IQSService.Stub {
} }
@Override @Override
public void startUnlockAndRun(Tile tile) { public void startUnlockAndRun(IBinder token) {
ComponentName componentName = tile.getComponentName(); CustomTile customTile = getTileForToken(token);
verifyCaller(componentName.getPackageName()); verifyCaller(customTile);
CustomTile customTile = getTileForComponent(componentName);
if (customTile != null) { if (customTile != null) {
customTile.startUnlockAndRun(); customTile.startUnlockAndRun();
} }
@@ -294,6 +294,12 @@ public class TileServices extends IQSService.Stub {
return keyguardMonitor.isSecure() && keyguardMonitor.isShowing(); return keyguardMonitor.isSecure() && keyguardMonitor.isShowing();
} }
private CustomTile getTileForToken(IBinder token) {
synchronized (mServices) {
return mTokenMap.get(token);
}
}
private CustomTile getTileForComponent(ComponentName component) { private CustomTile getTileForComponent(ComponentName component) {
synchronized (mServices) { synchronized (mServices) {
return mTiles.get(component); return mTiles.get(component);

View File

@@ -400,7 +400,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
ComponentName component = CustomTile.getComponentFromSpec(tileSpec); ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
Intent intent = new Intent().setComponent(component); Intent intent = new Intent().setComponent(component);
TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(), TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
mContext, mServices, new Tile(component), intent, mContext, mServices, new Tile(), intent,
new UserHandle(ActivityManager.getCurrentUser())); new UserHandle(ActivityManager.getCurrentUser()));
lifecycleManager.onStopListening(); lifecycleManager.onStopListening();
lifecycleManager.onTileRemoved(); lifecycleManager.onTileRemoved();
@@ -414,7 +414,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
ComponentName component = CustomTile.getComponentFromSpec(tileSpec); ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
Intent intent = new Intent().setComponent(component); Intent intent = new Intent().setComponent(component);
TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(), TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
mContext, mServices, new Tile(component), intent, mContext, mServices, new Tile(), intent,
new UserHandle(ActivityManager.getCurrentUser())); new UserHandle(ActivityManager.getCurrentUser()));
lifecycleManager.onTileAdded(); lifecycleManager.onTileAdded();
lifecycleManager.flushMessagesAndUnbind(); lifecycleManager.flushMessagesAndUnbind();

View File

@@ -58,7 +58,7 @@ public class TileLifecycleManagerTests extends AndroidTestCase {
mHandler = new Handler(mThread.getLooper()); mHandler = new Handler(mThread.getLooper());
ComponentName component = new ComponentName(mContext, FakeTileService.class); ComponentName component = new ComponentName(mContext, FakeTileService.class);
mStateManager = new TileLifecycleManager(mHandler, getContext(), mStateManager = new TileLifecycleManager(mHandler, getContext(),
Mockito.mock(IQSService.class), new Tile(component), Mockito.mock(IQSService.class), new Tile(),
new Intent().setComponent(component), new Intent().setComponent(component),
new UserHandle(UserHandle.myUserId())); new UserHandle(UserHandle.myUserId()));
mCallbacks.clear(); mCallbacks.clear();