blob: 950f34f55d11dd0048142f09c3aa4c5600e32840 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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 android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080020import com.android.internal.util.XmlUtils;
svetoslavganov75986cf2009-05-14 22:28:01 -070021import com.google.android.collect.Maps;
22
23import org.xmlpull.v1.XmlPullParserException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.ContextWrapper;
30import android.content.IContentProvider;
31import android.content.Intent;
32import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070033import android.content.IIntentReceiver;
34import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.ReceiverCallNotAllowedException;
36import android.content.ServiceConnection;
37import android.content.SharedPreferences;
38import android.content.pm.ActivityInfo;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.ComponentInfo;
Dianne Hackborn49237342009-08-27 20:08:01 -070041import android.content.pm.FeatureInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.content.pm.IPackageDataObserver;
43import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.content.pm.IPackageInstallObserver;
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -080045import android.content.pm.IPackageMoveObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070047import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.content.pm.InstrumentationInfo;
49import android.content.pm.PackageInfo;
50import android.content.pm.PackageManager;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
53import android.content.pm.ProviderInfo;
54import android.content.pm.ResolveInfo;
55import android.content.pm.ServiceInfo;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080056import android.content.pm.PackageParser.Package;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.res.AssetManager;
58import android.content.res.Resources;
59import android.content.res.XmlResourceParser;
60import android.database.sqlite.SQLiteDatabase;
61import android.database.sqlite.SQLiteDatabase.CursorFactory;
62import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.graphics.drawable.Drawable;
64import android.hardware.SensorManager;
65import android.location.ILocationManager;
66import android.location.LocationManager;
67import android.media.AudioManager;
68import android.net.ConnectivityManager;
69import android.net.IConnectivityManager;
70import android.net.Uri;
71import android.net.wifi.IWifiManager;
72import android.net.wifi.WifiManager;
73import android.os.Binder;
74import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080075import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080076import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.FileUtils;
78import android.os.Handler;
79import android.os.IBinder;
80import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070081import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.os.PowerManager;
83import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070084import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.os.ServiceManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080086import android.os.StatFs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.Vibrator;
88import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080089import android.os.storage.StorageManager;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080090import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.telephony.TelephonyManager;
92import android.text.ClipboardManager;
93import android.util.AndroidRuntimeException;
94import android.util.Log;
95import android.view.ContextThemeWrapper;
96import android.view.LayoutInflater;
97import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070098import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -0700100import android.accounts.AccountManager;
101import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800102import android.app.admin.DevicePolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103
Dan Egnorf18a01c2009-11-12 11:32:50 -0800104import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import java.io.File;
107import java.io.FileInputStream;
108import java.io.FileNotFoundException;
109import java.io.FileOutputStream;
110import java.io.IOException;
111import java.io.InputStream;
112import java.lang.ref.WeakReference;
113import java.util.ArrayList;
114import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700115import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import java.util.Iterator;
117import java.util.List;
118import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700119import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700120import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121import java.util.Map.Entry;
122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123class ReceiverRestrictedContext extends ContextWrapper {
124 ReceiverRestrictedContext(Context base) {
125 super(base);
126 }
127
128 @Override
129 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
130 return registerReceiver(receiver, filter, null, null);
131 }
132
133 @Override
134 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
135 String broadcastPermission, Handler scheduler) {
136 throw new ReceiverCallNotAllowedException(
137 "IntentReceiver components are not allowed to register to receive intents");
138 //ex.fillInStackTrace();
139 //Log.e("IntentReceiver", ex.getMessage(), ex);
140 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
141 // scheduler);
142 }
143
144 @Override
145 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
146 throw new ReceiverCallNotAllowedException(
147 "IntentReceiver components are not allowed to bind to services");
148 //ex.fillInStackTrace();
149 //Log.e("IntentReceiver", ex.getMessage(), ex);
150 //return mContext.bindService(service, interfaceName, conn, flags);
151 }
152}
153
154/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800155 * Common implementation of Context API, which provides the base
156 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800158class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700160 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 private final static boolean DEBUG_ICONS = false;
162
163 private static final Object sSync = new Object();
164 private static AlarmManager sAlarmManager;
165 private static PowerManager sPowerManager;
166 private static ConnectivityManager sConnectivityManager;
167 private static WifiManager sWifiManager;
168 private static LocationManager sLocationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
170 new HashMap<File, SharedPreferencesImpl>();
171
172 private AudioManager mAudioManager;
173 /*package*/ ActivityThread.PackageInfo mPackageInfo;
174 private Resources mResources;
175 /*package*/ ActivityThread mMainThread;
176 private Context mOuterContext;
177 private IBinder mActivityToken = null;
178 private ApplicationContentResolver mContentResolver;
179 private int mThemeResource = 0;
180 private Resources.Theme mTheme = null;
181 private PackageManager mPackageManager;
182 private NotificationManager mNotificationManager = null;
183 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700184 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 private Context mReceiverRestrictedContext = null;
186 private SearchManager mSearchManager = null;
187 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800188 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 private Vibrator mVibrator = null;
190 private LayoutInflater mLayoutInflater = null;
191 private StatusBarManager mStatusBarManager = null;
192 private TelephonyManager mTelephonyManager = null;
193 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700194 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700195 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800196 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800197 private DevicePolicyManager mDevicePolicyManager = null;
Tobias Haamel53332882010-02-18 16:15:43 -0800198 private UiModeManager mUiModeManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199
200 private final Object mSync = new Object();
201
202 private File mDatabasesDir;
203 private File mPreferencesDir;
204 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800206 private File mExternalFilesDir;
207 private File mExternalCacheDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 private static long sInstanceCount = 0;
210
211 private static final String[] EMPTY_FILE_LIST = {};
212
Carl Shapiro82fe5642010-02-24 00:14:23 -0800213 // For debug only
214 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 @Override
216 protected void finalize() throws Throwable {
217 super.finalize();
218 --sInstanceCount;
219 }
Carl Shapiro82fe5642010-02-24 00:14:23 -0800220 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
222 public static long getInstanceCount() {
223 return sInstanceCount;
224 }
225
226 @Override
227 public AssetManager getAssets() {
228 return mResources.getAssets();
229 }
230
231 @Override
232 public Resources getResources() {
233 return mResources;
234 }
235
236 @Override
237 public PackageManager getPackageManager() {
238 if (mPackageManager != null) {
239 return mPackageManager;
240 }
241
242 IPackageManager pm = ActivityThread.getPackageManager();
243 if (pm != null) {
244 // Doesn't matter if we make more than one instance.
245 return (mPackageManager = new ApplicationPackageManager(this, pm));
246 }
247
248 return null;
249 }
250
251 @Override
252 public ContentResolver getContentResolver() {
253 return mContentResolver;
254 }
255
256 @Override
257 public Looper getMainLooper() {
258 return mMainThread.getLooper();
259 }
260
261 @Override
262 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700263 return (mPackageInfo != null) ?
264 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
266
267 @Override
268 public void setTheme(int resid) {
269 mThemeResource = resid;
270 }
271
272 @Override
273 public Resources.Theme getTheme() {
274 if (mTheme == null) {
275 if (mThemeResource == 0) {
276 mThemeResource = com.android.internal.R.style.Theme;
277 }
278 mTheme = mResources.newTheme();
279 mTheme.applyStyle(mThemeResource, true);
280 }
281 return mTheme;
282 }
283
284 @Override
285 public ClassLoader getClassLoader() {
286 return mPackageInfo != null ?
287 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
288 }
289
290 @Override
291 public String getPackageName() {
292 if (mPackageInfo != null) {
293 return mPackageInfo.getPackageName();
294 }
295 throw new RuntimeException("Not supported in system context");
296 }
297
298 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700299 public ApplicationInfo getApplicationInfo() {
300 if (mPackageInfo != null) {
301 return mPackageInfo.getApplicationInfo();
302 }
303 throw new RuntimeException("Not supported in system context");
304 }
305
306 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 public String getPackageResourcePath() {
308 if (mPackageInfo != null) {
309 return mPackageInfo.getResDir();
310 }
311 throw new RuntimeException("Not supported in system context");
312 }
313
314 @Override
315 public String getPackageCodePath() {
316 if (mPackageInfo != null) {
317 return mPackageInfo.getAppDir();
318 }
319 throw new RuntimeException("Not supported in system context");
320 }
321
322 private static File makeBackupFile(File prefsFile) {
323 return new File(prefsFile.getPath() + ".bak");
324 }
325
Joe Onorato23ecae32009-06-10 17:07:15 -0700326 public File getSharedPrefsFile(String name) {
327 return makeFilename(getPreferencesDir(), name + ".xml");
328 }
329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 @Override
331 public SharedPreferences getSharedPreferences(String name, int mode) {
332 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700333 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 synchronized (sSharedPrefs) {
335 sp = sSharedPrefs.get(f);
336 if (sp != null && !sp.hasFileChanged()) {
337 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
338 return sp;
339 }
340 }
341
342 FileInputStream str = null;
343 File backup = makeBackupFile(f);
344 if (backup.exists()) {
345 f.delete();
346 backup.renameTo(f);
347 }
348
349 // Debugging
350 if (f.exists() && !f.canRead()) {
351 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
352 }
353
354 Map map = null;
355 if (f.exists() && f.canRead()) {
356 try {
357 str = new FileInputStream(f);
358 map = XmlUtils.readMapXml(str);
359 str.close();
360 } catch (org.xmlpull.v1.XmlPullParserException e) {
361 Log.w(TAG, "getSharedPreferences", e);
362 } catch (FileNotFoundException e) {
363 Log.w(TAG, "getSharedPreferences", e);
364 } catch (IOException e) {
365 Log.w(TAG, "getSharedPreferences", e);
366 }
367 }
368
369 synchronized (sSharedPrefs) {
370 if (sp != null) {
371 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
372 sp.replace(map);
373 } else {
374 sp = sSharedPrefs.get(f);
375 if (sp == null) {
376 sp = new SharedPreferencesImpl(f, mode, map);
377 sSharedPrefs.put(f, sp);
378 }
379 }
380 return sp;
381 }
382 }
383
384 private File getPreferencesDir() {
385 synchronized (mSync) {
386 if (mPreferencesDir == null) {
387 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
388 }
389 return mPreferencesDir;
390 }
391 }
392
393 @Override
394 public FileInputStream openFileInput(String name)
395 throws FileNotFoundException {
396 File f = makeFilename(getFilesDir(), name);
397 return new FileInputStream(f);
398 }
399
400 @Override
401 public FileOutputStream openFileOutput(String name, int mode)
402 throws FileNotFoundException {
403 final boolean append = (mode&MODE_APPEND) != 0;
404 File f = makeFilename(getFilesDir(), name);
405 try {
406 FileOutputStream fos = new FileOutputStream(f, append);
407 setFilePermissionsFromMode(f.getPath(), mode, 0);
408 return fos;
409 } catch (FileNotFoundException e) {
410 }
411
412 File parent = f.getParentFile();
413 parent.mkdir();
414 FileUtils.setPermissions(
415 parent.getPath(),
416 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
417 -1, -1);
418 FileOutputStream fos = new FileOutputStream(f, append);
419 setFilePermissionsFromMode(f.getPath(), mode, 0);
420 return fos;
421 }
422
423 @Override
424 public boolean deleteFile(String name) {
425 File f = makeFilename(getFilesDir(), name);
426 return f.delete();
427 }
428
429 @Override
430 public File getFilesDir() {
431 synchronized (mSync) {
432 if (mFilesDir == null) {
433 mFilesDir = new File(getDataDirFile(), "files");
434 }
435 if (!mFilesDir.exists()) {
436 if(!mFilesDir.mkdirs()) {
437 Log.w(TAG, "Unable to create files directory");
438 return null;
439 }
440 FileUtils.setPermissions(
441 mFilesDir.getPath(),
442 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
443 -1, -1);
444 }
445 return mFilesDir;
446 }
447 }
448
449 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800450 public File getExternalFilesDir(String type) {
451 synchronized (mSync) {
452 if (mExternalFilesDir == null) {
453 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
454 getPackageName());
455 }
456 if (!mExternalFilesDir.exists()) {
457 try {
458 (new File(Environment.getExternalStorageAndroidDataDir(),
459 ".nomedia")).createNewFile();
460 } catch (IOException e) {
461 }
462 if (!mExternalFilesDir.mkdirs()) {
463 Log.w(TAG, "Unable to create external files directory");
464 return null;
465 }
466 }
467 if (type == null) {
468 return mExternalFilesDir;
469 }
470 File dir = new File(mExternalFilesDir, type);
471 if (!dir.exists()) {
472 if (!dir.mkdirs()) {
473 Log.w(TAG, "Unable to create external media directory " + dir);
474 return null;
475 }
476 }
477 return dir;
478 }
479 }
480
481 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 public File getCacheDir() {
483 synchronized (mSync) {
484 if (mCacheDir == null) {
485 mCacheDir = new File(getDataDirFile(), "cache");
486 }
487 if (!mCacheDir.exists()) {
488 if(!mCacheDir.mkdirs()) {
489 Log.w(TAG, "Unable to create cache directory");
490 return null;
491 }
492 FileUtils.setPermissions(
493 mCacheDir.getPath(),
494 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
495 -1, -1);
496 }
497 }
498 return mCacheDir;
499 }
500
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800501 @Override
502 public File getExternalCacheDir() {
503 synchronized (mSync) {
504 if (mExternalCacheDir == null) {
505 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
506 getPackageName());
507 }
508 if (!mExternalCacheDir.exists()) {
509 try {
510 (new File(Environment.getExternalStorageAndroidDataDir(),
511 ".nomedia")).createNewFile();
512 } catch (IOException e) {
513 }
514 if (!mExternalCacheDir.mkdirs()) {
515 Log.w(TAG, "Unable to create external cache directory");
516 return null;
517 }
518 }
519 return mExternalCacheDir;
520 }
521 }
522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 @Override
524 public File getFileStreamPath(String name) {
525 return makeFilename(getFilesDir(), name);
526 }
527
528 @Override
529 public String[] fileList() {
530 final String[] list = getFilesDir().list();
531 return (list != null) ? list : EMPTY_FILE_LIST;
532 }
533
534 @Override
535 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800536 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
538 setFilePermissionsFromMode(f.getPath(), mode, 0);
539 return db;
540 }
541
542 @Override
543 public boolean deleteDatabase(String name) {
544 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800545 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 return f.delete();
547 } catch (Exception e) {
548 }
549 return false;
550 }
551
552 @Override
553 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800554 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 }
556
557 @Override
558 public String[] databaseList() {
559 final String[] list = getDatabasesDir().list();
560 return (list != null) ? list : EMPTY_FILE_LIST;
561 }
562
563
564 private File getDatabasesDir() {
565 synchronized (mSync) {
566 if (mDatabasesDir == null) {
567 mDatabasesDir = new File(getDataDirFile(), "databases");
568 }
569 if (mDatabasesDir.getPath().equals("databases")) {
570 mDatabasesDir = new File("/data/system");
571 }
572 return mDatabasesDir;
573 }
574 }
575
576 @Override
577 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700578 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 }
580
581 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700582 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700583 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 }
585
586 @Override
587 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700588 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 }
590
591 @Override
592 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700593 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595
596 @Override
597 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700598 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 }
600
601 @Override
602 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700603 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
605
606 @Override
607 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700608 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
610
611 @Override
612 public void startActivity(Intent intent) {
613 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
614 throw new AndroidRuntimeException(
615 "Calling startActivity() from outside of an Activity "
616 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
617 + " Is this really what you want?");
618 }
619 mMainThread.getInstrumentation().execStartActivity(
620 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
621 }
622
623 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700624 public void startIntentSender(IntentSender intent,
625 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
626 throws IntentSender.SendIntentException {
627 try {
628 String resolvedType = null;
629 if (fillInIntent != null) {
630 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
631 }
632 int result = ActivityManagerNative.getDefault()
633 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
634 fillInIntent, resolvedType, null, null,
635 0, flagsMask, flagsValues);
636 if (result == IActivityManager.START_CANCELED) {
637 throw new IntentSender.SendIntentException();
638 }
639 Instrumentation.checkStartActivityResult(result, null);
640 } catch (RemoteException e) {
641 }
642 }
643
644 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 public void sendBroadcast(Intent intent) {
646 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
647 try {
648 ActivityManagerNative.getDefault().broadcastIntent(
649 mMainThread.getApplicationThread(), intent, resolvedType, null,
650 Activity.RESULT_OK, null, null, null, false, false);
651 } catch (RemoteException e) {
652 }
653 }
654
655 @Override
656 public void sendBroadcast(Intent intent, String receiverPermission) {
657 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
658 try {
659 ActivityManagerNative.getDefault().broadcastIntent(
660 mMainThread.getApplicationThread(), intent, resolvedType, null,
661 Activity.RESULT_OK, null, null, receiverPermission, false, false);
662 } catch (RemoteException e) {
663 }
664 }
665
666 @Override
667 public void sendOrderedBroadcast(Intent intent,
668 String receiverPermission) {
669 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
670 try {
671 ActivityManagerNative.getDefault().broadcastIntent(
672 mMainThread.getApplicationThread(), intent, resolvedType, null,
673 Activity.RESULT_OK, null, null, receiverPermission, true, false);
674 } catch (RemoteException e) {
675 }
676 }
677
678 @Override
679 public void sendOrderedBroadcast(Intent intent,
680 String receiverPermission, BroadcastReceiver resultReceiver,
681 Handler scheduler, int initialCode, String initialData,
682 Bundle initialExtras) {
683 IIntentReceiver rd = null;
684 if (resultReceiver != null) {
685 if (mPackageInfo != null) {
686 if (scheduler == null) {
687 scheduler = mMainThread.getHandler();
688 }
689 rd = mPackageInfo.getReceiverDispatcher(
690 resultReceiver, getOuterContext(), scheduler,
691 mMainThread.getInstrumentation(), false);
692 } else {
693 if (scheduler == null) {
694 scheduler = mMainThread.getHandler();
695 }
696 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
697 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
698 }
699 }
700 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
701 try {
702 ActivityManagerNative.getDefault().broadcastIntent(
703 mMainThread.getApplicationThread(), intent, resolvedType, rd,
704 initialCode, initialData, initialExtras, receiverPermission,
705 true, false);
706 } catch (RemoteException e) {
707 }
708 }
709
710 @Override
711 public void sendStickyBroadcast(Intent intent) {
712 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
713 try {
714 ActivityManagerNative.getDefault().broadcastIntent(
715 mMainThread.getApplicationThread(), intent, resolvedType, null,
716 Activity.RESULT_OK, null, null, null, false, true);
717 } catch (RemoteException e) {
718 }
719 }
720
721 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700722 public void sendStickyOrderedBroadcast(Intent intent,
723 BroadcastReceiver resultReceiver,
724 Handler scheduler, int initialCode, String initialData,
725 Bundle initialExtras) {
726 IIntentReceiver rd = null;
727 if (resultReceiver != null) {
728 if (mPackageInfo != null) {
729 if (scheduler == null) {
730 scheduler = mMainThread.getHandler();
731 }
732 rd = mPackageInfo.getReceiverDispatcher(
733 resultReceiver, getOuterContext(), scheduler,
734 mMainThread.getInstrumentation(), false);
735 } else {
736 if (scheduler == null) {
737 scheduler = mMainThread.getHandler();
738 }
739 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
740 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
741 }
742 }
743 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
744 try {
745 ActivityManagerNative.getDefault().broadcastIntent(
746 mMainThread.getApplicationThread(), intent, resolvedType, rd,
747 initialCode, initialData, initialExtras, null,
748 true, true);
749 } catch (RemoteException e) {
750 }
751 }
752
753 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 public void removeStickyBroadcast(Intent intent) {
755 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
756 if (resolvedType != null) {
757 intent = new Intent(intent);
758 intent.setDataAndType(intent.getData(), resolvedType);
759 }
760 try {
761 ActivityManagerNative.getDefault().unbroadcastIntent(
762 mMainThread.getApplicationThread(), intent);
763 } catch (RemoteException e) {
764 }
765 }
766
767 @Override
768 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
769 return registerReceiver(receiver, filter, null, null);
770 }
771
772 @Override
773 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
774 String broadcastPermission, Handler scheduler) {
775 return registerReceiverInternal(receiver, filter, broadcastPermission,
776 scheduler, getOuterContext());
777 }
778
779 private Intent registerReceiverInternal(BroadcastReceiver receiver,
780 IntentFilter filter, String broadcastPermission,
781 Handler scheduler, Context context) {
782 IIntentReceiver rd = null;
783 if (receiver != null) {
784 if (mPackageInfo != null && context != null) {
785 if (scheduler == null) {
786 scheduler = mMainThread.getHandler();
787 }
788 rd = mPackageInfo.getReceiverDispatcher(
789 receiver, context, scheduler,
790 mMainThread.getInstrumentation(), true);
791 } else {
792 if (scheduler == null) {
793 scheduler = mMainThread.getHandler();
794 }
795 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
796 receiver, context, scheduler, null, false).getIIntentReceiver();
797 }
798 }
799 try {
800 return ActivityManagerNative.getDefault().registerReceiver(
801 mMainThread.getApplicationThread(),
802 rd, filter, broadcastPermission);
803 } catch (RemoteException e) {
804 return null;
805 }
806 }
807
808 @Override
809 public void unregisterReceiver(BroadcastReceiver receiver) {
810 if (mPackageInfo != null) {
811 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
812 getOuterContext(), receiver);
813 try {
814 ActivityManagerNative.getDefault().unregisterReceiver(rd);
815 } catch (RemoteException e) {
816 }
817 } else {
818 throw new RuntimeException("Not supported in system context");
819 }
820 }
821
822 @Override
823 public ComponentName startService(Intent service) {
824 try {
825 ComponentName cn = ActivityManagerNative.getDefault().startService(
826 mMainThread.getApplicationThread(), service,
827 service.resolveTypeIfNeeded(getContentResolver()));
828 if (cn != null && cn.getPackageName().equals("!")) {
829 throw new SecurityException(
830 "Not allowed to start service " + service
831 + " without permission " + cn.getClassName());
832 }
833 return cn;
834 } catch (RemoteException e) {
835 return null;
836 }
837 }
838
839 @Override
840 public boolean stopService(Intent service) {
841 try {
842 int res = ActivityManagerNative.getDefault().stopService(
843 mMainThread.getApplicationThread(), service,
844 service.resolveTypeIfNeeded(getContentResolver()));
845 if (res < 0) {
846 throw new SecurityException(
847 "Not allowed to stop service " + service);
848 }
849 return res != 0;
850 } catch (RemoteException e) {
851 return false;
852 }
853 }
854
855 @Override
856 public boolean bindService(Intent service, ServiceConnection conn,
857 int flags) {
858 IServiceConnection sd;
859 if (mPackageInfo != null) {
860 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
861 mMainThread.getHandler(), flags);
862 } else {
863 throw new RuntimeException("Not supported in system context");
864 }
865 try {
866 int res = ActivityManagerNative.getDefault().bindService(
867 mMainThread.getApplicationThread(), getActivityToken(),
868 service, service.resolveTypeIfNeeded(getContentResolver()),
869 sd, flags);
870 if (res < 0) {
871 throw new SecurityException(
872 "Not allowed to bind to service " + service);
873 }
874 return res != 0;
875 } catch (RemoteException e) {
876 return false;
877 }
878 }
879
880 @Override
881 public void unbindService(ServiceConnection conn) {
882 if (mPackageInfo != null) {
883 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
884 getOuterContext(), conn);
885 try {
886 ActivityManagerNative.getDefault().unbindService(sd);
887 } catch (RemoteException e) {
888 }
889 } else {
890 throw new RuntimeException("Not supported in system context");
891 }
892 }
893
894 @Override
895 public boolean startInstrumentation(ComponentName className,
896 String profileFile, Bundle arguments) {
897 try {
898 return ActivityManagerNative.getDefault().startInstrumentation(
899 className, profileFile, 0, arguments, null);
900 } catch (RemoteException e) {
901 // System has crashed, nothing we can do.
902 }
903 return false;
904 }
905
906 @Override
907 public Object getSystemService(String name) {
908 if (WINDOW_SERVICE.equals(name)) {
909 return WindowManagerImpl.getDefault();
910 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
911 synchronized (mSync) {
912 LayoutInflater inflater = mLayoutInflater;
913 if (inflater != null) {
914 return inflater;
915 }
916 mLayoutInflater = inflater =
917 PolicyManager.makeNewLayoutInflater(getOuterContext());
918 return inflater;
919 }
920 } else if (ACTIVITY_SERVICE.equals(name)) {
921 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700922 } else if (INPUT_METHOD_SERVICE.equals(name)) {
923 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 } else if (ALARM_SERVICE.equals(name)) {
925 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700926 } else if (ACCOUNT_SERVICE.equals(name)) {
927 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 } else if (POWER_SERVICE.equals(name)) {
929 return getPowerManager();
930 } else if (CONNECTIVITY_SERVICE.equals(name)) {
931 return getConnectivityManager();
932 } else if (WIFI_SERVICE.equals(name)) {
933 return getWifiManager();
934 } else if (NOTIFICATION_SERVICE.equals(name)) {
935 return getNotificationManager();
936 } else if (KEYGUARD_SERVICE.equals(name)) {
937 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700938 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
939 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 } else if (LOCATION_SERVICE.equals(name)) {
941 return getLocationManager();
942 } else if (SEARCH_SERVICE.equals(name)) {
943 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700944 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800946 } else if (STORAGE_SERVICE.equals(name)) {
947 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 } else if (VIBRATOR_SERVICE.equals(name)) {
949 return getVibrator();
950 } else if (STATUS_BAR_SERVICE.equals(name)) {
951 synchronized (mSync) {
952 if (mStatusBarManager == null) {
953 mStatusBarManager = new StatusBarManager(getOuterContext());
954 }
955 return mStatusBarManager;
956 }
957 } else if (AUDIO_SERVICE.equals(name)) {
958 return getAudioManager();
959 } else if (TELEPHONY_SERVICE.equals(name)) {
960 return getTelephonyManager();
961 } else if (CLIPBOARD_SERVICE.equals(name)) {
962 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700963 } else if (WALLPAPER_SERVICE.equals(name)) {
964 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700965 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800966 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800967 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
968 return getDevicePolicyManager();
Tobias Haamel69fb5742010-02-22 21:54:05 +0100969 } else if (UI_MODE_SERVICE.equals(name)) {
Tobias Haamel53332882010-02-18 16:15:43 -0800970 return getUiModeManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 }
972
973 return null;
974 }
975
Fred Quintana60307342009-03-24 22:48:12 -0700976 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700977 synchronized (mSync) {
978 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -0700979 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
980 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -0700981 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -0700982 }
Fred Quintanae00a3112009-09-22 15:13:30 -0700983 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -0700984 }
Fred Quintana60307342009-03-24 22:48:12 -0700985 }
986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 private ActivityManager getActivityManager() {
988 synchronized (mSync) {
989 if (mActivityManager == null) {
990 mActivityManager = new ActivityManager(getOuterContext(),
991 mMainThread.getHandler());
992 }
993 }
994 return mActivityManager;
995 }
996
997 private AlarmManager getAlarmManager() {
998 synchronized (sSync) {
999 if (sAlarmManager == null) {
1000 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1001 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1002 sAlarmManager = new AlarmManager(service);
1003 }
1004 }
1005 return sAlarmManager;
1006 }
1007
1008 private PowerManager getPowerManager() {
1009 synchronized (sSync) {
1010 if (sPowerManager == null) {
1011 IBinder b = ServiceManager.getService(POWER_SERVICE);
1012 IPowerManager service = IPowerManager.Stub.asInterface(b);
1013 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1014 }
1015 }
1016 return sPowerManager;
1017 }
1018
1019 private ConnectivityManager getConnectivityManager()
1020 {
1021 synchronized (sSync) {
1022 if (sConnectivityManager == null) {
1023 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1024 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1025 sConnectivityManager = new ConnectivityManager(service);
1026 }
1027 }
1028 return sConnectivityManager;
1029 }
1030
1031 private WifiManager getWifiManager()
1032 {
1033 synchronized (sSync) {
1034 if (sWifiManager == null) {
1035 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1036 IWifiManager service = IWifiManager.Stub.asInterface(b);
1037 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1038 }
1039 }
1040 return sWifiManager;
1041 }
1042
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001043 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 synchronized (mSync) {
1045 if (mNotificationManager == null) {
1046 mNotificationManager = new NotificationManager(
1047 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1048 mMainThread.getHandler());
1049 }
1050 }
1051 return mNotificationManager;
1052 }
1053
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001054 private WallpaperManager getWallpaperManager() {
1055 synchronized (mSync) {
1056 if (mWallpaperManager == null) {
1057 mWallpaperManager = new WallpaperManager(getOuterContext(),
1058 mMainThread.getHandler());
1059 }
1060 }
1061 return mWallpaperManager;
1062 }
1063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 private TelephonyManager getTelephonyManager() {
1065 synchronized (mSync) {
1066 if (mTelephonyManager == null) {
1067 mTelephonyManager = new TelephonyManager(getOuterContext());
1068 }
1069 }
1070 return mTelephonyManager;
1071 }
1072
1073 private ClipboardManager getClipboardManager() {
1074 synchronized (mSync) {
1075 if (mClipboardManager == null) {
1076 mClipboardManager = new ClipboardManager(getOuterContext(),
1077 mMainThread.getHandler());
1078 }
1079 }
1080 return mClipboardManager;
1081 }
1082
1083 private LocationManager getLocationManager() {
1084 synchronized (sSync) {
1085 if (sLocationManager == null) {
1086 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1087 ILocationManager service = ILocationManager.Stub.asInterface(b);
1088 sLocationManager = new LocationManager(service);
1089 }
1090 }
1091 return sLocationManager;
1092 }
1093
1094 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 synchronized (mSync) {
1096 if (mSearchManager == null) {
1097 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1098 }
1099 }
1100 return mSearchManager;
1101 }
1102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 private SensorManager getSensorManager() {
1104 synchronized (mSync) {
1105 if (mSensorManager == null) {
1106 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1107 }
1108 }
1109 return mSensorManager;
1110 }
1111
San Mehatc9d81752010-02-01 10:23:27 -08001112 private StorageManager getStorageManager() {
1113 synchronized (mSync) {
1114 if (mStorageManager == null) {
1115 try {
1116 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1117 } catch (RemoteException rex) {
1118 Log.e(TAG, "Failed to create StorageManager", rex);
1119 mStorageManager = null;
1120 }
1121 }
1122 }
1123 return mStorageManager;
1124 }
1125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 private Vibrator getVibrator() {
1127 synchronized (mSync) {
1128 if (mVibrator == null) {
1129 mVibrator = new Vibrator();
1130 }
1131 }
1132 return mVibrator;
1133 }
Dan Egnor95240272009-10-27 18:23:39 -07001134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 private AudioManager getAudioManager()
1136 {
1137 if (mAudioManager == null) {
1138 mAudioManager = new AudioManager(this);
1139 }
1140 return mAudioManager;
1141 }
1142
Dan Egnorf18a01c2009-11-12 11:32:50 -08001143 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001144 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001145 if (mDropBoxManager == null) {
Dan Egnor95240272009-10-27 18:23:39 -07001146 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
Dan Egnorf18a01c2009-11-12 11:32:50 -08001147 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1148 mDropBoxManager = new DropBoxManager(service);
Dan Egnor95240272009-10-27 18:23:39 -07001149 }
1150 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001151 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001152 }
1153
Dianne Hackbornd6847842010-01-12 18:14:19 -08001154 private DevicePolicyManager getDevicePolicyManager() {
1155 synchronized (mSync) {
1156 if (mDevicePolicyManager == null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001157 mDevicePolicyManager = DevicePolicyManager.create(this,
Dianne Hackbornd6847842010-01-12 18:14:19 -08001158 mMainThread.getHandler());
1159 }
1160 }
1161 return mDevicePolicyManager;
1162 }
1163
Tobias Haamel53332882010-02-18 16:15:43 -08001164 private UiModeManager getUiModeManager() {
1165 synchronized (mSync) {
1166 if (mUiModeManager == null) {
1167 mUiModeManager = new UiModeManager();
1168 }
1169 }
1170 return mUiModeManager;
1171 }
1172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 @Override
1174 public int checkPermission(String permission, int pid, int uid) {
1175 if (permission == null) {
1176 throw new IllegalArgumentException("permission is null");
1177 }
1178
1179 if (!Process.supportsProcesses()) {
1180 return PackageManager.PERMISSION_GRANTED;
1181 }
1182 try {
1183 return ActivityManagerNative.getDefault().checkPermission(
1184 permission, pid, uid);
1185 } catch (RemoteException e) {
1186 return PackageManager.PERMISSION_DENIED;
1187 }
1188 }
1189
1190 @Override
1191 public int checkCallingPermission(String permission) {
1192 if (permission == null) {
1193 throw new IllegalArgumentException("permission is null");
1194 }
1195
1196 if (!Process.supportsProcesses()) {
1197 return PackageManager.PERMISSION_GRANTED;
1198 }
1199 int pid = Binder.getCallingPid();
1200 if (pid != Process.myPid()) {
1201 return checkPermission(permission, pid,
1202 Binder.getCallingUid());
1203 }
1204 return PackageManager.PERMISSION_DENIED;
1205 }
1206
1207 @Override
1208 public int checkCallingOrSelfPermission(String permission) {
1209 if (permission == null) {
1210 throw new IllegalArgumentException("permission is null");
1211 }
1212
1213 return checkPermission(permission, Binder.getCallingPid(),
1214 Binder.getCallingUid());
1215 }
1216
1217 private void enforce(
1218 String permission, int resultOfCheck,
1219 boolean selfToo, int uid, String message) {
1220 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1221 throw new SecurityException(
1222 (message != null ? (message + ": ") : "") +
1223 (selfToo
1224 ? "Neither user " + uid + " nor current process has "
1225 : "User " + uid + " does not have ") +
1226 permission +
1227 ".");
1228 }
1229 }
1230
1231 public void enforcePermission(
1232 String permission, int pid, int uid, String message) {
1233 enforce(permission,
1234 checkPermission(permission, pid, uid),
1235 false,
1236 uid,
1237 message);
1238 }
1239
1240 public void enforceCallingPermission(String permission, String message) {
1241 enforce(permission,
1242 checkCallingPermission(permission),
1243 false,
1244 Binder.getCallingUid(),
1245 message);
1246 }
1247
1248 public void enforceCallingOrSelfPermission(
1249 String permission, String message) {
1250 enforce(permission,
1251 checkCallingOrSelfPermission(permission),
1252 true,
1253 Binder.getCallingUid(),
1254 message);
1255 }
1256
1257 @Override
1258 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1259 try {
1260 ActivityManagerNative.getDefault().grantUriPermission(
1261 mMainThread.getApplicationThread(), toPackage, uri,
1262 modeFlags);
1263 } catch (RemoteException e) {
1264 }
1265 }
1266
1267 @Override
1268 public void revokeUriPermission(Uri uri, int modeFlags) {
1269 try {
1270 ActivityManagerNative.getDefault().revokeUriPermission(
1271 mMainThread.getApplicationThread(), uri,
1272 modeFlags);
1273 } catch (RemoteException e) {
1274 }
1275 }
1276
1277 @Override
1278 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1279 if (!Process.supportsProcesses()) {
1280 return PackageManager.PERMISSION_GRANTED;
1281 }
1282 try {
1283 return ActivityManagerNative.getDefault().checkUriPermission(
1284 uri, pid, uid, modeFlags);
1285 } catch (RemoteException e) {
1286 return PackageManager.PERMISSION_DENIED;
1287 }
1288 }
1289
1290 @Override
1291 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1292 if (!Process.supportsProcesses()) {
1293 return PackageManager.PERMISSION_GRANTED;
1294 }
1295 int pid = Binder.getCallingPid();
1296 if (pid != Process.myPid()) {
1297 return checkUriPermission(uri, pid,
1298 Binder.getCallingUid(), modeFlags);
1299 }
1300 return PackageManager.PERMISSION_DENIED;
1301 }
1302
1303 @Override
1304 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1305 return checkUriPermission(uri, Binder.getCallingPid(),
1306 Binder.getCallingUid(), modeFlags);
1307 }
1308
1309 @Override
1310 public int checkUriPermission(Uri uri, String readPermission,
1311 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001312 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1314 + readPermission + " writePermission=" + writePermission
1315 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1316 }
1317 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1318 if (readPermission == null
1319 || checkPermission(readPermission, pid, uid)
1320 == PackageManager.PERMISSION_GRANTED) {
1321 return PackageManager.PERMISSION_GRANTED;
1322 }
1323 }
1324 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1325 if (writePermission == null
1326 || checkPermission(writePermission, pid, uid)
1327 == PackageManager.PERMISSION_GRANTED) {
1328 return PackageManager.PERMISSION_GRANTED;
1329 }
1330 }
1331 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1332 : PackageManager.PERMISSION_DENIED;
1333 }
1334
1335 private String uriModeFlagToString(int uriModeFlags) {
1336 switch (uriModeFlags) {
1337 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1338 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1339 return "read and write";
1340 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1341 return "read";
1342 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1343 return "write";
1344 }
1345 throw new IllegalArgumentException(
1346 "Unknown permission mode flags: " + uriModeFlags);
1347 }
1348
1349 private void enforceForUri(
1350 int modeFlags, int resultOfCheck, boolean selfToo,
1351 int uid, Uri uri, String message) {
1352 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1353 throw new SecurityException(
1354 (message != null ? (message + ": ") : "") +
1355 (selfToo
1356 ? "Neither user " + uid + " nor current process has "
1357 : "User " + uid + " does not have ") +
1358 uriModeFlagToString(modeFlags) +
1359 " permission on " +
1360 uri +
1361 ".");
1362 }
1363 }
1364
1365 public void enforceUriPermission(
1366 Uri uri, int pid, int uid, int modeFlags, String message) {
1367 enforceForUri(
1368 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1369 false, uid, uri, message);
1370 }
1371
1372 public void enforceCallingUriPermission(
1373 Uri uri, int modeFlags, String message) {
1374 enforceForUri(
1375 modeFlags, checkCallingUriPermission(uri, modeFlags),
1376 false, Binder.getCallingUid(), uri, message);
1377 }
1378
1379 public void enforceCallingOrSelfUriPermission(
1380 Uri uri, int modeFlags, String message) {
1381 enforceForUri(
1382 modeFlags,
1383 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1384 Binder.getCallingUid(), uri, message);
1385 }
1386
1387 public void enforceUriPermission(
1388 Uri uri, String readPermission, String writePermission,
1389 int pid, int uid, int modeFlags, String message) {
1390 enforceForUri(modeFlags,
1391 checkUriPermission(
1392 uri, readPermission, writePermission, pid, uid,
1393 modeFlags),
1394 false,
1395 uid,
1396 uri,
1397 message);
1398 }
1399
1400 @Override
1401 public Context createPackageContext(String packageName, int flags)
1402 throws PackageManager.NameNotFoundException {
1403 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001404 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
1406
1407 ActivityThread.PackageInfo pi =
1408 mMainThread.getPackageInfo(packageName, flags);
1409 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001410 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001411 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001412 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 if (c.mResources != null) {
1414 return c;
1415 }
1416 }
1417
1418 // Should be a better exception.
1419 throw new PackageManager.NameNotFoundException(
1420 "Application package " + packageName + " not found");
1421 }
1422
Romain Guy870e09f2009-07-06 16:35:25 -07001423 @Override
1424 public boolean isRestricted() {
1425 return mRestricted;
1426 }
1427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 private File getDataDirFile() {
1429 if (mPackageInfo != null) {
1430 return mPackageInfo.getDataDirFile();
1431 }
1432 throw new RuntimeException("Not supported in system context");
1433 }
1434
1435 @Override
1436 public File getDir(String name, int mode) {
1437 name = "app_" + name;
1438 File file = makeFilename(getDataDirFile(), name);
1439 if (!file.exists()) {
1440 file.mkdir();
1441 setFilePermissionsFromMode(file.getPath(), mode,
1442 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1443 }
1444 return file;
1445 }
1446
Dianne Hackborn21556372010-02-04 16:34:40 -08001447 static ContextImpl createSystemContext(ActivityThread mainThread) {
1448 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 context.init(Resources.getSystem(), mainThread);
1450 return context;
1451 }
1452
Dianne Hackborn21556372010-02-04 16:34:40 -08001453 ContextImpl() {
Carl Shapiro82fe5642010-02-24 00:14:23 -08001454 // For debug only
1455 //++sInstanceCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 mOuterContext = this;
1457 }
1458
1459 /**
1460 * Create a new ApplicationContext from an existing one. The new one
1461 * works and operates the same as the one it is copying.
1462 *
1463 * @param context Existing application context.
1464 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001465 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 ++sInstanceCount;
1467 mPackageInfo = context.mPackageInfo;
1468 mResources = context.mResources;
1469 mMainThread = context.mMainThread;
1470 mContentResolver = context.mContentResolver;
1471 mOuterContext = this;
1472 }
1473
1474 final void init(ActivityThread.PackageInfo packageInfo,
1475 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001476 init(packageInfo, activityToken, mainThread, null);
1477 }
1478
1479 final void init(ActivityThread.PackageInfo packageInfo,
1480 IBinder activityToken, ActivityThread mainThread,
1481 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 mPackageInfo = packageInfo;
1483 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001484
Dianne Hackborn559a7872010-04-07 18:19:41 -07001485 if (mResources != null && container != null
1486 && container.getCompatibilityInfo().applicationScale !=
1487 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001488 if (DEBUG) {
1489 Log.d(TAG, "loaded context has different scaling. Using container's" +
1490 " compatiblity info:" + container.getDisplayMetrics());
1491 }
1492 mResources = mainThread.getTopLevelResources(
1493 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 mMainThread = mainThread;
1496 mContentResolver = new ApplicationContentResolver(this, mainThread);
1497
1498 setActivityToken(activityToken);
1499 }
1500
1501 final void init(Resources resources, ActivityThread mainThread) {
1502 mPackageInfo = null;
1503 mResources = resources;
1504 mMainThread = mainThread;
1505 mContentResolver = new ApplicationContentResolver(this, mainThread);
1506 }
1507
1508 final void scheduleFinalCleanup(String who, String what) {
1509 mMainThread.scheduleContextCleanup(this, who, what);
1510 }
1511
1512 final void performFinalCleanup(String who, String what) {
1513 //Log.i(TAG, "Cleanup up context: " + this);
1514 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1515 }
1516
1517 final Context getReceiverRestrictedContext() {
1518 if (mReceiverRestrictedContext != null) {
1519 return mReceiverRestrictedContext;
1520 }
1521 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1522 }
1523
1524 final void setActivityToken(IBinder token) {
1525 mActivityToken = token;
1526 }
1527
1528 final void setOuterContext(Context context) {
1529 mOuterContext = context;
1530 }
1531
1532 final Context getOuterContext() {
1533 return mOuterContext;
1534 }
1535
1536 final IBinder getActivityToken() {
1537 return mActivityToken;
1538 }
1539
1540 private static void setFilePermissionsFromMode(String name, int mode,
1541 int extraPermissions) {
1542 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1543 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1544 |extraPermissions;
1545 if ((mode&MODE_WORLD_READABLE) != 0) {
1546 perms |= FileUtils.S_IROTH;
1547 }
1548 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1549 perms |= FileUtils.S_IWOTH;
1550 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001551 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1553 + ", perms=0x" + Integer.toHexString(perms));
1554 }
1555 FileUtils.setPermissions(name, perms, -1, -1);
1556 }
1557
Oscar Montemayora8529f62009-11-18 10:14:20 -08001558 private File validateFilePath(String name, boolean createDirectory) {
1559 File dir;
1560 File f;
1561
1562 if (name.charAt(0) == File.separatorChar) {
1563 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1564 dir = new File(dirPath);
1565 name = name.substring(name.lastIndexOf(File.separatorChar));
1566 f = new File(dir, name);
1567 } else {
1568 dir = getDatabasesDir();
1569 f = makeFilename(dir, name);
1570 }
1571
1572 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1573 FileUtils.setPermissions(dir.getPath(),
1574 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1575 -1, -1);
1576 }
1577
1578 return f;
1579 }
1580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 private File makeFilename(File base, String name) {
1582 if (name.indexOf(File.separatorChar) < 0) {
1583 return new File(base, name);
1584 }
1585 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001586 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 }
1588
1589 // ----------------------------------------------------------------------
1590 // ----------------------------------------------------------------------
1591 // ----------------------------------------------------------------------
1592
1593 private static final class ApplicationContentResolver extends ContentResolver {
1594 public ApplicationContentResolver(Context context,
1595 ActivityThread mainThread)
1596 {
1597 super(context);
1598 mMainThread = mainThread;
1599 }
1600
1601 @Override
1602 protected IContentProvider acquireProvider(Context context, String name)
1603 {
1604 return mMainThread.acquireProvider(context, name);
1605 }
1606
1607 @Override
1608 public boolean releaseProvider(IContentProvider provider)
1609 {
1610 return mMainThread.releaseProvider(provider);
1611 }
1612
1613 private final ActivityThread mMainThread;
1614 }
1615
1616 // ----------------------------------------------------------------------
1617 // ----------------------------------------------------------------------
1618 // ----------------------------------------------------------------------
1619
1620 /*package*/
1621 static final class ApplicationPackageManager extends PackageManager {
1622 @Override
1623 public PackageInfo getPackageInfo(String packageName, int flags)
1624 throws NameNotFoundException {
1625 try {
1626 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1627 if (pi != null) {
1628 return pi;
1629 }
1630 } catch (RemoteException e) {
1631 throw new RuntimeException("Package manager has died", e);
1632 }
1633
1634 throw new NameNotFoundException(packageName);
1635 }
1636
Mihai Predaeae850c2009-05-13 10:13:48 +02001637 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001638 public String[] currentToCanonicalPackageNames(String[] names) {
1639 try {
1640 return mPM.currentToCanonicalPackageNames(names);
1641 } catch (RemoteException e) {
1642 throw new RuntimeException("Package manager has died", e);
1643 }
1644 }
1645
1646 @Override
1647 public String[] canonicalToCurrentPackageNames(String[] names) {
1648 try {
1649 return mPM.canonicalToCurrentPackageNames(names);
1650 } catch (RemoteException e) {
1651 throw new RuntimeException("Package manager has died", e);
1652 }
1653 }
1654
1655 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001656 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 // First see if the package has an INFO activity; the existence of
1658 // such an activity is implied to be the desired front-door for the
1659 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001660 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1661 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001662 intentToResolve.setPackage(packageName);
1663 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001666 if (resolveInfo == null) {
1667 // reuse the intent instance
1668 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1669 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001670 intentToResolve.setPackage(packageName);
1671 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001673 if (resolveInfo == null) {
1674 return null;
1675 }
1676 Intent intent = new Intent(Intent.ACTION_MAIN);
1677 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1678 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1679 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 @Override
1683 public int[] getPackageGids(String packageName)
1684 throws NameNotFoundException {
1685 try {
1686 int[] gids = mPM.getPackageGids(packageName);
1687 if (gids == null || gids.length > 0) {
1688 return gids;
1689 }
1690 } catch (RemoteException e) {
1691 throw new RuntimeException("Package manager has died", e);
1692 }
1693
1694 throw new NameNotFoundException(packageName);
1695 }
1696
1697 @Override
1698 public PermissionInfo getPermissionInfo(String name, int flags)
1699 throws NameNotFoundException {
1700 try {
1701 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1702 if (pi != null) {
1703 return pi;
1704 }
1705 } catch (RemoteException e) {
1706 throw new RuntimeException("Package manager has died", e);
1707 }
1708
1709 throw new NameNotFoundException(name);
1710 }
1711
1712 @Override
1713 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1714 throws NameNotFoundException {
1715 try {
1716 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1717 if (pi != null) {
1718 return pi;
1719 }
1720 } catch (RemoteException e) {
1721 throw new RuntimeException("Package manager has died", e);
1722 }
1723
1724 throw new NameNotFoundException(group);
1725 }
1726
1727 @Override
1728 public PermissionGroupInfo getPermissionGroupInfo(String name,
1729 int flags) throws NameNotFoundException {
1730 try {
1731 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1732 if (pgi != null) {
1733 return pgi;
1734 }
1735 } catch (RemoteException e) {
1736 throw new RuntimeException("Package manager has died", e);
1737 }
1738
1739 throw new NameNotFoundException(name);
1740 }
1741
1742 @Override
1743 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1744 try {
1745 return mPM.getAllPermissionGroups(flags);
1746 } catch (RemoteException e) {
1747 throw new RuntimeException("Package manager has died", e);
1748 }
1749 }
1750
1751 @Override
1752 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1753 throws NameNotFoundException {
1754 try {
1755 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1756 if (ai != null) {
1757 return ai;
1758 }
1759 } catch (RemoteException e) {
1760 throw new RuntimeException("Package manager has died", e);
1761 }
1762
1763 throw new NameNotFoundException(packageName);
1764 }
1765
1766 @Override
1767 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1768 throws NameNotFoundException {
1769 try {
1770 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1771 if (ai != null) {
1772 return ai;
1773 }
1774 } catch (RemoteException e) {
1775 throw new RuntimeException("Package manager has died", e);
1776 }
1777
1778 throw new NameNotFoundException(className.toString());
1779 }
1780
1781 @Override
1782 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1783 throws NameNotFoundException {
1784 try {
1785 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1786 if (ai != null) {
1787 return ai;
1788 }
1789 } catch (RemoteException e) {
1790 throw new RuntimeException("Package manager has died", e);
1791 }
1792
1793 throw new NameNotFoundException(className.toString());
1794 }
1795
1796 @Override
1797 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1798 throws NameNotFoundException {
1799 try {
1800 ServiceInfo si = mPM.getServiceInfo(className, flags);
1801 if (si != null) {
1802 return si;
1803 }
1804 } catch (RemoteException e) {
1805 throw new RuntimeException("Package manager has died", e);
1806 }
1807
1808 throw new NameNotFoundException(className.toString());
1809 }
1810
1811 @Override
1812 public String[] getSystemSharedLibraryNames() {
1813 try {
1814 return mPM.getSystemSharedLibraryNames();
1815 } catch (RemoteException e) {
1816 throw new RuntimeException("Package manager has died", e);
1817 }
1818 }
1819
1820 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001821 public FeatureInfo[] getSystemAvailableFeatures() {
1822 try {
1823 return mPM.getSystemAvailableFeatures();
1824 } catch (RemoteException e) {
1825 throw new RuntimeException("Package manager has died", e);
1826 }
1827 }
1828
1829 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001830 public boolean hasSystemFeature(String name) {
1831 try {
1832 return mPM.hasSystemFeature(name);
1833 } catch (RemoteException e) {
1834 throw new RuntimeException("Package manager has died", e);
1835 }
1836 }
1837
1838 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 public int checkPermission(String permName, String pkgName) {
1840 try {
1841 return mPM.checkPermission(permName, pkgName);
1842 } catch (RemoteException e) {
1843 throw new RuntimeException("Package manager has died", e);
1844 }
1845 }
1846
1847 @Override
1848 public boolean addPermission(PermissionInfo info) {
1849 try {
1850 return mPM.addPermission(info);
1851 } catch (RemoteException e) {
1852 throw new RuntimeException("Package manager has died", e);
1853 }
1854 }
1855
1856 @Override
Dianne Hackbornd7c09682010-03-30 10:42:20 -07001857 public boolean addPermissionAsync(PermissionInfo info) {
1858 try {
1859 return mPM.addPermissionAsync(info);
1860 } catch (RemoteException e) {
1861 throw new RuntimeException("Package manager has died", e);
1862 }
1863 }
1864
1865 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 public void removePermission(String name) {
1867 try {
1868 mPM.removePermission(name);
1869 } catch (RemoteException e) {
1870 throw new RuntimeException("Package manager has died", e);
1871 }
1872 }
1873
1874 @Override
1875 public int checkSignatures(String pkg1, String pkg2) {
1876 try {
1877 return mPM.checkSignatures(pkg1, pkg2);
1878 } catch (RemoteException e) {
1879 throw new RuntimeException("Package manager has died", e);
1880 }
1881 }
1882
1883 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001884 public int checkSignatures(int uid1, int uid2) {
1885 try {
1886 return mPM.checkUidSignatures(uid1, uid2);
1887 } catch (RemoteException e) {
1888 throw new RuntimeException("Package manager has died", e);
1889 }
1890 }
1891
1892 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 public String[] getPackagesForUid(int uid) {
1894 try {
1895 return mPM.getPackagesForUid(uid);
1896 } catch (RemoteException e) {
1897 throw new RuntimeException("Package manager has died", e);
1898 }
1899 }
1900
1901 @Override
1902 public String getNameForUid(int uid) {
1903 try {
1904 return mPM.getNameForUid(uid);
1905 } catch (RemoteException e) {
1906 throw new RuntimeException("Package manager has died", e);
1907 }
1908 }
1909
1910 @Override
1911 public int getUidForSharedUser(String sharedUserName)
1912 throws NameNotFoundException {
1913 try {
1914 int uid = mPM.getUidForSharedUser(sharedUserName);
1915 if(uid != -1) {
1916 return uid;
1917 }
1918 } catch (RemoteException e) {
1919 throw new RuntimeException("Package manager has died", e);
1920 }
1921 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1922 }
1923
1924 @Override
1925 public List<PackageInfo> getInstalledPackages(int flags) {
1926 try {
1927 return mPM.getInstalledPackages(flags);
1928 } catch (RemoteException e) {
1929 throw new RuntimeException("Package manager has died", e);
1930 }
1931 }
1932
1933 @Override
1934 public List<ApplicationInfo> getInstalledApplications(int flags) {
1935 try {
1936 return mPM.getInstalledApplications(flags);
1937 } catch (RemoteException e) {
1938 throw new RuntimeException("Package manager has died", e);
1939 }
1940 }
1941
1942 @Override
1943 public ResolveInfo resolveActivity(Intent intent, int flags) {
1944 try {
1945 return mPM.resolveIntent(
1946 intent,
1947 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1948 flags);
1949 } catch (RemoteException e) {
1950 throw new RuntimeException("Package manager has died", e);
1951 }
1952 }
1953
1954 @Override
1955 public List<ResolveInfo> queryIntentActivities(Intent intent,
1956 int flags) {
1957 try {
1958 return mPM.queryIntentActivities(
1959 intent,
1960 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1961 flags);
1962 } catch (RemoteException e) {
1963 throw new RuntimeException("Package manager has died", e);
1964 }
1965 }
1966
1967 @Override
1968 public List<ResolveInfo> queryIntentActivityOptions(
1969 ComponentName caller, Intent[] specifics, Intent intent,
1970 int flags) {
1971 final ContentResolver resolver = mContext.getContentResolver();
1972
1973 String[] specificTypes = null;
1974 if (specifics != null) {
1975 final int N = specifics.length;
1976 for (int i=0; i<N; i++) {
1977 Intent sp = specifics[i];
1978 if (sp != null) {
1979 String t = sp.resolveTypeIfNeeded(resolver);
1980 if (t != null) {
1981 if (specificTypes == null) {
1982 specificTypes = new String[N];
1983 }
1984 specificTypes[i] = t;
1985 }
1986 }
1987 }
1988 }
1989
1990 try {
1991 return mPM.queryIntentActivityOptions(caller, specifics,
1992 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
1993 flags);
1994 } catch (RemoteException e) {
1995 throw new RuntimeException("Package manager has died", e);
1996 }
1997 }
1998
1999 @Override
2000 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2001 try {
2002 return mPM.queryIntentReceivers(
2003 intent,
2004 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2005 flags);
2006 } catch (RemoteException e) {
2007 throw new RuntimeException("Package manager has died", e);
2008 }
2009 }
2010
2011 @Override
2012 public ResolveInfo resolveService(Intent intent, int flags) {
2013 try {
2014 return mPM.resolveService(
2015 intent,
2016 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2017 flags);
2018 } catch (RemoteException e) {
2019 throw new RuntimeException("Package manager has died", e);
2020 }
2021 }
2022
2023 @Override
2024 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2025 try {
2026 return mPM.queryIntentServices(
2027 intent,
2028 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2029 flags);
2030 } catch (RemoteException e) {
2031 throw new RuntimeException("Package manager has died", e);
2032 }
2033 }
2034
2035 @Override
2036 public ProviderInfo resolveContentProvider(String name,
2037 int flags) {
2038 try {
2039 return mPM.resolveContentProvider(name, flags);
2040 } catch (RemoteException e) {
2041 throw new RuntimeException("Package manager has died", e);
2042 }
2043 }
2044
2045 @Override
2046 public List<ProviderInfo> queryContentProviders(String processName,
2047 int uid, int flags) {
2048 try {
2049 return mPM.queryContentProviders(processName, uid, flags);
2050 } catch (RemoteException e) {
2051 throw new RuntimeException("Package manager has died", e);
2052 }
2053 }
2054
2055 @Override
2056 public InstrumentationInfo getInstrumentationInfo(
2057 ComponentName className, int flags)
2058 throws NameNotFoundException {
2059 try {
2060 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2061 className, flags);
2062 if (ii != null) {
2063 return ii;
2064 }
2065 } catch (RemoteException e) {
2066 throw new RuntimeException("Package manager has died", e);
2067 }
2068
2069 throw new NameNotFoundException(className.toString());
2070 }
2071
2072 @Override
2073 public List<InstrumentationInfo> queryInstrumentation(
2074 String targetPackage, int flags) {
2075 try {
2076 return mPM.queryInstrumentation(targetPackage, flags);
2077 } catch (RemoteException e) {
2078 throw new RuntimeException("Package manager has died", e);
2079 }
2080 }
2081
2082 @Override public Drawable getDrawable(String packageName, int resid,
2083 ApplicationInfo appInfo) {
2084 ResourceName name = new ResourceName(packageName, resid);
2085 Drawable dr = getCachedIcon(name);
2086 if (dr != null) {
2087 return dr;
2088 }
2089 if (appInfo == null) {
2090 try {
2091 appInfo = getApplicationInfo(packageName, 0);
2092 } catch (NameNotFoundException e) {
2093 return null;
2094 }
2095 }
2096 try {
2097 Resources r = getResourcesForApplication(appInfo);
2098 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002099 if (false) {
2100 RuntimeException e = new RuntimeException("here");
2101 e.fillInStackTrace();
2102 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2103 + " from package " + packageName
2104 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2105 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2106 e);
2107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2109 + Integer.toHexString(resid) + " from " + r
2110 + ": " + dr);
2111 putCachedIcon(name, dr);
2112 return dr;
2113 } catch (NameNotFoundException e) {
2114 Log.w("PackageManager", "Failure retrieving resources for"
2115 + appInfo.packageName);
2116 } catch (RuntimeException e) {
2117 // If an exception was thrown, fall through to return
2118 // default icon.
2119 Log.w("PackageManager", "Failure retrieving icon 0x"
2120 + Integer.toHexString(resid) + " in package "
2121 + packageName, e);
2122 }
2123 return null;
2124 }
2125
2126 @Override public Drawable getActivityIcon(ComponentName activityName)
2127 throws NameNotFoundException {
2128 return getActivityInfo(activityName, 0).loadIcon(this);
2129 }
2130
2131 @Override public Drawable getActivityIcon(Intent intent)
2132 throws NameNotFoundException {
2133 if (intent.getComponent() != null) {
2134 return getActivityIcon(intent.getComponent());
2135 }
2136
2137 ResolveInfo info = resolveActivity(
2138 intent, PackageManager.MATCH_DEFAULT_ONLY);
2139 if (info != null) {
2140 return info.activityInfo.loadIcon(this);
2141 }
2142
2143 throw new NameNotFoundException(intent.toURI());
2144 }
2145
2146 @Override public Drawable getDefaultActivityIcon() {
2147 return Resources.getSystem().getDrawable(
2148 com.android.internal.R.drawable.sym_def_app_icon);
2149 }
2150
2151 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002152 return info.loadIcon(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 }
2154
2155 @Override public Drawable getApplicationIcon(String packageName)
2156 throws NameNotFoundException {
2157 return getApplicationIcon(getApplicationInfo(packageName, 0));
2158 }
2159
2160 @Override public Resources getResourcesForActivity(
2161 ComponentName activityName) throws NameNotFoundException {
2162 return getResourcesForApplication(
2163 getActivityInfo(activityName, 0).applicationInfo);
2164 }
2165
2166 @Override public Resources getResourcesForApplication(
2167 ApplicationInfo app) throws NameNotFoundException {
2168 if (app.packageName.equals("system")) {
2169 return mContext.mMainThread.getSystemContext().getResources();
2170 }
2171 Resources r = mContext.mMainThread.getTopLevelResources(
2172 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002173 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 if (r != null) {
2175 return r;
2176 }
2177 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2178 }
2179
2180 @Override public Resources getResourcesForApplication(
2181 String appPackageName) throws NameNotFoundException {
2182 return getResourcesForApplication(
2183 getApplicationInfo(appPackageName, 0));
2184 }
2185
2186 int mCachedSafeMode = -1;
2187 @Override public boolean isSafeMode() {
2188 try {
2189 if (mCachedSafeMode < 0) {
2190 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2191 }
2192 return mCachedSafeMode != 0;
2193 } catch (RemoteException e) {
2194 throw new RuntimeException("Package manager has died", e);
2195 }
2196 }
2197
2198 static void configurationChanged() {
2199 synchronized (sSync) {
2200 sIconCache.clear();
2201 sStringCache.clear();
2202 }
2203 }
2204
Dianne Hackborn21556372010-02-04 16:34:40 -08002205 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002206 IPackageManager pm) {
2207 mContext = context;
2208 mPM = pm;
2209 }
2210
2211 private Drawable getCachedIcon(ResourceName name) {
2212 synchronized (sSync) {
2213 WeakReference<Drawable> wr = sIconCache.get(name);
2214 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2215 + name + ": " + wr);
2216 if (wr != null) { // we have the activity
2217 Drawable dr = wr.get();
2218 if (dr != null) {
2219 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2220 + name + ": " + dr);
2221 return dr;
2222 }
2223 // our entry has been purged
2224 sIconCache.remove(name);
2225 }
2226 }
2227 return null;
2228 }
2229
2230 private void establishPackageRemovedReceiver() {
2231 // mContext.registerReceiverInternal() winds up acquiring the
2232 // main ActivityManagerService.this lock. If we hold our usual
2233 // sSync global lock at the same time, we impose a required ordering
2234 // on those two locks, which is not good for deadlock prevention.
2235 // Use a dedicated lock around initialization of
2236 // sPackageRemovedReceiver to avoid this.
2237 synchronized (sPackageRemovedSync) {
2238 if (sPackageRemovedReceiver == null) {
2239 sPackageRemovedReceiver = new PackageRemovedReceiver();
2240 IntentFilter filter = new IntentFilter(
2241 Intent.ACTION_PACKAGE_REMOVED);
2242 filter.addDataScheme("package");
2243 mContext.registerReceiverInternal(sPackageRemovedReceiver,
2244 filter, null, null, null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002245 // Register for events related to sdcard installation.
2246 IntentFilter sdFilter = new IntentFilter();
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08002247 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002248 mContext.registerReceiverInternal(sPackageRemovedReceiver,
2249 sdFilter, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002250 }
2251 }
2252 }
2253
2254 private void putCachedIcon(ResourceName name, Drawable dr) {
2255 establishPackageRemovedReceiver();
2256
2257 synchronized (sSync) {
2258 sIconCache.put(name, new WeakReference<Drawable>(dr));
2259 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2260 + name + ": " + dr);
2261 }
2262 }
2263
2264 private static final class PackageRemovedReceiver extends BroadcastReceiver {
2265 @Override
2266 public void onReceive(Context context, Intent intent) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002267 String pkgList[] = null;
2268 String action = intent.getAction();
2269 boolean immediateGc = false;
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08002270 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002271 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
2272 immediateGc = true;
2273 } else {
2274 Uri data = intent.getData();
2275 if (data != null) {
2276 String ssp = data.getSchemeSpecificPart();
2277 if (ssp != null) {
2278 pkgList = new String[] { ssp };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 }
2280 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002281 }
2282 if (pkgList != null && (pkgList.length > 0)) {
2283 boolean needCleanup = false;
2284 boolean hasPkgInfo = false;
2285 for (String ssp : pkgList) {
2286 synchronized (sSync) {
2287 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2288 while (it.hasNext()) {
2289 ResourceName nm = it.next();
2290 if (nm.packageName.equals(ssp)) {
2291 //Log.i(TAG, "Removing cached drawable for " + nm);
2292 it.remove();
2293 needCleanup = true;
2294 }
2295 }
2296 it = sStringCache.keySet().iterator();
2297 while (it.hasNext()) {
2298 ResourceName nm = it.next();
2299 if (nm.packageName.equals(ssp)) {
2300 //Log.i(TAG, "Removing cached string for " + nm);
2301 it.remove();
2302 needCleanup = true;
2303 }
2304 }
2305 }
2306 if (!hasPkgInfo) {
2307 hasPkgInfo = ActivityThread.currentActivityThread().hasPackageInfo(ssp);
2308 }
2309 }
2310 if (needCleanup || hasPkgInfo) {
2311 if (immediateGc) {
2312 // Schedule an immediate gc.
2313 Runtime.getRuntime().gc();
2314 } else {
2315 ActivityThread.currentActivityThread().scheduleGcIdler();
2316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 }
2318 }
2319 }
2320 }
2321
2322 private static final class ResourceName {
2323 final String packageName;
2324 final int iconId;
2325
2326 ResourceName(String _packageName, int _iconId) {
2327 packageName = _packageName;
2328 iconId = _iconId;
2329 }
2330
2331 ResourceName(ApplicationInfo aInfo, int _iconId) {
2332 this(aInfo.packageName, _iconId);
2333 }
2334
2335 ResourceName(ComponentInfo cInfo, int _iconId) {
2336 this(cInfo.applicationInfo.packageName, _iconId);
2337 }
2338
2339 ResourceName(ResolveInfo rInfo, int _iconId) {
2340 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2341 }
2342
2343 @Override
2344 public boolean equals(Object o) {
2345 if (this == o) return true;
2346 if (o == null || getClass() != o.getClass()) return false;
2347
2348 ResourceName that = (ResourceName) o;
2349
2350 if (iconId != that.iconId) return false;
2351 return !(packageName != null ?
2352 !packageName.equals(that.packageName) : that.packageName != null);
2353
2354 }
2355
2356 @Override
2357 public int hashCode() {
2358 int result;
2359 result = packageName.hashCode();
2360 result = 31 * result + iconId;
2361 return result;
2362 }
2363
2364 @Override
2365 public String toString() {
2366 return "{ResourceName " + packageName + " / " + iconId + "}";
2367 }
2368 }
2369
2370 private CharSequence getCachedString(ResourceName name) {
2371 synchronized (sSync) {
2372 WeakReference<CharSequence> wr = sStringCache.get(name);
2373 if (wr != null) { // we have the activity
2374 CharSequence cs = wr.get();
2375 if (cs != null) {
2376 return cs;
2377 }
2378 // our entry has been purged
2379 sStringCache.remove(name);
2380 }
2381 }
2382 return null;
2383 }
2384
2385 private void putCachedString(ResourceName name, CharSequence cs) {
2386 establishPackageRemovedReceiver();
2387
2388 synchronized (sSync) {
2389 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2390 }
2391 }
2392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 @Override
2394 public CharSequence getText(String packageName, int resid,
2395 ApplicationInfo appInfo) {
2396 ResourceName name = new ResourceName(packageName, resid);
2397 CharSequence text = getCachedString(name);
2398 if (text != null) {
2399 return text;
2400 }
2401 if (appInfo == null) {
2402 try {
2403 appInfo = getApplicationInfo(packageName, 0);
2404 } catch (NameNotFoundException e) {
2405 return null;
2406 }
2407 }
2408 try {
2409 Resources r = getResourcesForApplication(appInfo);
2410 text = r.getText(resid);
2411 putCachedString(name, text);
2412 return text;
2413 } catch (NameNotFoundException e) {
2414 Log.w("PackageManager", "Failure retrieving resources for"
2415 + appInfo.packageName);
2416 } catch (RuntimeException e) {
2417 // If an exception was thrown, fall through to return
2418 // default icon.
2419 Log.w("PackageManager", "Failure retrieving text 0x"
2420 + Integer.toHexString(resid) + " in package "
2421 + packageName, e);
2422 }
2423 return null;
2424 }
2425
2426 @Override
2427 public XmlResourceParser getXml(String packageName, int resid,
2428 ApplicationInfo appInfo) {
2429 if (appInfo == null) {
2430 try {
2431 appInfo = getApplicationInfo(packageName, 0);
2432 } catch (NameNotFoundException e) {
2433 return null;
2434 }
2435 }
2436 try {
2437 Resources r = getResourcesForApplication(appInfo);
2438 return r.getXml(resid);
2439 } catch (RuntimeException e) {
2440 // If an exception was thrown, fall through to return
2441 // default icon.
2442 Log.w("PackageManager", "Failure retrieving xml 0x"
2443 + Integer.toHexString(resid) + " in package "
2444 + packageName, e);
2445 } catch (NameNotFoundException e) {
2446 Log.w("PackageManager", "Failure retrieving resources for"
2447 + appInfo.packageName);
2448 }
2449 return null;
2450 }
2451
2452 @Override
2453 public CharSequence getApplicationLabel(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002454 return info.loadLabel(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 }
2456
2457 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002458 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2459 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002461 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 } catch (RemoteException e) {
2463 // Should never happen!
2464 }
2465 }
2466
2467 @Override
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -08002468 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2469 try {
2470 mPM.movePackage(packageName, observer, flags);
2471 } catch (RemoteException e) {
2472 // Should never happen!
2473 }
2474 }
2475
2476 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002477 public String getInstallerPackageName(String packageName) {
2478 try {
2479 return mPM.getInstallerPackageName(packageName);
2480 } catch (RemoteException e) {
2481 // Should never happen!
2482 }
2483 return null;
2484 }
2485
2486 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2488 try {
2489 mPM.deletePackage(packageName, observer, flags);
2490 } catch (RemoteException e) {
2491 // Should never happen!
2492 }
2493 }
2494 @Override
2495 public void clearApplicationUserData(String packageName,
2496 IPackageDataObserver observer) {
2497 try {
2498 mPM.clearApplicationUserData(packageName, observer);
2499 } catch (RemoteException e) {
2500 // Should never happen!
2501 }
2502 }
2503 @Override
2504 public void deleteApplicationCacheFiles(String packageName,
2505 IPackageDataObserver observer) {
2506 try {
2507 mPM.deleteApplicationCacheFiles(packageName, observer);
2508 } catch (RemoteException e) {
2509 // Should never happen!
2510 }
2511 }
2512 @Override
2513 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2514 try {
2515 mPM.freeStorageAndNotify(idealStorageSize, observer);
2516 } catch (RemoteException e) {
2517 // Should never happen!
2518 }
2519 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002521 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002522 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002524 mPM.freeStorage(freeStorageSize, pi);
2525 } catch (RemoteException e) {
2526 // Should never happen!
2527 }
2528 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002529
2530 @Override
2531 public void getPackageSizeInfo(String packageName,
2532 IPackageStatsObserver observer) {
2533 try {
2534 mPM.getPackageSizeInfo(packageName, observer);
2535 } catch (RemoteException e) {
2536 // Should never happen!
2537 }
2538 }
2539 @Override
2540 public void addPackageToPreferred(String packageName) {
2541 try {
2542 mPM.addPackageToPreferred(packageName);
2543 } catch (RemoteException e) {
2544 // Should never happen!
2545 }
2546 }
2547
2548 @Override
2549 public void removePackageFromPreferred(String packageName) {
2550 try {
2551 mPM.removePackageFromPreferred(packageName);
2552 } catch (RemoteException e) {
2553 // Should never happen!
2554 }
2555 }
2556
2557 @Override
2558 public List<PackageInfo> getPreferredPackages(int flags) {
2559 try {
2560 return mPM.getPreferredPackages(flags);
2561 } catch (RemoteException e) {
2562 // Should never happen!
2563 }
2564 return new ArrayList<PackageInfo>();
2565 }
2566
2567 @Override
2568 public void addPreferredActivity(IntentFilter filter,
2569 int match, ComponentName[] set, ComponentName activity) {
2570 try {
2571 mPM.addPreferredActivity(filter, match, set, activity);
2572 } catch (RemoteException e) {
2573 // Should never happen!
2574 }
2575 }
2576
2577 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002578 public void replacePreferredActivity(IntentFilter filter,
2579 int match, ComponentName[] set, ComponentName activity) {
2580 try {
2581 mPM.replacePreferredActivity(filter, match, set, activity);
2582 } catch (RemoteException e) {
2583 // Should never happen!
2584 }
2585 }
2586
2587 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002588 public void clearPackagePreferredActivities(String packageName) {
2589 try {
2590 mPM.clearPackagePreferredActivities(packageName);
2591 } catch (RemoteException e) {
2592 // Should never happen!
2593 }
2594 }
2595
2596 @Override
2597 public int getPreferredActivities(List<IntentFilter> outFilters,
2598 List<ComponentName> outActivities, String packageName) {
2599 try {
2600 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2601 } catch (RemoteException e) {
2602 // Should never happen!
2603 }
2604 return 0;
2605 }
2606
2607 @Override
2608 public void setComponentEnabledSetting(ComponentName componentName,
2609 int newState, int flags) {
2610 try {
2611 mPM.setComponentEnabledSetting(componentName, newState, flags);
2612 } catch (RemoteException e) {
2613 // Should never happen!
2614 }
2615 }
2616
2617 @Override
2618 public int getComponentEnabledSetting(ComponentName componentName) {
2619 try {
2620 return mPM.getComponentEnabledSetting(componentName);
2621 } catch (RemoteException e) {
2622 // Should never happen!
2623 }
2624 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2625 }
2626
2627 @Override
2628 public void setApplicationEnabledSetting(String packageName,
2629 int newState, int flags) {
2630 try {
2631 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2632 } catch (RemoteException e) {
2633 // Should never happen!
2634 }
2635 }
2636
2637 @Override
2638 public int getApplicationEnabledSetting(String packageName) {
2639 try {
2640 return mPM.getApplicationEnabledSetting(packageName);
2641 } catch (RemoteException e) {
2642 // Should never happen!
2643 }
2644 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2645 }
2646
Dianne Hackborn21556372010-02-04 16:34:40 -08002647 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 private final IPackageManager mPM;
2649
2650 private static final Object sSync = new Object();
2651 private static final Object sPackageRemovedSync = new Object();
2652 private static BroadcastReceiver sPackageRemovedReceiver;
2653 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2654 = new HashMap<ResourceName, WeakReference<Drawable> >();
2655 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2656 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2657 }
2658
2659 // ----------------------------------------------------------------------
2660 // ----------------------------------------------------------------------
2661 // ----------------------------------------------------------------------
2662
2663 private static final class SharedPreferencesImpl implements SharedPreferences {
2664
2665 private final File mFile;
2666 private final File mBackupFile;
2667 private final int mMode;
2668 private Map mMap;
2669 private final FileStatus mFileStatus = new FileStatus();
2670 private long mTimestamp;
2671
The Android Open Source Project10592532009-03-18 17:39:46 -07002672 private static final Object mContent = new Object();
2673 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674
2675 SharedPreferencesImpl(
2676 File file, int mode, Map initialContents) {
2677 mFile = file;
2678 mBackupFile = makeBackupFile(file);
2679 mMode = mode;
2680 mMap = initialContents != null ? initialContents : new HashMap();
2681 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2682 mTimestamp = mFileStatus.mtime;
2683 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002684 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 }
2686
2687 public boolean hasFileChanged() {
2688 synchronized (this) {
2689 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2690 return true;
2691 }
2692 return mTimestamp != mFileStatus.mtime;
2693 }
2694 }
2695
2696 public void replace(Map newContents) {
2697 if (newContents != null) {
2698 synchronized (this) {
2699 mMap = newContents;
2700 }
2701 }
2702 }
2703
2704 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2705 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002706 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 }
2708 }
2709
2710 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2711 synchronized(this) {
2712 mListeners.remove(listener);
2713 }
2714 }
2715
2716 public Map<String, ?> getAll() {
2717 synchronized(this) {
2718 //noinspection unchecked
2719 return new HashMap(mMap);
2720 }
2721 }
2722
2723 public String getString(String key, String defValue) {
2724 synchronized (this) {
2725 String v = (String)mMap.get(key);
2726 return v != null ? v : defValue;
2727 }
2728 }
2729
2730 public int getInt(String key, int defValue) {
2731 synchronized (this) {
2732 Integer v = (Integer)mMap.get(key);
2733 return v != null ? v : defValue;
2734 }
2735 }
2736 public long getLong(String key, long defValue) {
2737 synchronized (this) {
2738 Long v = (Long) mMap.get(key);
2739 return v != null ? v : defValue;
2740 }
2741 }
2742 public float getFloat(String key, float defValue) {
2743 synchronized (this) {
2744 Float v = (Float)mMap.get(key);
2745 return v != null ? v : defValue;
2746 }
2747 }
2748 public boolean getBoolean(String key, boolean defValue) {
2749 synchronized (this) {
2750 Boolean v = (Boolean)mMap.get(key);
2751 return v != null ? v : defValue;
2752 }
2753 }
2754
2755 public boolean contains(String key) {
2756 synchronized (this) {
2757 return mMap.containsKey(key);
2758 }
2759 }
2760
2761 public final class EditorImpl implements Editor {
2762 private final Map<String, Object> mModified = Maps.newHashMap();
2763 private boolean mClear = false;
2764
2765 public Editor putString(String key, String value) {
2766 synchronized (this) {
2767 mModified.put(key, value);
2768 return this;
2769 }
2770 }
2771 public Editor putInt(String key, int value) {
2772 synchronized (this) {
2773 mModified.put(key, value);
2774 return this;
2775 }
2776 }
2777 public Editor putLong(String key, long value) {
2778 synchronized (this) {
2779 mModified.put(key, value);
2780 return this;
2781 }
2782 }
2783 public Editor putFloat(String key, float value) {
2784 synchronized (this) {
2785 mModified.put(key, value);
2786 return this;
2787 }
2788 }
2789 public Editor putBoolean(String key, boolean value) {
2790 synchronized (this) {
2791 mModified.put(key, value);
2792 return this;
2793 }
2794 }
2795
2796 public Editor remove(String key) {
2797 synchronized (this) {
2798 mModified.put(key, this);
2799 return this;
2800 }
2801 }
2802
2803 public Editor clear() {
2804 synchronized (this) {
2805 mClear = true;
2806 return this;
2807 }
2808 }
2809
2810 public boolean commit() {
2811 boolean returnValue;
2812
2813 boolean hasListeners;
2814 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002815 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816
2817 synchronized (SharedPreferencesImpl.this) {
2818 hasListeners = mListeners.size() > 0;
2819 if (hasListeners) {
2820 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002821 listeners =
2822 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 }
2824
2825 synchronized (this) {
2826 if (mClear) {
2827 mMap.clear();
2828 mClear = false;
2829 }
2830
The Android Open Source Project10592532009-03-18 17:39:46 -07002831 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002832 String k = e.getKey();
2833 Object v = e.getValue();
2834 if (v == this) {
2835 mMap.remove(k);
2836 } else {
2837 mMap.put(k, v);
2838 }
2839
2840 if (hasListeners) {
2841 keysModified.add(k);
2842 }
2843 }
2844
2845 mModified.clear();
2846 }
2847
2848 returnValue = writeFileLocked();
2849 }
2850
2851 if (hasListeners) {
2852 for (int i = keysModified.size() - 1; i >= 0; i--) {
2853 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002854 for (OnSharedPreferenceChangeListener listener : listeners) {
2855 if (listener != null) {
2856 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 }
2859 }
2860 }
2861
2862 return returnValue;
2863 }
2864 }
2865
2866 public Editor edit() {
2867 return new EditorImpl();
2868 }
2869
2870 private FileOutputStream createFileOutputStream(File file) {
2871 FileOutputStream str = null;
2872 try {
2873 str = new FileOutputStream(file);
2874 } catch (FileNotFoundException e) {
2875 File parent = file.getParentFile();
2876 if (!parent.mkdir()) {
2877 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2878 return null;
2879 }
2880 FileUtils.setPermissions(
2881 parent.getPath(),
2882 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2883 -1, -1);
2884 try {
2885 str = new FileOutputStream(file);
2886 } catch (FileNotFoundException e2) {
2887 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2888 }
2889 }
2890 return str;
2891 }
2892
2893 private boolean writeFileLocked() {
2894 // Rename the current file so it may be used as a backup during the next read
2895 if (mFile.exists()) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002896 if (!mBackupFile.exists()) {
2897 if (!mFile.renameTo(mBackupFile)) {
2898 Log.e(TAG, "Couldn't rename file " + mFile
2899 + " to backup file " + mBackupFile);
2900 return false;
2901 }
2902 } else {
2903 mFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002904 }
2905 }
2906
2907 // Attempt to write the file, delete the backup and return true as atomically as
2908 // possible. If any exception occurs, delete the new file; next time we will restore
2909 // from the backup.
2910 try {
2911 FileOutputStream str = createFileOutputStream(mFile);
2912 if (str == null) {
2913 return false;
2914 }
2915 XmlUtils.writeMapXml(mMap, str);
2916 str.close();
2917 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2918 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2919 mTimestamp = mFileStatus.mtime;
2920 }
2921
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002922 // Writing was successful, delete the backup file if there is one.
2923 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 return true;
2925 } catch (XmlPullParserException e) {
2926 Log.w(TAG, "writeFileLocked: Got exception:", e);
2927 } catch (IOException e) {
2928 Log.w(TAG, "writeFileLocked: Got exception:", e);
2929 }
2930 // Clean up an unsuccessfully written file
2931 if (mFile.exists()) {
2932 if (!mFile.delete()) {
2933 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2934 }
2935 }
2936 return false;
2937 }
2938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939}