From 97d2272be0bf3e77474e7ff9984217dfe247f4d0 Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Thu, 7 Apr 2016 11:41:47 -0400 Subject: [PATCH] Allow mode of TileService to be changed Since the mode of a tile service was set in onTileAdded, it couldn't be controlled by developers if they updated their tile. To handle the mode has been moved to a boolean meta-data flag to indicate a tile should be an active tile. Bug: 28043969 Change-Id: I6403d34f8cb70809edc07769389d5a1f835c1ab3 --- api/current.txt | 5 +- api/system-current.txt | 5 +- api/test-current.txt | 5 +- .../service/quicksettings/IQSService.aidl | 1 - .../service/quicksettings/TileService.java | 48 +++++++------------ .../systemui/qs/external/CustomTile.java | 4 +- .../qs/external/TileLifecycleManager.java | 16 ++++++- .../qs/external/TileServiceManager.java | 22 ++------- .../systemui/qs/external/TileServices.java | 13 +---- .../qs/external/TileServiceManagerTests.java | 4 +- 10 files changed, 43 insertions(+), 80 deletions(-) diff --git a/api/current.txt b/api/current.txt index 259b3f6a6e007..319be13283b2d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -34781,7 +34781,7 @@ package android.service.quicksettings { method public void onClick(); method public void onStartListening(); method public void onStopListening(); - method public int onTileAdded(); + method public void 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); @@ -34789,8 +34789,7 @@ package android.service.quicksettings { method public final void unlockAndRun(java.lang.Runnable); field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE"; field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES"; - field public static final int TILE_MODE_ACTIVE = 2; // 0x2 - field public static final int TILE_MODE_PASSIVE = 1; // 0x1 + field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE"; } } diff --git a/api/system-current.txt b/api/system-current.txt index db27d8ee2673b..43d976a96044f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -37316,7 +37316,7 @@ package android.service.quicksettings { method public void onClick(); method public void onStartListening(); method public void onStopListening(); - method public int onTileAdded(); + method public void onTileAdded(); method public void onTileRemoved(); method public static final void requestListeningState(android.content.Context, android.content.ComponentName); method public final void setStatusIcon(android.graphics.drawable.Icon, java.lang.String); @@ -37325,8 +37325,7 @@ package android.service.quicksettings { method public final void unlockAndRun(java.lang.Runnable); field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE"; field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES"; - field public static final int TILE_MODE_ACTIVE = 2; // 0x2 - field public static final int TILE_MODE_PASSIVE = 1; // 0x1 + field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE"; } } diff --git a/api/test-current.txt b/api/test-current.txt index bf29b407cc414..ddffa55a778ee 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -34853,7 +34853,7 @@ package android.service.quicksettings { method public void onClick(); method public void onStartListening(); method public void onStopListening(); - method public int onTileAdded(); + method public void 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); @@ -34861,8 +34861,7 @@ package android.service.quicksettings { method public final void unlockAndRun(java.lang.Runnable); field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE"; field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES"; - field public static final int TILE_MODE_ACTIVE = 2; // 0x2 - field public static final int TILE_MODE_PASSIVE = 1; // 0x1 + field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE"; } } diff --git a/core/java/android/service/quicksettings/IQSService.aidl b/core/java/android/service/quicksettings/IQSService.aidl index 5434e2ef5e2f6..747f18531d3b9 100644 --- a/core/java/android/service/quicksettings/IQSService.aidl +++ b/core/java/android/service/quicksettings/IQSService.aidl @@ -28,7 +28,6 @@ interface IQSService { String contentDescription); void onShowDialog(in Tile tile); void onStartActivity(in Tile tile); - void setTileMode(in ComponentName component, int mode); boolean isLocked(); boolean isSecure(); void startUnlockAndRun(in Tile tile); diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java index 553d539eafeea..4e9a0751f2e38 100644 --- a/core/java/android/service/quicksettings/TileService.java +++ b/core/java/android/service/quicksettings/TileService.java @@ -89,28 +89,24 @@ 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}. + * Meta-data for tile definition to set a tile into active mode. *

* 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. + * + * To make a TileService an active tile, set this meta-data to true on the TileService's + * manifest declaration. + *

