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