blob: 5217f5e4b3164f5874be78f4d7c2820c317b8620 [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;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070070import android.net.ThrottleManager;
71import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.net.Uri;
73import android.net.wifi.IWifiManager;
74import android.net.wifi.WifiManager;
75import android.os.Binder;
76import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080077import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080078import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.FileUtils;
80import android.os.Handler;
81import android.os.IBinder;
82import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070083import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.os.PowerManager;
85import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070086import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.ServiceManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080088import android.os.StatFs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.Vibrator;
90import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080091import android.os.storage.StorageManager;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080092import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.telephony.TelephonyManager;
94import android.text.ClipboardManager;
95import android.util.AndroidRuntimeException;
96import android.util.Log;
97import android.view.ContextThemeWrapper;
98import android.view.LayoutInflater;
99import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -0700100import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -0700102import android.accounts.AccountManager;
103import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800104import android.app.admin.DevicePolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
Dan Egnorf18a01c2009-11-12 11:32:50 -0800106import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import java.io.File;
109import java.io.FileInputStream;
110import java.io.FileNotFoundException;
111import java.io.FileOutputStream;
112import java.io.IOException;
113import java.io.InputStream;
114import java.lang.ref.WeakReference;
115import java.util.ArrayList;
116import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700117import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import java.util.Iterator;
119import java.util.List;
120import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700121import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700122import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import java.util.Map.Entry;
124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125class ReceiverRestrictedContext extends ContextWrapper {
126 ReceiverRestrictedContext(Context base) {
127 super(base);
128 }
129
130 @Override
131 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
132 return registerReceiver(receiver, filter, null, null);
133 }
134
135 @Override
136 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
137 String broadcastPermission, Handler scheduler) {
138 throw new ReceiverCallNotAllowedException(
139 "IntentReceiver components are not allowed to register to receive intents");
140 //ex.fillInStackTrace();
141 //Log.e("IntentReceiver", ex.getMessage(), ex);
142 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
143 // scheduler);
144 }
145
146 @Override
147 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
148 throw new ReceiverCallNotAllowedException(
149 "IntentReceiver components are not allowed to bind to services");
150 //ex.fillInStackTrace();
151 //Log.e("IntentReceiver", ex.getMessage(), ex);
152 //return mContext.bindService(service, interfaceName, conn, flags);
153 }
154}
155
156/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800157 * Common implementation of Context API, which provides the base
158 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800160class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700162 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 private final static boolean DEBUG_ICONS = false;
164
165 private static final Object sSync = new Object();
166 private static AlarmManager sAlarmManager;
167 private static PowerManager sPowerManager;
168 private static ConnectivityManager sConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700169 private static ThrottleManager sThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 private static WifiManager sWifiManager;
171 private static LocationManager sLocationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
173 new HashMap<File, SharedPreferencesImpl>();
174
175 private AudioManager mAudioManager;
176 /*package*/ ActivityThread.PackageInfo mPackageInfo;
177 private Resources mResources;
178 /*package*/ ActivityThread mMainThread;
179 private Context mOuterContext;
180 private IBinder mActivityToken = null;
181 private ApplicationContentResolver mContentResolver;
182 private int mThemeResource = 0;
183 private Resources.Theme mTheme = null;
184 private PackageManager mPackageManager;
185 private NotificationManager mNotificationManager = null;
186 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700187 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 private Context mReceiverRestrictedContext = null;
189 private SearchManager mSearchManager = null;
190 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800191 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 private Vibrator mVibrator = null;
193 private LayoutInflater mLayoutInflater = null;
194 private StatusBarManager mStatusBarManager = null;
195 private TelephonyManager mTelephonyManager = null;
196 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700197 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700198 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800199 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800200 private DevicePolicyManager mDevicePolicyManager = null;
Tobias Haamel53332882010-02-18 16:15:43 -0800201 private UiModeManager mUiModeManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202
203 private final Object mSync = new Object();
204
205 private File mDatabasesDir;
206 private File mPreferencesDir;
207 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800209 private File mExternalFilesDir;
210 private File mExternalCacheDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 private static long sInstanceCount = 0;
213
214 private static final String[] EMPTY_FILE_LIST = {};
215
Carl Shapiro82fe5642010-02-24 00:14:23 -0800216 // For debug only
217 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 @Override
219 protected void finalize() throws Throwable {
220 super.finalize();
221 --sInstanceCount;
222 }
Carl Shapiro82fe5642010-02-24 00:14:23 -0800223 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224
225 public static long getInstanceCount() {
226 return sInstanceCount;
227 }
228
229 @Override
230 public AssetManager getAssets() {
231 return mResources.getAssets();
232 }
233
234 @Override
235 public Resources getResources() {
236 return mResources;
237 }
238
239 @Override
240 public PackageManager getPackageManager() {
241 if (mPackageManager != null) {
242 return mPackageManager;
243 }
244
245 IPackageManager pm = ActivityThread.getPackageManager();
246 if (pm != null) {
247 // Doesn't matter if we make more than one instance.
248 return (mPackageManager = new ApplicationPackageManager(this, pm));
249 }
250
251 return null;
252 }
253
254 @Override
255 public ContentResolver getContentResolver() {
256 return mContentResolver;
257 }
258
259 @Override
260 public Looper getMainLooper() {
261 return mMainThread.getLooper();
262 }
263
264 @Override
265 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700266 return (mPackageInfo != null) ?
267 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 }
269
270 @Override
271 public void setTheme(int resid) {
272 mThemeResource = resid;
273 }
274
275 @Override
276 public Resources.Theme getTheme() {
277 if (mTheme == null) {
278 if (mThemeResource == 0) {
279 mThemeResource = com.android.internal.R.style.Theme;
280 }
281 mTheme = mResources.newTheme();
282 mTheme.applyStyle(mThemeResource, true);
283 }
284 return mTheme;
285 }
286
287 @Override
288 public ClassLoader getClassLoader() {
289 return mPackageInfo != null ?
290 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
291 }
292
293 @Override
294 public String getPackageName() {
295 if (mPackageInfo != null) {
296 return mPackageInfo.getPackageName();
297 }
298 throw new RuntimeException("Not supported in system context");
299 }
300
301 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700302 public ApplicationInfo getApplicationInfo() {
303 if (mPackageInfo != null) {
304 return mPackageInfo.getApplicationInfo();
305 }
306 throw new RuntimeException("Not supported in system context");
307 }
308
309 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 public String getPackageResourcePath() {
311 if (mPackageInfo != null) {
312 return mPackageInfo.getResDir();
313 }
314 throw new RuntimeException("Not supported in system context");
315 }
316
317 @Override
318 public String getPackageCodePath() {
319 if (mPackageInfo != null) {
320 return mPackageInfo.getAppDir();
321 }
322 throw new RuntimeException("Not supported in system context");
323 }
324
325 private static File makeBackupFile(File prefsFile) {
326 return new File(prefsFile.getPath() + ".bak");
327 }
328
Joe Onorato23ecae32009-06-10 17:07:15 -0700329 public File getSharedPrefsFile(String name) {
330 return makeFilename(getPreferencesDir(), name + ".xml");
331 }
332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 @Override
334 public SharedPreferences getSharedPreferences(String name, int mode) {
335 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700336 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 synchronized (sSharedPrefs) {
338 sp = sSharedPrefs.get(f);
339 if (sp != null && !sp.hasFileChanged()) {
340 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
341 return sp;
342 }
343 }
344
345 FileInputStream str = null;
346 File backup = makeBackupFile(f);
347 if (backup.exists()) {
348 f.delete();
349 backup.renameTo(f);
350 }
351
352 // Debugging
353 if (f.exists() && !f.canRead()) {
354 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
355 }
356
357 Map map = null;
358 if (f.exists() && f.canRead()) {
359 try {
360 str = new FileInputStream(f);
361 map = XmlUtils.readMapXml(str);
362 str.close();
363 } catch (org.xmlpull.v1.XmlPullParserException e) {
364 Log.w(TAG, "getSharedPreferences", e);
365 } catch (FileNotFoundException e) {
366 Log.w(TAG, "getSharedPreferences", e);
367 } catch (IOException e) {
368 Log.w(TAG, "getSharedPreferences", e);
369 }
370 }
371
372 synchronized (sSharedPrefs) {
373 if (sp != null) {
374 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
375 sp.replace(map);
376 } else {
377 sp = sSharedPrefs.get(f);
378 if (sp == null) {
379 sp = new SharedPreferencesImpl(f, mode, map);
380 sSharedPrefs.put(f, sp);
381 }
382 }
383 return sp;
384 }
385 }
386
387 private File getPreferencesDir() {
388 synchronized (mSync) {
389 if (mPreferencesDir == null) {
390 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
391 }
392 return mPreferencesDir;
393 }
394 }
395
396 @Override
397 public FileInputStream openFileInput(String name)
398 throws FileNotFoundException {
399 File f = makeFilename(getFilesDir(), name);
400 return new FileInputStream(f);
401 }
402
403 @Override
404 public FileOutputStream openFileOutput(String name, int mode)
405 throws FileNotFoundException {
406 final boolean append = (mode&MODE_APPEND) != 0;
407 File f = makeFilename(getFilesDir(), name);
408 try {
409 FileOutputStream fos = new FileOutputStream(f, append);
410 setFilePermissionsFromMode(f.getPath(), mode, 0);
411 return fos;
412 } catch (FileNotFoundException e) {
413 }
414
415 File parent = f.getParentFile();
416 parent.mkdir();
417 FileUtils.setPermissions(
418 parent.getPath(),
419 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
420 -1, -1);
421 FileOutputStream fos = new FileOutputStream(f, append);
422 setFilePermissionsFromMode(f.getPath(), mode, 0);
423 return fos;
424 }
425
426 @Override
427 public boolean deleteFile(String name) {
428 File f = makeFilename(getFilesDir(), name);
429 return f.delete();
430 }
431
432 @Override
433 public File getFilesDir() {
434 synchronized (mSync) {
435 if (mFilesDir == null) {
436 mFilesDir = new File(getDataDirFile(), "files");
437 }
438 if (!mFilesDir.exists()) {
439 if(!mFilesDir.mkdirs()) {
440 Log.w(TAG, "Unable to create files directory");
441 return null;
442 }
443 FileUtils.setPermissions(
444 mFilesDir.getPath(),
445 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
446 -1, -1);
447 }
448 return mFilesDir;
449 }
450 }
451
452 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800453 public File getExternalFilesDir(String type) {
454 synchronized (mSync) {
455 if (mExternalFilesDir == null) {
456 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
457 getPackageName());
458 }
459 if (!mExternalFilesDir.exists()) {
460 try {
461 (new File(Environment.getExternalStorageAndroidDataDir(),
462 ".nomedia")).createNewFile();
463 } catch (IOException e) {
464 }
465 if (!mExternalFilesDir.mkdirs()) {
466 Log.w(TAG, "Unable to create external files directory");
467 return null;
468 }
469 }
470 if (type == null) {
471 return mExternalFilesDir;
472 }
473 File dir = new File(mExternalFilesDir, type);
474 if (!dir.exists()) {
475 if (!dir.mkdirs()) {
476 Log.w(TAG, "Unable to create external media directory " + dir);
477 return null;
478 }
479 }
480 return dir;
481 }
482 }
483
484 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 public File getCacheDir() {
486 synchronized (mSync) {
487 if (mCacheDir == null) {
488 mCacheDir = new File(getDataDirFile(), "cache");
489 }
490 if (!mCacheDir.exists()) {
491 if(!mCacheDir.mkdirs()) {
492 Log.w(TAG, "Unable to create cache directory");
493 return null;
494 }
495 FileUtils.setPermissions(
496 mCacheDir.getPath(),
497 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
498 -1, -1);
499 }
500 }
501 return mCacheDir;
502 }
503
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800504 @Override
505 public File getExternalCacheDir() {
506 synchronized (mSync) {
507 if (mExternalCacheDir == null) {
508 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
509 getPackageName());
510 }
511 if (!mExternalCacheDir.exists()) {
512 try {
513 (new File(Environment.getExternalStorageAndroidDataDir(),
514 ".nomedia")).createNewFile();
515 } catch (IOException e) {
516 }
517 if (!mExternalCacheDir.mkdirs()) {
518 Log.w(TAG, "Unable to create external cache directory");
519 return null;
520 }
521 }
522 return mExternalCacheDir;
523 }
524 }
525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 @Override
527 public File getFileStreamPath(String name) {
528 return makeFilename(getFilesDir(), name);
529 }
530
531 @Override
532 public String[] fileList() {
533 final String[] list = getFilesDir().list();
534 return (list != null) ? list : EMPTY_FILE_LIST;
535 }
536
537 @Override
538 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800539 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
541 setFilePermissionsFromMode(f.getPath(), mode, 0);
542 return db;
543 }
544
545 @Override
546 public boolean deleteDatabase(String name) {
547 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800548 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 return f.delete();
550 } catch (Exception e) {
551 }
552 return false;
553 }
554
555 @Override
556 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800557 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 }
559
560 @Override
561 public String[] databaseList() {
562 final String[] list = getDatabasesDir().list();
563 return (list != null) ? list : EMPTY_FILE_LIST;
564 }
565
566
567 private File getDatabasesDir() {
568 synchronized (mSync) {
569 if (mDatabasesDir == null) {
570 mDatabasesDir = new File(getDataDirFile(), "databases");
571 }
572 if (mDatabasesDir.getPath().equals("databases")) {
573 mDatabasesDir = new File("/data/system");
574 }
575 return mDatabasesDir;
576 }
577 }
578
579 @Override
580 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700581 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 }
583
584 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700585 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700586 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
588
589 @Override
590 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700591 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 }
593
594 @Override
595 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700596 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 }
598
599 @Override
600 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700601 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 }
603
604 @Override
605 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700606 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 }
608
609 @Override
610 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700611 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 }
613
614 @Override
615 public void startActivity(Intent intent) {
616 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
617 throw new AndroidRuntimeException(
618 "Calling startActivity() from outside of an Activity "
619 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
620 + " Is this really what you want?");
621 }
622 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700623 getOuterContext(), mMainThread.getApplicationThread(), null,
624 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 }
626
627 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700628 public void startIntentSender(IntentSender intent,
629 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
630 throws IntentSender.SendIntentException {
631 try {
632 String resolvedType = null;
633 if (fillInIntent != null) {
634 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
635 }
636 int result = ActivityManagerNative.getDefault()
637 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
638 fillInIntent, resolvedType, null, null,
639 0, flagsMask, flagsValues);
640 if (result == IActivityManager.START_CANCELED) {
641 throw new IntentSender.SendIntentException();
642 }
643 Instrumentation.checkStartActivityResult(result, null);
644 } catch (RemoteException e) {
645 }
646 }
647
648 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 public void sendBroadcast(Intent intent) {
650 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
651 try {
652 ActivityManagerNative.getDefault().broadcastIntent(
653 mMainThread.getApplicationThread(), intent, resolvedType, null,
654 Activity.RESULT_OK, null, null, null, false, false);
655 } catch (RemoteException e) {
656 }
657 }
658
659 @Override
660 public void sendBroadcast(Intent intent, String receiverPermission) {
661 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
662 try {
663 ActivityManagerNative.getDefault().broadcastIntent(
664 mMainThread.getApplicationThread(), intent, resolvedType, null,
665 Activity.RESULT_OK, null, null, receiverPermission, false, false);
666 } catch (RemoteException e) {
667 }
668 }
669
670 @Override
671 public void sendOrderedBroadcast(Intent intent,
672 String receiverPermission) {
673 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
674 try {
675 ActivityManagerNative.getDefault().broadcastIntent(
676 mMainThread.getApplicationThread(), intent, resolvedType, null,
677 Activity.RESULT_OK, null, null, receiverPermission, true, false);
678 } catch (RemoteException e) {
679 }
680 }
681
682 @Override
683 public void sendOrderedBroadcast(Intent intent,
684 String receiverPermission, BroadcastReceiver resultReceiver,
685 Handler scheduler, int initialCode, String initialData,
686 Bundle initialExtras) {
687 IIntentReceiver rd = null;
688 if (resultReceiver != null) {
689 if (mPackageInfo != null) {
690 if (scheduler == null) {
691 scheduler = mMainThread.getHandler();
692 }
693 rd = mPackageInfo.getReceiverDispatcher(
694 resultReceiver, getOuterContext(), scheduler,
695 mMainThread.getInstrumentation(), false);
696 } else {
697 if (scheduler == null) {
698 scheduler = mMainThread.getHandler();
699 }
700 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
701 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
702 }
703 }
704 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
705 try {
706 ActivityManagerNative.getDefault().broadcastIntent(
707 mMainThread.getApplicationThread(), intent, resolvedType, rd,
708 initialCode, initialData, initialExtras, receiverPermission,
709 true, false);
710 } catch (RemoteException e) {
711 }
712 }
713
714 @Override
715 public void sendStickyBroadcast(Intent intent) {
716 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
717 try {
718 ActivityManagerNative.getDefault().broadcastIntent(
719 mMainThread.getApplicationThread(), intent, resolvedType, null,
720 Activity.RESULT_OK, null, null, null, false, true);
721 } catch (RemoteException e) {
722 }
723 }
724
725 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700726 public void sendStickyOrderedBroadcast(Intent intent,
727 BroadcastReceiver resultReceiver,
728 Handler scheduler, int initialCode, String initialData,
729 Bundle initialExtras) {
730 IIntentReceiver rd = null;
731 if (resultReceiver != null) {
732 if (mPackageInfo != null) {
733 if (scheduler == null) {
734 scheduler = mMainThread.getHandler();
735 }
736 rd = mPackageInfo.getReceiverDispatcher(
737 resultReceiver, getOuterContext(), scheduler,
738 mMainThread.getInstrumentation(), false);
739 } else {
740 if (scheduler == null) {
741 scheduler = mMainThread.getHandler();
742 }
743 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
744 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
745 }
746 }
747 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
748 try {
749 ActivityManagerNative.getDefault().broadcastIntent(
750 mMainThread.getApplicationThread(), intent, resolvedType, rd,
751 initialCode, initialData, initialExtras, null,
752 true, true);
753 } catch (RemoteException e) {
754 }
755 }
756
757 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 public void removeStickyBroadcast(Intent intent) {
759 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
760 if (resolvedType != null) {
761 intent = new Intent(intent);
762 intent.setDataAndType(intent.getData(), resolvedType);
763 }
764 try {
765 ActivityManagerNative.getDefault().unbroadcastIntent(
766 mMainThread.getApplicationThread(), intent);
767 } catch (RemoteException e) {
768 }
769 }
770
771 @Override
772 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
773 return registerReceiver(receiver, filter, null, null);
774 }
775
776 @Override
777 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
778 String broadcastPermission, Handler scheduler) {
779 return registerReceiverInternal(receiver, filter, broadcastPermission,
780 scheduler, getOuterContext());
781 }
782
783 private Intent registerReceiverInternal(BroadcastReceiver receiver,
784 IntentFilter filter, String broadcastPermission,
785 Handler scheduler, Context context) {
786 IIntentReceiver rd = null;
787 if (receiver != null) {
788 if (mPackageInfo != null && context != null) {
789 if (scheduler == null) {
790 scheduler = mMainThread.getHandler();
791 }
792 rd = mPackageInfo.getReceiverDispatcher(
793 receiver, context, scheduler,
794 mMainThread.getInstrumentation(), true);
795 } else {
796 if (scheduler == null) {
797 scheduler = mMainThread.getHandler();
798 }
799 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700800 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802 }
803 try {
804 return ActivityManagerNative.getDefault().registerReceiver(
805 mMainThread.getApplicationThread(),
806 rd, filter, broadcastPermission);
807 } catch (RemoteException e) {
808 return null;
809 }
810 }
811
812 @Override
813 public void unregisterReceiver(BroadcastReceiver receiver) {
814 if (mPackageInfo != null) {
815 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
816 getOuterContext(), receiver);
817 try {
818 ActivityManagerNative.getDefault().unregisterReceiver(rd);
819 } catch (RemoteException e) {
820 }
821 } else {
822 throw new RuntimeException("Not supported in system context");
823 }
824 }
825
826 @Override
827 public ComponentName startService(Intent service) {
828 try {
829 ComponentName cn = ActivityManagerNative.getDefault().startService(
830 mMainThread.getApplicationThread(), service,
831 service.resolveTypeIfNeeded(getContentResolver()));
832 if (cn != null && cn.getPackageName().equals("!")) {
833 throw new SecurityException(
834 "Not allowed to start service " + service
835 + " without permission " + cn.getClassName());
836 }
837 return cn;
838 } catch (RemoteException e) {
839 return null;
840 }
841 }
842
843 @Override
844 public boolean stopService(Intent service) {
845 try {
846 int res = ActivityManagerNative.getDefault().stopService(
847 mMainThread.getApplicationThread(), service,
848 service.resolveTypeIfNeeded(getContentResolver()));
849 if (res < 0) {
850 throw new SecurityException(
851 "Not allowed to stop service " + service);
852 }
853 return res != 0;
854 } catch (RemoteException e) {
855 return false;
856 }
857 }
858
859 @Override
860 public boolean bindService(Intent service, ServiceConnection conn,
861 int flags) {
862 IServiceConnection sd;
863 if (mPackageInfo != null) {
864 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
865 mMainThread.getHandler(), flags);
866 } else {
867 throw new RuntimeException("Not supported in system context");
868 }
869 try {
870 int res = ActivityManagerNative.getDefault().bindService(
871 mMainThread.getApplicationThread(), getActivityToken(),
872 service, service.resolveTypeIfNeeded(getContentResolver()),
873 sd, flags);
874 if (res < 0) {
875 throw new SecurityException(
876 "Not allowed to bind to service " + service);
877 }
878 return res != 0;
879 } catch (RemoteException e) {
880 return false;
881 }
882 }
883
884 @Override
885 public void unbindService(ServiceConnection conn) {
886 if (mPackageInfo != null) {
887 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
888 getOuterContext(), conn);
889 try {
890 ActivityManagerNative.getDefault().unbindService(sd);
891 } catch (RemoteException e) {
892 }
893 } else {
894 throw new RuntimeException("Not supported in system context");
895 }
896 }
897
898 @Override
899 public boolean startInstrumentation(ComponentName className,
900 String profileFile, Bundle arguments) {
901 try {
902 return ActivityManagerNative.getDefault().startInstrumentation(
903 className, profileFile, 0, arguments, null);
904 } catch (RemoteException e) {
905 // System has crashed, nothing we can do.
906 }
907 return false;
908 }
909
910 @Override
911 public Object getSystemService(String name) {
912 if (WINDOW_SERVICE.equals(name)) {
913 return WindowManagerImpl.getDefault();
914 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
915 synchronized (mSync) {
916 LayoutInflater inflater = mLayoutInflater;
917 if (inflater != null) {
918 return inflater;
919 }
920 mLayoutInflater = inflater =
921 PolicyManager.makeNewLayoutInflater(getOuterContext());
922 return inflater;
923 }
924 } else if (ACTIVITY_SERVICE.equals(name)) {
925 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700926 } else if (INPUT_METHOD_SERVICE.equals(name)) {
927 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 } else if (ALARM_SERVICE.equals(name)) {
929 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700930 } else if (ACCOUNT_SERVICE.equals(name)) {
931 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 } else if (POWER_SERVICE.equals(name)) {
933 return getPowerManager();
934 } else if (CONNECTIVITY_SERVICE.equals(name)) {
935 return getConnectivityManager();
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700936 } else if (THROTTLE_SERVICE.equals(name)) {
937 return getThrottleManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 } else if (WIFI_SERVICE.equals(name)) {
939 return getWifiManager();
940 } else if (NOTIFICATION_SERVICE.equals(name)) {
941 return getNotificationManager();
942 } else if (KEYGUARD_SERVICE.equals(name)) {
943 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700944 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
945 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 } else if (LOCATION_SERVICE.equals(name)) {
947 return getLocationManager();
948 } else if (SEARCH_SERVICE.equals(name)) {
949 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700950 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800952 } else if (STORAGE_SERVICE.equals(name)) {
953 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 } else if (VIBRATOR_SERVICE.equals(name)) {
955 return getVibrator();
956 } else if (STATUS_BAR_SERVICE.equals(name)) {
957 synchronized (mSync) {
958 if (mStatusBarManager == null) {
959 mStatusBarManager = new StatusBarManager(getOuterContext());
960 }
961 return mStatusBarManager;
962 }
963 } else if (AUDIO_SERVICE.equals(name)) {
964 return getAudioManager();
965 } else if (TELEPHONY_SERVICE.equals(name)) {
966 return getTelephonyManager();
967 } else if (CLIPBOARD_SERVICE.equals(name)) {
968 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700969 } else if (WALLPAPER_SERVICE.equals(name)) {
970 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700971 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800972 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800973 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
974 return getDevicePolicyManager();
Tobias Haamel69fb5742010-02-22 21:54:05 +0100975 } else if (UI_MODE_SERVICE.equals(name)) {
Tobias Haamel53332882010-02-18 16:15:43 -0800976 return getUiModeManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 }
978
979 return null;
980 }
981
Fred Quintana60307342009-03-24 22:48:12 -0700982 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700983 synchronized (mSync) {
984 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -0700985 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
986 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -0700987 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -0700988 }
Fred Quintanae00a3112009-09-22 15:13:30 -0700989 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -0700990 }
Fred Quintana60307342009-03-24 22:48:12 -0700991 }
992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 private ActivityManager getActivityManager() {
994 synchronized (mSync) {
995 if (mActivityManager == null) {
996 mActivityManager = new ActivityManager(getOuterContext(),
997 mMainThread.getHandler());
998 }
999 }
1000 return mActivityManager;
1001 }
1002
1003 private AlarmManager getAlarmManager() {
1004 synchronized (sSync) {
1005 if (sAlarmManager == null) {
1006 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1007 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1008 sAlarmManager = new AlarmManager(service);
1009 }
1010 }
1011 return sAlarmManager;
1012 }
1013
1014 private PowerManager getPowerManager() {
1015 synchronized (sSync) {
1016 if (sPowerManager == null) {
1017 IBinder b = ServiceManager.getService(POWER_SERVICE);
1018 IPowerManager service = IPowerManager.Stub.asInterface(b);
1019 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1020 }
1021 }
1022 return sPowerManager;
1023 }
1024
1025 private ConnectivityManager getConnectivityManager()
1026 {
1027 synchronized (sSync) {
1028 if (sConnectivityManager == null) {
1029 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1030 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1031 sConnectivityManager = new ConnectivityManager(service);
1032 }
1033 }
1034 return sConnectivityManager;
1035 }
1036
Irfan Sheriffc9b68512010-04-08 14:12:33 -07001037 private ThrottleManager getThrottleManager()
1038 {
1039 synchronized (sSync) {
1040 if (sThrottleManager == null) {
1041 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1042 IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1043 sThrottleManager = new ThrottleManager(service);
1044 }
1045 }
1046 return sThrottleManager;
1047 }
1048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 private WifiManager getWifiManager()
1050 {
1051 synchronized (sSync) {
1052 if (sWifiManager == null) {
1053 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1054 IWifiManager service = IWifiManager.Stub.asInterface(b);
1055 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1056 }
1057 }
1058 return sWifiManager;
1059 }
1060
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001061 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 synchronized (mSync) {
1063 if (mNotificationManager == null) {
1064 mNotificationManager = new NotificationManager(
1065 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1066 mMainThread.getHandler());
1067 }
1068 }
1069 return mNotificationManager;
1070 }
1071
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001072 private WallpaperManager getWallpaperManager() {
1073 synchronized (mSync) {
1074 if (mWallpaperManager == null) {
1075 mWallpaperManager = new WallpaperManager(getOuterContext(),
1076 mMainThread.getHandler());
1077 }
1078 }
1079 return mWallpaperManager;
1080 }
1081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 private TelephonyManager getTelephonyManager() {
1083 synchronized (mSync) {
1084 if (mTelephonyManager == null) {
1085 mTelephonyManager = new TelephonyManager(getOuterContext());
1086 }
1087 }
1088 return mTelephonyManager;
1089 }
1090
1091 private ClipboardManager getClipboardManager() {
1092 synchronized (mSync) {
1093 if (mClipboardManager == null) {
1094 mClipboardManager = new ClipboardManager(getOuterContext(),
1095 mMainThread.getHandler());
1096 }
1097 }
1098 return mClipboardManager;
1099 }
1100
1101 private LocationManager getLocationManager() {
1102 synchronized (sSync) {
1103 if (sLocationManager == null) {
1104 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1105 ILocationManager service = ILocationManager.Stub.asInterface(b);
1106 sLocationManager = new LocationManager(service);
1107 }
1108 }
1109 return sLocationManager;
1110 }
1111
1112 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 synchronized (mSync) {
1114 if (mSearchManager == null) {
1115 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1116 }
1117 }
1118 return mSearchManager;
1119 }
1120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 private SensorManager getSensorManager() {
1122 synchronized (mSync) {
1123 if (mSensorManager == null) {
1124 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1125 }
1126 }
1127 return mSensorManager;
1128 }
1129
San Mehatc9d81752010-02-01 10:23:27 -08001130 private StorageManager getStorageManager() {
1131 synchronized (mSync) {
1132 if (mStorageManager == null) {
1133 try {
1134 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1135 } catch (RemoteException rex) {
1136 Log.e(TAG, "Failed to create StorageManager", rex);
1137 mStorageManager = null;
1138 }
1139 }
1140 }
1141 return mStorageManager;
1142 }
1143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 private Vibrator getVibrator() {
1145 synchronized (mSync) {
1146 if (mVibrator == null) {
1147 mVibrator = new Vibrator();
1148 }
1149 }
1150 return mVibrator;
1151 }
Dan Egnor95240272009-10-27 18:23:39 -07001152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 private AudioManager getAudioManager()
1154 {
1155 if (mAudioManager == null) {
1156 mAudioManager = new AudioManager(this);
1157 }
1158 return mAudioManager;
1159 }
1160
Dan Egnorf18a01c2009-11-12 11:32:50 -08001161 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001162 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001163 if (mDropBoxManager == null) {
Dan Egnor95240272009-10-27 18:23:39 -07001164 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
Dan Egnorf18a01c2009-11-12 11:32:50 -08001165 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1166 mDropBoxManager = new DropBoxManager(service);
Dan Egnor95240272009-10-27 18:23:39 -07001167 }
1168 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001169 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001170 }
1171
Dianne Hackbornd6847842010-01-12 18:14:19 -08001172 private DevicePolicyManager getDevicePolicyManager() {
1173 synchronized (mSync) {
1174 if (mDevicePolicyManager == null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001175 mDevicePolicyManager = DevicePolicyManager.create(this,
Dianne Hackbornd6847842010-01-12 18:14:19 -08001176 mMainThread.getHandler());
1177 }
1178 }
1179 return mDevicePolicyManager;
1180 }
1181
Tobias Haamel53332882010-02-18 16:15:43 -08001182 private UiModeManager getUiModeManager() {
1183 synchronized (mSync) {
1184 if (mUiModeManager == null) {
1185 mUiModeManager = new UiModeManager();
1186 }
1187 }
1188 return mUiModeManager;
1189 }
1190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 @Override
1192 public int checkPermission(String permission, int pid, int uid) {
1193 if (permission == null) {
1194 throw new IllegalArgumentException("permission is null");
1195 }
1196
1197 if (!Process.supportsProcesses()) {
1198 return PackageManager.PERMISSION_GRANTED;
1199 }
1200 try {
1201 return ActivityManagerNative.getDefault().checkPermission(
1202 permission, pid, uid);
1203 } catch (RemoteException e) {
1204 return PackageManager.PERMISSION_DENIED;
1205 }
1206 }
1207
1208 @Override
1209 public int checkCallingPermission(String permission) {
1210 if (permission == null) {
1211 throw new IllegalArgumentException("permission is null");
1212 }
1213
1214 if (!Process.supportsProcesses()) {
1215 return PackageManager.PERMISSION_GRANTED;
1216 }
1217 int pid = Binder.getCallingPid();
1218 if (pid != Process.myPid()) {
1219 return checkPermission(permission, pid,
1220 Binder.getCallingUid());
1221 }
1222 return PackageManager.PERMISSION_DENIED;
1223 }
1224
1225 @Override
1226 public int checkCallingOrSelfPermission(String permission) {
1227 if (permission == null) {
1228 throw new IllegalArgumentException("permission is null");
1229 }
1230
1231 return checkPermission(permission, Binder.getCallingPid(),
1232 Binder.getCallingUid());
1233 }
1234
1235 private void enforce(
1236 String permission, int resultOfCheck,
1237 boolean selfToo, int uid, String message) {
1238 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1239 throw new SecurityException(
1240 (message != null ? (message + ": ") : "") +
1241 (selfToo
1242 ? "Neither user " + uid + " nor current process has "
1243 : "User " + uid + " does not have ") +
1244 permission +
1245 ".");
1246 }
1247 }
1248
1249 public void enforcePermission(
1250 String permission, int pid, int uid, String message) {
1251 enforce(permission,
1252 checkPermission(permission, pid, uid),
1253 false,
1254 uid,
1255 message);
1256 }
1257
1258 public void enforceCallingPermission(String permission, String message) {
1259 enforce(permission,
1260 checkCallingPermission(permission),
1261 false,
1262 Binder.getCallingUid(),
1263 message);
1264 }
1265
1266 public void enforceCallingOrSelfPermission(
1267 String permission, String message) {
1268 enforce(permission,
1269 checkCallingOrSelfPermission(permission),
1270 true,
1271 Binder.getCallingUid(),
1272 message);
1273 }
1274
1275 @Override
1276 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1277 try {
1278 ActivityManagerNative.getDefault().grantUriPermission(
1279 mMainThread.getApplicationThread(), toPackage, uri,
1280 modeFlags);
1281 } catch (RemoteException e) {
1282 }
1283 }
1284
1285 @Override
1286 public void revokeUriPermission(Uri uri, int modeFlags) {
1287 try {
1288 ActivityManagerNative.getDefault().revokeUriPermission(
1289 mMainThread.getApplicationThread(), uri,
1290 modeFlags);
1291 } catch (RemoteException e) {
1292 }
1293 }
1294
1295 @Override
1296 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1297 if (!Process.supportsProcesses()) {
1298 return PackageManager.PERMISSION_GRANTED;
1299 }
1300 try {
1301 return ActivityManagerNative.getDefault().checkUriPermission(
1302 uri, pid, uid, modeFlags);
1303 } catch (RemoteException e) {
1304 return PackageManager.PERMISSION_DENIED;
1305 }
1306 }
1307
1308 @Override
1309 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1310 if (!Process.supportsProcesses()) {
1311 return PackageManager.PERMISSION_GRANTED;
1312 }
1313 int pid = Binder.getCallingPid();
1314 if (pid != Process.myPid()) {
1315 return checkUriPermission(uri, pid,
1316 Binder.getCallingUid(), modeFlags);
1317 }
1318 return PackageManager.PERMISSION_DENIED;
1319 }
1320
1321 @Override
1322 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1323 return checkUriPermission(uri, Binder.getCallingPid(),
1324 Binder.getCallingUid(), modeFlags);
1325 }
1326
1327 @Override
1328 public int checkUriPermission(Uri uri, String readPermission,
1329 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001330 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1332 + readPermission + " writePermission=" + writePermission
1333 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1334 }
1335 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1336 if (readPermission == null
1337 || checkPermission(readPermission, pid, uid)
1338 == PackageManager.PERMISSION_GRANTED) {
1339 return PackageManager.PERMISSION_GRANTED;
1340 }
1341 }
1342 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1343 if (writePermission == null
1344 || checkPermission(writePermission, pid, uid)
1345 == PackageManager.PERMISSION_GRANTED) {
1346 return PackageManager.PERMISSION_GRANTED;
1347 }
1348 }
1349 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1350 : PackageManager.PERMISSION_DENIED;
1351 }
1352
1353 private String uriModeFlagToString(int uriModeFlags) {
1354 switch (uriModeFlags) {
1355 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1356 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1357 return "read and write";
1358 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1359 return "read";
1360 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1361 return "write";
1362 }
1363 throw new IllegalArgumentException(
1364 "Unknown permission mode flags: " + uriModeFlags);
1365 }
1366
1367 private void enforceForUri(
1368 int modeFlags, int resultOfCheck, boolean selfToo,
1369 int uid, Uri uri, String message) {
1370 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1371 throw new SecurityException(
1372 (message != null ? (message + ": ") : "") +
1373 (selfToo
1374 ? "Neither user " + uid + " nor current process has "
1375 : "User " + uid + " does not have ") +
1376 uriModeFlagToString(modeFlags) +
1377 " permission on " +
1378 uri +
1379 ".");
1380 }
1381 }
1382
1383 public void enforceUriPermission(
1384 Uri uri, int pid, int uid, int modeFlags, String message) {
1385 enforceForUri(
1386 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1387 false, uid, uri, message);
1388 }
1389
1390 public void enforceCallingUriPermission(
1391 Uri uri, int modeFlags, String message) {
1392 enforceForUri(
1393 modeFlags, checkCallingUriPermission(uri, modeFlags),
1394 false, Binder.getCallingUid(), uri, message);
1395 }
1396
1397 public void enforceCallingOrSelfUriPermission(
1398 Uri uri, int modeFlags, String message) {
1399 enforceForUri(
1400 modeFlags,
1401 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1402 Binder.getCallingUid(), uri, message);
1403 }
1404
1405 public void enforceUriPermission(
1406 Uri uri, String readPermission, String writePermission,
1407 int pid, int uid, int modeFlags, String message) {
1408 enforceForUri(modeFlags,
1409 checkUriPermission(
1410 uri, readPermission, writePermission, pid, uid,
1411 modeFlags),
1412 false,
1413 uid,
1414 uri,
1415 message);
1416 }
1417
1418 @Override
1419 public Context createPackageContext(String packageName, int flags)
1420 throws PackageManager.NameNotFoundException {
1421 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001422 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424
1425 ActivityThread.PackageInfo pi =
1426 mMainThread.getPackageInfo(packageName, flags);
1427 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001428 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001429 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001430 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 if (c.mResources != null) {
1432 return c;
1433 }
1434 }
1435
1436 // Should be a better exception.
1437 throw new PackageManager.NameNotFoundException(
1438 "Application package " + packageName + " not found");
1439 }
1440
Romain Guy870e09f2009-07-06 16:35:25 -07001441 @Override
1442 public boolean isRestricted() {
1443 return mRestricted;
1444 }
1445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 private File getDataDirFile() {
1447 if (mPackageInfo != null) {
1448 return mPackageInfo.getDataDirFile();
1449 }
1450 throw new RuntimeException("Not supported in system context");
1451 }
1452
1453 @Override
1454 public File getDir(String name, int mode) {
1455 name = "app_" + name;
1456 File file = makeFilename(getDataDirFile(), name);
1457 if (!file.exists()) {
1458 file.mkdir();
1459 setFilePermissionsFromMode(file.getPath(), mode,
1460 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1461 }
1462 return file;
1463 }
1464
Dianne Hackborn21556372010-02-04 16:34:40 -08001465 static ContextImpl createSystemContext(ActivityThread mainThread) {
1466 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 context.init(Resources.getSystem(), mainThread);
1468 return context;
1469 }
1470
Dianne Hackborn21556372010-02-04 16:34:40 -08001471 ContextImpl() {
Carl Shapiro82fe5642010-02-24 00:14:23 -08001472 // For debug only
1473 //++sInstanceCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 mOuterContext = this;
1475 }
1476
1477 /**
1478 * Create a new ApplicationContext from an existing one. The new one
1479 * works and operates the same as the one it is copying.
1480 *
1481 * @param context Existing application context.
1482 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001483 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 ++sInstanceCount;
1485 mPackageInfo = context.mPackageInfo;
1486 mResources = context.mResources;
1487 mMainThread = context.mMainThread;
1488 mContentResolver = context.mContentResolver;
1489 mOuterContext = this;
1490 }
1491
1492 final void init(ActivityThread.PackageInfo packageInfo,
1493 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001494 init(packageInfo, activityToken, mainThread, null);
1495 }
1496
1497 final void init(ActivityThread.PackageInfo packageInfo,
1498 IBinder activityToken, ActivityThread mainThread,
1499 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 mPackageInfo = packageInfo;
1501 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001502
Dianne Hackborn559a7872010-04-07 18:19:41 -07001503 if (mResources != null && container != null
1504 && container.getCompatibilityInfo().applicationScale !=
1505 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001506 if (DEBUG) {
1507 Log.d(TAG, "loaded context has different scaling. Using container's" +
1508 " compatiblity info:" + container.getDisplayMetrics());
1509 }
1510 mResources = mainThread.getTopLevelResources(
1511 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 mMainThread = mainThread;
1514 mContentResolver = new ApplicationContentResolver(this, mainThread);
1515
1516 setActivityToken(activityToken);
1517 }
1518
1519 final void init(Resources resources, ActivityThread mainThread) {
1520 mPackageInfo = null;
1521 mResources = resources;
1522 mMainThread = mainThread;
1523 mContentResolver = new ApplicationContentResolver(this, mainThread);
1524 }
1525
1526 final void scheduleFinalCleanup(String who, String what) {
1527 mMainThread.scheduleContextCleanup(this, who, what);
1528 }
1529
1530 final void performFinalCleanup(String who, String what) {
1531 //Log.i(TAG, "Cleanup up context: " + this);
1532 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1533 }
1534
1535 final Context getReceiverRestrictedContext() {
1536 if (mReceiverRestrictedContext != null) {
1537 return mReceiverRestrictedContext;
1538 }
1539 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1540 }
1541
1542 final void setActivityToken(IBinder token) {
1543 mActivityToken = token;
1544 }
1545
1546 final void setOuterContext(Context context) {
1547 mOuterContext = context;
1548 }
1549
1550 final Context getOuterContext() {
1551 return mOuterContext;
1552 }
1553
1554 final IBinder getActivityToken() {
1555 return mActivityToken;
1556 }
1557
1558 private static void setFilePermissionsFromMode(String name, int mode,
1559 int extraPermissions) {
1560 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1561 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1562 |extraPermissions;
1563 if ((mode&MODE_WORLD_READABLE) != 0) {
1564 perms |= FileUtils.S_IROTH;
1565 }
1566 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1567 perms |= FileUtils.S_IWOTH;
1568 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001569 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1571 + ", perms=0x" + Integer.toHexString(perms));
1572 }
1573 FileUtils.setPermissions(name, perms, -1, -1);
1574 }
1575
Oscar Montemayora8529f62009-11-18 10:14:20 -08001576 private File validateFilePath(String name, boolean createDirectory) {
1577 File dir;
1578 File f;
1579
1580 if (name.charAt(0) == File.separatorChar) {
1581 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1582 dir = new File(dirPath);
1583 name = name.substring(name.lastIndexOf(File.separatorChar));
1584 f = new File(dir, name);
1585 } else {
1586 dir = getDatabasesDir();
1587 f = makeFilename(dir, name);
1588 }
1589
1590 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1591 FileUtils.setPermissions(dir.getPath(),
1592 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1593 -1, -1);
1594 }
1595
1596 return f;
1597 }
1598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 private File makeFilename(File base, String name) {
1600 if (name.indexOf(File.separatorChar) < 0) {
1601 return new File(base, name);
1602 }
1603 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001604 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 }
1606
1607 // ----------------------------------------------------------------------
1608 // ----------------------------------------------------------------------
1609 // ----------------------------------------------------------------------
1610
1611 private static final class ApplicationContentResolver extends ContentResolver {
1612 public ApplicationContentResolver(Context context,
1613 ActivityThread mainThread)
1614 {
1615 super(context);
1616 mMainThread = mainThread;
1617 }
1618
1619 @Override
1620 protected IContentProvider acquireProvider(Context context, String name)
1621 {
1622 return mMainThread.acquireProvider(context, name);
1623 }
1624
1625 @Override
1626 public boolean releaseProvider(IContentProvider provider)
1627 {
1628 return mMainThread.releaseProvider(provider);
1629 }
1630
1631 private final ActivityThread mMainThread;
1632 }
1633
1634 // ----------------------------------------------------------------------
1635 // ----------------------------------------------------------------------
1636 // ----------------------------------------------------------------------
1637
1638 /*package*/
1639 static final class ApplicationPackageManager extends PackageManager {
1640 @Override
1641 public PackageInfo getPackageInfo(String packageName, int flags)
1642 throws NameNotFoundException {
1643 try {
1644 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1645 if (pi != null) {
1646 return pi;
1647 }
1648 } catch (RemoteException e) {
1649 throw new RuntimeException("Package manager has died", e);
1650 }
1651
1652 throw new NameNotFoundException(packageName);
1653 }
1654
Mihai Predaeae850c2009-05-13 10:13:48 +02001655 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001656 public String[] currentToCanonicalPackageNames(String[] names) {
1657 try {
1658 return mPM.currentToCanonicalPackageNames(names);
1659 } catch (RemoteException e) {
1660 throw new RuntimeException("Package manager has died", e);
1661 }
1662 }
1663
1664 @Override
1665 public String[] canonicalToCurrentPackageNames(String[] names) {
1666 try {
1667 return mPM.canonicalToCurrentPackageNames(names);
1668 } catch (RemoteException e) {
1669 throw new RuntimeException("Package manager has died", e);
1670 }
1671 }
1672
1673 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001674 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 // First see if the package has an INFO activity; the existence of
1676 // such an activity is implied to be the desired front-door for the
1677 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001678 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1679 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001680 intentToResolve.setPackage(packageName);
1681 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001684 if (resolveInfo == null) {
1685 // reuse the intent instance
1686 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1687 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001688 intentToResolve.setPackage(packageName);
1689 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001690 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001691 if (resolveInfo == null) {
1692 return null;
1693 }
1694 Intent intent = new Intent(Intent.ACTION_MAIN);
1695 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1696 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1697 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001698 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001700 @Override
1701 public int[] getPackageGids(String packageName)
1702 throws NameNotFoundException {
1703 try {
1704 int[] gids = mPM.getPackageGids(packageName);
1705 if (gids == null || gids.length > 0) {
1706 return gids;
1707 }
1708 } catch (RemoteException e) {
1709 throw new RuntimeException("Package manager has died", e);
1710 }
1711
1712 throw new NameNotFoundException(packageName);
1713 }
1714
1715 @Override
1716 public PermissionInfo getPermissionInfo(String name, int flags)
1717 throws NameNotFoundException {
1718 try {
1719 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1720 if (pi != null) {
1721 return pi;
1722 }
1723 } catch (RemoteException e) {
1724 throw new RuntimeException("Package manager has died", e);
1725 }
1726
1727 throw new NameNotFoundException(name);
1728 }
1729
1730 @Override
1731 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1732 throws NameNotFoundException {
1733 try {
1734 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1735 if (pi != null) {
1736 return pi;
1737 }
1738 } catch (RemoteException e) {
1739 throw new RuntimeException("Package manager has died", e);
1740 }
1741
1742 throw new NameNotFoundException(group);
1743 }
1744
1745 @Override
1746 public PermissionGroupInfo getPermissionGroupInfo(String name,
1747 int flags) throws NameNotFoundException {
1748 try {
1749 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1750 if (pgi != null) {
1751 return pgi;
1752 }
1753 } catch (RemoteException e) {
1754 throw new RuntimeException("Package manager has died", e);
1755 }
1756
1757 throw new NameNotFoundException(name);
1758 }
1759
1760 @Override
1761 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1762 try {
1763 return mPM.getAllPermissionGroups(flags);
1764 } catch (RemoteException e) {
1765 throw new RuntimeException("Package manager has died", e);
1766 }
1767 }
1768
1769 @Override
1770 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1771 throws NameNotFoundException {
1772 try {
1773 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1774 if (ai != null) {
1775 return ai;
1776 }
1777 } catch (RemoteException e) {
1778 throw new RuntimeException("Package manager has died", e);
1779 }
1780
1781 throw new NameNotFoundException(packageName);
1782 }
1783
1784 @Override
1785 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1786 throws NameNotFoundException {
1787 try {
1788 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1789 if (ai != null) {
1790 return ai;
1791 }
1792 } catch (RemoteException e) {
1793 throw new RuntimeException("Package manager has died", e);
1794 }
1795
1796 throw new NameNotFoundException(className.toString());
1797 }
1798
1799 @Override
1800 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1801 throws NameNotFoundException {
1802 try {
1803 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1804 if (ai != null) {
1805 return ai;
1806 }
1807 } catch (RemoteException e) {
1808 throw new RuntimeException("Package manager has died", e);
1809 }
1810
1811 throw new NameNotFoundException(className.toString());
1812 }
1813
1814 @Override
1815 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1816 throws NameNotFoundException {
1817 try {
1818 ServiceInfo si = mPM.getServiceInfo(className, flags);
1819 if (si != null) {
1820 return si;
1821 }
1822 } catch (RemoteException e) {
1823 throw new RuntimeException("Package manager has died", e);
1824 }
1825
1826 throw new NameNotFoundException(className.toString());
1827 }
1828
1829 @Override
1830 public String[] getSystemSharedLibraryNames() {
1831 try {
1832 return mPM.getSystemSharedLibraryNames();
1833 } catch (RemoteException e) {
1834 throw new RuntimeException("Package manager has died", e);
1835 }
1836 }
1837
1838 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001839 public FeatureInfo[] getSystemAvailableFeatures() {
1840 try {
1841 return mPM.getSystemAvailableFeatures();
1842 } catch (RemoteException e) {
1843 throw new RuntimeException("Package manager has died", e);
1844 }
1845 }
1846
1847 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001848 public boolean hasSystemFeature(String name) {
1849 try {
1850 return mPM.hasSystemFeature(name);
1851 } catch (RemoteException e) {
1852 throw new RuntimeException("Package manager has died", e);
1853 }
1854 }
1855
1856 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 public int checkPermission(String permName, String pkgName) {
1858 try {
1859 return mPM.checkPermission(permName, pkgName);
1860 } catch (RemoteException e) {
1861 throw new RuntimeException("Package manager has died", e);
1862 }
1863 }
1864
1865 @Override
1866 public boolean addPermission(PermissionInfo info) {
1867 try {
1868 return mPM.addPermission(info);
1869 } catch (RemoteException e) {
1870 throw new RuntimeException("Package manager has died", e);
1871 }
1872 }
1873
1874 @Override
Dianne Hackbornd7c09682010-03-30 10:42:20 -07001875 public boolean addPermissionAsync(PermissionInfo info) {
1876 try {
1877 return mPM.addPermissionAsync(info);
1878 } catch (RemoteException e) {
1879 throw new RuntimeException("Package manager has died", e);
1880 }
1881 }
1882
1883 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 public void removePermission(String name) {
1885 try {
1886 mPM.removePermission(name);
1887 } catch (RemoteException e) {
1888 throw new RuntimeException("Package manager has died", e);
1889 }
1890 }
1891
1892 @Override
1893 public int checkSignatures(String pkg1, String pkg2) {
1894 try {
1895 return mPM.checkSignatures(pkg1, pkg2);
1896 } catch (RemoteException e) {
1897 throw new RuntimeException("Package manager has died", e);
1898 }
1899 }
1900
1901 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001902 public int checkSignatures(int uid1, int uid2) {
1903 try {
1904 return mPM.checkUidSignatures(uid1, uid2);
1905 } catch (RemoteException e) {
1906 throw new RuntimeException("Package manager has died", e);
1907 }
1908 }
1909
1910 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 public String[] getPackagesForUid(int uid) {
1912 try {
1913 return mPM.getPackagesForUid(uid);
1914 } catch (RemoteException e) {
1915 throw new RuntimeException("Package manager has died", e);
1916 }
1917 }
1918
1919 @Override
1920 public String getNameForUid(int uid) {
1921 try {
1922 return mPM.getNameForUid(uid);
1923 } catch (RemoteException e) {
1924 throw new RuntimeException("Package manager has died", e);
1925 }
1926 }
1927
1928 @Override
1929 public int getUidForSharedUser(String sharedUserName)
1930 throws NameNotFoundException {
1931 try {
1932 int uid = mPM.getUidForSharedUser(sharedUserName);
1933 if(uid != -1) {
1934 return uid;
1935 }
1936 } catch (RemoteException e) {
1937 throw new RuntimeException("Package manager has died", e);
1938 }
1939 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1940 }
1941
1942 @Override
1943 public List<PackageInfo> getInstalledPackages(int flags) {
1944 try {
1945 return mPM.getInstalledPackages(flags);
1946 } catch (RemoteException e) {
1947 throw new RuntimeException("Package manager has died", e);
1948 }
1949 }
1950
1951 @Override
1952 public List<ApplicationInfo> getInstalledApplications(int flags) {
1953 try {
1954 return mPM.getInstalledApplications(flags);
1955 } catch (RemoteException e) {
1956 throw new RuntimeException("Package manager has died", e);
1957 }
1958 }
1959
1960 @Override
1961 public ResolveInfo resolveActivity(Intent intent, int flags) {
1962 try {
1963 return mPM.resolveIntent(
1964 intent,
1965 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1966 flags);
1967 } catch (RemoteException e) {
1968 throw new RuntimeException("Package manager has died", e);
1969 }
1970 }
1971
1972 @Override
1973 public List<ResolveInfo> queryIntentActivities(Intent intent,
1974 int flags) {
1975 try {
1976 return mPM.queryIntentActivities(
1977 intent,
1978 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1979 flags);
1980 } catch (RemoteException e) {
1981 throw new RuntimeException("Package manager has died", e);
1982 }
1983 }
1984
1985 @Override
1986 public List<ResolveInfo> queryIntentActivityOptions(
1987 ComponentName caller, Intent[] specifics, Intent intent,
1988 int flags) {
1989 final ContentResolver resolver = mContext.getContentResolver();
1990
1991 String[] specificTypes = null;
1992 if (specifics != null) {
1993 final int N = specifics.length;
1994 for (int i=0; i<N; i++) {
1995 Intent sp = specifics[i];
1996 if (sp != null) {
1997 String t = sp.resolveTypeIfNeeded(resolver);
1998 if (t != null) {
1999 if (specificTypes == null) {
2000 specificTypes = new String[N];
2001 }
2002 specificTypes[i] = t;
2003 }
2004 }
2005 }
2006 }
2007
2008 try {
2009 return mPM.queryIntentActivityOptions(caller, specifics,
2010 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2011 flags);
2012 } catch (RemoteException e) {
2013 throw new RuntimeException("Package manager has died", e);
2014 }
2015 }
2016
2017 @Override
2018 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2019 try {
2020 return mPM.queryIntentReceivers(
2021 intent,
2022 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2023 flags);
2024 } catch (RemoteException e) {
2025 throw new RuntimeException("Package manager has died", e);
2026 }
2027 }
2028
2029 @Override
2030 public ResolveInfo resolveService(Intent intent, int flags) {
2031 try {
2032 return mPM.resolveService(
2033 intent,
2034 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2035 flags);
2036 } catch (RemoteException e) {
2037 throw new RuntimeException("Package manager has died", e);
2038 }
2039 }
2040
2041 @Override
2042 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2043 try {
2044 return mPM.queryIntentServices(
2045 intent,
2046 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2047 flags);
2048 } catch (RemoteException e) {
2049 throw new RuntimeException("Package manager has died", e);
2050 }
2051 }
2052
2053 @Override
2054 public ProviderInfo resolveContentProvider(String name,
2055 int flags) {
2056 try {
2057 return mPM.resolveContentProvider(name, flags);
2058 } catch (RemoteException e) {
2059 throw new RuntimeException("Package manager has died", e);
2060 }
2061 }
2062
2063 @Override
2064 public List<ProviderInfo> queryContentProviders(String processName,
2065 int uid, int flags) {
2066 try {
2067 return mPM.queryContentProviders(processName, uid, flags);
2068 } catch (RemoteException e) {
2069 throw new RuntimeException("Package manager has died", e);
2070 }
2071 }
2072
2073 @Override
2074 public InstrumentationInfo getInstrumentationInfo(
2075 ComponentName className, int flags)
2076 throws NameNotFoundException {
2077 try {
2078 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2079 className, flags);
2080 if (ii != null) {
2081 return ii;
2082 }
2083 } catch (RemoteException e) {
2084 throw new RuntimeException("Package manager has died", e);
2085 }
2086
2087 throw new NameNotFoundException(className.toString());
2088 }
2089
2090 @Override
2091 public List<InstrumentationInfo> queryInstrumentation(
2092 String targetPackage, int flags) {
2093 try {
2094 return mPM.queryInstrumentation(targetPackage, flags);
2095 } catch (RemoteException e) {
2096 throw new RuntimeException("Package manager has died", e);
2097 }
2098 }
2099
2100 @Override public Drawable getDrawable(String packageName, int resid,
2101 ApplicationInfo appInfo) {
2102 ResourceName name = new ResourceName(packageName, resid);
2103 Drawable dr = getCachedIcon(name);
2104 if (dr != null) {
2105 return dr;
2106 }
2107 if (appInfo == null) {
2108 try {
2109 appInfo = getApplicationInfo(packageName, 0);
2110 } catch (NameNotFoundException e) {
2111 return null;
2112 }
2113 }
2114 try {
2115 Resources r = getResourcesForApplication(appInfo);
2116 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002117 if (false) {
2118 RuntimeException e = new RuntimeException("here");
2119 e.fillInStackTrace();
2120 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2121 + " from package " + packageName
2122 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2123 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2124 e);
2125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2127 + Integer.toHexString(resid) + " from " + r
2128 + ": " + dr);
2129 putCachedIcon(name, dr);
2130 return dr;
2131 } catch (NameNotFoundException e) {
2132 Log.w("PackageManager", "Failure retrieving resources for"
2133 + appInfo.packageName);
2134 } catch (RuntimeException e) {
2135 // If an exception was thrown, fall through to return
2136 // default icon.
2137 Log.w("PackageManager", "Failure retrieving icon 0x"
2138 + Integer.toHexString(resid) + " in package "
2139 + packageName, e);
2140 }
2141 return null;
2142 }
2143
2144 @Override public Drawable getActivityIcon(ComponentName activityName)
2145 throws NameNotFoundException {
2146 return getActivityInfo(activityName, 0).loadIcon(this);
2147 }
2148
2149 @Override public Drawable getActivityIcon(Intent intent)
2150 throws NameNotFoundException {
2151 if (intent.getComponent() != null) {
2152 return getActivityIcon(intent.getComponent());
2153 }
2154
2155 ResolveInfo info = resolveActivity(
2156 intent, PackageManager.MATCH_DEFAULT_ONLY);
2157 if (info != null) {
2158 return info.activityInfo.loadIcon(this);
2159 }
2160
2161 throw new NameNotFoundException(intent.toURI());
2162 }
2163
2164 @Override public Drawable getDefaultActivityIcon() {
2165 return Resources.getSystem().getDrawable(
2166 com.android.internal.R.drawable.sym_def_app_icon);
2167 }
2168
2169 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002170 return info.loadIcon(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 }
2172
2173 @Override public Drawable getApplicationIcon(String packageName)
2174 throws NameNotFoundException {
2175 return getApplicationIcon(getApplicationInfo(packageName, 0));
2176 }
Adam Powell81cd2e92010-04-21 16:35:18 -07002177
2178 @Override
2179 public Drawable getActivityLogo(ComponentName activityName)
2180 throws NameNotFoundException {
2181 return getActivityInfo(activityName, 0).loadLogo(this);
2182 }
2183
2184 @Override
2185 public Drawable getActivityLogo(Intent intent)
2186 throws NameNotFoundException {
2187 if (intent.getComponent() != null) {
2188 return getActivityLogo(intent.getComponent());
2189 }
2190
2191 ResolveInfo info = resolveActivity(
2192 intent, PackageManager.MATCH_DEFAULT_ONLY);
2193 if (info != null) {
2194 return info.activityInfo.loadLogo(this);
2195 }
2196
2197 throw new NameNotFoundException(intent.toUri(0));
2198 }
2199
2200 @Override
2201 public Drawable getApplicationLogo(ApplicationInfo info) {
2202 return info.loadLogo(this);
2203 }
2204
2205 @Override
2206 public Drawable getApplicationLogo(String packageName)
2207 throws NameNotFoundException {
2208 return getApplicationLogo(getApplicationInfo(packageName, 0));
2209 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210
2211 @Override public Resources getResourcesForActivity(
2212 ComponentName activityName) throws NameNotFoundException {
2213 return getResourcesForApplication(
2214 getActivityInfo(activityName, 0).applicationInfo);
2215 }
2216
2217 @Override public Resources getResourcesForApplication(
2218 ApplicationInfo app) throws NameNotFoundException {
2219 if (app.packageName.equals("system")) {
2220 return mContext.mMainThread.getSystemContext().getResources();
2221 }
2222 Resources r = mContext.mMainThread.getTopLevelResources(
2223 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002224 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002225 if (r != null) {
2226 return r;
2227 }
2228 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2229 }
2230
2231 @Override public Resources getResourcesForApplication(
2232 String appPackageName) throws NameNotFoundException {
2233 return getResourcesForApplication(
2234 getApplicationInfo(appPackageName, 0));
2235 }
2236
2237 int mCachedSafeMode = -1;
2238 @Override public boolean isSafeMode() {
2239 try {
2240 if (mCachedSafeMode < 0) {
2241 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2242 }
2243 return mCachedSafeMode != 0;
2244 } catch (RemoteException e) {
2245 throw new RuntimeException("Package manager has died", e);
2246 }
2247 }
2248
2249 static void configurationChanged() {
2250 synchronized (sSync) {
2251 sIconCache.clear();
2252 sStringCache.clear();
2253 }
2254 }
2255
Dianne Hackborn21556372010-02-04 16:34:40 -08002256 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 IPackageManager pm) {
2258 mContext = context;
2259 mPM = pm;
2260 }
2261
2262 private Drawable getCachedIcon(ResourceName name) {
2263 synchronized (sSync) {
2264 WeakReference<Drawable> wr = sIconCache.get(name);
2265 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2266 + name + ": " + wr);
2267 if (wr != null) { // we have the activity
2268 Drawable dr = wr.get();
2269 if (dr != null) {
2270 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2271 + name + ": " + dr);
2272 return dr;
2273 }
2274 // our entry has been purged
2275 sIconCache.remove(name);
2276 }
2277 }
2278 return null;
2279 }
2280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 private void putCachedIcon(ResourceName name, Drawable dr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 synchronized (sSync) {
2283 sIconCache.put(name, new WeakReference<Drawable>(dr));
2284 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2285 + name + ": " + dr);
2286 }
2287 }
2288
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002289 static final void handlePackageBroadcast(int cmd, String[] pkgList,
2290 boolean hasPkgInfo) {
2291 boolean immediateGc = false;
2292 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2293 immediateGc = true;
2294 }
2295 if (pkgList != null && (pkgList.length > 0)) {
2296 boolean needCleanup = false;
2297 for (String ssp : pkgList) {
2298 synchronized (sSync) {
2299 if (sIconCache.size() > 0) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002300 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2301 while (it.hasNext()) {
2302 ResourceName nm = it.next();
2303 if (nm.packageName.equals(ssp)) {
2304 //Log.i(TAG, "Removing cached drawable for " + nm);
2305 it.remove();
2306 needCleanup = true;
2307 }
2308 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002309 }
2310 if (sStringCache.size() > 0) {
2311 Iterator<ResourceName> it = sStringCache.keySet().iterator();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002312 while (it.hasNext()) {
2313 ResourceName nm = it.next();
2314 if (nm.packageName.equals(ssp)) {
2315 //Log.i(TAG, "Removing cached string for " + nm);
2316 it.remove();
2317 needCleanup = true;
2318 }
2319 }
2320 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002321 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002322 }
2323 if (needCleanup || hasPkgInfo) {
2324 if (immediateGc) {
2325 // Schedule an immediate gc.
2326 Runtime.getRuntime().gc();
2327 } else {
2328 ActivityThread.currentActivityThread().scheduleGcIdler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 }
2330 }
2331 }
2332 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 private static final class ResourceName {
2335 final String packageName;
2336 final int iconId;
2337
2338 ResourceName(String _packageName, int _iconId) {
2339 packageName = _packageName;
2340 iconId = _iconId;
2341 }
2342
2343 ResourceName(ApplicationInfo aInfo, int _iconId) {
2344 this(aInfo.packageName, _iconId);
2345 }
2346
2347 ResourceName(ComponentInfo cInfo, int _iconId) {
2348 this(cInfo.applicationInfo.packageName, _iconId);
2349 }
2350
2351 ResourceName(ResolveInfo rInfo, int _iconId) {
2352 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2353 }
2354
2355 @Override
2356 public boolean equals(Object o) {
2357 if (this == o) return true;
2358 if (o == null || getClass() != o.getClass()) return false;
2359
2360 ResourceName that = (ResourceName) o;
2361
2362 if (iconId != that.iconId) return false;
2363 return !(packageName != null ?
2364 !packageName.equals(that.packageName) : that.packageName != null);
2365
2366 }
2367
2368 @Override
2369 public int hashCode() {
2370 int result;
2371 result = packageName.hashCode();
2372 result = 31 * result + iconId;
2373 return result;
2374 }
2375
2376 @Override
2377 public String toString() {
2378 return "{ResourceName " + packageName + " / " + iconId + "}";
2379 }
2380 }
2381
2382 private CharSequence getCachedString(ResourceName name) {
2383 synchronized (sSync) {
2384 WeakReference<CharSequence> wr = sStringCache.get(name);
2385 if (wr != null) { // we have the activity
2386 CharSequence cs = wr.get();
2387 if (cs != null) {
2388 return cs;
2389 }
2390 // our entry has been purged
2391 sStringCache.remove(name);
2392 }
2393 }
2394 return null;
2395 }
2396
2397 private void putCachedString(ResourceName name, CharSequence cs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002398 synchronized (sSync) {
2399 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2400 }
2401 }
2402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002403 @Override
2404 public CharSequence getText(String packageName, int resid,
2405 ApplicationInfo appInfo) {
2406 ResourceName name = new ResourceName(packageName, resid);
2407 CharSequence text = getCachedString(name);
2408 if (text != null) {
2409 return text;
2410 }
2411 if (appInfo == null) {
2412 try {
2413 appInfo = getApplicationInfo(packageName, 0);
2414 } catch (NameNotFoundException e) {
2415 return null;
2416 }
2417 }
2418 try {
2419 Resources r = getResourcesForApplication(appInfo);
2420 text = r.getText(resid);
2421 putCachedString(name, text);
2422 return text;
2423 } catch (NameNotFoundException e) {
2424 Log.w("PackageManager", "Failure retrieving resources for"
2425 + appInfo.packageName);
2426 } catch (RuntimeException e) {
2427 // If an exception was thrown, fall through to return
2428 // default icon.
2429 Log.w("PackageManager", "Failure retrieving text 0x"
2430 + Integer.toHexString(resid) + " in package "
2431 + packageName, e);
2432 }
2433 return null;
2434 }
2435
2436 @Override
2437 public XmlResourceParser getXml(String packageName, int resid,
2438 ApplicationInfo appInfo) {
2439 if (appInfo == null) {
2440 try {
2441 appInfo = getApplicationInfo(packageName, 0);
2442 } catch (NameNotFoundException e) {
2443 return null;
2444 }
2445 }
2446 try {
2447 Resources r = getResourcesForApplication(appInfo);
2448 return r.getXml(resid);
2449 } catch (RuntimeException e) {
2450 // If an exception was thrown, fall through to return
2451 // default icon.
2452 Log.w("PackageManager", "Failure retrieving xml 0x"
2453 + Integer.toHexString(resid) + " in package "
2454 + packageName, e);
2455 } catch (NameNotFoundException e) {
2456 Log.w("PackageManager", "Failure retrieving resources for"
2457 + appInfo.packageName);
2458 }
2459 return null;
2460 }
2461
2462 @Override
2463 public CharSequence getApplicationLabel(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002464 return info.loadLabel(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 }
2466
2467 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002468 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2469 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002470 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002471 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 } catch (RemoteException e) {
2473 // Should never happen!
2474 }
2475 }
2476
2477 @Override
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -08002478 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2479 try {
2480 mPM.movePackage(packageName, observer, flags);
2481 } catch (RemoteException e) {
2482 // Should never happen!
2483 }
2484 }
2485
2486 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002487 public String getInstallerPackageName(String packageName) {
2488 try {
2489 return mPM.getInstallerPackageName(packageName);
2490 } catch (RemoteException e) {
2491 // Should never happen!
2492 }
2493 return null;
2494 }
2495
2496 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2498 try {
2499 mPM.deletePackage(packageName, observer, flags);
2500 } catch (RemoteException e) {
2501 // Should never happen!
2502 }
2503 }
2504 @Override
2505 public void clearApplicationUserData(String packageName,
2506 IPackageDataObserver observer) {
2507 try {
2508 mPM.clearApplicationUserData(packageName, observer);
2509 } catch (RemoteException e) {
2510 // Should never happen!
2511 }
2512 }
2513 @Override
2514 public void deleteApplicationCacheFiles(String packageName,
2515 IPackageDataObserver observer) {
2516 try {
2517 mPM.deleteApplicationCacheFiles(packageName, observer);
2518 } catch (RemoteException e) {
2519 // Should never happen!
2520 }
2521 }
2522 @Override
2523 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2524 try {
2525 mPM.freeStorageAndNotify(idealStorageSize, observer);
2526 } catch (RemoteException e) {
2527 // Should never happen!
2528 }
2529 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002531 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002532 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002533 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002534 mPM.freeStorage(freeStorageSize, pi);
2535 } catch (RemoteException e) {
2536 // Should never happen!
2537 }
2538 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539
2540 @Override
2541 public void getPackageSizeInfo(String packageName,
2542 IPackageStatsObserver observer) {
2543 try {
2544 mPM.getPackageSizeInfo(packageName, observer);
2545 } catch (RemoteException e) {
2546 // Should never happen!
2547 }
2548 }
2549 @Override
2550 public void addPackageToPreferred(String packageName) {
2551 try {
2552 mPM.addPackageToPreferred(packageName);
2553 } catch (RemoteException e) {
2554 // Should never happen!
2555 }
2556 }
2557
2558 @Override
2559 public void removePackageFromPreferred(String packageName) {
2560 try {
2561 mPM.removePackageFromPreferred(packageName);
2562 } catch (RemoteException e) {
2563 // Should never happen!
2564 }
2565 }
2566
2567 @Override
2568 public List<PackageInfo> getPreferredPackages(int flags) {
2569 try {
2570 return mPM.getPreferredPackages(flags);
2571 } catch (RemoteException e) {
2572 // Should never happen!
2573 }
2574 return new ArrayList<PackageInfo>();
2575 }
2576
2577 @Override
2578 public void addPreferredActivity(IntentFilter filter,
2579 int match, ComponentName[] set, ComponentName activity) {
2580 try {
2581 mPM.addPreferredActivity(filter, match, set, activity);
2582 } catch (RemoteException e) {
2583 // Should never happen!
2584 }
2585 }
2586
2587 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002588 public void replacePreferredActivity(IntentFilter filter,
2589 int match, ComponentName[] set, ComponentName activity) {
2590 try {
2591 mPM.replacePreferredActivity(filter, match, set, activity);
2592 } catch (RemoteException e) {
2593 // Should never happen!
2594 }
2595 }
2596
2597 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 public void clearPackagePreferredActivities(String packageName) {
2599 try {
2600 mPM.clearPackagePreferredActivities(packageName);
2601 } catch (RemoteException e) {
2602 // Should never happen!
2603 }
2604 }
2605
2606 @Override
2607 public int getPreferredActivities(List<IntentFilter> outFilters,
2608 List<ComponentName> outActivities, String packageName) {
2609 try {
2610 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2611 } catch (RemoteException e) {
2612 // Should never happen!
2613 }
2614 return 0;
2615 }
2616
2617 @Override
2618 public void setComponentEnabledSetting(ComponentName componentName,
2619 int newState, int flags) {
2620 try {
2621 mPM.setComponentEnabledSetting(componentName, newState, flags);
2622 } catch (RemoteException e) {
2623 // Should never happen!
2624 }
2625 }
2626
2627 @Override
2628 public int getComponentEnabledSetting(ComponentName componentName) {
2629 try {
2630 return mPM.getComponentEnabledSetting(componentName);
2631 } catch (RemoteException e) {
2632 // Should never happen!
2633 }
2634 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2635 }
2636
2637 @Override
2638 public void setApplicationEnabledSetting(String packageName,
2639 int newState, int flags) {
2640 try {
2641 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2642 } catch (RemoteException e) {
2643 // Should never happen!
2644 }
2645 }
2646
2647 @Override
2648 public int getApplicationEnabledSetting(String packageName) {
2649 try {
2650 return mPM.getApplicationEnabledSetting(packageName);
2651 } catch (RemoteException e) {
2652 // Should never happen!
2653 }
2654 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2655 }
2656
Dianne Hackborn21556372010-02-04 16:34:40 -08002657 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 private final IPackageManager mPM;
2659
2660 private static final Object sSync = new Object();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2662 = new HashMap<ResourceName, WeakReference<Drawable> >();
2663 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2664 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2665 }
2666
2667 // ----------------------------------------------------------------------
2668 // ----------------------------------------------------------------------
2669 // ----------------------------------------------------------------------
2670
2671 private static final class SharedPreferencesImpl implements SharedPreferences {
2672
2673 private final File mFile;
2674 private final File mBackupFile;
2675 private final int mMode;
2676 private Map mMap;
2677 private final FileStatus mFileStatus = new FileStatus();
2678 private long mTimestamp;
2679
The Android Open Source Project10592532009-03-18 17:39:46 -07002680 private static final Object mContent = new Object();
2681 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682
2683 SharedPreferencesImpl(
2684 File file, int mode, Map initialContents) {
2685 mFile = file;
2686 mBackupFile = makeBackupFile(file);
2687 mMode = mode;
2688 mMap = initialContents != null ? initialContents : new HashMap();
2689 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2690 mTimestamp = mFileStatus.mtime;
2691 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002692 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002693 }
2694
2695 public boolean hasFileChanged() {
2696 synchronized (this) {
2697 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2698 return true;
2699 }
2700 return mTimestamp != mFileStatus.mtime;
2701 }
2702 }
2703
2704 public void replace(Map newContents) {
2705 if (newContents != null) {
2706 synchronized (this) {
2707 mMap = newContents;
2708 }
2709 }
2710 }
2711
2712 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2713 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002714 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 }
2716 }
2717
2718 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2719 synchronized(this) {
2720 mListeners.remove(listener);
2721 }
2722 }
2723
2724 public Map<String, ?> getAll() {
2725 synchronized(this) {
2726 //noinspection unchecked
2727 return new HashMap(mMap);
2728 }
2729 }
2730
2731 public String getString(String key, String defValue) {
2732 synchronized (this) {
2733 String v = (String)mMap.get(key);
2734 return v != null ? v : defValue;
2735 }
2736 }
Adam Powell212db7d2010-04-08 16:24:46 -07002737
2738 public Set<String> getStringSet(String key, Set<String> defValues) {
2739 synchronized (this) {
2740 Set<String> v = (Set<String>) mMap.get(key);
2741 return v != null ? v : defValues;
2742 }
2743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744
2745 public int getInt(String key, int defValue) {
2746 synchronized (this) {
2747 Integer v = (Integer)mMap.get(key);
2748 return v != null ? v : defValue;
2749 }
2750 }
2751 public long getLong(String key, long defValue) {
2752 synchronized (this) {
2753 Long v = (Long) mMap.get(key);
2754 return v != null ? v : defValue;
2755 }
2756 }
2757 public float getFloat(String key, float defValue) {
2758 synchronized (this) {
2759 Float v = (Float)mMap.get(key);
2760 return v != null ? v : defValue;
2761 }
2762 }
2763 public boolean getBoolean(String key, boolean defValue) {
2764 synchronized (this) {
2765 Boolean v = (Boolean)mMap.get(key);
2766 return v != null ? v : defValue;
2767 }
2768 }
2769
2770 public boolean contains(String key) {
2771 synchronized (this) {
2772 return mMap.containsKey(key);
2773 }
2774 }
2775
2776 public final class EditorImpl implements Editor {
2777 private final Map<String, Object> mModified = Maps.newHashMap();
2778 private boolean mClear = false;
2779
2780 public Editor putString(String key, String value) {
2781 synchronized (this) {
2782 mModified.put(key, value);
2783 return this;
2784 }
2785 }
Adam Powell212db7d2010-04-08 16:24:46 -07002786 public Editor putStringSet(String key, Set<String> values) {
2787 synchronized (this) {
2788 mModified.put(key, values);
2789 return this;
2790 }
2791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792 public Editor putInt(String key, int value) {
2793 synchronized (this) {
2794 mModified.put(key, value);
2795 return this;
2796 }
2797 }
2798 public Editor putLong(String key, long value) {
2799 synchronized (this) {
2800 mModified.put(key, value);
2801 return this;
2802 }
2803 }
2804 public Editor putFloat(String key, float value) {
2805 synchronized (this) {
2806 mModified.put(key, value);
2807 return this;
2808 }
2809 }
2810 public Editor putBoolean(String key, boolean value) {
2811 synchronized (this) {
2812 mModified.put(key, value);
2813 return this;
2814 }
2815 }
2816
2817 public Editor remove(String key) {
2818 synchronized (this) {
2819 mModified.put(key, this);
2820 return this;
2821 }
2822 }
2823
2824 public Editor clear() {
2825 synchronized (this) {
2826 mClear = true;
2827 return this;
2828 }
2829 }
2830
2831 public boolean commit() {
2832 boolean returnValue;
2833
2834 boolean hasListeners;
2835 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002836 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002837
2838 synchronized (SharedPreferencesImpl.this) {
2839 hasListeners = mListeners.size() > 0;
2840 if (hasListeners) {
2841 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002842 listeners =
2843 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002844 }
2845
2846 synchronized (this) {
2847 if (mClear) {
2848 mMap.clear();
2849 mClear = false;
2850 }
2851
The Android Open Source Project10592532009-03-18 17:39:46 -07002852 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 String k = e.getKey();
2854 Object v = e.getValue();
2855 if (v == this) {
2856 mMap.remove(k);
2857 } else {
2858 mMap.put(k, v);
2859 }
2860
2861 if (hasListeners) {
2862 keysModified.add(k);
2863 }
2864 }
2865
2866 mModified.clear();
2867 }
2868
2869 returnValue = writeFileLocked();
2870 }
2871
2872 if (hasListeners) {
2873 for (int i = keysModified.size() - 1; i >= 0; i--) {
2874 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002875 for (OnSharedPreferenceChangeListener listener : listeners) {
2876 if (listener != null) {
2877 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002879 }
2880 }
2881 }
2882
2883 return returnValue;
2884 }
2885 }
2886
2887 public Editor edit() {
2888 return new EditorImpl();
2889 }
2890
2891 private FileOutputStream createFileOutputStream(File file) {
2892 FileOutputStream str = null;
2893 try {
2894 str = new FileOutputStream(file);
2895 } catch (FileNotFoundException e) {
2896 File parent = file.getParentFile();
2897 if (!parent.mkdir()) {
2898 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2899 return null;
2900 }
2901 FileUtils.setPermissions(
2902 parent.getPath(),
2903 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2904 -1, -1);
2905 try {
2906 str = new FileOutputStream(file);
2907 } catch (FileNotFoundException e2) {
2908 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2909 }
2910 }
2911 return str;
2912 }
2913
2914 private boolean writeFileLocked() {
2915 // Rename the current file so it may be used as a backup during the next read
2916 if (mFile.exists()) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002917 if (!mBackupFile.exists()) {
2918 if (!mFile.renameTo(mBackupFile)) {
2919 Log.e(TAG, "Couldn't rename file " + mFile
2920 + " to backup file " + mBackupFile);
2921 return false;
2922 }
2923 } else {
2924 mFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002925 }
2926 }
2927
2928 // Attempt to write the file, delete the backup and return true as atomically as
2929 // possible. If any exception occurs, delete the new file; next time we will restore
2930 // from the backup.
2931 try {
2932 FileOutputStream str = createFileOutputStream(mFile);
2933 if (str == null) {
2934 return false;
2935 }
2936 XmlUtils.writeMapXml(mMap, str);
2937 str.close();
2938 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2939 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2940 mTimestamp = mFileStatus.mtime;
2941 }
2942
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002943 // Writing was successful, delete the backup file if there is one.
2944 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002945 return true;
2946 } catch (XmlPullParserException e) {
2947 Log.w(TAG, "writeFileLocked: Got exception:", e);
2948 } catch (IOException e) {
2949 Log.w(TAG, "writeFileLocked: Got exception:", e);
2950 }
2951 // Clean up an unsuccessfully written file
2952 if (mFile.exists()) {
2953 if (!mFile.delete()) {
2954 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2955 }
2956 }
2957 return false;
2958 }
2959 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960}