diff --git a/cm/lib/java/org/cyanogenmod/platform/internal/CMStatusBarManagerService.java b/cm/lib/java/org/cyanogenmod/platform/internal/CMStatusBarManagerService.java index 88472a1..b640aaf 100644 --- a/cm/lib/java/org/cyanogenmod/platform/internal/CMStatusBarManagerService.java +++ b/cm/lib/java/org/cyanogenmod/platform/internal/CMStatusBarManagerService.java @@ -98,7 +98,7 @@ public class CMStatusBarManagerService extends SystemService { userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, true, false, "cancelCustomTileWithTag", pkg); removeCustomTileWithTagInternal(Binder.getCallingUid(), - Binder.getCallingPid(), pkg, tag, id, userId); + Binder.getCallingPid(), pkg, tag, id, userId, null); } /** @@ -124,6 +124,29 @@ public class CMStatusBarManagerService extends SystemService { enforceBindCustomTileListener(); mCustomTileListeners.unregisterService(listener, userid); } + + /** + * Allow an ICustomTileListener to simulate clearing (dismissing) a single customTile. + * + * @param token The binder for the listener, to check that the caller is allowed + */ + @Override + public void removeCustomTileFromListener(ICustomTileListener token, String pkg, + String tag, int id) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + long identity = Binder.clearCallingIdentity(); + try { + synchronized (mQSTileList) { + final ManagedServices.ManagedServiceInfo info + = mCustomTileListeners.checkServiceTokenLocked(token); + removeCustomTileFromListenerLocked(info, callingUid, callingPid, + pkg, tag, id, info.userid); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } }; void createCustomTileWithTagInternal(final String pkg, final String opPkg, final int callingUid, @@ -281,8 +304,14 @@ public class CMStatusBarManagerService extends SystemService { || r.getUserId() == userId; } + private void removeCustomTileFromListenerLocked(ManagedServices.ManagedServiceInfo info, + int callingUid, int callingPid, String pkg, String tag, int id, int userId) { + removeCustomTileWithTagInternal(callingUid, callingPid, pkg, tag, id, userId, info); + } + void removeCustomTileWithTagInternal(final int callingUid, final int callingPid, - final String pkg, final String tag, final int id, final int userId) { + final String pkg, final String tag, final int id, final int userId, + final ManagedServices.ManagedServiceInfo listener) { mHandler.post(new Runnable() { @Override public void run() { diff --git a/src/java/cyanogenmod/app/CustomTileListenerService.java b/src/java/cyanogenmod/app/CustomTileListenerService.java index 6c7dce0..1cd8d2d 100644 --- a/src/java/cyanogenmod/app/CustomTileListenerService.java +++ b/src/java/cyanogenmod/app/CustomTileListenerService.java @@ -191,4 +191,37 @@ public class CustomTileListenerService extends Service { public void onListenerConnected() { // optional } + + /** + * Inform the {@link cyanogenmod.app.CMStatusBarManager} about dismissal of a single custom tile. + *

+ * Use this if your listener has a user interface that allows the user to dismiss individual + * custom tiles, similar to the behavior of Android's status bar and notification panel. + * It should be called after the user dismisses a single custom tile using your UI; + * upon being informed, the cmstatusbar manager will actually remove the custom tile + * and you will get an {@link #onCustomTileRemoved(StatusBarPanelCustomTile)} callback. + *

+ * + * @param pkg Package of the notifying app. + * @param tag Tag of the custom tile as specified by the notifying app + * @param id ID of the notification as specified by the notifying app + *

+ */ + public final void removeCustomTile(String pkg, String tag, int id) { + if (!isBound()) return; + try { + getStatusBarInterface().removeCustomTileFromListener( + mWrapper, pkg, tag, id); + } catch (android.os.RemoteException ex) { + Log.v(TAG, "Unable to contact cmstautusbar manager", ex); + } + } + + private boolean isBound() { + if (mWrapper == null) { + Log.w(TAG, "CustomTile listener service not yet bound."); + return false; + } + return true; + } } diff --git a/src/java/cyanogenmod/app/ICMStatusBarManager.aidl b/src/java/cyanogenmod/app/ICMStatusBarManager.aidl index 439acce..88e28b0 100644 --- a/src/java/cyanogenmod/app/ICMStatusBarManager.aidl +++ b/src/java/cyanogenmod/app/ICMStatusBarManager.aidl @@ -34,4 +34,5 @@ interface ICMStatusBarManager { // You need the BIND_QUICK_SETTINGS_TILE_LISTENER permission void registerListener(in ICustomTileListener listener, in ComponentName component, int userid); void unregisterListener(in ICustomTileListener listener, int userid); + void removeCustomTileFromListener(in ICustomTileListener listener, String pkg, String tag, int id); }