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