AppWidgetService.java revision a00271533f639c8ed36429c663889ac9f654bc72
1/* 2 * Copyright (C) 2007 The Android Open Source 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 17package com.android.server; 18 19import android.app.ActivityManager; 20import android.appwidget.AppWidgetProviderInfo; 21import android.content.BroadcastReceiver; 22import android.content.ComponentName; 23import android.content.Context; 24import android.content.Intent; 25import android.content.IntentFilter; 26import android.content.pm.PackageManager; 27import android.os.Binder; 28import android.os.Bundle; 29import android.os.Handler; 30import android.os.IBinder; 31import android.os.RemoteException; 32import android.os.UserHandle; 33import android.util.Slog; 34import android.util.SparseArray; 35import android.widget.RemoteViews; 36 37import com.android.internal.appwidget.IAppWidgetHost; 38import com.android.internal.appwidget.IAppWidgetService; 39import com.android.internal.os.BackgroundThread; 40import com.android.internal.util.IndentingPrintWriter; 41 42import java.io.FileDescriptor; 43import java.io.PrintWriter; 44import java.util.List; 45import java.util.Locale; 46 47 48/** 49 * Redirects calls to this service to the instance of the service for the appropriate user. 50 */ 51class AppWidgetService extends IAppWidgetService.Stub 52{ 53 private static final String TAG = "AppWidgetService"; 54 55 Context mContext; 56 Locale mLocale; 57 PackageManager mPackageManager; 58 boolean mSafeMode; 59 private final Handler mSaveStateHandler; 60 61 private final SparseArray<AppWidgetServiceImpl> mAppWidgetServices; 62 63 AppWidgetService(Context context) { 64 mContext = context; 65 66 mSaveStateHandler = BackgroundThread.getHandler(); 67 68 mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5); 69 AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler); 70 mAppWidgetServices.append(0, primary); 71 } 72 73 public void systemRunning(boolean safeMode) { 74 mSafeMode = safeMode; 75 76 mAppWidgetServices.get(0).systemReady(safeMode); 77 78 // Register for the boot completed broadcast, so we can send the 79 // ENABLE broacasts. If we try to send them now, they time out, 80 // because the system isn't ready to handle them yet. 81 mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, 82 new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); 83 84 // Register for configuration changes so we can update the names 85 // of the widgets when the locale changes. 86 mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, 87 new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED), null, null); 88 89 // Register for broadcasts about package install, etc., so we can 90 // update the provider list. 91 IntentFilter filter = new IntentFilter(); 92 filter.addAction(Intent.ACTION_PACKAGE_ADDED); 93 filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 94 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 95 filter.addDataScheme("package"); 96 mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, 97 filter, null, null); 98 // Register for events related to sdcard installation. 99 IntentFilter sdFilter = new IntentFilter(); 100 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 101 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 102 mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, 103 sdFilter, null, null); 104 105 IntentFilter userFilter = new IntentFilter(); 106 userFilter.addAction(Intent.ACTION_USER_REMOVED); 107 userFilter.addAction(Intent.ACTION_USER_STOPPING); 108 mContext.registerReceiver(new BroadcastReceiver() { 109 @Override 110 public void onReceive(Context context, Intent intent) { 111 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { 112 onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 113 UserHandle.USER_NULL)); 114 } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) { 115 onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 116 UserHandle.USER_NULL)); 117 } 118 } 119 }, userFilter); 120 } 121 122 @Override 123 public int allocateAppWidgetId(String packageName, int hostId, int userId) 124 throws RemoteException { 125 return getImplForUser(userId).allocateAppWidgetId(packageName, hostId); 126 } 127 128 @Override 129 public int[] getAppWidgetIdsForHost(int hostId, int userId) throws RemoteException { 130 return getImplForUser(userId).getAppWidgetIdsForHost(hostId); 131 } 132 133 @Override 134 public void deleteAppWidgetId(int appWidgetId, int userId) throws RemoteException { 135 getImplForUser(userId).deleteAppWidgetId(appWidgetId); 136 } 137 138 @Override 139 public void deleteHost(int hostId, int userId) throws RemoteException { 140 getImplForUser(userId).deleteHost(hostId); 141 } 142 143 @Override 144 public void deleteAllHosts(int userId) throws RemoteException { 145 getImplForUser(userId).deleteAllHosts(); 146 } 147 148 @Override 149 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options, int userId) 150 throws RemoteException { 151 getImplForUser(userId).bindAppWidgetId(appWidgetId, provider, options); 152 } 153 154 @Override 155 public boolean bindAppWidgetIdIfAllowed( 156 String packageName, int appWidgetId, ComponentName provider, Bundle options, int userId) 157 throws RemoteException { 158 return getImplForUser(userId).bindAppWidgetIdIfAllowed( 159 packageName, appWidgetId, provider, options); 160 } 161 162 @Override 163 public boolean hasBindAppWidgetPermission(String packageName, int userId) 164 throws RemoteException { 165 return getImplForUser(userId).hasBindAppWidgetPermission(packageName); 166 } 167 168 @Override 169 public void setBindAppWidgetPermission(String packageName, boolean permission, int userId) 170 throws RemoteException { 171 getImplForUser(userId).setBindAppWidgetPermission(packageName, permission); 172 } 173 174 @Override 175 public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection, 176 int userId) throws RemoteException { 177 getImplForUser(userId).bindRemoteViewsService(appWidgetId, intent, connection); 178 } 179 180 @Override 181 public int[] startListening(IAppWidgetHost host, String packageName, int hostId, 182 List<RemoteViews> updatedViews, int userId) throws RemoteException { 183 return getImplForUser(userId).startListening(host, packageName, hostId, updatedViews); 184 } 185 186 public void onUserRemoved(int userId) { 187 if (userId < 1) return; 188 synchronized (mAppWidgetServices) { 189 AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); 190 mAppWidgetServices.remove(userId); 191 192 if (impl == null) { 193 AppWidgetServiceImpl.getSettingsFile(userId).delete(); 194 } else { 195 impl.onUserRemoved(); 196 } 197 } 198 } 199 200 public void onUserStopping(int userId) { 201 if (userId < 1) return; 202 synchronized (mAppWidgetServices) { 203 AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); 204 if (impl != null) { 205 mAppWidgetServices.remove(userId); 206 impl.onUserStopping(); 207 } 208 } 209 } 210 211 private void checkPermission(int userId) { 212 int realUserId = ActivityManager.handleIncomingUser( 213 Binder.getCallingPid(), 214 Binder.getCallingUid(), 215 userId, 216 false, /* allowAll */ 217 true, /* requireFull */ 218 this.getClass().getSimpleName(), 219 this.getClass().getPackage().getName()); 220 } 221 222 private AppWidgetServiceImpl getImplForUser(int userId) { 223 checkPermission(userId); 224 boolean sendInitial = false; 225 AppWidgetServiceImpl service; 226 synchronized (mAppWidgetServices) { 227 service = mAppWidgetServices.get(userId); 228 if (service == null) { 229 Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + ", adding"); 230 // TODO: Verify that it's a valid user 231 service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler); 232 service.systemReady(mSafeMode); 233 // Assume that BOOT_COMPLETED was received, as this is a non-primary user. 234 mAppWidgetServices.append(userId, service); 235 sendInitial = true; 236 } 237 } 238 if (sendInitial) { 239 service.sendInitialBroadcasts(); 240 } 241 return service; 242 } 243 244 @Override 245 public int[] getAppWidgetIds(ComponentName provider, int userId) throws RemoteException { 246 return getImplForUser(userId).getAppWidgetIds(provider); 247 } 248 249 @Override 250 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId) 251 throws RemoteException { 252 return getImplForUser(userId).getAppWidgetInfo(appWidgetId); 253 } 254 255 @Override 256 public RemoteViews getAppWidgetViews(int appWidgetId, int userId) throws RemoteException { 257 return getImplForUser(userId).getAppWidgetViews(appWidgetId); 258 } 259 260 @Override 261 public void updateAppWidgetOptions(int appWidgetId, Bundle options, int userId) { 262 getImplForUser(userId).updateAppWidgetOptions(appWidgetId, options); 263 } 264 265 @Override 266 public Bundle getAppWidgetOptions(int appWidgetId, int userId) { 267 return getImplForUser(userId).getAppWidgetOptions(appWidgetId); 268 } 269 270 @Override 271 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId) 272 throws RemoteException { 273 return getImplForUser(userId).getInstalledProviders(categoryFilter); 274 } 275 276 @Override 277 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId, int userId) 278 throws RemoteException { 279 getImplForUser(userId).notifyAppWidgetViewDataChanged( 280 appWidgetIds, viewId); 281 } 282 283 @Override 284 public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId) 285 throws RemoteException { 286 getImplForUser(userId).partiallyUpdateAppWidgetIds( 287 appWidgetIds, views); 288 } 289 290 @Override 291 public void stopListening(int hostId, int userId) throws RemoteException { 292 getImplForUser(userId).stopListening(hostId); 293 } 294 295 @Override 296 public void unbindRemoteViewsService(int appWidgetId, Intent intent, int userId) 297 throws RemoteException { 298 getImplForUser(userId).unbindRemoteViewsService( 299 appWidgetId, intent); 300 } 301 302 @Override 303 public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId) 304 throws RemoteException { 305 getImplForUser(userId).updateAppWidgetIds(appWidgetIds, views); 306 } 307 308 @Override 309 public void updateAppWidgetProvider(ComponentName provider, RemoteViews views, int userId) 310 throws RemoteException { 311 getImplForUser(userId).updateAppWidgetProvider(provider, views); 312 } 313 314 @Override 315 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 316 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 317 318 // Dump the state of all the app widget providers 319 synchronized (mAppWidgetServices) { 320 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 321 for (int i = 0; i < mAppWidgetServices.size(); i++) { 322 pw.println("User: " + mAppWidgetServices.keyAt(i)); 323 ipw.increaseIndent(); 324 AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); 325 service.dump(fd, ipw, args); 326 ipw.decreaseIndent(); 327 } 328 } 329 } 330 331 BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 332 public void onReceive(Context context, Intent intent) { 333 String action = intent.getAction(); 334 // Slog.d(TAG, "received " + action); 335 if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { 336 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 337 if (userId >= 0) { 338 getImplForUser(userId).sendInitialBroadcasts(); 339 } else { 340 Slog.w(TAG, "Incorrect user handle supplied in " + intent); 341 } 342 } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { 343 for (int i = 0; i < mAppWidgetServices.size(); i++) { 344 AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); 345 service.onConfigurationChanged(); 346 } 347 } else { 348 int sendingUser = getSendingUserId(); 349 if (sendingUser == UserHandle.USER_ALL) { 350 for (int i = 0; i < mAppWidgetServices.size(); i++) { 351 AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); 352 service.onBroadcastReceived(intent); 353 } 354 } else { 355 AppWidgetServiceImpl service = mAppWidgetServices.get(sendingUser); 356 if (service != null) { 357 service.onBroadcastReceived(intent); 358 } 359 } 360 } 361 } 362 }; 363} 364