blob: fc3cdcfd30b88868caaa6fc15d49c6435b885800 [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -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
25import android.bluetooth.BluetoothDevice;
26import android.bluetooth.IBluetoothDevice;
27import android.content.BroadcastReceiver;
28import android.content.ComponentName;
29import android.content.ContentResolver;
30import android.content.Context;
31import android.content.ContextWrapper;
32import android.content.IContentProvider;
33import android.content.Intent;
34import android.content.IntentFilter;
35import 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;
41import android.content.pm.IPackageDataObserver;
42import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.content.pm.IPackageInstallObserver;
44import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070045import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.content.pm.InstrumentationInfo;
47import android.content.pm.PackageInfo;
48import android.content.pm.PackageManager;
49import android.content.pm.PermissionGroupInfo;
50import android.content.pm.PermissionInfo;
51import android.content.pm.ProviderInfo;
52import android.content.pm.ResolveInfo;
53import android.content.pm.ServiceInfo;
54import android.content.res.AssetManager;
55import android.content.res.Resources;
56import android.content.res.XmlResourceParser;
57import android.database.sqlite.SQLiteDatabase;
58import android.database.sqlite.SQLiteDatabase.CursorFactory;
59import android.graphics.Bitmap;
60import android.graphics.BitmapFactory;
61import android.graphics.drawable.BitmapDrawable;
62import android.graphics.drawable.Drawable;
63import android.hardware.SensorManager;
64import android.location.ILocationManager;
65import android.location.LocationManager;
66import android.media.AudioManager;
67import android.net.ConnectivityManager;
68import android.net.IConnectivityManager;
69import android.net.Uri;
70import android.net.wifi.IWifiManager;
71import android.net.wifi.WifiManager;
72import android.os.Binder;
73import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.FileUtils;
75import android.os.Handler;
76import android.os.IBinder;
77import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070078import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.ParcelFileDescriptor;
80import android.os.PowerManager;
81import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070082import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.ServiceManager;
84import android.os.Vibrator;
85import android.os.FileUtils.FileStatus;
86import android.telephony.TelephonyManager;
87import android.text.ClipboardManager;
88import android.util.AndroidRuntimeException;
89import android.util.Log;
90import android.view.ContextThemeWrapper;
91import android.view.LayoutInflater;
92import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070093import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.view.inputmethod.InputMethodManager;
95
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import java.io.File;
97import java.io.FileInputStream;
98import java.io.FileNotFoundException;
99import java.io.FileOutputStream;
100import java.io.IOException;
101import java.io.InputStream;
102import java.lang.ref.WeakReference;
103import java.util.ArrayList;
104import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700105import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import java.util.Iterator;
107import java.util.List;
108import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700109import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700110import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import java.util.Map.Entry;
112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113class ReceiverRestrictedContext extends ContextWrapper {
114 ReceiverRestrictedContext(Context base) {
115 super(base);
116 }
117
118 @Override
119 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
120 return registerReceiver(receiver, filter, null, null);
121 }
122
123 @Override
124 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
125 String broadcastPermission, Handler scheduler) {
126 throw new ReceiverCallNotAllowedException(
127 "IntentReceiver components are not allowed to register to receive intents");
128 //ex.fillInStackTrace();
129 //Log.e("IntentReceiver", ex.getMessage(), ex);
130 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
131 // scheduler);
132 }
133
134 @Override
135 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
136 throw new ReceiverCallNotAllowedException(
137 "IntentReceiver components are not allowed to bind to services");
138 //ex.fillInStackTrace();
139 //Log.e("IntentReceiver", ex.getMessage(), ex);
140 //return mContext.bindService(service, interfaceName, conn, flags);
141 }
142}
143
144/**
145 * Common implementation of Context API, which Activity and other application
146 * classes inherit.
147 */
148class ApplicationContext extends Context {
149 private final static String TAG = "ApplicationContext";
150 private final static boolean DEBUG_ICONS = false;
151
152 private static final Object sSync = new Object();
153 private static AlarmManager sAlarmManager;
154 private static PowerManager sPowerManager;
155 private static ConnectivityManager sConnectivityManager;
156 private static WifiManager sWifiManager;
157 private static LocationManager sLocationManager;
158 private static boolean sIsBluetoothDeviceCached = false;
159 private static BluetoothDevice sBluetoothDevice;
160 private static IWallpaperService sWallpaperService;
161 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
162 new HashMap<File, SharedPreferencesImpl>();
163
164 private AudioManager mAudioManager;
165 /*package*/ ActivityThread.PackageInfo mPackageInfo;
166 private Resources mResources;
167 /*package*/ ActivityThread mMainThread;
168 private Context mOuterContext;
169 private IBinder mActivityToken = null;
170 private ApplicationContentResolver mContentResolver;
171 private int mThemeResource = 0;
172 private Resources.Theme mTheme = null;
173 private PackageManager mPackageManager;
174 private NotificationManager mNotificationManager = null;
svetoslavganov75986cf2009-05-14 22:28:01 -0700175 private AccessibilityManager mAccessibilityManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 private ActivityManager mActivityManager = null;
177 private Context mReceiverRestrictedContext = null;
178 private SearchManager mSearchManager = null;
179 private SensorManager mSensorManager = null;
180 private Vibrator mVibrator = null;
181 private LayoutInflater mLayoutInflater = null;
182 private StatusBarManager mStatusBarManager = null;
183 private TelephonyManager mTelephonyManager = null;
184 private ClipboardManager mClipboardManager = null;
185
186 private final Object mSync = new Object();
187
188 private File mDatabasesDir;
189 private File mPreferencesDir;
190 private File mFilesDir;
191
192
193 private File mCacheDir;
194
195 private Drawable mWallpaper;
196 private IWallpaperServiceCallback mWallpaperCallback = null;
197
198 private static long sInstanceCount = 0;
199
200 private static final String[] EMPTY_FILE_LIST = {};
201
202 @Override
203 protected void finalize() throws Throwable {
204 super.finalize();
205 --sInstanceCount;
206 }
207
208 public static long getInstanceCount() {
209 return sInstanceCount;
210 }
211
212 @Override
213 public AssetManager getAssets() {
214 return mResources.getAssets();
215 }
216
217 @Override
218 public Resources getResources() {
219 return mResources;
220 }
221
222 @Override
223 public PackageManager getPackageManager() {
224 if (mPackageManager != null) {
225 return mPackageManager;
226 }
227
228 IPackageManager pm = ActivityThread.getPackageManager();
229 if (pm != null) {
230 // Doesn't matter if we make more than one instance.
231 return (mPackageManager = new ApplicationPackageManager(this, pm));
232 }
233
234 return null;
235 }
236
237 @Override
238 public ContentResolver getContentResolver() {
239 return mContentResolver;
240 }
241
242 @Override
243 public Looper getMainLooper() {
244 return mMainThread.getLooper();
245 }
246
247 @Override
248 public Context getApplicationContext() {
249 return mMainThread.getApplication();
250 }
251
252 @Override
253 public void setTheme(int resid) {
254 mThemeResource = resid;
255 }
256
257 @Override
258 public Resources.Theme getTheme() {
259 if (mTheme == null) {
260 if (mThemeResource == 0) {
261 mThemeResource = com.android.internal.R.style.Theme;
262 }
263 mTheme = mResources.newTheme();
264 mTheme.applyStyle(mThemeResource, true);
265 }
266 return mTheme;
267 }
268
269 @Override
270 public ClassLoader getClassLoader() {
271 return mPackageInfo != null ?
272 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
273 }
274
275 @Override
276 public String getPackageName() {
277 if (mPackageInfo != null) {
278 return mPackageInfo.getPackageName();
279 }
280 throw new RuntimeException("Not supported in system context");
281 }
282
283 @Override
284 public String getPackageResourcePath() {
285 if (mPackageInfo != null) {
286 return mPackageInfo.getResDir();
287 }
288 throw new RuntimeException("Not supported in system context");
289 }
290
291 @Override
292 public String getPackageCodePath() {
293 if (mPackageInfo != null) {
294 return mPackageInfo.getAppDir();
295 }
296 throw new RuntimeException("Not supported in system context");
297 }
298
299 private static File makeBackupFile(File prefsFile) {
300 return new File(prefsFile.getPath() + ".bak");
301 }
302
Joe Onorato23ecae32009-06-10 17:07:15 -0700303 public File getSharedPrefsFile(String name) {
304 return makeFilename(getPreferencesDir(), name + ".xml");
305 }
306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 @Override
308 public SharedPreferences getSharedPreferences(String name, int mode) {
309 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700310 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 synchronized (sSharedPrefs) {
312 sp = sSharedPrefs.get(f);
313 if (sp != null && !sp.hasFileChanged()) {
314 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
315 return sp;
316 }
317 }
318
319 FileInputStream str = null;
320 File backup = makeBackupFile(f);
321 if (backup.exists()) {
322 f.delete();
323 backup.renameTo(f);
324 }
325
326 // Debugging
327 if (f.exists() && !f.canRead()) {
328 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
329 }
330
331 Map map = null;
332 if (f.exists() && f.canRead()) {
333 try {
334 str = new FileInputStream(f);
335 map = XmlUtils.readMapXml(str);
336 str.close();
337 } catch (org.xmlpull.v1.XmlPullParserException e) {
338 Log.w(TAG, "getSharedPreferences", e);
339 } catch (FileNotFoundException e) {
340 Log.w(TAG, "getSharedPreferences", e);
341 } catch (IOException e) {
342 Log.w(TAG, "getSharedPreferences", e);
343 }
344 }
345
346 synchronized (sSharedPrefs) {
347 if (sp != null) {
348 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
349 sp.replace(map);
350 } else {
351 sp = sSharedPrefs.get(f);
352 if (sp == null) {
353 sp = new SharedPreferencesImpl(f, mode, map);
354 sSharedPrefs.put(f, sp);
355 }
356 }
357 return sp;
358 }
359 }
360
361 private File getPreferencesDir() {
362 synchronized (mSync) {
363 if (mPreferencesDir == null) {
364 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
365 }
366 return mPreferencesDir;
367 }
368 }
369
370 @Override
371 public FileInputStream openFileInput(String name)
372 throws FileNotFoundException {
373 File f = makeFilename(getFilesDir(), name);
374 return new FileInputStream(f);
375 }
376
377 @Override
378 public FileOutputStream openFileOutput(String name, int mode)
379 throws FileNotFoundException {
380 final boolean append = (mode&MODE_APPEND) != 0;
381 File f = makeFilename(getFilesDir(), name);
382 try {
383 FileOutputStream fos = new FileOutputStream(f, append);
384 setFilePermissionsFromMode(f.getPath(), mode, 0);
385 return fos;
386 } catch (FileNotFoundException e) {
387 }
388
389 File parent = f.getParentFile();
390 parent.mkdir();
391 FileUtils.setPermissions(
392 parent.getPath(),
393 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
394 -1, -1);
395 FileOutputStream fos = new FileOutputStream(f, append);
396 setFilePermissionsFromMode(f.getPath(), mode, 0);
397 return fos;
398 }
399
400 @Override
401 public boolean deleteFile(String name) {
402 File f = makeFilename(getFilesDir(), name);
403 return f.delete();
404 }
405
406 @Override
407 public File getFilesDir() {
408 synchronized (mSync) {
409 if (mFilesDir == null) {
410 mFilesDir = new File(getDataDirFile(), "files");
411 }
412 if (!mFilesDir.exists()) {
413 if(!mFilesDir.mkdirs()) {
414 Log.w(TAG, "Unable to create files directory");
415 return null;
416 }
417 FileUtils.setPermissions(
418 mFilesDir.getPath(),
419 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
420 -1, -1);
421 }
422 return mFilesDir;
423 }
424 }
425
426 @Override
427 public File getCacheDir() {
428 synchronized (mSync) {
429 if (mCacheDir == null) {
430 mCacheDir = new File(getDataDirFile(), "cache");
431 }
432 if (!mCacheDir.exists()) {
433 if(!mCacheDir.mkdirs()) {
434 Log.w(TAG, "Unable to create cache directory");
435 return null;
436 }
437 FileUtils.setPermissions(
438 mCacheDir.getPath(),
439 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
440 -1, -1);
441 }
442 }
443 return mCacheDir;
444 }
445
446
447 @Override
448 public File getFileStreamPath(String name) {
449 return makeFilename(getFilesDir(), name);
450 }
451
452 @Override
453 public String[] fileList() {
454 final String[] list = getFilesDir().list();
455 return (list != null) ? list : EMPTY_FILE_LIST;
456 }
457
458 @Override
459 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
460 File dir = getDatabasesDir();
461 if (!dir.isDirectory() && dir.mkdir()) {
462 FileUtils.setPermissions(dir.getPath(),
463 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
464 -1, -1);
465 }
466
467 File f = makeFilename(dir, name);
468 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
469 setFilePermissionsFromMode(f.getPath(), mode, 0);
470 return db;
471 }
472
473 @Override
474 public boolean deleteDatabase(String name) {
475 try {
476 File f = makeFilename(getDatabasesDir(), name);
477 return f.delete();
478 } catch (Exception e) {
479 }
480 return false;
481 }
482
483 @Override
484 public File getDatabasePath(String name) {
485 return makeFilename(getDatabasesDir(), name);
486 }
487
488 @Override
489 public String[] databaseList() {
490 final String[] list = getDatabasesDir().list();
491 return (list != null) ? list : EMPTY_FILE_LIST;
492 }
493
494
495 private File getDatabasesDir() {
496 synchronized (mSync) {
497 if (mDatabasesDir == null) {
498 mDatabasesDir = new File(getDataDirFile(), "databases");
499 }
500 if (mDatabasesDir.getPath().equals("databases")) {
501 mDatabasesDir = new File("/data/system");
502 }
503 return mDatabasesDir;
504 }
505 }
506
507 @Override
508 public Drawable getWallpaper() {
509 Drawable dr = peekWallpaper();
510 return dr != null ? dr : getResources().getDrawable(
511 com.android.internal.R.drawable.default_wallpaper);
512 }
513
514 @Override
515 public synchronized Drawable peekWallpaper() {
516 if (mWallpaper != null) {
517 return mWallpaper;
518 }
519 mWallpaperCallback = new WallpaperCallback(this);
520 mWallpaper = getCurrentWallpaperLocked();
521 return mWallpaper;
522 }
523
524 private Drawable getCurrentWallpaperLocked() {
525 try {
526 ParcelFileDescriptor fd = getWallpaperService().getWallpaper(mWallpaperCallback);
527 if (fd != null) {
528 Bitmap bm = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
529 if (bm != null) {
530 return new BitmapDrawable(bm);
531 }
532 }
533 } catch (RemoteException e) {
534 }
535 return null;
536 }
537
538 @Override
539 public int getWallpaperDesiredMinimumWidth() {
540 try {
541 return getWallpaperService().getWidthHint();
542 } catch (RemoteException e) {
543 // Shouldn't happen!
544 return 0;
545 }
546 }
547
548 @Override
549 public int getWallpaperDesiredMinimumHeight() {
550 try {
551 return getWallpaperService().getHeightHint();
552 } catch (RemoteException e) {
553 // Shouldn't happen!
554 return 0;
555 }
556 }
557
558 @Override
559 public void setWallpaper(Bitmap bitmap) throws IOException {
560 try {
561 ParcelFileDescriptor fd = getWallpaperService().setWallpaper();
562 if (fd == null) {
563 return;
564 }
565 FileOutputStream fos = null;
566 try {
567 fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
568 bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
569 } finally {
570 if (fos != null) {
571 fos.close();
572 }
573 }
574 } catch (RemoteException e) {
575 }
576 }
577
578 @Override
579 public void setWallpaper(InputStream data) throws IOException {
580 try {
581 ParcelFileDescriptor fd = getWallpaperService().setWallpaper();
582 if (fd == null) {
583 return;
584 }
585 FileOutputStream fos = null;
586 try {
587 fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
588 setWallpaper(data, fos);
589 } finally {
590 if (fos != null) {
591 fos.close();
592 }
593 }
594 } catch (RemoteException e) {
595 }
596 }
597
598 private void setWallpaper(InputStream data, FileOutputStream fos)
599 throws IOException {
600 byte[] buffer = new byte[32768];
601 int amt;
602 while ((amt=data.read(buffer)) > 0) {
603 fos.write(buffer, 0, amt);
604 }
605 }
606
607 @Override
608 public void clearWallpaper() throws IOException {
609 try {
610 /* Set the wallpaper to the default values */
611 ParcelFileDescriptor fd = getWallpaperService().setWallpaper();
612 if (fd != null) {
613 FileOutputStream fos = null;
614 try {
615 fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
616 setWallpaper(getResources().openRawResource(
617 com.android.internal.R.drawable.default_wallpaper),
618 fos);
619 } finally {
620 if (fos != null) {
621 fos.close();
622 }
623 }
624 }
625 } catch (RemoteException e) {
626 }
627 }
628
629 @Override
630 public void startActivity(Intent intent) {
631 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
632 throw new AndroidRuntimeException(
633 "Calling startActivity() from outside of an Activity "
634 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
635 + " Is this really what you want?");
636 }
637 mMainThread.getInstrumentation().execStartActivity(
638 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
639 }
640
641 @Override
642 public void sendBroadcast(Intent intent) {
643 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
644 try {
645 ActivityManagerNative.getDefault().broadcastIntent(
646 mMainThread.getApplicationThread(), intent, resolvedType, null,
647 Activity.RESULT_OK, null, null, null, false, false);
648 } catch (RemoteException e) {
649 }
650 }
651
652 @Override
653 public void sendBroadcast(Intent intent, String receiverPermission) {
654 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
655 try {
656 ActivityManagerNative.getDefault().broadcastIntent(
657 mMainThread.getApplicationThread(), intent, resolvedType, null,
658 Activity.RESULT_OK, null, null, receiverPermission, false, false);
659 } catch (RemoteException e) {
660 }
661 }
662
663 @Override
664 public void sendOrderedBroadcast(Intent intent,
665 String receiverPermission) {
666 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
667 try {
668 ActivityManagerNative.getDefault().broadcastIntent(
669 mMainThread.getApplicationThread(), intent, resolvedType, null,
670 Activity.RESULT_OK, null, null, receiverPermission, true, false);
671 } catch (RemoteException e) {
672 }
673 }
674
675 @Override
676 public void sendOrderedBroadcast(Intent intent,
677 String receiverPermission, BroadcastReceiver resultReceiver,
678 Handler scheduler, int initialCode, String initialData,
679 Bundle initialExtras) {
680 IIntentReceiver rd = null;
681 if (resultReceiver != null) {
682 if (mPackageInfo != null) {
683 if (scheduler == null) {
684 scheduler = mMainThread.getHandler();
685 }
686 rd = mPackageInfo.getReceiverDispatcher(
687 resultReceiver, getOuterContext(), scheduler,
688 mMainThread.getInstrumentation(), false);
689 } else {
690 if (scheduler == null) {
691 scheduler = mMainThread.getHandler();
692 }
693 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
694 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
695 }
696 }
697 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
698 try {
699 ActivityManagerNative.getDefault().broadcastIntent(
700 mMainThread.getApplicationThread(), intent, resolvedType, rd,
701 initialCode, initialData, initialExtras, receiverPermission,
702 true, false);
703 } catch (RemoteException e) {
704 }
705 }
706
707 @Override
708 public void sendStickyBroadcast(Intent intent) {
709 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
710 try {
711 ActivityManagerNative.getDefault().broadcastIntent(
712 mMainThread.getApplicationThread(), intent, resolvedType, null,
713 Activity.RESULT_OK, null, null, null, false, true);
714 } catch (RemoteException e) {
715 }
716 }
717
718 @Override
719 public void removeStickyBroadcast(Intent intent) {
720 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
721 if (resolvedType != null) {
722 intent = new Intent(intent);
723 intent.setDataAndType(intent.getData(), resolvedType);
724 }
725 try {
726 ActivityManagerNative.getDefault().unbroadcastIntent(
727 mMainThread.getApplicationThread(), intent);
728 } catch (RemoteException e) {
729 }
730 }
731
732 @Override
733 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
734 return registerReceiver(receiver, filter, null, null);
735 }
736
737 @Override
738 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
739 String broadcastPermission, Handler scheduler) {
740 return registerReceiverInternal(receiver, filter, broadcastPermission,
741 scheduler, getOuterContext());
742 }
743
744 private Intent registerReceiverInternal(BroadcastReceiver receiver,
745 IntentFilter filter, String broadcastPermission,
746 Handler scheduler, Context context) {
747 IIntentReceiver rd = null;
748 if (receiver != null) {
749 if (mPackageInfo != null && context != null) {
750 if (scheduler == null) {
751 scheduler = mMainThread.getHandler();
752 }
753 rd = mPackageInfo.getReceiverDispatcher(
754 receiver, context, scheduler,
755 mMainThread.getInstrumentation(), true);
756 } else {
757 if (scheduler == null) {
758 scheduler = mMainThread.getHandler();
759 }
760 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
761 receiver, context, scheduler, null, false).getIIntentReceiver();
762 }
763 }
764 try {
765 return ActivityManagerNative.getDefault().registerReceiver(
766 mMainThread.getApplicationThread(),
767 rd, filter, broadcastPermission);
768 } catch (RemoteException e) {
769 return null;
770 }
771 }
772
773 @Override
774 public void unregisterReceiver(BroadcastReceiver receiver) {
775 if (mPackageInfo != null) {
776 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
777 getOuterContext(), receiver);
778 try {
779 ActivityManagerNative.getDefault().unregisterReceiver(rd);
780 } catch (RemoteException e) {
781 }
782 } else {
783 throw new RuntimeException("Not supported in system context");
784 }
785 }
786
787 @Override
788 public ComponentName startService(Intent service) {
789 try {
790 ComponentName cn = ActivityManagerNative.getDefault().startService(
791 mMainThread.getApplicationThread(), service,
792 service.resolveTypeIfNeeded(getContentResolver()));
793 if (cn != null && cn.getPackageName().equals("!")) {
794 throw new SecurityException(
795 "Not allowed to start service " + service
796 + " without permission " + cn.getClassName());
797 }
798 return cn;
799 } catch (RemoteException e) {
800 return null;
801 }
802 }
803
804 @Override
805 public boolean stopService(Intent service) {
806 try {
807 int res = ActivityManagerNative.getDefault().stopService(
808 mMainThread.getApplicationThread(), service,
809 service.resolveTypeIfNeeded(getContentResolver()));
810 if (res < 0) {
811 throw new SecurityException(
812 "Not allowed to stop service " + service);
813 }
814 return res != 0;
815 } catch (RemoteException e) {
816 return false;
817 }
818 }
819
820 @Override
821 public boolean bindService(Intent service, ServiceConnection conn,
822 int flags) {
823 IServiceConnection sd;
824 if (mPackageInfo != null) {
825 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
826 mMainThread.getHandler(), flags);
827 } else {
828 throw new RuntimeException("Not supported in system context");
829 }
830 try {
831 int res = ActivityManagerNative.getDefault().bindService(
832 mMainThread.getApplicationThread(), getActivityToken(),
833 service, service.resolveTypeIfNeeded(getContentResolver()),
834 sd, flags);
835 if (res < 0) {
836 throw new SecurityException(
837 "Not allowed to bind to service " + service);
838 }
839 return res != 0;
840 } catch (RemoteException e) {
841 return false;
842 }
843 }
844
845 @Override
846 public void unbindService(ServiceConnection conn) {
847 if (mPackageInfo != null) {
848 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
849 getOuterContext(), conn);
850 try {
851 ActivityManagerNative.getDefault().unbindService(sd);
852 } catch (RemoteException e) {
853 }
854 } else {
855 throw new RuntimeException("Not supported in system context");
856 }
857 }
858
859 @Override
860 public boolean startInstrumentation(ComponentName className,
861 String profileFile, Bundle arguments) {
862 try {
863 return ActivityManagerNative.getDefault().startInstrumentation(
864 className, profileFile, 0, arguments, null);
865 } catch (RemoteException e) {
866 // System has crashed, nothing we can do.
867 }
868 return false;
869 }
870
871 @Override
872 public Object getSystemService(String name) {
873 if (WINDOW_SERVICE.equals(name)) {
874 return WindowManagerImpl.getDefault();
875 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
876 synchronized (mSync) {
877 LayoutInflater inflater = mLayoutInflater;
878 if (inflater != null) {
879 return inflater;
880 }
881 mLayoutInflater = inflater =
882 PolicyManager.makeNewLayoutInflater(getOuterContext());
883 return inflater;
884 }
885 } else if (ACTIVITY_SERVICE.equals(name)) {
886 return getActivityManager();
887 } else if (ALARM_SERVICE.equals(name)) {
888 return getAlarmManager();
889 } else if (POWER_SERVICE.equals(name)) {
890 return getPowerManager();
891 } else if (CONNECTIVITY_SERVICE.equals(name)) {
892 return getConnectivityManager();
893 } else if (WIFI_SERVICE.equals(name)) {
894 return getWifiManager();
895 } else if (NOTIFICATION_SERVICE.equals(name)) {
896 return getNotificationManager();
897 } else if (KEYGUARD_SERVICE.equals(name)) {
898 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700899 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
900 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 } else if (LOCATION_SERVICE.equals(name)) {
902 return getLocationManager();
903 } else if (SEARCH_SERVICE.equals(name)) {
904 return getSearchManager();
905 } else if ( SENSOR_SERVICE.equals(name)) {
906 return getSensorManager();
907 } else if (BLUETOOTH_SERVICE.equals(name)) {
908 return getBluetoothDevice();
909 } else if (VIBRATOR_SERVICE.equals(name)) {
910 return getVibrator();
911 } else if (STATUS_BAR_SERVICE.equals(name)) {
912 synchronized (mSync) {
913 if (mStatusBarManager == null) {
914 mStatusBarManager = new StatusBarManager(getOuterContext());
915 }
916 return mStatusBarManager;
917 }
918 } else if (AUDIO_SERVICE.equals(name)) {
919 return getAudioManager();
920 } else if (TELEPHONY_SERVICE.equals(name)) {
921 return getTelephonyManager();
922 } else if (CLIPBOARD_SERVICE.equals(name)) {
923 return getClipboardManager();
924 } else if (INPUT_METHOD_SERVICE.equals(name)) {
925 return InputMethodManager.getInstance(this);
926 }
927
928 return null;
929 }
930
931 private ActivityManager getActivityManager() {
932 synchronized (mSync) {
933 if (mActivityManager == null) {
934 mActivityManager = new ActivityManager(getOuterContext(),
935 mMainThread.getHandler());
936 }
937 }
938 return mActivityManager;
939 }
940
941 private AlarmManager getAlarmManager() {
942 synchronized (sSync) {
943 if (sAlarmManager == null) {
944 IBinder b = ServiceManager.getService(ALARM_SERVICE);
945 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
946 sAlarmManager = new AlarmManager(service);
947 }
948 }
949 return sAlarmManager;
950 }
951
952 private PowerManager getPowerManager() {
953 synchronized (sSync) {
954 if (sPowerManager == null) {
955 IBinder b = ServiceManager.getService(POWER_SERVICE);
956 IPowerManager service = IPowerManager.Stub.asInterface(b);
957 sPowerManager = new PowerManager(service, mMainThread.getHandler());
958 }
959 }
960 return sPowerManager;
961 }
962
963 private ConnectivityManager getConnectivityManager()
964 {
965 synchronized (sSync) {
966 if (sConnectivityManager == null) {
967 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
968 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
969 sConnectivityManager = new ConnectivityManager(service);
970 }
971 }
972 return sConnectivityManager;
973 }
974
975 private WifiManager getWifiManager()
976 {
977 synchronized (sSync) {
978 if (sWifiManager == null) {
979 IBinder b = ServiceManager.getService(WIFI_SERVICE);
980 IWifiManager service = IWifiManager.Stub.asInterface(b);
981 sWifiManager = new WifiManager(service, mMainThread.getHandler());
982 }
983 }
984 return sWifiManager;
985 }
986
987 private NotificationManager getNotificationManager()
988 {
989 synchronized (mSync) {
990 if (mNotificationManager == null) {
991 mNotificationManager = new NotificationManager(
992 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
993 mMainThread.getHandler());
994 }
995 }
996 return mNotificationManager;
997 }
998
999 private TelephonyManager getTelephonyManager() {
1000 synchronized (mSync) {
1001 if (mTelephonyManager == null) {
1002 mTelephonyManager = new TelephonyManager(getOuterContext());
1003 }
1004 }
1005 return mTelephonyManager;
1006 }
1007
1008 private ClipboardManager getClipboardManager() {
1009 synchronized (mSync) {
1010 if (mClipboardManager == null) {
1011 mClipboardManager = new ClipboardManager(getOuterContext(),
1012 mMainThread.getHandler());
1013 }
1014 }
1015 return mClipboardManager;
1016 }
1017
1018 private LocationManager getLocationManager() {
1019 synchronized (sSync) {
1020 if (sLocationManager == null) {
1021 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1022 ILocationManager service = ILocationManager.Stub.asInterface(b);
1023 sLocationManager = new LocationManager(service);
1024 }
1025 }
1026 return sLocationManager;
1027 }
1028
1029 private SearchManager getSearchManager() {
1030 // This is only useable in Activity Contexts
1031 if (getActivityToken() == null) {
1032 throw new AndroidRuntimeException(
1033 "Acquiring SearchManager objects only valid in Activity Contexts.");
1034 }
1035 synchronized (mSync) {
1036 if (mSearchManager == null) {
1037 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1038 }
1039 }
1040 return mSearchManager;
1041 }
1042
1043 private BluetoothDevice getBluetoothDevice() {
1044 if (sIsBluetoothDeviceCached) {
1045 return sBluetoothDevice;
1046 }
1047 synchronized (sSync) {
1048 IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
1049 if (b == null) {
1050 sBluetoothDevice = null;
1051 } else {
1052 IBluetoothDevice service = IBluetoothDevice.Stub.asInterface(b);
1053 sBluetoothDevice = new BluetoothDevice(service);
1054 }
1055 sIsBluetoothDeviceCached = true;
1056 }
1057 return sBluetoothDevice;
1058 }
1059
1060 private SensorManager getSensorManager() {
1061 synchronized (mSync) {
1062 if (mSensorManager == null) {
1063 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1064 }
1065 }
1066 return mSensorManager;
1067 }
1068
1069 private Vibrator getVibrator() {
1070 synchronized (mSync) {
1071 if (mVibrator == null) {
1072 mVibrator = new Vibrator();
1073 }
1074 }
1075 return mVibrator;
1076 }
1077
1078 private IWallpaperService getWallpaperService() {
1079 synchronized (sSync) {
1080 if (sWallpaperService == null) {
1081 IBinder b = ServiceManager.getService(WALLPAPER_SERVICE);
1082 sWallpaperService = IWallpaperService.Stub.asInterface(b);
1083 }
1084 }
1085 return sWallpaperService;
1086 }
1087
1088 private AudioManager getAudioManager()
1089 {
1090 if (mAudioManager == null) {
1091 mAudioManager = new AudioManager(this);
1092 }
1093 return mAudioManager;
1094 }
1095
1096 @Override
1097 public int checkPermission(String permission, int pid, int uid) {
1098 if (permission == null) {
1099 throw new IllegalArgumentException("permission is null");
1100 }
1101
1102 if (!Process.supportsProcesses()) {
1103 return PackageManager.PERMISSION_GRANTED;
1104 }
1105 try {
1106 return ActivityManagerNative.getDefault().checkPermission(
1107 permission, pid, uid);
1108 } catch (RemoteException e) {
1109 return PackageManager.PERMISSION_DENIED;
1110 }
1111 }
1112
1113 @Override
1114 public int checkCallingPermission(String permission) {
1115 if (permission == null) {
1116 throw new IllegalArgumentException("permission is null");
1117 }
1118
1119 if (!Process.supportsProcesses()) {
1120 return PackageManager.PERMISSION_GRANTED;
1121 }
1122 int pid = Binder.getCallingPid();
1123 if (pid != Process.myPid()) {
1124 return checkPermission(permission, pid,
1125 Binder.getCallingUid());
1126 }
1127 return PackageManager.PERMISSION_DENIED;
1128 }
1129
1130 @Override
1131 public int checkCallingOrSelfPermission(String permission) {
1132 if (permission == null) {
1133 throw new IllegalArgumentException("permission is null");
1134 }
1135
1136 return checkPermission(permission, Binder.getCallingPid(),
1137 Binder.getCallingUid());
1138 }
1139
1140 private void enforce(
1141 String permission, int resultOfCheck,
1142 boolean selfToo, int uid, String message) {
1143 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1144 throw new SecurityException(
1145 (message != null ? (message + ": ") : "") +
1146 (selfToo
1147 ? "Neither user " + uid + " nor current process has "
1148 : "User " + uid + " does not have ") +
1149 permission +
1150 ".");
1151 }
1152 }
1153
1154 public void enforcePermission(
1155 String permission, int pid, int uid, String message) {
1156 enforce(permission,
1157 checkPermission(permission, pid, uid),
1158 false,
1159 uid,
1160 message);
1161 }
1162
1163 public void enforceCallingPermission(String permission, String message) {
1164 enforce(permission,
1165 checkCallingPermission(permission),
1166 false,
1167 Binder.getCallingUid(),
1168 message);
1169 }
1170
1171 public void enforceCallingOrSelfPermission(
1172 String permission, String message) {
1173 enforce(permission,
1174 checkCallingOrSelfPermission(permission),
1175 true,
1176 Binder.getCallingUid(),
1177 message);
1178 }
1179
1180 @Override
1181 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1182 try {
1183 ActivityManagerNative.getDefault().grantUriPermission(
1184 mMainThread.getApplicationThread(), toPackage, uri,
1185 modeFlags);
1186 } catch (RemoteException e) {
1187 }
1188 }
1189
1190 @Override
1191 public void revokeUriPermission(Uri uri, int modeFlags) {
1192 try {
1193 ActivityManagerNative.getDefault().revokeUriPermission(
1194 mMainThread.getApplicationThread(), uri,
1195 modeFlags);
1196 } catch (RemoteException e) {
1197 }
1198 }
1199
1200 @Override
1201 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1202 if (!Process.supportsProcesses()) {
1203 return PackageManager.PERMISSION_GRANTED;
1204 }
1205 try {
1206 return ActivityManagerNative.getDefault().checkUriPermission(
1207 uri, pid, uid, modeFlags);
1208 } catch (RemoteException e) {
1209 return PackageManager.PERMISSION_DENIED;
1210 }
1211 }
1212
1213 @Override
1214 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1215 if (!Process.supportsProcesses()) {
1216 return PackageManager.PERMISSION_GRANTED;
1217 }
1218 int pid = Binder.getCallingPid();
1219 if (pid != Process.myPid()) {
1220 return checkUriPermission(uri, pid,
1221 Binder.getCallingUid(), modeFlags);
1222 }
1223 return PackageManager.PERMISSION_DENIED;
1224 }
1225
1226 @Override
1227 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1228 return checkUriPermission(uri, Binder.getCallingPid(),
1229 Binder.getCallingUid(), modeFlags);
1230 }
1231
1232 @Override
1233 public int checkUriPermission(Uri uri, String readPermission,
1234 String writePermission, int pid, int uid, int modeFlags) {
1235 if (false) {
1236 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1237 + readPermission + " writePermission=" + writePermission
1238 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1239 }
1240 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1241 if (readPermission == null
1242 || checkPermission(readPermission, pid, uid)
1243 == PackageManager.PERMISSION_GRANTED) {
1244 return PackageManager.PERMISSION_GRANTED;
1245 }
1246 }
1247 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1248 if (writePermission == null
1249 || checkPermission(writePermission, pid, uid)
1250 == PackageManager.PERMISSION_GRANTED) {
1251 return PackageManager.PERMISSION_GRANTED;
1252 }
1253 }
1254 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1255 : PackageManager.PERMISSION_DENIED;
1256 }
1257
1258 private String uriModeFlagToString(int uriModeFlags) {
1259 switch (uriModeFlags) {
1260 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1261 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1262 return "read and write";
1263 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1264 return "read";
1265 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1266 return "write";
1267 }
1268 throw new IllegalArgumentException(
1269 "Unknown permission mode flags: " + uriModeFlags);
1270 }
1271
1272 private void enforceForUri(
1273 int modeFlags, int resultOfCheck, boolean selfToo,
1274 int uid, Uri uri, String message) {
1275 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1276 throw new SecurityException(
1277 (message != null ? (message + ": ") : "") +
1278 (selfToo
1279 ? "Neither user " + uid + " nor current process has "
1280 : "User " + uid + " does not have ") +
1281 uriModeFlagToString(modeFlags) +
1282 " permission on " +
1283 uri +
1284 ".");
1285 }
1286 }
1287
1288 public void enforceUriPermission(
1289 Uri uri, int pid, int uid, int modeFlags, String message) {
1290 enforceForUri(
1291 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1292 false, uid, uri, message);
1293 }
1294
1295 public void enforceCallingUriPermission(
1296 Uri uri, int modeFlags, String message) {
1297 enforceForUri(
1298 modeFlags, checkCallingUriPermission(uri, modeFlags),
1299 false, Binder.getCallingUid(), uri, message);
1300 }
1301
1302 public void enforceCallingOrSelfUriPermission(
1303 Uri uri, int modeFlags, String message) {
1304 enforceForUri(
1305 modeFlags,
1306 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1307 Binder.getCallingUid(), uri, message);
1308 }
1309
1310 public void enforceUriPermission(
1311 Uri uri, String readPermission, String writePermission,
1312 int pid, int uid, int modeFlags, String message) {
1313 enforceForUri(modeFlags,
1314 checkUriPermission(
1315 uri, readPermission, writePermission, pid, uid,
1316 modeFlags),
1317 false,
1318 uid,
1319 uri,
1320 message);
1321 }
1322
1323 @Override
1324 public Context createPackageContext(String packageName, int flags)
1325 throws PackageManager.NameNotFoundException {
1326 if (packageName.equals("system") || packageName.equals("android")) {
1327 return new ApplicationContext(mMainThread.getSystemContext());
1328 }
1329
1330 ActivityThread.PackageInfo pi =
1331 mMainThread.getPackageInfo(packageName, flags);
1332 if (pi != null) {
1333 ApplicationContext c = new ApplicationContext();
1334 c.init(pi, null, mMainThread);
1335 if (c.mResources != null) {
1336 return c;
1337 }
1338 }
1339
1340 // Should be a better exception.
1341 throw new PackageManager.NameNotFoundException(
1342 "Application package " + packageName + " not found");
1343 }
1344
1345 private File getDataDirFile() {
1346 if (mPackageInfo != null) {
1347 return mPackageInfo.getDataDirFile();
1348 }
1349 throw new RuntimeException("Not supported in system context");
1350 }
1351
1352 @Override
1353 public File getDir(String name, int mode) {
1354 name = "app_" + name;
1355 File file = makeFilename(getDataDirFile(), name);
1356 if (!file.exists()) {
1357 file.mkdir();
1358 setFilePermissionsFromMode(file.getPath(), mode,
1359 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1360 }
1361 return file;
1362 }
1363
1364 static ApplicationContext createSystemContext(ActivityThread mainThread) {
1365 ApplicationContext context = new ApplicationContext();
1366 context.init(Resources.getSystem(), mainThread);
1367 return context;
1368 }
1369
1370 ApplicationContext() {
1371 ++sInstanceCount;
1372 mOuterContext = this;
1373 }
1374
1375 /**
1376 * Create a new ApplicationContext from an existing one. The new one
1377 * works and operates the same as the one it is copying.
1378 *
1379 * @param context Existing application context.
1380 */
1381 public ApplicationContext(ApplicationContext context) {
1382 ++sInstanceCount;
1383 mPackageInfo = context.mPackageInfo;
1384 mResources = context.mResources;
1385 mMainThread = context.mMainThread;
1386 mContentResolver = context.mContentResolver;
1387 mOuterContext = this;
1388 }
1389
1390 final void init(ActivityThread.PackageInfo packageInfo,
1391 IBinder activityToken, ActivityThread mainThread) {
1392 mPackageInfo = packageInfo;
1393 mResources = mPackageInfo.getResources(mainThread);
1394 mMainThread = mainThread;
1395 mContentResolver = new ApplicationContentResolver(this, mainThread);
1396
1397 setActivityToken(activityToken);
1398 }
1399
1400 final void init(Resources resources, ActivityThread mainThread) {
1401 mPackageInfo = null;
1402 mResources = resources;
1403 mMainThread = mainThread;
1404 mContentResolver = new ApplicationContentResolver(this, mainThread);
1405 }
1406
1407 final void scheduleFinalCleanup(String who, String what) {
1408 mMainThread.scheduleContextCleanup(this, who, what);
1409 }
1410
1411 final void performFinalCleanup(String who, String what) {
1412 //Log.i(TAG, "Cleanup up context: " + this);
1413 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1414 }
1415
1416 final Context getReceiverRestrictedContext() {
1417 if (mReceiverRestrictedContext != null) {
1418 return mReceiverRestrictedContext;
1419 }
1420 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1421 }
1422
1423 final void setActivityToken(IBinder token) {
1424 mActivityToken = token;
1425 }
1426
1427 final void setOuterContext(Context context) {
1428 mOuterContext = context;
1429 }
1430
1431 final Context getOuterContext() {
1432 return mOuterContext;
1433 }
1434
1435 final IBinder getActivityToken() {
1436 return mActivityToken;
1437 }
1438
1439 private static void setFilePermissionsFromMode(String name, int mode,
1440 int extraPermissions) {
1441 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1442 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1443 |extraPermissions;
1444 if ((mode&MODE_WORLD_READABLE) != 0) {
1445 perms |= FileUtils.S_IROTH;
1446 }
1447 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1448 perms |= FileUtils.S_IWOTH;
1449 }
1450 if (false) {
1451 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1452 + ", perms=0x" + Integer.toHexString(perms));
1453 }
1454 FileUtils.setPermissions(name, perms, -1, -1);
1455 }
1456
1457 private File makeFilename(File base, String name) {
1458 if (name.indexOf(File.separatorChar) < 0) {
1459 return new File(base, name);
1460 }
1461 throw new IllegalArgumentException(
1462 "File " + name + " contains a path separator");
1463 }
1464
1465 // ----------------------------------------------------------------------
1466 // ----------------------------------------------------------------------
1467 // ----------------------------------------------------------------------
1468
1469 private static final class ApplicationContentResolver extends ContentResolver {
1470 public ApplicationContentResolver(Context context,
1471 ActivityThread mainThread)
1472 {
1473 super(context);
1474 mMainThread = mainThread;
1475 }
1476
1477 @Override
1478 protected IContentProvider acquireProvider(Context context, String name)
1479 {
1480 return mMainThread.acquireProvider(context, name);
1481 }
1482
1483 @Override
1484 public boolean releaseProvider(IContentProvider provider)
1485 {
1486 return mMainThread.releaseProvider(provider);
1487 }
1488
1489 private final ActivityThread mMainThread;
1490 }
1491
1492 // ----------------------------------------------------------------------
1493 // ----------------------------------------------------------------------
1494 // ----------------------------------------------------------------------
1495
1496 /*package*/
1497 static final class ApplicationPackageManager extends PackageManager {
1498 @Override
1499 public PackageInfo getPackageInfo(String packageName, int flags)
1500 throws NameNotFoundException {
1501 try {
1502 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1503 if (pi != null) {
1504 return pi;
1505 }
1506 } catch (RemoteException e) {
1507 throw new RuntimeException("Package manager has died", e);
1508 }
1509
1510 throw new NameNotFoundException(packageName);
1511 }
1512
Mihai Predaeae850c2009-05-13 10:13:48 +02001513 @Override
1514 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 // First see if the package has an INFO activity; the existence of
1516 // such an activity is implied to be the desired front-door for the
1517 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001518 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1519 intentToResolve.addCategory(Intent.CATEGORY_INFO);
1520 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0, packageName);
1521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001523 if (resolveInfo == null) {
1524 // reuse the intent instance
1525 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1526 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
1527 resolveInfo = resolveActivity(intentToResolve, 0, packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001529 if (resolveInfo == null) {
1530 return null;
1531 }
1532 Intent intent = new Intent(Intent.ACTION_MAIN);
1533 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1534 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1535 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 @Override
1539 public int[] getPackageGids(String packageName)
1540 throws NameNotFoundException {
1541 try {
1542 int[] gids = mPM.getPackageGids(packageName);
1543 if (gids == null || gids.length > 0) {
1544 return gids;
1545 }
1546 } catch (RemoteException e) {
1547 throw new RuntimeException("Package manager has died", e);
1548 }
1549
1550 throw new NameNotFoundException(packageName);
1551 }
1552
1553 @Override
1554 public PermissionInfo getPermissionInfo(String name, int flags)
1555 throws NameNotFoundException {
1556 try {
1557 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1558 if (pi != null) {
1559 return pi;
1560 }
1561 } catch (RemoteException e) {
1562 throw new RuntimeException("Package manager has died", e);
1563 }
1564
1565 throw new NameNotFoundException(name);
1566 }
1567
1568 @Override
1569 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1570 throws NameNotFoundException {
1571 try {
1572 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1573 if (pi != null) {
1574 return pi;
1575 }
1576 } catch (RemoteException e) {
1577 throw new RuntimeException("Package manager has died", e);
1578 }
1579
1580 throw new NameNotFoundException(group);
1581 }
1582
1583 @Override
1584 public PermissionGroupInfo getPermissionGroupInfo(String name,
1585 int flags) throws NameNotFoundException {
1586 try {
1587 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1588 if (pgi != null) {
1589 return pgi;
1590 }
1591 } catch (RemoteException e) {
1592 throw new RuntimeException("Package manager has died", e);
1593 }
1594
1595 throw new NameNotFoundException(name);
1596 }
1597
1598 @Override
1599 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1600 try {
1601 return mPM.getAllPermissionGroups(flags);
1602 } catch (RemoteException e) {
1603 throw new RuntimeException("Package manager has died", e);
1604 }
1605 }
1606
1607 @Override
1608 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1609 throws NameNotFoundException {
1610 try {
1611 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1612 if (ai != null) {
1613 return ai;
1614 }
1615 } catch (RemoteException e) {
1616 throw new RuntimeException("Package manager has died", e);
1617 }
1618
1619 throw new NameNotFoundException(packageName);
1620 }
1621
1622 @Override
1623 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1624 throws NameNotFoundException {
1625 try {
1626 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1627 if (ai != null) {
1628 return ai;
1629 }
1630 } catch (RemoteException e) {
1631 throw new RuntimeException("Package manager has died", e);
1632 }
1633
1634 throw new NameNotFoundException(className.toString());
1635 }
1636
1637 @Override
1638 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1639 throws NameNotFoundException {
1640 try {
1641 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1642 if (ai != null) {
1643 return ai;
1644 }
1645 } catch (RemoteException e) {
1646 throw new RuntimeException("Package manager has died", e);
1647 }
1648
1649 throw new NameNotFoundException(className.toString());
1650 }
1651
1652 @Override
1653 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1654 throws NameNotFoundException {
1655 try {
1656 ServiceInfo si = mPM.getServiceInfo(className, flags);
1657 if (si != null) {
1658 return si;
1659 }
1660 } catch (RemoteException e) {
1661 throw new RuntimeException("Package manager has died", e);
1662 }
1663
1664 throw new NameNotFoundException(className.toString());
1665 }
1666
1667 @Override
1668 public String[] getSystemSharedLibraryNames() {
1669 try {
1670 return mPM.getSystemSharedLibraryNames();
1671 } catch (RemoteException e) {
1672 throw new RuntimeException("Package manager has died", e);
1673 }
1674 }
1675
1676 @Override
1677 public int checkPermission(String permName, String pkgName) {
1678 try {
1679 return mPM.checkPermission(permName, pkgName);
1680 } catch (RemoteException e) {
1681 throw new RuntimeException("Package manager has died", e);
1682 }
1683 }
1684
1685 @Override
1686 public boolean addPermission(PermissionInfo info) {
1687 try {
1688 return mPM.addPermission(info);
1689 } catch (RemoteException e) {
1690 throw new RuntimeException("Package manager has died", e);
1691 }
1692 }
1693
1694 @Override
1695 public void removePermission(String name) {
1696 try {
1697 mPM.removePermission(name);
1698 } catch (RemoteException e) {
1699 throw new RuntimeException("Package manager has died", e);
1700 }
1701 }
1702
1703 @Override
1704 public int checkSignatures(String pkg1, String pkg2) {
1705 try {
1706 return mPM.checkSignatures(pkg1, pkg2);
1707 } catch (RemoteException e) {
1708 throw new RuntimeException("Package manager has died", e);
1709 }
1710 }
1711
1712 @Override
1713 public String[] getPackagesForUid(int uid) {
1714 try {
1715 return mPM.getPackagesForUid(uid);
1716 } catch (RemoteException e) {
1717 throw new RuntimeException("Package manager has died", e);
1718 }
1719 }
1720
1721 @Override
1722 public String getNameForUid(int uid) {
1723 try {
1724 return mPM.getNameForUid(uid);
1725 } catch (RemoteException e) {
1726 throw new RuntimeException("Package manager has died", e);
1727 }
1728 }
1729
1730 @Override
1731 public int getUidForSharedUser(String sharedUserName)
1732 throws NameNotFoundException {
1733 try {
1734 int uid = mPM.getUidForSharedUser(sharedUserName);
1735 if(uid != -1) {
1736 return uid;
1737 }
1738 } catch (RemoteException e) {
1739 throw new RuntimeException("Package manager has died", e);
1740 }
1741 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1742 }
1743
1744 @Override
1745 public List<PackageInfo> getInstalledPackages(int flags) {
1746 try {
1747 return mPM.getInstalledPackages(flags);
1748 } catch (RemoteException e) {
1749 throw new RuntimeException("Package manager has died", e);
1750 }
1751 }
1752
1753 @Override
1754 public List<ApplicationInfo> getInstalledApplications(int flags) {
1755 try {
1756 return mPM.getInstalledApplications(flags);
1757 } catch (RemoteException e) {
1758 throw new RuntimeException("Package manager has died", e);
1759 }
1760 }
1761
1762 @Override
1763 public ResolveInfo resolveActivity(Intent intent, int flags) {
1764 try {
1765 return mPM.resolveIntent(
1766 intent,
1767 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1768 flags);
1769 } catch (RemoteException e) {
1770 throw new RuntimeException("Package manager has died", e);
1771 }
1772 }
1773
1774 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001775 public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
1776 try {
1777 return mPM.resolveIntentForPackage(
1778 intent,
1779 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1780 flags,
1781 packageName);
1782 } catch (RemoteException e) {
1783 throw new RuntimeException("Package manager has died", e);
1784 }
1785 }
1786
1787 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001788 public List<ResolveInfo> queryIntentActivities(Intent intent,
1789 int flags) {
1790 try {
1791 return mPM.queryIntentActivities(
1792 intent,
1793 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1794 flags);
1795 } catch (RemoteException e) {
1796 throw new RuntimeException("Package manager has died", e);
1797 }
1798 }
1799
1800 @Override
1801 public List<ResolveInfo> queryIntentActivityOptions(
1802 ComponentName caller, Intent[] specifics, Intent intent,
1803 int flags) {
1804 final ContentResolver resolver = mContext.getContentResolver();
1805
1806 String[] specificTypes = null;
1807 if (specifics != null) {
1808 final int N = specifics.length;
1809 for (int i=0; i<N; i++) {
1810 Intent sp = specifics[i];
1811 if (sp != null) {
1812 String t = sp.resolveTypeIfNeeded(resolver);
1813 if (t != null) {
1814 if (specificTypes == null) {
1815 specificTypes = new String[N];
1816 }
1817 specificTypes[i] = t;
1818 }
1819 }
1820 }
1821 }
1822
1823 try {
1824 return mPM.queryIntentActivityOptions(caller, specifics,
1825 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
1826 flags);
1827 } catch (RemoteException e) {
1828 throw new RuntimeException("Package manager has died", e);
1829 }
1830 }
1831
1832 @Override
1833 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
1834 try {
1835 return mPM.queryIntentReceivers(
1836 intent,
1837 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1838 flags);
1839 } catch (RemoteException e) {
1840 throw new RuntimeException("Package manager has died", e);
1841 }
1842 }
1843
1844 @Override
1845 public ResolveInfo resolveService(Intent intent, int flags) {
1846 try {
1847 return mPM.resolveService(
1848 intent,
1849 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1850 flags);
1851 } catch (RemoteException e) {
1852 throw new RuntimeException("Package manager has died", e);
1853 }
1854 }
1855
1856 @Override
1857 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
1858 try {
1859 return mPM.queryIntentServices(
1860 intent,
1861 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1862 flags);
1863 } catch (RemoteException e) {
1864 throw new RuntimeException("Package manager has died", e);
1865 }
1866 }
1867
1868 @Override
1869 public ProviderInfo resolveContentProvider(String name,
1870 int flags) {
1871 try {
1872 return mPM.resolveContentProvider(name, flags);
1873 } catch (RemoteException e) {
1874 throw new RuntimeException("Package manager has died", e);
1875 }
1876 }
1877
1878 @Override
1879 public List<ProviderInfo> queryContentProviders(String processName,
1880 int uid, int flags) {
1881 try {
1882 return mPM.queryContentProviders(processName, uid, flags);
1883 } catch (RemoteException e) {
1884 throw new RuntimeException("Package manager has died", e);
1885 }
1886 }
1887
1888 @Override
1889 public InstrumentationInfo getInstrumentationInfo(
1890 ComponentName className, int flags)
1891 throws NameNotFoundException {
1892 try {
1893 InstrumentationInfo ii = mPM.getInstrumentationInfo(
1894 className, flags);
1895 if (ii != null) {
1896 return ii;
1897 }
1898 } catch (RemoteException e) {
1899 throw new RuntimeException("Package manager has died", e);
1900 }
1901
1902 throw new NameNotFoundException(className.toString());
1903 }
1904
1905 @Override
1906 public List<InstrumentationInfo> queryInstrumentation(
1907 String targetPackage, int flags) {
1908 try {
1909 return mPM.queryInstrumentation(targetPackage, flags);
1910 } catch (RemoteException e) {
1911 throw new RuntimeException("Package manager has died", e);
1912 }
1913 }
1914
1915 @Override public Drawable getDrawable(String packageName, int resid,
1916 ApplicationInfo appInfo) {
1917 ResourceName name = new ResourceName(packageName, resid);
1918 Drawable dr = getCachedIcon(name);
1919 if (dr != null) {
1920 return dr;
1921 }
1922 if (appInfo == null) {
1923 try {
1924 appInfo = getApplicationInfo(packageName, 0);
1925 } catch (NameNotFoundException e) {
1926 return null;
1927 }
1928 }
1929 try {
1930 Resources r = getResourcesForApplication(appInfo);
1931 dr = r.getDrawable(resid);
1932 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
1933 + Integer.toHexString(resid) + " from " + r
1934 + ": " + dr);
1935 putCachedIcon(name, dr);
1936 return dr;
1937 } catch (NameNotFoundException e) {
1938 Log.w("PackageManager", "Failure retrieving resources for"
1939 + appInfo.packageName);
1940 } catch (RuntimeException e) {
1941 // If an exception was thrown, fall through to return
1942 // default icon.
1943 Log.w("PackageManager", "Failure retrieving icon 0x"
1944 + Integer.toHexString(resid) + " in package "
1945 + packageName, e);
1946 }
1947 return null;
1948 }
1949
1950 @Override public Drawable getActivityIcon(ComponentName activityName)
1951 throws NameNotFoundException {
1952 return getActivityInfo(activityName, 0).loadIcon(this);
1953 }
1954
1955 @Override public Drawable getActivityIcon(Intent intent)
1956 throws NameNotFoundException {
1957 if (intent.getComponent() != null) {
1958 return getActivityIcon(intent.getComponent());
1959 }
1960
1961 ResolveInfo info = resolveActivity(
1962 intent, PackageManager.MATCH_DEFAULT_ONLY);
1963 if (info != null) {
1964 return info.activityInfo.loadIcon(this);
1965 }
1966
1967 throw new NameNotFoundException(intent.toURI());
1968 }
1969
1970 @Override public Drawable getDefaultActivityIcon() {
1971 return Resources.getSystem().getDrawable(
1972 com.android.internal.R.drawable.sym_def_app_icon);
1973 }
1974
1975 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
1976 final int icon = info.icon;
1977 if (icon != 0) {
1978 ResourceName name = new ResourceName(info, icon);
1979 Drawable dr = getCachedIcon(name);
1980 if (dr != null) {
1981 return dr;
1982 }
1983 try {
1984 Resources r = getResourcesForApplication(info);
1985 dr = r.getDrawable(icon);
1986 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
1987 + Integer.toHexString(icon) + " from " + r
1988 + ": " + dr);
1989 putCachedIcon(name, dr);
1990 return dr;
1991 } catch (NameNotFoundException e) {
1992 Log.w("PackageManager", "Failure retrieving resources for"
1993 + info.packageName);
1994 } catch (RuntimeException e) {
1995 // If an exception was thrown, fall through to return
1996 // default icon.
1997 Log.w("PackageManager", "Failure retrieving app icon", e);
1998 }
1999 }
2000 return getDefaultActivityIcon();
2001 }
2002
2003 @Override public Drawable getApplicationIcon(String packageName)
2004 throws NameNotFoundException {
2005 return getApplicationIcon(getApplicationInfo(packageName, 0));
2006 }
2007
2008 @Override public Resources getResourcesForActivity(
2009 ComponentName activityName) throws NameNotFoundException {
2010 return getResourcesForApplication(
2011 getActivityInfo(activityName, 0).applicationInfo);
2012 }
2013
2014 @Override public Resources getResourcesForApplication(
2015 ApplicationInfo app) throws NameNotFoundException {
2016 if (app.packageName.equals("system")) {
2017 return mContext.mMainThread.getSystemContext().getResources();
2018 }
Mitsuru Oshima8169dae2009-04-28 18:12:09 -07002019 ActivityThread.PackageInfo pi = mContext.mMainThread.getPackageInfoNoCheck(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 Resources r = mContext.mMainThread.getTopLevelResources(
2021 app.uid == Process.myUid() ? app.sourceDir
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002022 : app.publicSourceDir, pi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 if (r != null) {
2024 return r;
2025 }
2026 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2027 }
2028
2029 @Override public Resources getResourcesForApplication(
2030 String appPackageName) throws NameNotFoundException {
2031 return getResourcesForApplication(
2032 getApplicationInfo(appPackageName, 0));
2033 }
2034
2035 int mCachedSafeMode = -1;
2036 @Override public boolean isSafeMode() {
2037 try {
2038 if (mCachedSafeMode < 0) {
2039 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2040 }
2041 return mCachedSafeMode != 0;
2042 } catch (RemoteException e) {
2043 throw new RuntimeException("Package manager has died", e);
2044 }
2045 }
2046
2047 static void configurationChanged() {
2048 synchronized (sSync) {
2049 sIconCache.clear();
2050 sStringCache.clear();
2051 }
2052 }
2053
2054 ApplicationPackageManager(ApplicationContext context,
2055 IPackageManager pm) {
2056 mContext = context;
2057 mPM = pm;
2058 }
2059
2060 private Drawable getCachedIcon(ResourceName name) {
2061 synchronized (sSync) {
2062 WeakReference<Drawable> wr = sIconCache.get(name);
2063 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2064 + name + ": " + wr);
2065 if (wr != null) { // we have the activity
2066 Drawable dr = wr.get();
2067 if (dr != null) {
2068 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2069 + name + ": " + dr);
2070 return dr;
2071 }
2072 // our entry has been purged
2073 sIconCache.remove(name);
2074 }
2075 }
2076 return null;
2077 }
2078
2079 private void establishPackageRemovedReceiver() {
2080 // mContext.registerReceiverInternal() winds up acquiring the
2081 // main ActivityManagerService.this lock. If we hold our usual
2082 // sSync global lock at the same time, we impose a required ordering
2083 // on those two locks, which is not good for deadlock prevention.
2084 // Use a dedicated lock around initialization of
2085 // sPackageRemovedReceiver to avoid this.
2086 synchronized (sPackageRemovedSync) {
2087 if (sPackageRemovedReceiver == null) {
2088 sPackageRemovedReceiver = new PackageRemovedReceiver();
2089 IntentFilter filter = new IntentFilter(
2090 Intent.ACTION_PACKAGE_REMOVED);
2091 filter.addDataScheme("package");
2092 mContext.registerReceiverInternal(sPackageRemovedReceiver,
2093 filter, null, null, null);
2094 }
2095 }
2096 }
2097
2098 private void putCachedIcon(ResourceName name, Drawable dr) {
2099 establishPackageRemovedReceiver();
2100
2101 synchronized (sSync) {
2102 sIconCache.put(name, new WeakReference<Drawable>(dr));
2103 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2104 + name + ": " + dr);
2105 }
2106 }
2107
2108 private static final class PackageRemovedReceiver extends BroadcastReceiver {
2109 @Override
2110 public void onReceive(Context context, Intent intent) {
2111 Uri data = intent.getData();
2112 String ssp;
2113 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
2114 boolean needCleanup = false;
2115 synchronized (sSync) {
2116 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2117 while (it.hasNext()) {
2118 ResourceName nm = it.next();
2119 if (nm.packageName.equals(ssp)) {
2120 //Log.i(TAG, "Removing cached drawable for " + nm);
2121 it.remove();
2122 needCleanup = true;
2123 }
2124 }
2125 it = sStringCache.keySet().iterator();
2126 while (it.hasNext()) {
2127 ResourceName nm = it.next();
2128 if (nm.packageName.equals(ssp)) {
2129 //Log.i(TAG, "Removing cached string for " + nm);
2130 it.remove();
2131 needCleanup = true;
2132 }
2133 }
2134 }
2135 if (needCleanup || ActivityThread.currentActivityThread().hasPackageInfo(ssp)) {
2136 ActivityThread.currentActivityThread().scheduleGcIdler();
2137 }
2138 }
2139 }
2140 }
2141
2142 private static final class ResourceName {
2143 final String packageName;
2144 final int iconId;
2145
2146 ResourceName(String _packageName, int _iconId) {
2147 packageName = _packageName;
2148 iconId = _iconId;
2149 }
2150
2151 ResourceName(ApplicationInfo aInfo, int _iconId) {
2152 this(aInfo.packageName, _iconId);
2153 }
2154
2155 ResourceName(ComponentInfo cInfo, int _iconId) {
2156 this(cInfo.applicationInfo.packageName, _iconId);
2157 }
2158
2159 ResourceName(ResolveInfo rInfo, int _iconId) {
2160 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2161 }
2162
2163 @Override
2164 public boolean equals(Object o) {
2165 if (this == o) return true;
2166 if (o == null || getClass() != o.getClass()) return false;
2167
2168 ResourceName that = (ResourceName) o;
2169
2170 if (iconId != that.iconId) return false;
2171 return !(packageName != null ?
2172 !packageName.equals(that.packageName) : that.packageName != null);
2173
2174 }
2175
2176 @Override
2177 public int hashCode() {
2178 int result;
2179 result = packageName.hashCode();
2180 result = 31 * result + iconId;
2181 return result;
2182 }
2183
2184 @Override
2185 public String toString() {
2186 return "{ResourceName " + packageName + " / " + iconId + "}";
2187 }
2188 }
2189
2190 private CharSequence getCachedString(ResourceName name) {
2191 synchronized (sSync) {
2192 WeakReference<CharSequence> wr = sStringCache.get(name);
2193 if (wr != null) { // we have the activity
2194 CharSequence cs = wr.get();
2195 if (cs != null) {
2196 return cs;
2197 }
2198 // our entry has been purged
2199 sStringCache.remove(name);
2200 }
2201 }
2202 return null;
2203 }
2204
2205 private void putCachedString(ResourceName name, CharSequence cs) {
2206 establishPackageRemovedReceiver();
2207
2208 synchronized (sSync) {
2209 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2210 }
2211 }
2212
2213 private CharSequence getLabel(ResourceName name, ApplicationInfo app, int id) {
2214 CharSequence cs = getCachedString(name);
2215 if (cs != null) {
2216 return cs;
2217 }
2218 try {
2219 Resources r = getResourcesForApplication(app);
2220 cs = r.getText(id);
2221 putCachedString(name, cs);
2222 } catch (NameNotFoundException e) {
2223 Log.w("PackageManager", "Failure retrieving resources for"
2224 + app.packageName);
2225 } catch (RuntimeException e) {
2226 // If an exception was thrown, fall through to return null
2227 Log.w("ApplicationInfo", "Failure retrieving activity name", e);
2228 }
2229 return cs;
2230 }
2231
2232 @Override
2233 public CharSequence getText(String packageName, int resid,
2234 ApplicationInfo appInfo) {
2235 ResourceName name = new ResourceName(packageName, resid);
2236 CharSequence text = getCachedString(name);
2237 if (text != null) {
2238 return text;
2239 }
2240 if (appInfo == null) {
2241 try {
2242 appInfo = getApplicationInfo(packageName, 0);
2243 } catch (NameNotFoundException e) {
2244 return null;
2245 }
2246 }
2247 try {
2248 Resources r = getResourcesForApplication(appInfo);
2249 text = r.getText(resid);
2250 putCachedString(name, text);
2251 return text;
2252 } catch (NameNotFoundException e) {
2253 Log.w("PackageManager", "Failure retrieving resources for"
2254 + appInfo.packageName);
2255 } catch (RuntimeException e) {
2256 // If an exception was thrown, fall through to return
2257 // default icon.
2258 Log.w("PackageManager", "Failure retrieving text 0x"
2259 + Integer.toHexString(resid) + " in package "
2260 + packageName, e);
2261 }
2262 return null;
2263 }
2264
2265 @Override
2266 public XmlResourceParser getXml(String packageName, int resid,
2267 ApplicationInfo appInfo) {
2268 if (appInfo == null) {
2269 try {
2270 appInfo = getApplicationInfo(packageName, 0);
2271 } catch (NameNotFoundException e) {
2272 return null;
2273 }
2274 }
2275 try {
2276 Resources r = getResourcesForApplication(appInfo);
2277 return r.getXml(resid);
2278 } catch (RuntimeException e) {
2279 // If an exception was thrown, fall through to return
2280 // default icon.
2281 Log.w("PackageManager", "Failure retrieving xml 0x"
2282 + Integer.toHexString(resid) + " in package "
2283 + packageName, e);
2284 } catch (NameNotFoundException e) {
2285 Log.w("PackageManager", "Failure retrieving resources for"
2286 + appInfo.packageName);
2287 }
2288 return null;
2289 }
2290
2291 @Override
2292 public CharSequence getApplicationLabel(ApplicationInfo info) {
2293 if (info.nonLocalizedLabel != null) {
2294 return info.nonLocalizedLabel;
2295 }
2296 final int id = info.labelRes;
2297 if (id != 0) {
2298 CharSequence cs = getLabel(new ResourceName(info, id), info, id);
2299 if (cs != null) {
2300 return cs;
2301 }
2302 }
2303 return info.packageName;
2304 }
2305
2306 @Override
Jacek Surazskic64322c2009-04-28 15:26:38 +02002307 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2308 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 try {
Jacek Surazskic64322c2009-04-28 15:26:38 +02002310 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 } catch (RemoteException e) {
2312 // Should never happen!
2313 }
2314 }
2315
2316 @Override
Jacek Surazskic64322c2009-04-28 15:26:38 +02002317 public String getInstallerPackageName(String packageName) {
2318 try {
2319 return mPM.getInstallerPackageName(packageName);
2320 } catch (RemoteException e) {
2321 // Should never happen!
2322 }
2323 return null;
2324 }
2325
2326 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2328 try {
2329 mPM.deletePackage(packageName, observer, flags);
2330 } catch (RemoteException e) {
2331 // Should never happen!
2332 }
2333 }
2334 @Override
2335 public void clearApplicationUserData(String packageName,
2336 IPackageDataObserver observer) {
2337 try {
2338 mPM.clearApplicationUserData(packageName, observer);
2339 } catch (RemoteException e) {
2340 // Should never happen!
2341 }
2342 }
2343 @Override
2344 public void deleteApplicationCacheFiles(String packageName,
2345 IPackageDataObserver observer) {
2346 try {
2347 mPM.deleteApplicationCacheFiles(packageName, observer);
2348 } catch (RemoteException e) {
2349 // Should never happen!
2350 }
2351 }
2352 @Override
2353 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2354 try {
2355 mPM.freeStorageAndNotify(idealStorageSize, observer);
2356 } catch (RemoteException e) {
2357 // Should never happen!
2358 }
2359 }
2360
2361 @Override
2362 public void freeStorage(long idealStorageSize, PendingIntent opFinishedIntent) {
2363 try {
2364 mPM.freeStorage(idealStorageSize, opFinishedIntent);
2365 } catch (RemoteException e) {
2366 // Should never happen!
2367 }
2368 }
2369
2370 @Override
2371 public void getPackageSizeInfo(String packageName,
2372 IPackageStatsObserver observer) {
2373 try {
2374 mPM.getPackageSizeInfo(packageName, observer);
2375 } catch (RemoteException e) {
2376 // Should never happen!
2377 }
2378 }
2379 @Override
2380 public void addPackageToPreferred(String packageName) {
2381 try {
2382 mPM.addPackageToPreferred(packageName);
2383 } catch (RemoteException e) {
2384 // Should never happen!
2385 }
2386 }
2387
2388 @Override
2389 public void removePackageFromPreferred(String packageName) {
2390 try {
2391 mPM.removePackageFromPreferred(packageName);
2392 } catch (RemoteException e) {
2393 // Should never happen!
2394 }
2395 }
2396
2397 @Override
2398 public List<PackageInfo> getPreferredPackages(int flags) {
2399 try {
2400 return mPM.getPreferredPackages(flags);
2401 } catch (RemoteException e) {
2402 // Should never happen!
2403 }
2404 return new ArrayList<PackageInfo>();
2405 }
2406
2407 @Override
2408 public void addPreferredActivity(IntentFilter filter,
2409 int match, ComponentName[] set, ComponentName activity) {
2410 try {
2411 mPM.addPreferredActivity(filter, match, set, activity);
2412 } catch (RemoteException e) {
2413 // Should never happen!
2414 }
2415 }
2416
2417 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002418 public void replacePreferredActivity(IntentFilter filter,
2419 int match, ComponentName[] set, ComponentName activity) {
2420 try {
2421 mPM.replacePreferredActivity(filter, match, set, activity);
2422 } catch (RemoteException e) {
2423 // Should never happen!
2424 }
2425 }
2426
2427 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002428 public void clearPackagePreferredActivities(String packageName) {
2429 try {
2430 mPM.clearPackagePreferredActivities(packageName);
2431 } catch (RemoteException e) {
2432 // Should never happen!
2433 }
2434 }
2435
2436 @Override
2437 public int getPreferredActivities(List<IntentFilter> outFilters,
2438 List<ComponentName> outActivities, String packageName) {
2439 try {
2440 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2441 } catch (RemoteException e) {
2442 // Should never happen!
2443 }
2444 return 0;
2445 }
2446
2447 @Override
2448 public void setComponentEnabledSetting(ComponentName componentName,
2449 int newState, int flags) {
2450 try {
2451 mPM.setComponentEnabledSetting(componentName, newState, flags);
2452 } catch (RemoteException e) {
2453 // Should never happen!
2454 }
2455 }
2456
2457 @Override
2458 public int getComponentEnabledSetting(ComponentName componentName) {
2459 try {
2460 return mPM.getComponentEnabledSetting(componentName);
2461 } catch (RemoteException e) {
2462 // Should never happen!
2463 }
2464 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2465 }
2466
2467 @Override
2468 public void setApplicationEnabledSetting(String packageName,
2469 int newState, int flags) {
2470 try {
2471 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2472 } catch (RemoteException e) {
2473 // Should never happen!
2474 }
2475 }
2476
2477 @Override
2478 public int getApplicationEnabledSetting(String packageName) {
2479 try {
2480 return mPM.getApplicationEnabledSetting(packageName);
2481 } catch (RemoteException e) {
2482 // Should never happen!
2483 }
2484 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2485 }
2486
2487 private final ApplicationContext mContext;
2488 private final IPackageManager mPM;
2489
2490 private static final Object sSync = new Object();
2491 private static final Object sPackageRemovedSync = new Object();
2492 private static BroadcastReceiver sPackageRemovedReceiver;
2493 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2494 = new HashMap<ResourceName, WeakReference<Drawable> >();
2495 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2496 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2497 }
2498
2499 // ----------------------------------------------------------------------
2500 // ----------------------------------------------------------------------
2501 // ----------------------------------------------------------------------
2502
2503 private static final class SharedPreferencesImpl implements SharedPreferences {
2504
2505 private final File mFile;
2506 private final File mBackupFile;
2507 private final int mMode;
2508 private Map mMap;
2509 private final FileStatus mFileStatus = new FileStatus();
2510 private long mTimestamp;
2511
The Android Open Source Project10592532009-03-18 17:39:46 -07002512 private static final Object mContent = new Object();
2513 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514
2515 SharedPreferencesImpl(
2516 File file, int mode, Map initialContents) {
2517 mFile = file;
2518 mBackupFile = makeBackupFile(file);
2519 mMode = mode;
2520 mMap = initialContents != null ? initialContents : new HashMap();
2521 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2522 mTimestamp = mFileStatus.mtime;
2523 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002524 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002525 }
2526
2527 public boolean hasFileChanged() {
2528 synchronized (this) {
2529 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2530 return true;
2531 }
2532 return mTimestamp != mFileStatus.mtime;
2533 }
2534 }
2535
2536 public void replace(Map newContents) {
2537 if (newContents != null) {
2538 synchronized (this) {
2539 mMap = newContents;
2540 }
2541 }
2542 }
2543
2544 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2545 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002546 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002547 }
2548 }
2549
2550 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2551 synchronized(this) {
2552 mListeners.remove(listener);
2553 }
2554 }
2555
2556 public Map<String, ?> getAll() {
2557 synchronized(this) {
2558 //noinspection unchecked
2559 return new HashMap(mMap);
2560 }
2561 }
2562
2563 public String getString(String key, String defValue) {
2564 synchronized (this) {
2565 String v = (String)mMap.get(key);
2566 return v != null ? v : defValue;
2567 }
2568 }
2569
2570 public int getInt(String key, int defValue) {
2571 synchronized (this) {
2572 Integer v = (Integer)mMap.get(key);
2573 return v != null ? v : defValue;
2574 }
2575 }
2576 public long getLong(String key, long defValue) {
2577 synchronized (this) {
2578 Long v = (Long) mMap.get(key);
2579 return v != null ? v : defValue;
2580 }
2581 }
2582 public float getFloat(String key, float defValue) {
2583 synchronized (this) {
2584 Float v = (Float)mMap.get(key);
2585 return v != null ? v : defValue;
2586 }
2587 }
2588 public boolean getBoolean(String key, boolean defValue) {
2589 synchronized (this) {
2590 Boolean v = (Boolean)mMap.get(key);
2591 return v != null ? v : defValue;
2592 }
2593 }
2594
2595 public boolean contains(String key) {
2596 synchronized (this) {
2597 return mMap.containsKey(key);
2598 }
2599 }
2600
2601 public final class EditorImpl implements Editor {
2602 private final Map<String, Object> mModified = Maps.newHashMap();
2603 private boolean mClear = false;
2604
2605 public Editor putString(String key, String value) {
2606 synchronized (this) {
2607 mModified.put(key, value);
2608 return this;
2609 }
2610 }
2611 public Editor putInt(String key, int value) {
2612 synchronized (this) {
2613 mModified.put(key, value);
2614 return this;
2615 }
2616 }
2617 public Editor putLong(String key, long value) {
2618 synchronized (this) {
2619 mModified.put(key, value);
2620 return this;
2621 }
2622 }
2623 public Editor putFloat(String key, float value) {
2624 synchronized (this) {
2625 mModified.put(key, value);
2626 return this;
2627 }
2628 }
2629 public Editor putBoolean(String key, boolean value) {
2630 synchronized (this) {
2631 mModified.put(key, value);
2632 return this;
2633 }
2634 }
2635
2636 public Editor remove(String key) {
2637 synchronized (this) {
2638 mModified.put(key, this);
2639 return this;
2640 }
2641 }
2642
2643 public Editor clear() {
2644 synchronized (this) {
2645 mClear = true;
2646 return this;
2647 }
2648 }
2649
2650 public boolean commit() {
2651 boolean returnValue;
2652
2653 boolean hasListeners;
2654 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002655 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656
2657 synchronized (SharedPreferencesImpl.this) {
2658 hasListeners = mListeners.size() > 0;
2659 if (hasListeners) {
2660 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002661 listeners =
2662 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 }
2664
2665 synchronized (this) {
2666 if (mClear) {
2667 mMap.clear();
2668 mClear = false;
2669 }
2670
The Android Open Source Project10592532009-03-18 17:39:46 -07002671 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 String k = e.getKey();
2673 Object v = e.getValue();
2674 if (v == this) {
2675 mMap.remove(k);
2676 } else {
2677 mMap.put(k, v);
2678 }
2679
2680 if (hasListeners) {
2681 keysModified.add(k);
2682 }
2683 }
2684
2685 mModified.clear();
2686 }
2687
2688 returnValue = writeFileLocked();
2689 }
2690
2691 if (hasListeners) {
2692 for (int i = keysModified.size() - 1; i >= 0; i--) {
2693 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002694 for (OnSharedPreferenceChangeListener listener : listeners) {
2695 if (listener != null) {
2696 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 }
2699 }
2700 }
2701
2702 return returnValue;
2703 }
2704 }
2705
2706 public Editor edit() {
2707 return new EditorImpl();
2708 }
2709
2710 private FileOutputStream createFileOutputStream(File file) {
2711 FileOutputStream str = null;
2712 try {
2713 str = new FileOutputStream(file);
2714 } catch (FileNotFoundException e) {
2715 File parent = file.getParentFile();
2716 if (!parent.mkdir()) {
2717 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2718 return null;
2719 }
2720 FileUtils.setPermissions(
2721 parent.getPath(),
2722 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2723 -1, -1);
2724 try {
2725 str = new FileOutputStream(file);
2726 } catch (FileNotFoundException e2) {
2727 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2728 }
2729 }
2730 return str;
2731 }
2732
2733 private boolean writeFileLocked() {
2734 // Rename the current file so it may be used as a backup during the next read
2735 if (mFile.exists()) {
2736 if (!mFile.renameTo(mBackupFile)) {
2737 Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile);
2738 }
2739 }
2740
2741 // Attempt to write the file, delete the backup and return true as atomically as
2742 // possible. If any exception occurs, delete the new file; next time we will restore
2743 // from the backup.
2744 try {
2745 FileOutputStream str = createFileOutputStream(mFile);
2746 if (str == null) {
2747 return false;
2748 }
2749 XmlUtils.writeMapXml(mMap, str);
2750 str.close();
2751 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2752 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2753 mTimestamp = mFileStatus.mtime;
2754 }
2755
Dianne Hackborn1bf5e222009-03-24 19:11:58 -07002756 // Writing was successful, delete the backup file if there is one.
2757 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 return true;
2759 } catch (XmlPullParserException e) {
2760 Log.w(TAG, "writeFileLocked: Got exception:", e);
2761 } catch (IOException e) {
2762 Log.w(TAG, "writeFileLocked: Got exception:", e);
2763 }
2764 // Clean up an unsuccessfully written file
2765 if (mFile.exists()) {
2766 if (!mFile.delete()) {
2767 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2768 }
2769 }
2770 return false;
2771 }
2772 }
2773
2774 private static class WallpaperCallback extends IWallpaperServiceCallback.Stub {
2775 private WeakReference<ApplicationContext> mContext;
2776
2777 public WallpaperCallback(ApplicationContext context) {
2778 mContext = new WeakReference<ApplicationContext>(context);
2779 }
2780
2781 public synchronized void onWallpaperChanged() {
2782
2783 /* The wallpaper has changed but we shouldn't eagerly load the
2784 * wallpaper as that would be inefficient. Reset the cached wallpaper
2785 * to null so if the user requests the wallpaper again then we'll
2786 * fetch it.
2787 */
2788 final ApplicationContext applicationContext = mContext.get();
2789 if (applicationContext != null) {
2790 applicationContext.mWallpaper = null;
2791 }
2792 }
2793 }
2794}