+     * {@literal
+     * 
+     * }
+     * 
*/ - public static final int TILE_MODE_ACTIVE = 2; + public static final String META_DATA_ACTIVE_TILE + = "android.service.quicksettings.ACTIVE_TILE"; /** * Used to notify SysUI that Listening has be requested. @@ -147,12 +143,8 @@ 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 int onTileAdded() { - return TILE_MODE_PASSIVE; + public void onTileAdded() { } /** @@ -386,15 +378,7 @@ public class TileService extends Service { } break; case MSG_TILE_ADDED: - int mode = TileService.this.onTileAdded(); - if (mService == null) { - return; - } - try { - mService.setTileMode(new ComponentName(TileService.this, - TileService.this.getClass()), mode); - } catch (RemoteException e) { - } + TileService.this.onTileAdded(); break; case MSG_TILE_REMOVED: if (mListening) { @@ -431,8 +415,8 @@ 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. + * This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined + * as true on their TileService Manifest declaration, and will do nothing otherwise. */ public static final void requestListeningState(Context context, ComponentName component) { Intent intent = new Intent(ACTION_REQUEST_LISTENING); 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 6114573f627e2..6b20681a7c66c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -138,7 +138,7 @@ public class CustomTile extends QSTile { mListening = listening; try { if (listening) { - if (mServiceManager.getType() == TileService.TILE_MODE_PASSIVE) { + if (!mServiceManager.isActiveTile()) { mServiceManager.setBindRequested(true); mService.onStartListening(); } @@ -209,7 +209,7 @@ public class CustomTile extends QSTile { } catch (RemoteException e) { } try { - if (mServiceManager.getType() == TileService.TILE_MODE_ACTIVE) { + if (mServiceManager.isActiveTile()) { mServiceManager.setBindRequested(true); mService.onStartListening(); } 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 8910d44e64882..5a26a4abd395f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java @@ -15,8 +15,6 @@ */ package com.android.systemui.qs.external; -import libcore.util.Objects; - import android.app.AppGlobals; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -25,6 +23,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Handler; @@ -34,9 +33,11 @@ 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.support.annotation.VisibleForTesting; import android.util.ArraySet; import android.util.Log; +import libcore.util.Objects; import java.util.Set; @@ -98,6 +99,17 @@ public class TileLifecycleManager extends BroadcastReceiver implements } } + public boolean isActiveTile() { + try { + ServiceInfo info = mContext.getPackageManager().getServiceInfo(mIntent.getComponent(), + PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA); + return info.metaData != null + && info.metaData.getBoolean(TileService.META_DATA_ACTIVE_TILE, false); + } catch (NameNotFoundException e) { + return false; + } + } + /** * Binds just long enough to send any queued messages, then unbinds. */ 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 664ddd6f00a0c..ab215320ac069 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java @@ -21,7 +21,6 @@ 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; @@ -51,7 +50,6 @@ public class TileServiceManager { private int mPriority; private boolean mJustBound; private long mLastUpdate; - private int mType; private boolean mShowingDialog; // Whether we have a pending bind going out to the service without a response yet. // This defaults to true to ensure tiles start out unavailable. @@ -69,25 +67,11 @@ 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 boolean isActiveTile() { + return mStateManager.isActiveTile(); } public void setShowingDialog(boolean dialog) { @@ -114,7 +98,7 @@ public class TileServiceManager { public void setLastUpdate(long lastUpdate) { mLastUpdate = lastUpdate; - if (mBound && mType == TileService.TILE_MODE_ACTIVE) { + if (mBound && isActiveTile()) { mStateManager.onStopListening(); setBindRequested(false); } 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 5bb2a3588acfb..f36d013b85965 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java @@ -153,7 +153,7 @@ public class TileServices extends IQSService.Stub { return; } TileServiceManager service = mServices.get(customTile); - if (service.getType() != TileService.TILE_MODE_ACTIVE) { + if (!service.isActiveTile()) { return; } service.setBindRequested(true); @@ -164,17 +164,6 @@ public class TileServices extends IQSService.Stub { } } - @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) { ComponentName componentName = tile.getComponentName(); 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 f24b541e2950f..1e27603983e68 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 @@ -18,7 +18,6 @@ package com.android.systemui.qs.external; import android.content.ComponentName; import android.os.Handler; import android.os.HandlerThread; -import android.service.quicksettings.TileService; import android.test.suitebuilder.annotation.SmallTest; import com.android.systemui.SysuiTestCase; import org.mockito.ArgumentCaptor; @@ -42,11 +41,10 @@ public class TileServiceManagerTests extends SysuiTestCase { mTileServices = Mockito.mock(TileServices.class); Mockito.when(mTileServices.getContext()).thenReturn(mContext); mTileLifecycle = Mockito.mock(TileLifecycleManager.class); + Mockito.when(mTileLifecycle.isActiveTile()).thenReturn(false); 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); }