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