Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (c) 2015, The CyanogenMod Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package cyanogenmod.app; |
| 18 | |
| 19 | import android.content.Context; |
| 20 | import android.os.IBinder; |
| 21 | import android.os.RemoteException; |
| 22 | import android.os.ServiceManager; |
| 23 | import android.os.UserHandle; |
| 24 | import android.util.Log; |
| 25 | import android.util.Slog; |
| 26 | |
| 27 | import cyanogenmod.app.ICMStatusBarManager; |
| 28 | |
| 29 | /** |
| 30 | * The CMStatusBarManager allows you to publish and remove CustomTiles within the |
| 31 | * Quick Settings Panel. |
| 32 | * |
| 33 | * <p> |
| 34 | * Each of the publish methods takes an int id parameter and optionally a |
| 35 | * {@link String} tag parameter, which may be {@code null}. These parameters |
| 36 | * are used to form a pair (tag, id), or ({@code null}, id) if tag is |
| 37 | * unspecified. This pair identifies this custom tile from your app to the |
| 38 | * system, so that pair should be unique within your app. If you call one |
| 39 | * of the publish methods with a (tag, id) pair that is currently active and |
| 40 | * a new set of custom tile parameters, it will be updated. For example, |
| 41 | * if you pass a new custom tile icon, the old icon in the panel will |
| 42 | * be replaced with the new one. This is also the same tag and id you pass |
| 43 | * to the {@link #removeTile(int)} or {@link #removeTile(String, int)} method to clear |
| 44 | * this custom tile. |
| 45 | * |
| 46 | * <p> |
| 47 | * To get the instance of this class, utilize CMStatusBarManager#getInstance(Context context) |
| 48 | * |
| 49 | * @see cyanogenmod.app.CustomTile |
| 50 | */ |
| 51 | public class CMStatusBarManager { |
| 52 | private static final String TAG = "CMStatusBarManager"; |
| 53 | private static boolean localLOGV = false; |
| 54 | |
| 55 | private Context mContext; |
| 56 | |
| 57 | private static ICMStatusBarManager sService; |
| 58 | |
| 59 | private static CMStatusBarManager sCMStatusBarManagerInstance; |
| 60 | private CMStatusBarManager(Context context) { |
| 61 | Context appContext = context.getApplicationContext(); |
| 62 | if (appContext != null) { |
| 63 | mContext = appContext; |
| 64 | } else { |
| 65 | mContext = context; |
| 66 | } |
| 67 | sService = getService(); |
Adnan Begovic | cdf85ad | 2016-03-15 11:29:41 -0700 | [diff] [blame] | 68 | |
| 69 | if (context.getPackageManager().hasSystemFeature( |
| 70 | cyanogenmod.app.CMContextConstants.Features.STATUSBAR) && sService == null) { |
| 71 | throw new RuntimeException("Unable to get CMStatusBarService. The service either" + |
| 72 | " crashed, was not started, or the interface has been called to early in" + |
| 73 | " SystemServer init"); |
| 74 | } |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | /** |
| 78 | * Get or create an instance of the {@link cyanogenmod.app.CMStatusBarManager} |
| 79 | * @param context |
| 80 | * @return {@link cyanogenmod.app.CMStatusBarManager} |
| 81 | */ |
| 82 | public static CMStatusBarManager getInstance(Context context) { |
| 83 | if (sCMStatusBarManagerInstance == null) { |
| 84 | sCMStatusBarManagerInstance = new CMStatusBarManager(context); |
| 85 | } |
| 86 | return sCMStatusBarManagerInstance; |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * Post a custom tile to be shown in the status bar panel. If a custom tile with |
| 91 | * the same id has already been posted by your application and has not yet been removed, it |
| 92 | * will be replaced by the updated information. |
| 93 | * |
Adnan Begovic | 8c36c41 | 2015-05-19 13:27:17 -0700 | [diff] [blame] | 94 | * You will need the cyanogenmod.permission.PUBLISH_CUSTOM_TILE |
| 95 | * to utilize this functionality. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 96 | * |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 97 | * @param id An identifier for this customTile unique within your |
| 98 | * application. |
| 99 | * @param customTile A {@link CustomTile} object describing what to show the user. |
| 100 | * Must not be null. |
| 101 | */ |
| 102 | public void publishTile(int id, CustomTile customTile) { |
| 103 | publishTile(null, id, customTile); |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * Post a custom tile to be shown in the status bar panel. If a custom tile with |
| 108 | * the same tag and id has already been posted by your application and has not yet been |
| 109 | * removed, it will be replaced by the updated information. |
| 110 | * |
Adnan Begovic | 8c36c41 | 2015-05-19 13:27:17 -0700 | [diff] [blame] | 111 | * You will need the cyanogenmod.permission.PUBLISH_CUSTOM_TILE |
| 112 | * to utilize this functionality. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 113 | * |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 114 | * @param tag A string identifier for this custom tile. May be {@code null}. |
| 115 | * @param id An identifier for this custom tile. The pair (tag, id) must be unique |
| 116 | * within your application. |
| 117 | * @param customTile A {@link cyanogenmod.app.CustomTile} object describing what to |
| 118 | * show the user. Must not be null. |
| 119 | */ |
| 120 | public void publishTile(String tag, int id, CustomTile customTile) { |
| 121 | if (sService == null) { |
| 122 | Log.w(TAG, "not connected to CMStatusBarManagerService"); |
| 123 | return; |
| 124 | } |
| 125 | |
| 126 | int[] idOut = new int[1]; |
| 127 | String pkg = mContext.getPackageName(); |
| 128 | if (localLOGV) Log.v(TAG, pkg + ": create(" + id + ", " + customTile + ")"); |
| 129 | try { |
| 130 | sService.createCustomTileWithTag(pkg, mContext.getOpPackageName(), tag, id, |
| 131 | customTile, idOut, UserHandle.myUserId()); |
| 132 | if (id != idOut[0]) { |
| 133 | Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); |
| 134 | } |
| 135 | } catch (RemoteException e) { |
| 136 | Slog.w("CMStatusBarManager", "warning: no cm status bar service"); |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * Similar to {@link cyanogenmod.app.CMStatusBarManager#publishTile(int id, cyanogenmod.app.CustomTile)}, |
| 142 | * however lets you specify a {@link android.os.UserHandle} |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 143 | * |
Adnan Begovic | 8c36c41 | 2015-05-19 13:27:17 -0700 | [diff] [blame] | 144 | * You will need the cyanogenmod.permission.PUBLISH_CUSTOM_TILE |
| 145 | * to utilize this functionality. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 146 | * |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 147 | * @param tag A string identifier for this custom tile. May be {@code null}. |
| 148 | * @param id An identifier for this custom tile. The pair (tag, id) must be unique |
| 149 | * within your application. |
| 150 | * @param customTile A {@link cyanogenmod.app.CustomTile} object describing what to |
| 151 | * show the user. Must not be null. |
| 152 | * @param user A user handle to publish the tile as. |
| 153 | */ |
| 154 | public void publishTileAsUser(String tag, int id, CustomTile customTile, UserHandle user) { |
| 155 | if (sService == null) { |
| 156 | Log.w(TAG, "not connected to CMStatusBarManagerService"); |
| 157 | return; |
| 158 | } |
| 159 | |
| 160 | int[] idOut = new int[1]; |
| 161 | String pkg = mContext.getPackageName(); |
| 162 | if (localLOGV) Log.v(TAG, pkg + ": create(" + id + ", " + customTile + ")"); |
| 163 | try { |
| 164 | sService.createCustomTileWithTag(pkg, mContext.getOpPackageName(), tag, id, |
| 165 | customTile, idOut, user.getIdentifier()); |
| 166 | if (id != idOut[0]) { |
| 167 | Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); |
| 168 | } |
| 169 | } catch (RemoteException e) { |
| 170 | Slog.w("CMStatusBarManager", "warning: no cm status bar service"); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | /** |
| 175 | * Remove a custom tile that's currently published to the StatusBarPanel. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 176 | * |
Adnan Begovic | 8c36c41 | 2015-05-19 13:27:17 -0700 | [diff] [blame] | 177 | * You will need the cyanogenmod.permission.PUBLISH_CUSTOM_TILE |
| 178 | * to utilize this functionality. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 179 | * |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 180 | * @param id The identifier for the custom tile to be removed. |
| 181 | */ |
| 182 | public void removeTile(int id) { |
| 183 | removeTile(null, id); |
| 184 | } |
| 185 | |
| 186 | /** |
| 187 | * Remove a custom tile that's currently published to the StatusBarPanel. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 188 | * |
Adnan Begovic | 8c36c41 | 2015-05-19 13:27:17 -0700 | [diff] [blame] | 189 | * You will need the cyanogenmod.platform.PUBLISH_CUSTOM_TILE |
| 190 | * to utilize this functionality. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 191 | * |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 192 | * @param tag The string identifier for the custom tile to be removed. |
| 193 | * @param id The identifier for the custom tile to be removed. |
| 194 | */ |
| 195 | public void removeTile(String tag, int id) { |
| 196 | if (sService == null) { |
| 197 | Log.w(TAG, "not connected to CMStatusBarManagerService"); |
| 198 | return; |
| 199 | } |
| 200 | |
| 201 | String pkg = mContext.getPackageName(); |
| 202 | if (localLOGV) Log.v(TAG, pkg + ": remove(" + id + ")"); |
| 203 | try { |
| 204 | sService.removeCustomTileWithTag(pkg, tag, id, UserHandle.myUserId()); |
| 205 | } catch (RemoteException e) { |
| 206 | Slog.w("CMStatusBarManager", "warning: no cm status bar service"); |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | /** |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 211 | * Similar to {@link cyanogenmod.app.CMStatusBarManager#removeTile(String tag, int id)} |
| 212 | * however lets you specific a {@link android.os.UserHandle} |
| 213 | * |
Adnan Begovic | 8c36c41 | 2015-05-19 13:27:17 -0700 | [diff] [blame] | 214 | * You will need the cyanogenmod.platform.PUBLISH_CUSTOM_TILE |
| 215 | * to utilize this functionality. |
Adnan Begovic | e54a96d | 2015-04-30 17:26:01 -0700 | [diff] [blame] | 216 | * |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 217 | * @param tag The string identifier for the custom tile to be removed. |
| 218 | * @param id The identifier for the custom tile to be removed. |
| 219 | * @param user The user handle to remove the tile from. |
| 220 | */ |
| 221 | public void removeTileAsUser(String tag, int id, UserHandle user) { |
| 222 | if (sService == null) { |
| 223 | Log.w(TAG, "not connected to CMStatusBarManagerService"); |
| 224 | return; |
| 225 | } |
| 226 | |
| 227 | String pkg = mContext.getPackageName(); |
| 228 | if (localLOGV) Log.v(TAG, pkg + ": remove(" + id + ")"); |
| 229 | try { |
| 230 | sService.removeCustomTileWithTag(pkg, tag, id, user.getIdentifier()); |
| 231 | } catch (RemoteException e) { |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | /** @hide */ |
| 236 | public ICMStatusBarManager getService() { |
| 237 | if (sService != null) { |
| 238 | return sService; |
| 239 | } |
| 240 | IBinder b = ServiceManager.getService(CMContextConstants.CM_STATUS_BAR_SERVICE); |
Jorge Ruesga | f58b595 | 2015-05-30 18:29:55 +0200 | [diff] [blame] | 241 | if (b != null) { |
| 242 | sService = ICMStatusBarManager.Stub.asInterface(b); |
| 243 | return sService; |
| 244 | } |
| 245 | return null; |
Adnan Begovic | aa8614e | 2015-04-23 23:16:27 -0700 | [diff] [blame] | 246 | } |
| 247 | } |