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