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