diff --git a/api/current.txt b/api/current.txt
index 53510e054ce8b..94bb21a4b362e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33634,10 +33634,13 @@ package android.service.quicksettings {
method public void onClick();
method public void onStartListening();
method public void onStopListening();
- method public void onTileAdded();
+ method public int onTileAdded();
method public void onTileRemoved();
+ method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void showDialog(android.app.Dialog);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ field public static final int TILE_MODE_ACTIVE = 2; // 0x2
+ field public static final int TILE_MODE_PASSIVE = 1; // 0x1
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 1cf66626692e0..79e44ea737272 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -35802,10 +35802,13 @@ package android.service.quicksettings {
method public void onClick();
method public void onStartListening();
method public void onStopListening();
- method public void onTileAdded();
+ method public int onTileAdded();
method public void onTileRemoved();
+ method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void showDialog(android.app.Dialog);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ field public static final int TILE_MODE_ACTIVE = 2; // 0x2
+ field public static final int TILE_MODE_PASSIVE = 1; // 0x1
}
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 49c3edc54efec..090644bd3dc60 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -33637,10 +33637,13 @@ package android.service.quicksettings {
method public void onClick();
method public void onStartListening();
method public void onStopListening();
- method public void onTileAdded();
+ method public int onTileAdded();
method public void onTileRemoved();
+ method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void showDialog(android.app.Dialog);
field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ field public static final int TILE_MODE_ACTIVE = 2; // 0x2
+ field public static final int TILE_MODE_PASSIVE = 1; // 0x1
}
}
diff --git a/core/java/android/service/quicksettings/IQSService.aidl b/core/java/android/service/quicksettings/IQSService.aidl
index 7e70501de39b6..75da82fc43c0c 100644
--- a/core/java/android/service/quicksettings/IQSService.aidl
+++ b/core/java/android/service/quicksettings/IQSService.aidl
@@ -24,4 +24,5 @@ import android.service.quicksettings.Tile;
interface IQSService {
void updateQsTile(in Tile tile);
void onShowDialog(in Tile tile);
+ void setTileMode(in ComponentName component, int mode);
}
diff --git a/core/java/android/service/quicksettings/IQSTileService.aidl b/core/java/android/service/quicksettings/IQSTileService.aidl
index 63a4c5e30df9c..4997f754d2a78 100644
--- a/core/java/android/service/quicksettings/IQSTileService.aidl
+++ b/core/java/android/service/quicksettings/IQSTileService.aidl
@@ -22,6 +22,7 @@ import android.service.quicksettings.IQSService;
* @hide
*/
oneway interface IQSTileService {
+ void setQSService(in IQSService service);
void setQSTile(in Tile tile);
void onTileAdded();
void onTileRemoved();
diff --git a/core/java/android/service/quicksettings/Tile.java b/core/java/android/service/quicksettings/Tile.java
index a53fc59d362cf..6104913642f8a 100644
--- a/core/java/android/service/quicksettings/Tile.java
+++ b/core/java/android/service/quicksettings/Tile.java
@@ -37,11 +37,12 @@ public final class Tile implements Parcelable {
private static final String TAG = "Tile";
private ComponentName mComponentName;
- private IQSService mService;
private Icon mIcon;
private CharSequence mLabel;
private CharSequence mContentDescription;
+ private IQSService mService;
+
/**
* @hide
*/
@@ -52,8 +53,14 @@ public final class Tile implements Parcelable {
/**
* @hide
*/
- public Tile(ComponentName componentName, IQSService service) {
+ public Tile(ComponentName componentName) {
mComponentName = componentName;
+ }
+
+ /**
+ * @hide
+ */
+ public void setService(IQSService service) {
mService = service;
}
@@ -64,6 +71,13 @@ public final class Tile implements Parcelable {
return mComponentName;
}
+ /**
+ * @hide
+ */
+ public IQSService getQsService() {
+ return mService;
+ }
+
/**
* Gets the current icon for the tile.
*/
@@ -137,21 +151,8 @@ public final class Tile implements Parcelable {
}
}
- /**
- * @hide
- * Notifies the IQSService that this tile is showing a dialog.
- */
- void onShowDialog() {
- try {
- mService.onShowDialog(this);
- } catch (RemoteException e) {
- Log.e(TAG, "Couldn't onShowDialog");
- }
- }
-
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeStrongInterface(mService);
if (mComponentName != null) {
dest.writeByte((byte) 1);
mComponentName.writeToParcel(dest, flags);
@@ -169,7 +170,6 @@ public final class Tile implements Parcelable {
}
private void readFromParcel(Parcel source) {
- mService = IQSService.Stub.asInterface(source.readStrongBinder());
if (source.readByte() != 0) {
mComponentName = ComponentName.CREATOR.createFromParcel(source);
} else {
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 55fe4cd901e10..1e134c7efaba6 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -15,8 +15,11 @@
*/
package android.service.quicksettings;
+import android.Manifest;
import android.app.Dialog;
import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
@@ -42,7 +45,7 @@ import android.view.WindowManager;
*
When a tile should be up to date and listing will be indicated by
* {@link #onStartListening()} and {@link #onStopListening()}.
*
- * When the user removes a tile from Quick Settings {@link #onStopListening()}
+ * When the user removes a tile from Quick Settings {@link #onTileRemoved()}
* will be called.
*
* TileService will be detected by tiles that match the {@value #ACTION_QS_TILE}
@@ -71,11 +74,48 @@ public class TileService extends Service {
*/
public static final String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
+ /**
+ * The tile mode hasn't been set yet.
+ * @hide
+ */
+ public static final int TILE_MODE_UNSET = 0;
+
+ /**
+ * Constant to be returned by {@link #onTileAdded}.
+ *
+ * Passive mode is the default mode for tiles. The System will tell the tile
+ * when it is most important to update by putting it in the listening state.
+ */
+ public static final int TILE_MODE_PASSIVE = 1;
+
+ /**
+ * Constant to be returned by {@link #onTileAdded}.
+ *
+ * Active mode is for tiles which already listen and keep track of their state in their
+ * own process. These tiles may request to send an update to the System while their process
+ * is alive using {@link #requestListeningState}. The System will only bind these tiles
+ * on its own when a click needs to occur.
+ */
+ public static final int TILE_MODE_ACTIVE = 2;
+
+ /**
+ * Used to notify SysUI that Listening has be requested.
+ * @hide
+ */
+ public static final String ACTION_REQUEST_LISTENING
+ = "android.service.quicksettings.action.REQUEST_LISTENING";
+
+ /**
+ * @hide
+ */
+ public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
+
private final H mHandler = new H(Looper.getMainLooper());
private boolean mListening = false;
private Tile mTile;
private IBinder mToken;
+ private IQSService mService;
@Override
public void onDestroy() {
@@ -92,8 +132,12 @@ public class TileService extends Service {
* Note that this is not guaranteed to be called between {@link #onCreate()}
* and {@link #onStartListening()}, it will only be called when the tile is added
* and not on subsequent binds.
+ *
+ * @see #TILE_MODE_PASSIVE
+ * @see #TILE_MODE_ACTIVE
*/
- public void onTileAdded() {
+ public int onTileAdded() {
+ return TILE_MODE_PASSIVE;
}
/**
@@ -138,7 +182,10 @@ public class TileService extends Service {
dialog.getWindow().getAttributes().token = mToken;
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_QS_DIALOG);
dialog.show();
- getQsTile().onShowDialog();
+ try {
+ mService.onShowDialog(mTile);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -155,6 +202,11 @@ public class TileService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new IQSTileService.Stub() {
+ @Override
+ public void setQSService(IQSService service) throws RemoteException {
+ mHandler.obtainMessage(H.MSG_SET_SERVICE, service).sendToTarget();
+ }
+
@Override
public void setQSTile(Tile tile) throws RemoteException {
mHandler.obtainMessage(H.MSG_SET_TILE, tile).sendToTarget();
@@ -194,6 +246,7 @@ public class TileService extends Service {
private static final int MSG_TILE_ADDED = 4;
private static final int MSG_TILE_REMOVED = 5;
private static final int MSG_TILE_CLICKED = 6;
+ private static final int MSG_SET_SERVICE = 7;
public H(Looper looper) {
super(looper);
@@ -202,11 +255,28 @@ public class TileService extends Service {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case MSG_SET_SERVICE:
+ mService = (IQSService) msg.obj;
+ if (mTile != null) {
+ mTile.setService(mService);
+ }
+ break;
case MSG_SET_TILE:
mTile = (Tile) msg.obj;
+ if (mService != null && mTile != null) {
+ mTile.setService(mService);
+ }
break;
case MSG_TILE_ADDED:
- TileService.this.onTileAdded();
+ int mode = TileService.this.onTileAdded();
+ if (mService == null) {
+ return;
+ }
+ try {
+ mService.setTileMode(new ComponentName(TileService.this,
+ TileService.this.getClass()), mode);
+ } catch (RemoteException e) {
+ }
break;
case MSG_TILE_REMOVED:
TileService.this.onTileRemoved();
@@ -230,4 +300,16 @@ public class TileService extends Service {
}
}
}
+
+ /**
+ * Requests that a tile be put in the listening state so it can send an update.
+ *
+ * This method is only applicable to tiles that return {@link #TILE_MODE_ACTIVE} from
+ * {@link #onTileAdded()}, and will do nothing otherwise.
+ */
+ public static final void requestListeningState(Context context, ComponentName component) {
+ Intent intent = new Intent(ACTION_REQUEST_LISTENING);
+ intent.putExtra(EXTRA_COMPONENT, component);
+ context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index e622e1154396b..2e5a0b2775526 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -24,6 +24,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
import android.util.Log;
import android.view.IWindowManager;
import android.view.WindowManager;
@@ -59,7 +60,7 @@ public class CustomTile extends QSTile {
mComponent = ComponentName.unflattenFromString(action);
mServiceManager = host.getTileServices().getTileWrapper(this);
mService = mServiceManager.getTileService();
- mTile = new Tile(mComponent, host.getTileServices());
+ mTile = new Tile(mComponent);
try {
PackageManager pm = mContext.getPackageManager();
ServiceInfo info = pm.getServiceInfo(mComponent, 0);
@@ -68,6 +69,11 @@ public class CustomTile extends QSTile {
mTile.setLabel(info.loadLabel(pm));
} catch (Exception e) {
}
+ try {
+ mService.setQSTile(mTile);
+ } catch (RemoteException e) {
+ // Called through wrapper, won't happen here.
+ }
}
public ComponentName getComponent() {
@@ -94,9 +100,10 @@ public class CustomTile extends QSTile {
mListening = listening;
try {
if (listening) {
- mServiceManager.setBindRequested(true);
- mService.setQSTile(mTile);
- mService.onStartListening();
+ if (mServiceManager.getType() == TileService.TILE_MODE_PASSIVE) {
+ mServiceManager.setBindRequested(true);
+ mService.onStartListening();
+ }
} else {
mService.onStopListening();
if (mIsTokenGranted && !mIsShowingDialog) {
@@ -139,20 +146,20 @@ public class CustomTile extends QSTile {
@Override
protected void handleClick() {
- if (mService != null) {
- try {
- if (DEBUG) Log.d(TAG, "Adding token");
- mWindowManager.addWindowToken(mToken, WindowManager.LayoutParams.TYPE_QS_DIALOG);
- mIsTokenGranted = true;
- } catch (RemoteException e) {
+ try {
+ if (DEBUG) Log.d(TAG, "Adding token");
+ mWindowManager.addWindowToken(mToken, WindowManager.LayoutParams.TYPE_QS_DIALOG);
+ mIsTokenGranted = true;
+ } catch (RemoteException e) {
+ }
+ try {
+ if (mServiceManager.getType() == TileService.TILE_MODE_ACTIVE) {
+ mServiceManager.setBindRequested(true);
+ mService.onStartListening();
}
- try {
- mService.onClick(mToken);
- } catch (RemoteException e) {
- // Called through wrapper, won't happen here.
- }
- } else {
- Log.e(TAG, "Click with no service " + getTileSpec());
+ mService.onClick(mToken);
+ } catch (RemoteException e) {
+ // Called through wrapper, won't happen here.
}
MetricsLogger.action(mContext, getMetricsCategory(), mComponent.getPackageName());
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
index d656686b88a56..d41cdde37958b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
@@ -16,6 +16,7 @@
package com.android.systemui.qs.external;
import android.os.IBinder;
+import android.service.quicksettings.IQSService;
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.Tile;
import android.util.Log;
@@ -93,4 +94,14 @@ public class QSTileServiceWrapper {
return false;
}
}
+
+ public boolean setQSService(IQSService service) {
+ try {
+ mService.setQSService(service);
+ return true;
+ } catch (Exception e) {
+ Log.d(TAG, "Caught exception from TileService", e);
+ return false;
+ }
+ }
}
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 500ee1941bd9d..41fce9f1fb987 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -29,6 +29,7 @@ import android.os.Handler;
import android.os.IBinder;
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.support.annotation.VisibleForTesting;
@@ -74,6 +75,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
private boolean mBound;
@VisibleForTesting
boolean mReceiverRegistered;
+ private IQSService mService;
public TileLifecycleManager(Handler handler, Context context, Intent intent, UserHandle user) {
mContext = context;
@@ -82,6 +84,10 @@ public class TileLifecycleManager extends BroadcastReceiver implements
mUser = user;
}
+ public ComponentName getComponent() {
+ return mIntent.getComponent();
+ }
+
public boolean hasPendingClick() {
synchronized (mQueuedMessages) {
return mQueuedMessages.contains(MSG_ON_CLICK);
@@ -108,6 +114,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
if (DEBUG) Log.d(TAG, "Unbinding service " + mIntent);
// Give it another chance next time it needs to be bound, out of kindness.
mBindTryCount = 0;
+ mWrapper = null;
mContext.unbindService(this);
}
}
@@ -122,6 +129,8 @@ public class TileLifecycleManager extends BroadcastReceiver implements
service.linkToDeath(this, 0);
} catch (RemoteException e) {
}
+ setQSService(mService);
+ setQSTile(mTile);
handlePendingMessages();
}
@@ -145,7 +154,6 @@ public class TileLifecycleManager extends BroadcastReceiver implements
}
if (mListening) {
if (DEBUG) Log.d(TAG, "Handling pending onStartListening");
- setQSTile(mTile);
onStartListening();
}
if (queue.contains(MSG_ON_CLICK)) {
@@ -272,6 +280,14 @@ public class TileLifecycleManager extends BroadcastReceiver implements
}
}
+ @Override
+ public void setQSService(IQSService service) {
+ mService = service;
+ if (mWrapper == null || !mWrapper.setQSService(service)) {
+ handleDeath();
+ }
+ }
+
@Override
public void onTileAdded() {
if (DEBUG) Log.d(TAG, "onTileAdded");
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index ca589df5ed3fd..2f77a303c36cc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.os.Handler;
import android.os.UserHandle;
import android.service.quicksettings.IQSTileService;
+import android.service.quicksettings.TileService;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
@@ -38,6 +39,9 @@ public class TileServiceManager {
private static final String TAG = "TileServiceManager";
+ @VisibleForTesting
+ static final String PREFS_FILE = "CustomTileModes";
+
private final TileServices mServices;
private final TileLifecycleManager mStateManager;
private final Handler mHandler;
@@ -47,6 +51,7 @@ public class TileServiceManager {
private int mPriority;
private boolean mJustBound;
private long mLastUpdate;
+ private int mType;
TileServiceManager(TileServices tileServices, Handler handler, ComponentName component) {
this(tileServices, handler, new TileLifecycleManager(handler,
@@ -60,6 +65,25 @@ public class TileServiceManager {
mServices = tileServices;
mHandler = handler;
mStateManager = tileLifecycleManager;
+ mType = tileServices.getContext().getSharedPreferences(PREFS_FILE, 0)
+ .getInt(tileLifecycleManager.getComponent().flattenToString(),
+ TileService.TILE_MODE_UNSET);
+ mStateManager.setQSService(tileServices);
+ if (mType == TileService.TILE_MODE_UNSET) {
+ bindService();
+ mStateManager.onTileAdded();
+ }
+ }
+
+ public int getType() {
+ return mType;
+ }
+
+ public void setType(int type) {
+ mServices.getContext().getSharedPreferences(PREFS_FILE, 0).edit()
+ .putInt(mStateManager.getComponent().flattenToString(), type).commit();
+ mType = type;
+ mServices.recalculateBindAllowance();
}
public IQSTileService getTileService() {
@@ -70,17 +94,22 @@ public class TileServiceManager {
if (mBindRequested == bindRequested) return;
mBindRequested = bindRequested;
if (mBindAllowed && mBindRequested && !mBound) {
+ mHandler.removeCallbacks(mUnbind);
bindService();
} else {
mServices.recalculateBindAllowance();
}
if (mBound && !mBindRequested) {
- // TODO: Schedule unbind.
+ mHandler.postDelayed(mUnbind, UNBIND_DELAY);
}
}
public void setLastUpdate(long lastUpdate) {
mLastUpdate = lastUpdate;
+ if (mBound && mType == TileService.TILE_MODE_ACTIVE) {
+ mStateManager.onStopListening();
+ setBindRequested(false);
+ }
mServices.recalculateBindAllowance();
}
@@ -148,6 +177,15 @@ public class TileServiceManager {
return mPriority;
}
+ private final Runnable mUnbind = new Runnable() {
+ @Override
+ public void run() {
+ if (mBound && !mBindRequested) {
+ unbindService();
+ }
+ }
+ };
+
@VisibleForTesting
final Runnable mJustBoundOver = new Runnable() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index d110d978293ab..00f76990c1e83 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -15,15 +15,21 @@
*/
package com.android.systemui.qs.external;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
+import android.os.RemoteException;
import android.service.quicksettings.IQSService;
import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
import android.util.ArrayMap;
+import android.util.Log;
import com.android.systemui.statusbar.phone.QSTileHost;
import java.util.ArrayList;
@@ -48,6 +54,8 @@ public class TileServices extends IQSService.Stub {
public TileServices(QSTileHost host, Looper looper) {
mHost = host;
mContext = mHost.getContext();
+ mContext.registerReceiver(mRequestListeningReceiver,
+ new IntentFilter(TileService.ACTION_REQUEST_LISTENING));
mHandler = new Handler(looper);
}
@@ -121,12 +129,44 @@ public class TileServices extends IQSService.Stub {
}
}
+ private void requestListening(ComponentName component) {
+ synchronized (mServices) {
+ CustomTile customTile = getTileForComponent(component);
+ if (customTile == null) {
+ Log.d("TileServices", "Couldn't find tile for " + component);
+ return;
+ }
+ TileServiceManager service = mServices.get(customTile);
+ if (service.getType() != TileService.TILE_MODE_ACTIVE) {
+ return;
+ }
+ service.setBindRequested(true);
+ try {
+ service.getTileService().onStartListening();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @Override
+ public void setTileMode(ComponentName component, int mode) {
+ verifyCaller(component.getPackageName());
+ CustomTile customTile = getTileForComponent(component);
+ if (customTile != null) {
+ synchronized (mServices) {
+ mServices.get(customTile).setType(mode);
+ }
+ }
+ }
+
@Override
public void updateQsTile(Tile tile) {
verifyCaller(tile.getComponentName().getPackageName());
CustomTile customTile = getTileForComponent(tile.getComponentName());
if (customTile != null) {
- mServices.get(customTile).setLastUpdate(System.currentTimeMillis());
+ synchronized (mServices) {
+ mServices.get(customTile).setLastUpdate(System.currentTimeMillis());
+ }
customTile.updateState(tile);
customTile.refreshState();
}
@@ -143,9 +183,21 @@ public class TileServices extends IQSService.Stub {
}
private CustomTile getTileForComponent(ComponentName component) {
- return mTiles.get(component);
+ synchronized (mServices) {
+ return mTiles.get(component);
+ }
}
+ private final BroadcastReceiver mRequestListeningReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (TileService.ACTION_REQUEST_LISTENING.equals(intent.getAction())) {
+ requestListening(
+ (ComponentName) intent.getParcelableExtra(TileService.EXTRA_COMPONENT));
+ }
+ }
+ };
+
private static final Comparator SERVICE_SORT =
new Comparator() {
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
index 059421136086c..6ebf488937f91 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.qs.external;
+import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -23,9 +24,13 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
-import android.service.quicksettings.TileService;
+import android.service.quicksettings.IQSService;
+import android.service.quicksettings.IQSTileService;
+import android.service.quicksettings.Tile;
import android.test.AndroidTestCase;
import android.util.ArraySet;
import android.util.Log;
@@ -238,9 +243,49 @@ public class TileLifecycleManagerTests extends AndroidTestCase {
}
};
- public static class FakeTileService extends TileService {
+ public static class FakeTileService extends Service {
public static final String ACTION_KILL = "com.android.systemui.test.KILL";
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new IQSTileService.Stub() {
+
+ @Override
+ public void setQSService(IQSService service) {
+
+ }
+
+ @Override
+ public void setQSTile(Tile tile) throws RemoteException {
+ }
+
+ @Override
+ public void onTileAdded() throws RemoteException {
+ sendCallback("onTileAdded");
+ }
+
+ @Override
+ public void onTileRemoved() throws RemoteException {
+ sendCallback("onTileRemoved");
+ }
+
+ @Override
+ public void onStartListening() throws RemoteException {
+ sendCallback("onStartListening");
+ }
+
+ @Override
+ public void onStopListening() throws RemoteException {
+ sendCallback("onStopListening");
+ }
+
+ @Override
+ public void onClick(IBinder iBinder) throws RemoteException {
+ sendCallback("onClick");
+ }
+ };
+ }
+
@Override
public void onCreate() {
super.onCreate();
@@ -255,31 +300,6 @@ public class TileLifecycleManagerTests extends AndroidTestCase {
sendCallback("onDestroy");
}
- @Override
- public void onTileAdded() {
- sendCallback("onTileAdded");
- }
-
- @Override
- public void onTileRemoved() {
- sendCallback("onTileRemoved");
- }
-
- @Override
- public void onStartListening() {
- sendCallback("onStartListening");
- }
-
- @Override
- public void onStopListening() {
- sendCallback("onStopListening");
- }
-
- @Override
- public void onClick() {
- sendCallback("onClick");
- }
-
private void sendCallback(String callback) {
Log.d("TileLifecycleManager", "Relaying: " + callback);
sendBroadcast(new Intent(TILE_UPDATE_BROADCAST)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java
index c4f686e98cf5c..4586c2813f727 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTests.java
@@ -15,8 +15,10 @@
*/
package com.android.systemui.qs.external;
+import android.content.ComponentName;
import android.os.Handler;
import android.os.HandlerThread;
+import android.service.quicksettings.TileService;
import com.android.systemui.SysuiTestCase;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -36,7 +38,13 @@ public class TileServiceManagerTests extends SysuiTestCase {
mThread.start();
mHandler = new Handler(mThread.getLooper());
mTileServices = Mockito.mock(TileServices.class);
+ Mockito.when(mTileServices.getContext()).thenReturn(mContext);
mTileLifecycle = Mockito.mock(TileLifecycleManager.class);
+ ComponentName componentName = new ComponentName(mContext,
+ TileServiceManagerTests.class);
+ Mockito.when(mTileLifecycle.getComponent()).thenReturn(componentName);
+ mContext.getSharedPreferences(TileServiceManager.PREFS_FILE, 0).edit()
+ .putInt(componentName.flattenToString(), TileService.TILE_MODE_PASSIVE).commit();
mTileServiceManager = new TileServiceManager(mTileServices, mHandler, mTileLifecycle);
}