blob: 860c5de068e49b71e0a5b2a1dc879396ad7d7efd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080020import com.android.internal.util.XmlUtils;
svetoslavganov75986cf2009-05-14 22:28:01 -070021
22import org.xmlpull.v1.XmlPullParserException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.BroadcastReceiver;
25import android.content.ComponentName;
26import android.content.ContentResolver;
27import android.content.Context;
28import android.content.ContextWrapper;
29import android.content.IContentProvider;
30import android.content.Intent;
31import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070032import android.content.IIntentReceiver;
33import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.ReceiverCallNotAllowedException;
35import android.content.ServiceConnection;
36import android.content.SharedPreferences;
37import android.content.pm.ActivityInfo;
38import android.content.pm.ApplicationInfo;
39import android.content.pm.ComponentInfo;
Dianne Hackborn49237342009-08-27 20:08:01 -070040import android.content.pm.FeatureInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.content.pm.IPackageDataObserver;
42import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.content.pm.IPackageInstallObserver;
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -080044import android.content.pm.IPackageMoveObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070046import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.content.pm.InstrumentationInfo;
48import android.content.pm.PackageInfo;
49import android.content.pm.PackageManager;
50import android.content.pm.PermissionGroupInfo;
51import android.content.pm.PermissionInfo;
52import android.content.pm.ProviderInfo;
53import android.content.pm.ResolveInfo;
54import android.content.pm.ServiceInfo;
55import android.content.res.AssetManager;
56import android.content.res.Resources;
57import android.content.res.XmlResourceParser;
Vasu Nori74f170f2010-06-01 18:06:18 -070058import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.database.sqlite.SQLiteDatabase;
60import android.database.sqlite.SQLiteDatabase.CursorFactory;
61import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.graphics.drawable.Drawable;
63import android.hardware.SensorManager;
Bai Taoa58a8752010-07-13 15:32:16 +080064import android.location.CountryDetector;
65import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.location.ILocationManager;
67import android.location.LocationManager;
68import android.media.AudioManager;
69import android.net.ConnectivityManager;
70import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070071import android.net.ThrottleManager;
72import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.net.Uri;
74import android.net.wifi.IWifiManager;
75import android.net.wifi.WifiManager;
76import android.os.Binder;
Adam Powellc63806d2010-09-23 16:21:30 -070077import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080079import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080080import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.FileUtils;
82import android.os.Handler;
83import android.os.IBinder;
84import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070085import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.os.PowerManager;
87import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070088import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.ServiceManager;
90import android.os.Vibrator;
91import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080092import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070094import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import android.util.AndroidRuntimeException;
96import android.util.Log;
97import android.view.ContextThemeWrapper;
98import android.view.LayoutInflater;
99import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -0700100import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -0700102import android.accounts.AccountManager;
103import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800104import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -0800105import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import java.io.File;
108import java.io.FileInputStream;
109import java.io.FileNotFoundException;
110import java.io.FileOutputStream;
111import java.io.IOException;
112import java.io.InputStream;
113import java.lang.ref.WeakReference;
114import java.util.ArrayList;
115import java.util.HashMap;
116import java.util.Iterator;
117import java.util.List;
118import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700119import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700120import java.util.WeakHashMap;
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700121import java.util.concurrent.CountDownLatch;
122import java.util.concurrent.ExecutorService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124class ReceiverRestrictedContext extends ContextWrapper {
125 ReceiverRestrictedContext(Context base) {
126 super(base);
127 }
128
129 @Override
130 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
131 return registerReceiver(receiver, filter, null, null);
132 }
133
134 @Override
135 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
136 String broadcastPermission, Handler scheduler) {
137 throw new ReceiverCallNotAllowedException(
138 "IntentReceiver components are not allowed to register to receive intents");
139 //ex.fillInStackTrace();
140 //Log.e("IntentReceiver", ex.getMessage(), ex);
141 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
142 // scheduler);
143 }
144
145 @Override
146 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
147 throw new ReceiverCallNotAllowedException(
148 "IntentReceiver components are not allowed to bind to services");
149 //ex.fillInStackTrace();
150 //Log.e("IntentReceiver", ex.getMessage(), ex);
151 //return mContext.bindService(service, interfaceName, conn, flags);
152 }
153}
154
155/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800156 * Common implementation of Context API, which provides the base
157 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800159class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700161 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 private final static boolean DEBUG_ICONS = false;
163
164 private static final Object sSync = new Object();
165 private static AlarmManager sAlarmManager;
166 private static PowerManager sPowerManager;
167 private static ConnectivityManager sConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700168 private static ThrottleManager sThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 private static WifiManager sWifiManager;
170 private static LocationManager sLocationManager;
Bai Taoa58a8752010-07-13 15:32:16 +0800171 private static CountryDetector sCountryDetector;
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700172 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
173 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174
175 private AudioManager mAudioManager;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700176 /*package*/ LoadedApk mPackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 private Resources mResources;
178 /*package*/ ActivityThread mMainThread;
179 private Context mOuterContext;
180 private IBinder mActivityToken = null;
181 private ApplicationContentResolver mContentResolver;
182 private int mThemeResource = 0;
183 private Resources.Theme mTheme = null;
184 private PackageManager mPackageManager;
185 private NotificationManager mNotificationManager = null;
186 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700187 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 private Context mReceiverRestrictedContext = null;
189 private SearchManager mSearchManager = null;
190 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800191 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 private Vibrator mVibrator = null;
193 private LayoutInflater mLayoutInflater = null;
194 private StatusBarManager mStatusBarManager = null;
195 private TelephonyManager mTelephonyManager = null;
196 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700197 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700198 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800199 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800200 private DevicePolicyManager mDevicePolicyManager = null;
Tobias Haamel53332882010-02-18 16:15:43 -0800201 private UiModeManager mUiModeManager = null;
Steve Howarda2709362010-07-02 17:12:48 -0700202 private DownloadManager mDownloadManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203
204 private final Object mSync = new Object();
205
206 private File mDatabasesDir;
207 private File mPreferencesDir;
208 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800210 private File mExternalFilesDir;
211 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 private static final String[] EMPTY_FILE_LIST = {};
214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 @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 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 @Override
251 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700252 return (mPackageInfo != null) ?
253 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 @Override
257 public void setTheme(int resid) {
258 mThemeResource = resid;
259 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 @Override
262 public Resources.Theme getTheme() {
263 if (mTheme == null) {
264 if (mThemeResource == 0) {
Joe Onorato170e5482010-10-29 13:26:11 -0700265 final Context outerContext = getOuterContext();
266 mThemeResource = (outerContext.getApplicationInfo().targetSdkVersion
267 >= Build.VERSION_CODES.HONEYCOMB)
268 ? com.android.internal.R.style.Theme_Holo
269 : com.android.internal.R.style.Theme;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 }
271 mTheme = mResources.newTheme();
272 mTheme.applyStyle(mThemeResource, true);
273 }
274 return mTheme;
275 }
276
277 @Override
278 public ClassLoader getClassLoader() {
279 return mPackageInfo != null ?
280 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
281 }
282
283 @Override
284 public String getPackageName() {
285 if (mPackageInfo != null) {
286 return mPackageInfo.getPackageName();
287 }
288 throw new RuntimeException("Not supported in system context");
289 }
290
291 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700292 public ApplicationInfo getApplicationInfo() {
293 if (mPackageInfo != null) {
294 return mPackageInfo.getApplicationInfo();
295 }
296 throw new RuntimeException("Not supported in system context");
297 }
298
299 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 public String getPackageResourcePath() {
301 if (mPackageInfo != null) {
302 return mPackageInfo.getResDir();
303 }
304 throw new RuntimeException("Not supported in system context");
305 }
306
307 @Override
308 public String getPackageCodePath() {
309 if (mPackageInfo != null) {
310 return mPackageInfo.getAppDir();
311 }
312 throw new RuntimeException("Not supported in system context");
313 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200314
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -0800315 static File makeBackupFile(File prefsFile) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 return new File(prefsFile.getPath() + ".bak");
317 }
318
Joe Onorato23ecae32009-06-10 17:07:15 -0700319 public File getSharedPrefsFile(String name) {
320 return makeFilename(getPreferencesDir(), name + ".xml");
321 }
322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 @Override
324 public SharedPreferences getSharedPreferences(String name, int mode) {
325 SharedPreferencesImpl sp;
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700326 File prefsFile;
327 boolean needInitialLoad = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700329 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700330 if (sp != null && !sp.hasFileChangedUnexpectedly()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 return sp;
332 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700333 prefsFile = getSharedPrefsFile(name);
334 if (sp == null) {
335 sp = new SharedPreferencesImpl(prefsFile, mode, null);
336 sSharedPrefs.put(name, sp);
337 needInitialLoad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
339 }
340
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700341 synchronized (sp) {
342 if (needInitialLoad && sp.isLoaded()) {
343 // lost the race to load; another thread handled it
344 return sp;
345 }
346 File backup = makeBackupFile(prefsFile);
347 if (backup.exists()) {
348 prefsFile.delete();
349 backup.renameTo(prefsFile);
350 }
351
352 // Debugging
353 if (prefsFile.exists() && !prefsFile.canRead()) {
354 Log.w(TAG, "Attempt to read preferences file " + prefsFile + " without permission");
355 }
356
357 Map map = null;
358 if (prefsFile.exists() && prefsFile.canRead()) {
359 try {
360 FileInputStream str = new FileInputStream(prefsFile);
361 map = XmlUtils.readMapXml(str);
362 str.close();
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -0800363 } catch (XmlPullParserException e) {
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700364 Log.w(TAG, "getSharedPreferences", e);
365 } catch (FileNotFoundException e) {
366 Log.w(TAG, "getSharedPreferences", e);
367 } catch (IOException e) {
368 Log.w(TAG, "getSharedPreferences", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 }
370 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700371 sp.replace(map);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700373 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 }
375
376 private File getPreferencesDir() {
377 synchronized (mSync) {
378 if (mPreferencesDir == null) {
379 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
380 }
381 return mPreferencesDir;
382 }
383 }
384
385 @Override
386 public FileInputStream openFileInput(String name)
387 throws FileNotFoundException {
388 File f = makeFilename(getFilesDir(), name);
389 return new FileInputStream(f);
390 }
391
392 @Override
393 public FileOutputStream openFileOutput(String name, int mode)
394 throws FileNotFoundException {
395 final boolean append = (mode&MODE_APPEND) != 0;
396 File f = makeFilename(getFilesDir(), name);
397 try {
398 FileOutputStream fos = new FileOutputStream(f, append);
399 setFilePermissionsFromMode(f.getPath(), mode, 0);
400 return fos;
401 } catch (FileNotFoundException e) {
402 }
403
404 File parent = f.getParentFile();
405 parent.mkdir();
406 FileUtils.setPermissions(
407 parent.getPath(),
408 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
409 -1, -1);
410 FileOutputStream fos = new FileOutputStream(f, append);
411 setFilePermissionsFromMode(f.getPath(), mode, 0);
412 return fos;
413 }
414
415 @Override
416 public boolean deleteFile(String name) {
417 File f = makeFilename(getFilesDir(), name);
418 return f.delete();
419 }
420
421 @Override
422 public File getFilesDir() {
423 synchronized (mSync) {
424 if (mFilesDir == null) {
425 mFilesDir = new File(getDataDirFile(), "files");
426 }
427 if (!mFilesDir.exists()) {
428 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200429 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 return null;
431 }
432 FileUtils.setPermissions(
433 mFilesDir.getPath(),
434 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
435 -1, -1);
436 }
437 return mFilesDir;
438 }
439 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800442 public File getExternalFilesDir(String type) {
443 synchronized (mSync) {
444 if (mExternalFilesDir == null) {
445 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
446 getPackageName());
447 }
448 if (!mExternalFilesDir.exists()) {
449 try {
450 (new File(Environment.getExternalStorageAndroidDataDir(),
451 ".nomedia")).createNewFile();
452 } catch (IOException e) {
453 }
454 if (!mExternalFilesDir.mkdirs()) {
455 Log.w(TAG, "Unable to create external files directory");
456 return null;
457 }
458 }
459 if (type == null) {
460 return mExternalFilesDir;
461 }
462 File dir = new File(mExternalFilesDir, type);
463 if (!dir.exists()) {
464 if (!dir.mkdirs()) {
465 Log.w(TAG, "Unable to create external media directory " + dir);
466 return null;
467 }
468 }
469 return dir;
470 }
471 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200472
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800473 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 public File getCacheDir() {
475 synchronized (mSync) {
476 if (mCacheDir == null) {
477 mCacheDir = new File(getDataDirFile(), "cache");
478 }
479 if (!mCacheDir.exists()) {
480 if(!mCacheDir.mkdirs()) {
481 Log.w(TAG, "Unable to create cache directory");
482 return null;
483 }
484 FileUtils.setPermissions(
485 mCacheDir.getPath(),
486 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
487 -1, -1);
488 }
489 }
490 return mCacheDir;
491 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200492
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800493 @Override
494 public File getExternalCacheDir() {
495 synchronized (mSync) {
496 if (mExternalCacheDir == null) {
497 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
498 getPackageName());
499 }
500 if (!mExternalCacheDir.exists()) {
501 try {
502 (new File(Environment.getExternalStorageAndroidDataDir(),
503 ".nomedia")).createNewFile();
504 } catch (IOException e) {
505 }
506 if (!mExternalCacheDir.mkdirs()) {
507 Log.w(TAG, "Unable to create external cache directory");
508 return null;
509 }
510 }
511 return mExternalCacheDir;
512 }
513 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 @Override
516 public File getFileStreamPath(String name) {
517 return makeFilename(getFilesDir(), name);
518 }
519
520 @Override
521 public String[] fileList() {
522 final String[] list = getFilesDir().list();
523 return (list != null) ? list : EMPTY_FILE_LIST;
524 }
525
526 @Override
527 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800528 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
530 setFilePermissionsFromMode(f.getPath(), mode, 0);
531 return db;
532 }
533
534 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700535 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
536 DatabaseErrorHandler errorHandler) {
537 File f = validateFilePath(name, true);
538 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
539 setFilePermissionsFromMode(f.getPath(), mode, 0);
540 return db;
541 }
542
543 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 public boolean deleteDatabase(String name) {
545 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800546 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 return f.delete();
548 } catch (Exception e) {
549 }
550 return false;
551 }
552
553 @Override
554 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800555 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 }
557
558 @Override
559 public String[] databaseList() {
560 final String[] list = getDatabasesDir().list();
561 return (list != null) ? list : EMPTY_FILE_LIST;
562 }
563
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 private File getDatabasesDir() {
566 synchronized (mSync) {
567 if (mDatabasesDir == null) {
568 mDatabasesDir = new File(getDataDirFile(), "databases");
569 }
570 if (mDatabasesDir.getPath().equals("databases")) {
571 mDatabasesDir = new File("/data/system");
572 }
573 return mDatabasesDir;
574 }
575 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 @Override
578 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700579 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 }
581
582 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700583 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700584 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586
587 @Override
588 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700589 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 }
591
592 @Override
593 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700594 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 }
596
597 @Override
598 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700599 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 }
601
602 @Override
603 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700604 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
606
607 @Override
608 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700609 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 }
611
612 @Override
613 public void startActivity(Intent intent) {
614 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
615 throw new AndroidRuntimeException(
616 "Calling startActivity() from outside of an Activity "
617 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
618 + " Is this really what you want?");
619 }
620 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700621 getOuterContext(), mMainThread.getApplicationThread(), null,
622 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 }
624
625 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700626 public void startIntentSender(IntentSender intent,
627 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
628 throws IntentSender.SendIntentException {
629 try {
630 String resolvedType = null;
631 if (fillInIntent != null) {
632 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
633 }
634 int result = ActivityManagerNative.getDefault()
635 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
636 fillInIntent, resolvedType, null, null,
637 0, flagsMask, flagsValues);
638 if (result == IActivityManager.START_CANCELED) {
639 throw new IntentSender.SendIntentException();
640 }
641 Instrumentation.checkStartActivityResult(result, null);
642 } catch (RemoteException e) {
643 }
644 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200645
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700646 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 public void sendBroadcast(Intent intent) {
648 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
649 try {
650 ActivityManagerNative.getDefault().broadcastIntent(
651 mMainThread.getApplicationThread(), intent, resolvedType, null,
652 Activity.RESULT_OK, null, null, null, false, false);
653 } catch (RemoteException e) {
654 }
655 }
656
657 @Override
658 public void sendBroadcast(Intent intent, String receiverPermission) {
659 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
660 try {
661 ActivityManagerNative.getDefault().broadcastIntent(
662 mMainThread.getApplicationThread(), intent, resolvedType, null,
663 Activity.RESULT_OK, null, null, receiverPermission, false, false);
664 } catch (RemoteException e) {
665 }
666 }
667
668 @Override
669 public void sendOrderedBroadcast(Intent intent,
670 String receiverPermission) {
671 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
672 try {
673 ActivityManagerNative.getDefault().broadcastIntent(
674 mMainThread.getApplicationThread(), intent, resolvedType, null,
675 Activity.RESULT_OK, null, null, receiverPermission, true, false);
676 } catch (RemoteException e) {
677 }
678 }
679
680 @Override
681 public void sendOrderedBroadcast(Intent intent,
682 String receiverPermission, BroadcastReceiver resultReceiver,
683 Handler scheduler, int initialCode, String initialData,
684 Bundle initialExtras) {
685 IIntentReceiver rd = null;
686 if (resultReceiver != null) {
687 if (mPackageInfo != null) {
688 if (scheduler == null) {
689 scheduler = mMainThread.getHandler();
690 }
691 rd = mPackageInfo.getReceiverDispatcher(
692 resultReceiver, getOuterContext(), scheduler,
693 mMainThread.getInstrumentation(), false);
694 } else {
695 if (scheduler == null) {
696 scheduler = mMainThread.getHandler();
697 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700698 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
700 }
701 }
702 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
703 try {
704 ActivityManagerNative.getDefault().broadcastIntent(
705 mMainThread.getApplicationThread(), intent, resolvedType, rd,
706 initialCode, initialData, initialExtras, receiverPermission,
707 true, false);
708 } catch (RemoteException e) {
709 }
710 }
711
712 @Override
713 public void sendStickyBroadcast(Intent intent) {
714 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
715 try {
716 ActivityManagerNative.getDefault().broadcastIntent(
717 mMainThread.getApplicationThread(), intent, resolvedType, null,
718 Activity.RESULT_OK, null, null, null, false, true);
719 } catch (RemoteException e) {
720 }
721 }
722
723 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700724 public void sendStickyOrderedBroadcast(Intent intent,
725 BroadcastReceiver resultReceiver,
726 Handler scheduler, int initialCode, String initialData,
727 Bundle initialExtras) {
728 IIntentReceiver rd = null;
729 if (resultReceiver != null) {
730 if (mPackageInfo != null) {
731 if (scheduler == null) {
732 scheduler = mMainThread.getHandler();
733 }
734 rd = mPackageInfo.getReceiverDispatcher(
735 resultReceiver, getOuterContext(), scheduler,
736 mMainThread.getInstrumentation(), false);
737 } else {
738 if (scheduler == null) {
739 scheduler = mMainThread.getHandler();
740 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700741 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700742 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
743 }
744 }
745 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
746 try {
747 ActivityManagerNative.getDefault().broadcastIntent(
748 mMainThread.getApplicationThread(), intent, resolvedType, rd,
749 initialCode, initialData, initialExtras, null,
750 true, true);
751 } catch (RemoteException e) {
752 }
753 }
754
755 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 public void removeStickyBroadcast(Intent intent) {
757 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
758 if (resolvedType != null) {
759 intent = new Intent(intent);
760 intent.setDataAndType(intent.getData(), resolvedType);
761 }
762 try {
763 ActivityManagerNative.getDefault().unbroadcastIntent(
764 mMainThread.getApplicationThread(), intent);
765 } catch (RemoteException e) {
766 }
767 }
768
769 @Override
770 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
771 return registerReceiver(receiver, filter, null, null);
772 }
773
774 @Override
775 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
776 String broadcastPermission, Handler scheduler) {
777 return registerReceiverInternal(receiver, filter, broadcastPermission,
778 scheduler, getOuterContext());
779 }
780
781 private Intent registerReceiverInternal(BroadcastReceiver receiver,
782 IntentFilter filter, String broadcastPermission,
783 Handler scheduler, Context context) {
784 IIntentReceiver rd = null;
785 if (receiver != null) {
786 if (mPackageInfo != null && context != null) {
787 if (scheduler == null) {
788 scheduler = mMainThread.getHandler();
789 }
790 rd = mPackageInfo.getReceiverDispatcher(
791 receiver, context, scheduler,
792 mMainThread.getInstrumentation(), true);
793 } else {
794 if (scheduler == null) {
795 scheduler = mMainThread.getHandler();
796 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700797 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700798 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
800 }
801 try {
802 return ActivityManagerNative.getDefault().registerReceiver(
803 mMainThread.getApplicationThread(),
804 rd, filter, broadcastPermission);
805 } catch (RemoteException e) {
806 return null;
807 }
808 }
809
810 @Override
811 public void unregisterReceiver(BroadcastReceiver receiver) {
812 if (mPackageInfo != null) {
813 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
814 getOuterContext(), receiver);
815 try {
816 ActivityManagerNative.getDefault().unregisterReceiver(rd);
817 } catch (RemoteException e) {
818 }
819 } else {
820 throw new RuntimeException("Not supported in system context");
821 }
822 }
823
824 @Override
825 public ComponentName startService(Intent service) {
826 try {
827 ComponentName cn = ActivityManagerNative.getDefault().startService(
828 mMainThread.getApplicationThread(), service,
829 service.resolveTypeIfNeeded(getContentResolver()));
830 if (cn != null && cn.getPackageName().equals("!")) {
831 throw new SecurityException(
832 "Not allowed to start service " + service
833 + " without permission " + cn.getClassName());
834 }
835 return cn;
836 } catch (RemoteException e) {
837 return null;
838 }
839 }
840
841 @Override
842 public boolean stopService(Intent service) {
843 try {
844 int res = ActivityManagerNative.getDefault().stopService(
845 mMainThread.getApplicationThread(), service,
846 service.resolveTypeIfNeeded(getContentResolver()));
847 if (res < 0) {
848 throw new SecurityException(
849 "Not allowed to stop service " + service);
850 }
851 return res != 0;
852 } catch (RemoteException e) {
853 return false;
854 }
855 }
856
857 @Override
858 public boolean bindService(Intent service, ServiceConnection conn,
859 int flags) {
860 IServiceConnection sd;
861 if (mPackageInfo != null) {
862 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
863 mMainThread.getHandler(), flags);
864 } else {
865 throw new RuntimeException("Not supported in system context");
866 }
867 try {
868 int res = ActivityManagerNative.getDefault().bindService(
869 mMainThread.getApplicationThread(), getActivityToken(),
870 service, service.resolveTypeIfNeeded(getContentResolver()),
871 sd, flags);
872 if (res < 0) {
873 throw new SecurityException(
874 "Not allowed to bind to service " + service);
875 }
876 return res != 0;
877 } catch (RemoteException e) {
878 return false;
879 }
880 }
881
882 @Override
883 public void unbindService(ServiceConnection conn) {
884 if (mPackageInfo != null) {
885 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
886 getOuterContext(), conn);
887 try {
888 ActivityManagerNative.getDefault().unbindService(sd);
889 } catch (RemoteException e) {
890 }
891 } else {
892 throw new RuntimeException("Not supported in system context");
893 }
894 }
895
896 @Override
897 public boolean startInstrumentation(ComponentName className,
898 String profileFile, Bundle arguments) {
899 try {
900 return ActivityManagerNative.getDefault().startInstrumentation(
901 className, profileFile, 0, arguments, null);
902 } catch (RemoteException e) {
903 // System has crashed, nothing we can do.
904 }
905 return false;
906 }
907
908 @Override
909 public Object getSystemService(String name) {
910 if (WINDOW_SERVICE.equals(name)) {
911 return WindowManagerImpl.getDefault();
912 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
913 synchronized (mSync) {
914 LayoutInflater inflater = mLayoutInflater;
915 if (inflater != null) {
916 return inflater;
917 }
918 mLayoutInflater = inflater =
919 PolicyManager.makeNewLayoutInflater(getOuterContext());
920 return inflater;
921 }
922 } else if (ACTIVITY_SERVICE.equals(name)) {
923 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700924 } else if (INPUT_METHOD_SERVICE.equals(name)) {
925 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 } else if (ALARM_SERVICE.equals(name)) {
927 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700928 } else if (ACCOUNT_SERVICE.equals(name)) {
929 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 } else if (POWER_SERVICE.equals(name)) {
931 return getPowerManager();
932 } else if (CONNECTIVITY_SERVICE.equals(name)) {
933 return getConnectivityManager();
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700934 } else if (THROTTLE_SERVICE.equals(name)) {
935 return getThrottleManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 } else if (WIFI_SERVICE.equals(name)) {
937 return getWifiManager();
938 } else if (NOTIFICATION_SERVICE.equals(name)) {
939 return getNotificationManager();
940 } else if (KEYGUARD_SERVICE.equals(name)) {
941 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700942 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
943 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 } else if (LOCATION_SERVICE.equals(name)) {
945 return getLocationManager();
Bai Taoa58a8752010-07-13 15:32:16 +0800946 } else if (COUNTRY_DETECTOR.equals(name)) {
947 return getCountryDetector();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 } else if (SEARCH_SERVICE.equals(name)) {
949 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700950 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800952 } else if (STORAGE_SERVICE.equals(name)) {
953 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 } else if (VIBRATOR_SERVICE.equals(name)) {
955 return getVibrator();
956 } else if (STATUS_BAR_SERVICE.equals(name)) {
957 synchronized (mSync) {
958 if (mStatusBarManager == null) {
959 mStatusBarManager = new StatusBarManager(getOuterContext());
960 }
961 return mStatusBarManager;
962 }
963 } else if (AUDIO_SERVICE.equals(name)) {
964 return getAudioManager();
965 } else if (TELEPHONY_SERVICE.equals(name)) {
966 return getTelephonyManager();
967 } else if (CLIPBOARD_SERVICE.equals(name)) {
968 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700969 } else if (WALLPAPER_SERVICE.equals(name)) {
970 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700971 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800972 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800973 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
974 return getDevicePolicyManager();
Tobias Haamel69fb5742010-02-22 21:54:05 +0100975 } else if (UI_MODE_SERVICE.equals(name)) {
Tobias Haamel53332882010-02-18 16:15:43 -0800976 return getUiModeManager();
Steve Howarda2709362010-07-02 17:12:48 -0700977 } else if (DOWNLOAD_SERVICE.equals(name)) {
978 return getDownloadManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 }
980
981 return null;
982 }
983
Fred Quintana60307342009-03-24 22:48:12 -0700984 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700985 synchronized (mSync) {
986 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -0700987 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
988 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -0700989 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -0700990 }
Fred Quintanae00a3112009-09-22 15:13:30 -0700991 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -0700992 }
Fred Quintana60307342009-03-24 22:48:12 -0700993 }
994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 private ActivityManager getActivityManager() {
996 synchronized (mSync) {
997 if (mActivityManager == null) {
998 mActivityManager = new ActivityManager(getOuterContext(),
999 mMainThread.getHandler());
1000 }
1001 }
1002 return mActivityManager;
1003 }
1004
1005 private AlarmManager getAlarmManager() {
1006 synchronized (sSync) {
1007 if (sAlarmManager == null) {
1008 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1009 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1010 sAlarmManager = new AlarmManager(service);
1011 }
1012 }
1013 return sAlarmManager;
1014 }
1015
1016 private PowerManager getPowerManager() {
1017 synchronized (sSync) {
1018 if (sPowerManager == null) {
1019 IBinder b = ServiceManager.getService(POWER_SERVICE);
1020 IPowerManager service = IPowerManager.Stub.asInterface(b);
1021 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1022 }
1023 }
1024 return sPowerManager;
1025 }
1026
1027 private ConnectivityManager getConnectivityManager()
1028 {
1029 synchronized (sSync) {
1030 if (sConnectivityManager == null) {
1031 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1032 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1033 sConnectivityManager = new ConnectivityManager(service);
1034 }
1035 }
1036 return sConnectivityManager;
1037 }
1038
Irfan Sheriffc9b68512010-04-08 14:12:33 -07001039 private ThrottleManager getThrottleManager()
1040 {
1041 synchronized (sSync) {
1042 if (sThrottleManager == null) {
1043 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1044 IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1045 sThrottleManager = new ThrottleManager(service);
1046 }
1047 }
1048 return sThrottleManager;
1049 }
1050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 private WifiManager getWifiManager()
1052 {
1053 synchronized (sSync) {
1054 if (sWifiManager == null) {
1055 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1056 IWifiManager service = IWifiManager.Stub.asInterface(b);
1057 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1058 }
1059 }
1060 return sWifiManager;
1061 }
1062
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001063 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 synchronized (mSync) {
1065 if (mNotificationManager == null) {
Adam Powellc63806d2010-09-23 16:21:30 -07001066 final Context outerContext = getOuterContext();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 mNotificationManager = new NotificationManager(
Adam Powellc63806d2010-09-23 16:21:30 -07001068 new ContextThemeWrapper(outerContext,
1069 outerContext.getApplicationInfo().targetSdkVersion >=
1070 Build.VERSION_CODES.HONEYCOMB
1071 ? com.android.internal.R.style.Theme_Holo_Dialog
1072 : com.android.internal.R.style.Theme_Dialog),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 mMainThread.getHandler());
1074 }
1075 }
1076 return mNotificationManager;
1077 }
1078
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001079 private WallpaperManager getWallpaperManager() {
1080 synchronized (mSync) {
1081 if (mWallpaperManager == null) {
1082 mWallpaperManager = new WallpaperManager(getOuterContext(),
1083 mMainThread.getHandler());
1084 }
1085 }
1086 return mWallpaperManager;
1087 }
1088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 private TelephonyManager getTelephonyManager() {
1090 synchronized (mSync) {
1091 if (mTelephonyManager == null) {
1092 mTelephonyManager = new TelephonyManager(getOuterContext());
1093 }
1094 }
1095 return mTelephonyManager;
1096 }
1097
1098 private ClipboardManager getClipboardManager() {
1099 synchronized (mSync) {
1100 if (mClipboardManager == null) {
1101 mClipboardManager = new ClipboardManager(getOuterContext(),
1102 mMainThread.getHandler());
1103 }
1104 }
1105 return mClipboardManager;
1106 }
1107
1108 private LocationManager getLocationManager() {
1109 synchronized (sSync) {
1110 if (sLocationManager == null) {
1111 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1112 ILocationManager service = ILocationManager.Stub.asInterface(b);
1113 sLocationManager = new LocationManager(service);
1114 }
1115 }
1116 return sLocationManager;
1117 }
1118
Bai Taoa58a8752010-07-13 15:32:16 +08001119 private CountryDetector getCountryDetector() {
1120 synchronized (sSync) {
1121 if (sCountryDetector == null) {
1122 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
1123 ICountryDetector service = ICountryDetector.Stub.asInterface(b);
1124 sCountryDetector = new CountryDetector(service);
1125 }
1126 }
1127 return sCountryDetector;
1128 }
1129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 synchronized (mSync) {
1132 if (mSearchManager == null) {
1133 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1134 }
1135 }
1136 return mSearchManager;
1137 }
1138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 private SensorManager getSensorManager() {
1140 synchronized (mSync) {
1141 if (mSensorManager == null) {
1142 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1143 }
1144 }
1145 return mSensorManager;
1146 }
1147
San Mehatc9d81752010-02-01 10:23:27 -08001148 private StorageManager getStorageManager() {
1149 synchronized (mSync) {
1150 if (mStorageManager == null) {
1151 try {
1152 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1153 } catch (RemoteException rex) {
1154 Log.e(TAG, "Failed to create StorageManager", rex);
1155 mStorageManager = null;
1156 }
1157 }
1158 }
1159 return mStorageManager;
1160 }
1161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 private Vibrator getVibrator() {
1163 synchronized (mSync) {
1164 if (mVibrator == null) {
1165 mVibrator = new Vibrator();
1166 }
1167 }
1168 return mVibrator;
1169 }
Dan Egnor95240272009-10-27 18:23:39 -07001170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 private AudioManager getAudioManager()
1172 {
1173 if (mAudioManager == null) {
1174 mAudioManager = new AudioManager(this);
1175 }
1176 return mAudioManager;
1177 }
1178
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001179 /* package */ static DropBoxManager createDropBoxManager() {
1180 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1181 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001182 if (service == null) {
1183 // Don't return a DropBoxManager that will NPE upon use.
1184 // This also avoids caching a broken DropBoxManager in
1185 // getDropBoxManager during early boot, before the
1186 // DROPBOX_SERVICE is registered.
1187 return null;
1188 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001189 return new DropBoxManager(service);
1190 }
1191
Dan Egnorf18a01c2009-11-12 11:32:50 -08001192 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001193 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001194 if (mDropBoxManager == null) {
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001195 mDropBoxManager = createDropBoxManager();
Dan Egnor95240272009-10-27 18:23:39 -07001196 }
1197 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001198 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001199 }
1200
Dianne Hackbornd6847842010-01-12 18:14:19 -08001201 private DevicePolicyManager getDevicePolicyManager() {
1202 synchronized (mSync) {
1203 if (mDevicePolicyManager == null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001204 mDevicePolicyManager = DevicePolicyManager.create(this,
Dianne Hackbornd6847842010-01-12 18:14:19 -08001205 mMainThread.getHandler());
1206 }
1207 }
1208 return mDevicePolicyManager;
1209 }
1210
Tobias Haamel53332882010-02-18 16:15:43 -08001211 private UiModeManager getUiModeManager() {
1212 synchronized (mSync) {
1213 if (mUiModeManager == null) {
1214 mUiModeManager = new UiModeManager();
1215 }
1216 }
1217 return mUiModeManager;
1218 }
1219
Steve Howarda2709362010-07-02 17:12:48 -07001220 private DownloadManager getDownloadManager() {
1221 synchronized (mSync) {
1222 if (mDownloadManager == null) {
Steve Howardb8e07a52010-07-21 14:53:21 -07001223 mDownloadManager = new DownloadManager(getContentResolver(), getPackageName());
Steve Howarda2709362010-07-02 17:12:48 -07001224 }
1225 }
1226 return mDownloadManager;
1227 }
1228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 @Override
1230 public int checkPermission(String permission, int pid, int uid) {
1231 if (permission == null) {
1232 throw new IllegalArgumentException("permission is null");
1233 }
1234
1235 if (!Process.supportsProcesses()) {
1236 return PackageManager.PERMISSION_GRANTED;
1237 }
1238 try {
1239 return ActivityManagerNative.getDefault().checkPermission(
1240 permission, pid, uid);
1241 } catch (RemoteException e) {
1242 return PackageManager.PERMISSION_DENIED;
1243 }
1244 }
1245
1246 @Override
1247 public int checkCallingPermission(String permission) {
1248 if (permission == null) {
1249 throw new IllegalArgumentException("permission is null");
1250 }
1251
1252 if (!Process.supportsProcesses()) {
1253 return PackageManager.PERMISSION_GRANTED;
1254 }
1255 int pid = Binder.getCallingPid();
1256 if (pid != Process.myPid()) {
1257 return checkPermission(permission, pid,
1258 Binder.getCallingUid());
1259 }
1260 return PackageManager.PERMISSION_DENIED;
1261 }
1262
1263 @Override
1264 public int checkCallingOrSelfPermission(String permission) {
1265 if (permission == null) {
1266 throw new IllegalArgumentException("permission is null");
1267 }
1268
1269 return checkPermission(permission, Binder.getCallingPid(),
1270 Binder.getCallingUid());
1271 }
1272
1273 private void enforce(
1274 String permission, int resultOfCheck,
1275 boolean selfToo, int uid, String message) {
1276 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1277 throw new SecurityException(
1278 (message != null ? (message + ": ") : "") +
1279 (selfToo
1280 ? "Neither user " + uid + " nor current process has "
1281 : "User " + uid + " does not have ") +
1282 permission +
1283 ".");
1284 }
1285 }
1286
1287 public void enforcePermission(
1288 String permission, int pid, int uid, String message) {
1289 enforce(permission,
1290 checkPermission(permission, pid, uid),
1291 false,
1292 uid,
1293 message);
1294 }
1295
1296 public void enforceCallingPermission(String permission, String message) {
1297 enforce(permission,
1298 checkCallingPermission(permission),
1299 false,
1300 Binder.getCallingUid(),
1301 message);
1302 }
1303
1304 public void enforceCallingOrSelfPermission(
1305 String permission, String message) {
1306 enforce(permission,
1307 checkCallingOrSelfPermission(permission),
1308 true,
1309 Binder.getCallingUid(),
1310 message);
1311 }
1312
1313 @Override
1314 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1315 try {
1316 ActivityManagerNative.getDefault().grantUriPermission(
1317 mMainThread.getApplicationThread(), toPackage, uri,
1318 modeFlags);
1319 } catch (RemoteException e) {
1320 }
1321 }
1322
1323 @Override
1324 public void revokeUriPermission(Uri uri, int modeFlags) {
1325 try {
1326 ActivityManagerNative.getDefault().revokeUriPermission(
1327 mMainThread.getApplicationThread(), uri,
1328 modeFlags);
1329 } catch (RemoteException e) {
1330 }
1331 }
1332
1333 @Override
1334 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1335 if (!Process.supportsProcesses()) {
1336 return PackageManager.PERMISSION_GRANTED;
1337 }
1338 try {
1339 return ActivityManagerNative.getDefault().checkUriPermission(
1340 uri, pid, uid, modeFlags);
1341 } catch (RemoteException e) {
1342 return PackageManager.PERMISSION_DENIED;
1343 }
1344 }
1345
1346 @Override
1347 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1348 if (!Process.supportsProcesses()) {
1349 return PackageManager.PERMISSION_GRANTED;
1350 }
1351 int pid = Binder.getCallingPid();
1352 if (pid != Process.myPid()) {
1353 return checkUriPermission(uri, pid,
1354 Binder.getCallingUid(), modeFlags);
1355 }
1356 return PackageManager.PERMISSION_DENIED;
1357 }
1358
1359 @Override
1360 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1361 return checkUriPermission(uri, Binder.getCallingPid(),
1362 Binder.getCallingUid(), modeFlags);
1363 }
1364
1365 @Override
1366 public int checkUriPermission(Uri uri, String readPermission,
1367 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001368 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1370 + readPermission + " writePermission=" + writePermission
1371 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1372 }
1373 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1374 if (readPermission == null
1375 || checkPermission(readPermission, pid, uid)
1376 == PackageManager.PERMISSION_GRANTED) {
1377 return PackageManager.PERMISSION_GRANTED;
1378 }
1379 }
1380 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1381 if (writePermission == null
1382 || checkPermission(writePermission, pid, uid)
1383 == PackageManager.PERMISSION_GRANTED) {
1384 return PackageManager.PERMISSION_GRANTED;
1385 }
1386 }
1387 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1388 : PackageManager.PERMISSION_DENIED;
1389 }
1390
1391 private String uriModeFlagToString(int uriModeFlags) {
1392 switch (uriModeFlags) {
1393 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1394 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1395 return "read and write";
1396 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1397 return "read";
1398 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1399 return "write";
1400 }
1401 throw new IllegalArgumentException(
1402 "Unknown permission mode flags: " + uriModeFlags);
1403 }
1404
1405 private void enforceForUri(
1406 int modeFlags, int resultOfCheck, boolean selfToo,
1407 int uid, Uri uri, String message) {
1408 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1409 throw new SecurityException(
1410 (message != null ? (message + ": ") : "") +
1411 (selfToo
1412 ? "Neither user " + uid + " nor current process has "
1413 : "User " + uid + " does not have ") +
1414 uriModeFlagToString(modeFlags) +
1415 " permission on " +
1416 uri +
1417 ".");
1418 }
1419 }
1420
1421 public void enforceUriPermission(
1422 Uri uri, int pid, int uid, int modeFlags, String message) {
1423 enforceForUri(
1424 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1425 false, uid, uri, message);
1426 }
1427
1428 public void enforceCallingUriPermission(
1429 Uri uri, int modeFlags, String message) {
1430 enforceForUri(
1431 modeFlags, checkCallingUriPermission(uri, modeFlags),
1432 false, Binder.getCallingUid(), uri, message);
1433 }
1434
1435 public void enforceCallingOrSelfUriPermission(
1436 Uri uri, int modeFlags, String message) {
1437 enforceForUri(
1438 modeFlags,
1439 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1440 Binder.getCallingUid(), uri, message);
1441 }
1442
1443 public void enforceUriPermission(
1444 Uri uri, String readPermission, String writePermission,
1445 int pid, int uid, int modeFlags, String message) {
1446 enforceForUri(modeFlags,
1447 checkUriPermission(
1448 uri, readPermission, writePermission, pid, uid,
1449 modeFlags),
1450 false,
1451 uid,
1452 uri,
1453 message);
1454 }
1455
1456 @Override
1457 public Context createPackageContext(String packageName, int flags)
1458 throws PackageManager.NameNotFoundException {
1459 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001460 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 }
1462
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001463 LoadedApk pi =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 mMainThread.getPackageInfo(packageName, flags);
1465 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001466 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001467 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001468 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 if (c.mResources != null) {
1470 return c;
1471 }
1472 }
1473
1474 // Should be a better exception.
1475 throw new PackageManager.NameNotFoundException(
1476 "Application package " + packageName + " not found");
1477 }
1478
Romain Guy870e09f2009-07-06 16:35:25 -07001479 @Override
1480 public boolean isRestricted() {
1481 return mRestricted;
1482 }
1483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 private File getDataDirFile() {
1485 if (mPackageInfo != null) {
1486 return mPackageInfo.getDataDirFile();
1487 }
1488 throw new RuntimeException("Not supported in system context");
1489 }
1490
1491 @Override
1492 public File getDir(String name, int mode) {
1493 name = "app_" + name;
1494 File file = makeFilename(getDataDirFile(), name);
1495 if (!file.exists()) {
1496 file.mkdir();
1497 setFilePermissionsFromMode(file.getPath(), mode,
1498 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1499 }
1500 return file;
1501 }
1502
Dianne Hackborn21556372010-02-04 16:34:40 -08001503 static ContextImpl createSystemContext(ActivityThread mainThread) {
1504 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 context.init(Resources.getSystem(), mainThread);
1506 return context;
1507 }
1508
Dianne Hackborn21556372010-02-04 16:34:40 -08001509 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 mOuterContext = this;
1511 }
1512
1513 /**
1514 * Create a new ApplicationContext from an existing one. The new one
1515 * works and operates the same as the one it is copying.
1516 *
1517 * @param context Existing application context.
1518 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001519 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 mPackageInfo = context.mPackageInfo;
1521 mResources = context.mResources;
1522 mMainThread = context.mMainThread;
1523 mContentResolver = context.mContentResolver;
1524 mOuterContext = this;
1525 }
1526
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001527 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001529 init(packageInfo, activityToken, mainThread, null);
1530 }
1531
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001532 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001533 IBinder activityToken, ActivityThread mainThread,
1534 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 mPackageInfo = packageInfo;
1536 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001537
Dianne Hackborn559a7872010-04-07 18:19:41 -07001538 if (mResources != null && container != null
1539 && container.getCompatibilityInfo().applicationScale !=
1540 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001541 if (DEBUG) {
1542 Log.d(TAG, "loaded context has different scaling. Using container's" +
1543 " compatiblity info:" + container.getDisplayMetrics());
1544 }
1545 mResources = mainThread.getTopLevelResources(
1546 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 mMainThread = mainThread;
1549 mContentResolver = new ApplicationContentResolver(this, mainThread);
1550
1551 setActivityToken(activityToken);
1552 }
1553
1554 final void init(Resources resources, ActivityThread mainThread) {
1555 mPackageInfo = null;
1556 mResources = resources;
1557 mMainThread = mainThread;
1558 mContentResolver = new ApplicationContentResolver(this, mainThread);
1559 }
1560
1561 final void scheduleFinalCleanup(String who, String what) {
1562 mMainThread.scheduleContextCleanup(this, who, what);
1563 }
1564
1565 final void performFinalCleanup(String who, String what) {
1566 //Log.i(TAG, "Cleanup up context: " + this);
1567 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1568 }
1569
1570 final Context getReceiverRestrictedContext() {
1571 if (mReceiverRestrictedContext != null) {
1572 return mReceiverRestrictedContext;
1573 }
1574 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1575 }
1576
1577 final void setActivityToken(IBinder token) {
1578 mActivityToken = token;
1579 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 final void setOuterContext(Context context) {
1582 mOuterContext = context;
1583 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 final Context getOuterContext() {
1586 return mOuterContext;
1587 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 final IBinder getActivityToken() {
1590 return mActivityToken;
1591 }
1592
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001593 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 int extraPermissions) {
1595 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1596 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1597 |extraPermissions;
1598 if ((mode&MODE_WORLD_READABLE) != 0) {
1599 perms |= FileUtils.S_IROTH;
1600 }
1601 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1602 perms |= FileUtils.S_IWOTH;
1603 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001604 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1606 + ", perms=0x" + Integer.toHexString(perms));
1607 }
1608 FileUtils.setPermissions(name, perms, -1, -1);
1609 }
1610
Oscar Montemayora8529f62009-11-18 10:14:20 -08001611 private File validateFilePath(String name, boolean createDirectory) {
1612 File dir;
1613 File f;
1614
1615 if (name.charAt(0) == File.separatorChar) {
1616 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1617 dir = new File(dirPath);
1618 name = name.substring(name.lastIndexOf(File.separatorChar));
1619 f = new File(dir, name);
1620 } else {
1621 dir = getDatabasesDir();
1622 f = makeFilename(dir, name);
1623 }
1624
1625 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1626 FileUtils.setPermissions(dir.getPath(),
1627 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1628 -1, -1);
1629 }
1630
1631 return f;
1632 }
1633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 private File makeFilename(File base, String name) {
1635 if (name.indexOf(File.separatorChar) < 0) {
1636 return new File(base, name);
1637 }
1638 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001639 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001640 }
1641
1642 // ----------------------------------------------------------------------
1643 // ----------------------------------------------------------------------
1644 // ----------------------------------------------------------------------
1645
1646 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001647 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 super(context);
1649 mMainThread = mainThread;
1650 }
1651
1652 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001653 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 return mMainThread.acquireProvider(context, name);
1655 }
1656
1657 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001658 protected IContentProvider acquireExistingProvider(Context context, String name) {
1659 return mMainThread.acquireExistingProvider(context, name);
1660 }
1661
1662 @Override
1663 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 return mMainThread.releaseProvider(provider);
1665 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 private final ActivityThread mMainThread;
1668 }
1669
1670 // ----------------------------------------------------------------------
1671 // ----------------------------------------------------------------------
1672 // ----------------------------------------------------------------------
1673
1674 /*package*/
1675 static final class ApplicationPackageManager extends PackageManager {
1676 @Override
1677 public PackageInfo getPackageInfo(String packageName, int flags)
1678 throws NameNotFoundException {
1679 try {
1680 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1681 if (pi != null) {
1682 return pi;
1683 }
1684 } catch (RemoteException e) {
1685 throw new RuntimeException("Package manager has died", e);
1686 }
1687
1688 throw new NameNotFoundException(packageName);
1689 }
1690
Mihai Predaeae850c2009-05-13 10:13:48 +02001691 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001692 public String[] currentToCanonicalPackageNames(String[] names) {
1693 try {
1694 return mPM.currentToCanonicalPackageNames(names);
1695 } catch (RemoteException e) {
1696 throw new RuntimeException("Package manager has died", e);
1697 }
1698 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001699
Dianne Hackborn47096932010-02-11 15:57:09 -08001700 @Override
1701 public String[] canonicalToCurrentPackageNames(String[] names) {
1702 try {
1703 return mPM.canonicalToCurrentPackageNames(names);
1704 } catch (RemoteException e) {
1705 throw new RuntimeException("Package manager has died", e);
1706 }
1707 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001708
Dianne Hackborn47096932010-02-11 15:57:09 -08001709 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001710 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 // First see if the package has an INFO activity; the existence of
1712 // such an activity is implied to be the desired front-door for the
1713 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001714 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1715 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001716 intentToResolve.setPackage(packageName);
1717 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001720 if (resolveInfo == null) {
1721 // reuse the intent instance
1722 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1723 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001724 intentToResolve.setPackage(packageName);
1725 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001727 if (resolveInfo == null) {
1728 return null;
1729 }
Johan Erlandssondf4cfa362010-03-31 08:20:51 +02001730 Intent intent = new Intent(intentToResolve);
1731 intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
1732 resolveInfo.activityInfo.name);
Mihai Predaeae850c2009-05-13 10:13:48 +02001733 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1734 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001737 @Override
1738 public int[] getPackageGids(String packageName)
1739 throws NameNotFoundException {
1740 try {
1741 int[] gids = mPM.getPackageGids(packageName);
1742 if (gids == null || gids.length > 0) {
1743 return gids;
1744 }
1745 } catch (RemoteException e) {
1746 throw new RuntimeException("Package manager has died", e);
1747 }
1748
1749 throw new NameNotFoundException(packageName);
1750 }
1751
1752 @Override
1753 public PermissionInfo getPermissionInfo(String name, int flags)
1754 throws NameNotFoundException {
1755 try {
1756 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1757 if (pi != null) {
1758 return pi;
1759 }
1760 } catch (RemoteException e) {
1761 throw new RuntimeException("Package manager has died", e);
1762 }
1763
1764 throw new NameNotFoundException(name);
1765 }
1766
1767 @Override
1768 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1769 throws NameNotFoundException {
1770 try {
1771 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1772 if (pi != null) {
1773 return pi;
1774 }
1775 } catch (RemoteException e) {
1776 throw new RuntimeException("Package manager has died", e);
1777 }
1778
1779 throw new NameNotFoundException(group);
1780 }
1781
1782 @Override
1783 public PermissionGroupInfo getPermissionGroupInfo(String name,
1784 int flags) throws NameNotFoundException {
1785 try {
1786 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1787 if (pgi != null) {
1788 return pgi;
1789 }
1790 } catch (RemoteException e) {
1791 throw new RuntimeException("Package manager has died", e);
1792 }
1793
1794 throw new NameNotFoundException(name);
1795 }
1796
1797 @Override
1798 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1799 try {
1800 return mPM.getAllPermissionGroups(flags);
1801 } catch (RemoteException e) {
1802 throw new RuntimeException("Package manager has died", e);
1803 }
1804 }
1805
1806 @Override
1807 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1808 throws NameNotFoundException {
1809 try {
1810 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1811 if (ai != null) {
1812 return ai;
1813 }
1814 } catch (RemoteException e) {
1815 throw new RuntimeException("Package manager has died", e);
1816 }
1817
1818 throw new NameNotFoundException(packageName);
1819 }
1820
1821 @Override
1822 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1823 throws NameNotFoundException {
1824 try {
1825 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1826 if (ai != null) {
1827 return ai;
1828 }
1829 } catch (RemoteException e) {
1830 throw new RuntimeException("Package manager has died", e);
1831 }
1832
1833 throw new NameNotFoundException(className.toString());
1834 }
1835
1836 @Override
1837 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1838 throws NameNotFoundException {
1839 try {
1840 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1841 if (ai != null) {
1842 return ai;
1843 }
1844 } catch (RemoteException e) {
1845 throw new RuntimeException("Package manager has died", e);
1846 }
1847
1848 throw new NameNotFoundException(className.toString());
1849 }
1850
1851 @Override
1852 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1853 throws NameNotFoundException {
1854 try {
1855 ServiceInfo si = mPM.getServiceInfo(className, flags);
1856 if (si != null) {
1857 return si;
1858 }
1859 } catch (RemoteException e) {
1860 throw new RuntimeException("Package manager has died", e);
1861 }
1862
1863 throw new NameNotFoundException(className.toString());
1864 }
1865
1866 @Override
Dianne Hackborn361199b2010-08-30 17:42:07 -07001867 public ProviderInfo getProviderInfo(ComponentName className, int flags)
1868 throws NameNotFoundException {
1869 try {
1870 ProviderInfo pi = mPM.getProviderInfo(className, flags);
1871 if (pi != null) {
1872 return pi;
1873 }
1874 } catch (RemoteException e) {
1875 throw new RuntimeException("Package manager has died", e);
1876 }
1877
1878 throw new NameNotFoundException(className.toString());
1879 }
1880
1881 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 public String[] getSystemSharedLibraryNames() {
1883 try {
1884 return mPM.getSystemSharedLibraryNames();
1885 } catch (RemoteException e) {
1886 throw new RuntimeException("Package manager has died", e);
1887 }
1888 }
1889
1890 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001891 public FeatureInfo[] getSystemAvailableFeatures() {
1892 try {
1893 return mPM.getSystemAvailableFeatures();
1894 } catch (RemoteException e) {
1895 throw new RuntimeException("Package manager has died", e);
1896 }
1897 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001898
Dianne Hackborn49237342009-08-27 20:08:01 -07001899 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001900 public boolean hasSystemFeature(String name) {
1901 try {
1902 return mPM.hasSystemFeature(name);
1903 } catch (RemoteException e) {
1904 throw new RuntimeException("Package manager has died", e);
1905 }
1906 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001907
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001908 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 public int checkPermission(String permName, String pkgName) {
1910 try {
1911 return mPM.checkPermission(permName, pkgName);
1912 } catch (RemoteException e) {
1913 throw new RuntimeException("Package manager has died", e);
1914 }
1915 }
1916
1917 @Override
1918 public boolean addPermission(PermissionInfo info) {
1919 try {
1920 return mPM.addPermission(info);
1921 } catch (RemoteException e) {
1922 throw new RuntimeException("Package manager has died", e);
1923 }
1924 }
1925
1926 @Override
Dianne Hackbornd7c09682010-03-30 10:42:20 -07001927 public boolean addPermissionAsync(PermissionInfo info) {
1928 try {
1929 return mPM.addPermissionAsync(info);
1930 } catch (RemoteException e) {
1931 throw new RuntimeException("Package manager has died", e);
1932 }
1933 }
1934
1935 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 public void removePermission(String name) {
1937 try {
1938 mPM.removePermission(name);
1939 } catch (RemoteException e) {
1940 throw new RuntimeException("Package manager has died", e);
1941 }
1942 }
1943
1944 @Override
1945 public int checkSignatures(String pkg1, String pkg2) {
1946 try {
1947 return mPM.checkSignatures(pkg1, pkg2);
1948 } catch (RemoteException e) {
1949 throw new RuntimeException("Package manager has died", e);
1950 }
1951 }
1952
1953 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001954 public int checkSignatures(int uid1, int uid2) {
1955 try {
1956 return mPM.checkUidSignatures(uid1, uid2);
1957 } catch (RemoteException e) {
1958 throw new RuntimeException("Package manager has died", e);
1959 }
1960 }
1961
1962 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001963 public String[] getPackagesForUid(int uid) {
1964 try {
1965 return mPM.getPackagesForUid(uid);
1966 } catch (RemoteException e) {
1967 throw new RuntimeException("Package manager has died", e);
1968 }
1969 }
1970
1971 @Override
1972 public String getNameForUid(int uid) {
1973 try {
1974 return mPM.getNameForUid(uid);
1975 } catch (RemoteException e) {
1976 throw new RuntimeException("Package manager has died", e);
1977 }
1978 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001981 public int getUidForSharedUser(String sharedUserName)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001982 throws NameNotFoundException {
1983 try {
1984 int uid = mPM.getUidForSharedUser(sharedUserName);
1985 if(uid != -1) {
1986 return uid;
1987 }
1988 } catch (RemoteException e) {
1989 throw new RuntimeException("Package manager has died", e);
1990 }
1991 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1992 }
1993
1994 @Override
1995 public List<PackageInfo> getInstalledPackages(int flags) {
1996 try {
1997 return mPM.getInstalledPackages(flags);
1998 } catch (RemoteException e) {
1999 throw new RuntimeException("Package manager has died", e);
2000 }
2001 }
2002
2003 @Override
2004 public List<ApplicationInfo> getInstalledApplications(int flags) {
2005 try {
2006 return mPM.getInstalledApplications(flags);
2007 } catch (RemoteException e) {
2008 throw new RuntimeException("Package manager has died", e);
2009 }
2010 }
2011
2012 @Override
2013 public ResolveInfo resolveActivity(Intent intent, int flags) {
2014 try {
2015 return mPM.resolveIntent(
2016 intent,
2017 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2018 flags);
2019 } catch (RemoteException e) {
2020 throw new RuntimeException("Package manager has died", e);
2021 }
2022 }
2023
2024 @Override
2025 public List<ResolveInfo> queryIntentActivities(Intent intent,
2026 int flags) {
2027 try {
2028 return mPM.queryIntentActivities(
2029 intent,
2030 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2031 flags);
2032 } catch (RemoteException e) {
2033 throw new RuntimeException("Package manager has died", e);
2034 }
2035 }
2036
2037 @Override
2038 public List<ResolveInfo> queryIntentActivityOptions(
2039 ComponentName caller, Intent[] specifics, Intent intent,
2040 int flags) {
2041 final ContentResolver resolver = mContext.getContentResolver();
2042
2043 String[] specificTypes = null;
2044 if (specifics != null) {
2045 final int N = specifics.length;
2046 for (int i=0; i<N; i++) {
2047 Intent sp = specifics[i];
2048 if (sp != null) {
2049 String t = sp.resolveTypeIfNeeded(resolver);
2050 if (t != null) {
2051 if (specificTypes == null) {
2052 specificTypes = new String[N];
2053 }
2054 specificTypes[i] = t;
2055 }
2056 }
2057 }
2058 }
2059
2060 try {
2061 return mPM.queryIntentActivityOptions(caller, specifics,
2062 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2063 flags);
2064 } catch (RemoteException e) {
2065 throw new RuntimeException("Package manager has died", e);
2066 }
2067 }
2068
2069 @Override
2070 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2071 try {
2072 return mPM.queryIntentReceivers(
2073 intent,
2074 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2075 flags);
2076 } catch (RemoteException e) {
2077 throw new RuntimeException("Package manager has died", e);
2078 }
2079 }
2080
2081 @Override
2082 public ResolveInfo resolveService(Intent intent, int flags) {
2083 try {
2084 return mPM.resolveService(
2085 intent,
2086 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2087 flags);
2088 } catch (RemoteException e) {
2089 throw new RuntimeException("Package manager has died", e);
2090 }
2091 }
2092
2093 @Override
2094 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2095 try {
2096 return mPM.queryIntentServices(
2097 intent,
2098 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2099 flags);
2100 } catch (RemoteException e) {
2101 throw new RuntimeException("Package manager has died", e);
2102 }
2103 }
2104
2105 @Override
2106 public ProviderInfo resolveContentProvider(String name,
2107 int flags) {
2108 try {
2109 return mPM.resolveContentProvider(name, flags);
2110 } catch (RemoteException e) {
2111 throw new RuntimeException("Package manager has died", e);
2112 }
2113 }
2114
2115 @Override
2116 public List<ProviderInfo> queryContentProviders(String processName,
2117 int uid, int flags) {
2118 try {
2119 return mPM.queryContentProviders(processName, uid, flags);
2120 } catch (RemoteException e) {
2121 throw new RuntimeException("Package manager has died", e);
2122 }
2123 }
2124
2125 @Override
2126 public InstrumentationInfo getInstrumentationInfo(
2127 ComponentName className, int flags)
2128 throws NameNotFoundException {
2129 try {
2130 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2131 className, flags);
2132 if (ii != null) {
2133 return ii;
2134 }
2135 } catch (RemoteException e) {
2136 throw new RuntimeException("Package manager has died", e);
2137 }
2138
2139 throw new NameNotFoundException(className.toString());
2140 }
2141
2142 @Override
2143 public List<InstrumentationInfo> queryInstrumentation(
2144 String targetPackage, int flags) {
2145 try {
2146 return mPM.queryInstrumentation(targetPackage, flags);
2147 } catch (RemoteException e) {
2148 throw new RuntimeException("Package manager has died", e);
2149 }
2150 }
2151
2152 @Override public Drawable getDrawable(String packageName, int resid,
2153 ApplicationInfo appInfo) {
2154 ResourceName name = new ResourceName(packageName, resid);
2155 Drawable dr = getCachedIcon(name);
2156 if (dr != null) {
2157 return dr;
2158 }
2159 if (appInfo == null) {
2160 try {
2161 appInfo = getApplicationInfo(packageName, 0);
2162 } catch (NameNotFoundException e) {
2163 return null;
2164 }
2165 }
2166 try {
2167 Resources r = getResourcesForApplication(appInfo);
2168 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002169 if (false) {
2170 RuntimeException e = new RuntimeException("here");
2171 e.fillInStackTrace();
2172 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2173 + " from package " + packageName
2174 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2175 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2176 e);
2177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2179 + Integer.toHexString(resid) + " from " + r
2180 + ": " + dr);
2181 putCachedIcon(name, dr);
2182 return dr;
2183 } catch (NameNotFoundException e) {
2184 Log.w("PackageManager", "Failure retrieving resources for"
2185 + appInfo.packageName);
2186 } catch (RuntimeException e) {
2187 // If an exception was thrown, fall through to return
2188 // default icon.
2189 Log.w("PackageManager", "Failure retrieving icon 0x"
2190 + Integer.toHexString(resid) + " in package "
2191 + packageName, e);
2192 }
2193 return null;
2194 }
2195
2196 @Override public Drawable getActivityIcon(ComponentName activityName)
2197 throws NameNotFoundException {
2198 return getActivityInfo(activityName, 0).loadIcon(this);
2199 }
2200
2201 @Override public Drawable getActivityIcon(Intent intent)
2202 throws NameNotFoundException {
2203 if (intent.getComponent() != null) {
2204 return getActivityIcon(intent.getComponent());
2205 }
2206
2207 ResolveInfo info = resolveActivity(
2208 intent, PackageManager.MATCH_DEFAULT_ONLY);
2209 if (info != null) {
2210 return info.activityInfo.loadIcon(this);
2211 }
2212
2213 throw new NameNotFoundException(intent.toURI());
2214 }
2215
2216 @Override public Drawable getDefaultActivityIcon() {
2217 return Resources.getSystem().getDrawable(
2218 com.android.internal.R.drawable.sym_def_app_icon);
2219 }
2220
2221 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002222 return info.loadIcon(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002223 }
2224
2225 @Override public Drawable getApplicationIcon(String packageName)
2226 throws NameNotFoundException {
2227 return getApplicationIcon(getApplicationInfo(packageName, 0));
2228 }
Adam Powell81cd2e92010-04-21 16:35:18 -07002229
2230 @Override
2231 public Drawable getActivityLogo(ComponentName activityName)
2232 throws NameNotFoundException {
2233 return getActivityInfo(activityName, 0).loadLogo(this);
2234 }
2235
2236 @Override
2237 public Drawable getActivityLogo(Intent intent)
2238 throws NameNotFoundException {
2239 if (intent.getComponent() != null) {
2240 return getActivityLogo(intent.getComponent());
2241 }
2242
2243 ResolveInfo info = resolveActivity(
2244 intent, PackageManager.MATCH_DEFAULT_ONLY);
2245 if (info != null) {
2246 return info.activityInfo.loadLogo(this);
2247 }
2248
2249 throw new NameNotFoundException(intent.toUri(0));
2250 }
2251
2252 @Override
2253 public Drawable getApplicationLogo(ApplicationInfo info) {
2254 return info.loadLogo(this);
2255 }
2256
2257 @Override
2258 public Drawable getApplicationLogo(String packageName)
2259 throws NameNotFoundException {
2260 return getApplicationLogo(getApplicationInfo(packageName, 0));
2261 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262
2263 @Override public Resources getResourcesForActivity(
2264 ComponentName activityName) throws NameNotFoundException {
2265 return getResourcesForApplication(
2266 getActivityInfo(activityName, 0).applicationInfo);
2267 }
2268
2269 @Override public Resources getResourcesForApplication(
2270 ApplicationInfo app) throws NameNotFoundException {
2271 if (app.packageName.equals("system")) {
2272 return mContext.mMainThread.getSystemContext().getResources();
2273 }
2274 Resources r = mContext.mMainThread.getTopLevelResources(
2275 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002276 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002277 if (r != null) {
2278 return r;
2279 }
2280 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2281 }
2282
2283 @Override public Resources getResourcesForApplication(
2284 String appPackageName) throws NameNotFoundException {
2285 return getResourcesForApplication(
2286 getApplicationInfo(appPackageName, 0));
2287 }
2288
2289 int mCachedSafeMode = -1;
2290 @Override public boolean isSafeMode() {
2291 try {
2292 if (mCachedSafeMode < 0) {
2293 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2294 }
2295 return mCachedSafeMode != 0;
2296 } catch (RemoteException e) {
2297 throw new RuntimeException("Package manager has died", e);
2298 }
2299 }
2300
2301 static void configurationChanged() {
2302 synchronized (sSync) {
2303 sIconCache.clear();
2304 sStringCache.clear();
2305 }
2306 }
2307
Dianne Hackborn21556372010-02-04 16:34:40 -08002308 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 IPackageManager pm) {
2310 mContext = context;
2311 mPM = pm;
2312 }
2313
2314 private Drawable getCachedIcon(ResourceName name) {
2315 synchronized (sSync) {
2316 WeakReference<Drawable> wr = sIconCache.get(name);
2317 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2318 + name + ": " + wr);
2319 if (wr != null) { // we have the activity
2320 Drawable dr = wr.get();
2321 if (dr != null) {
2322 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2323 + name + ": " + dr);
2324 return dr;
2325 }
2326 // our entry has been purged
2327 sIconCache.remove(name);
2328 }
2329 }
2330 return null;
2331 }
2332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 private void putCachedIcon(ResourceName name, Drawable dr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 synchronized (sSync) {
2335 sIconCache.put(name, new WeakReference<Drawable>(dr));
2336 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2337 + name + ": " + dr);
2338 }
2339 }
2340
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002341 static final void handlePackageBroadcast(int cmd, String[] pkgList,
2342 boolean hasPkgInfo) {
2343 boolean immediateGc = false;
2344 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2345 immediateGc = true;
2346 }
2347 if (pkgList != null && (pkgList.length > 0)) {
2348 boolean needCleanup = false;
2349 for (String ssp : pkgList) {
2350 synchronized (sSync) {
2351 if (sIconCache.size() > 0) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002352 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2353 while (it.hasNext()) {
2354 ResourceName nm = it.next();
2355 if (nm.packageName.equals(ssp)) {
2356 //Log.i(TAG, "Removing cached drawable for " + nm);
2357 it.remove();
2358 needCleanup = true;
2359 }
2360 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002361 }
2362 if (sStringCache.size() > 0) {
2363 Iterator<ResourceName> it = sStringCache.keySet().iterator();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002364 while (it.hasNext()) {
2365 ResourceName nm = it.next();
2366 if (nm.packageName.equals(ssp)) {
2367 //Log.i(TAG, "Removing cached string for " + nm);
2368 it.remove();
2369 needCleanup = true;
2370 }
2371 }
2372 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002373 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002374 }
2375 if (needCleanup || hasPkgInfo) {
2376 if (immediateGc) {
2377 // Schedule an immediate gc.
2378 Runtime.getRuntime().gc();
2379 } else {
2380 ActivityThread.currentActivityThread().scheduleGcIdler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 }
2382 }
2383 }
2384 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 private static final class ResourceName {
2387 final String packageName;
2388 final int iconId;
2389
2390 ResourceName(String _packageName, int _iconId) {
2391 packageName = _packageName;
2392 iconId = _iconId;
2393 }
2394
2395 ResourceName(ApplicationInfo aInfo, int _iconId) {
2396 this(aInfo.packageName, _iconId);
2397 }
2398
2399 ResourceName(ComponentInfo cInfo, int _iconId) {
2400 this(cInfo.applicationInfo.packageName, _iconId);
2401 }
2402
2403 ResourceName(ResolveInfo rInfo, int _iconId) {
2404 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2405 }
2406
2407 @Override
2408 public boolean equals(Object o) {
2409 if (this == o) return true;
2410 if (o == null || getClass() != o.getClass()) return false;
2411
2412 ResourceName that = (ResourceName) o;
2413
2414 if (iconId != that.iconId) return false;
2415 return !(packageName != null ?
2416 !packageName.equals(that.packageName) : that.packageName != null);
2417
2418 }
2419
2420 @Override
2421 public int hashCode() {
2422 int result;
2423 result = packageName.hashCode();
2424 result = 31 * result + iconId;
2425 return result;
2426 }
2427
2428 @Override
2429 public String toString() {
2430 return "{ResourceName " + packageName + " / " + iconId + "}";
2431 }
2432 }
2433
2434 private CharSequence getCachedString(ResourceName name) {
2435 synchronized (sSync) {
2436 WeakReference<CharSequence> wr = sStringCache.get(name);
2437 if (wr != null) { // we have the activity
2438 CharSequence cs = wr.get();
2439 if (cs != null) {
2440 return cs;
2441 }
2442 // our entry has been purged
2443 sStringCache.remove(name);
2444 }
2445 }
2446 return null;
2447 }
2448
2449 private void putCachedString(ResourceName name, CharSequence cs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 synchronized (sSync) {
2451 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2452 }
2453 }
2454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 @Override
2456 public CharSequence getText(String packageName, int resid,
2457 ApplicationInfo appInfo) {
2458 ResourceName name = new ResourceName(packageName, resid);
2459 CharSequence text = getCachedString(name);
2460 if (text != null) {
2461 return text;
2462 }
2463 if (appInfo == null) {
2464 try {
2465 appInfo = getApplicationInfo(packageName, 0);
2466 } catch (NameNotFoundException e) {
2467 return null;
2468 }
2469 }
2470 try {
2471 Resources r = getResourcesForApplication(appInfo);
2472 text = r.getText(resid);
2473 putCachedString(name, text);
2474 return text;
2475 } catch (NameNotFoundException e) {
2476 Log.w("PackageManager", "Failure retrieving resources for"
2477 + appInfo.packageName);
2478 } catch (RuntimeException e) {
2479 // If an exception was thrown, fall through to return
2480 // default icon.
2481 Log.w("PackageManager", "Failure retrieving text 0x"
2482 + Integer.toHexString(resid) + " in package "
2483 + packageName, e);
2484 }
2485 return null;
2486 }
2487
2488 @Override
2489 public XmlResourceParser getXml(String packageName, int resid,
2490 ApplicationInfo appInfo) {
2491 if (appInfo == null) {
2492 try {
2493 appInfo = getApplicationInfo(packageName, 0);
2494 } catch (NameNotFoundException e) {
2495 return null;
2496 }
2497 }
2498 try {
2499 Resources r = getResourcesForApplication(appInfo);
2500 return r.getXml(resid);
2501 } catch (RuntimeException e) {
2502 // If an exception was thrown, fall through to return
2503 // default icon.
2504 Log.w("PackageManager", "Failure retrieving xml 0x"
2505 + Integer.toHexString(resid) + " in package "
2506 + packageName, e);
2507 } catch (NameNotFoundException e) {
2508 Log.w("PackageManager", "Failure retrieving resources for"
2509 + appInfo.packageName);
2510 }
2511 return null;
2512 }
2513
2514 @Override
2515 public CharSequence getApplicationLabel(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002516 return info.loadLabel(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 }
2518
2519 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002520 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2521 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002523 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 } catch (RemoteException e) {
2525 // Should never happen!
2526 }
2527 }
2528
2529 @Override
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -08002530 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2531 try {
2532 mPM.movePackage(packageName, observer, flags);
2533 } catch (RemoteException e) {
2534 // Should never happen!
2535 }
2536 }
2537
2538 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002539 public String getInstallerPackageName(String packageName) {
2540 try {
2541 return mPM.getInstallerPackageName(packageName);
2542 } catch (RemoteException e) {
2543 // Should never happen!
2544 }
2545 return null;
2546 }
2547
2548 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2550 try {
2551 mPM.deletePackage(packageName, observer, flags);
2552 } catch (RemoteException e) {
2553 // Should never happen!
2554 }
2555 }
2556 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002557 public void clearApplicationUserData(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002558 IPackageDataObserver observer) {
2559 try {
2560 mPM.clearApplicationUserData(packageName, observer);
2561 } catch (RemoteException e) {
2562 // Should never happen!
2563 }
2564 }
2565 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002566 public void deleteApplicationCacheFiles(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 IPackageDataObserver observer) {
2568 try {
2569 mPM.deleteApplicationCacheFiles(packageName, observer);
2570 } catch (RemoteException e) {
2571 // Should never happen!
2572 }
2573 }
2574 @Override
2575 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2576 try {
2577 mPM.freeStorageAndNotify(idealStorageSize, observer);
2578 } catch (RemoteException e) {
2579 // Should never happen!
2580 }
2581 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002584 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002586 mPM.freeStorage(freeStorageSize, pi);
2587 } catch (RemoteException e) {
2588 // Should never happen!
2589 }
2590 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002593 public void getPackageSizeInfo(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002594 IPackageStatsObserver observer) {
2595 try {
2596 mPM.getPackageSizeInfo(packageName, observer);
2597 } catch (RemoteException e) {
2598 // Should never happen!
2599 }
2600 }
2601 @Override
2602 public void addPackageToPreferred(String packageName) {
2603 try {
2604 mPM.addPackageToPreferred(packageName);
2605 } catch (RemoteException e) {
2606 // Should never happen!
2607 }
2608 }
2609
2610 @Override
2611 public void removePackageFromPreferred(String packageName) {
2612 try {
2613 mPM.removePackageFromPreferred(packageName);
2614 } catch (RemoteException e) {
2615 // Should never happen!
2616 }
2617 }
2618
2619 @Override
2620 public List<PackageInfo> getPreferredPackages(int flags) {
2621 try {
2622 return mPM.getPreferredPackages(flags);
2623 } catch (RemoteException e) {
2624 // Should never happen!
2625 }
2626 return new ArrayList<PackageInfo>();
2627 }
2628
2629 @Override
2630 public void addPreferredActivity(IntentFilter filter,
2631 int match, ComponentName[] set, ComponentName activity) {
2632 try {
2633 mPM.addPreferredActivity(filter, match, set, activity);
2634 } catch (RemoteException e) {
2635 // Should never happen!
2636 }
2637 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002640 public void replacePreferredActivity(IntentFilter filter,
2641 int match, ComponentName[] set, ComponentName activity) {
2642 try {
2643 mPM.replacePreferredActivity(filter, match, set, activity);
2644 } catch (RemoteException e) {
2645 // Should never happen!
2646 }
2647 }
2648
2649 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002650 public void clearPackagePreferredActivities(String packageName) {
2651 try {
2652 mPM.clearPackagePreferredActivities(packageName);
2653 } catch (RemoteException e) {
2654 // Should never happen!
2655 }
2656 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 @Override
2659 public int getPreferredActivities(List<IntentFilter> outFilters,
2660 List<ComponentName> outActivities, String packageName) {
2661 try {
2662 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2663 } catch (RemoteException e) {
2664 // Should never happen!
2665 }
2666 return 0;
2667 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002669 @Override
2670 public void setComponentEnabledSetting(ComponentName componentName,
2671 int newState, int flags) {
2672 try {
2673 mPM.setComponentEnabledSetting(componentName, newState, flags);
2674 } catch (RemoteException e) {
2675 // Should never happen!
2676 }
2677 }
2678
2679 @Override
2680 public int getComponentEnabledSetting(ComponentName componentName) {
2681 try {
2682 return mPM.getComponentEnabledSetting(componentName);
2683 } catch (RemoteException e) {
2684 // Should never happen!
2685 }
2686 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2687 }
2688
2689 @Override
2690 public void setApplicationEnabledSetting(String packageName,
2691 int newState, int flags) {
2692 try {
2693 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2694 } catch (RemoteException e) {
2695 // Should never happen!
2696 }
2697 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002699 @Override
2700 public int getApplicationEnabledSetting(String packageName) {
2701 try {
2702 return mPM.getApplicationEnabledSetting(packageName);
2703 } catch (RemoteException e) {
2704 // Should never happen!
2705 }
2706 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2707 }
2708
Kenny Root93565c42010-06-18 15:46:06 -07002709 @Override
2710 public void setPackageObbPath(String packageName, String path) {
2711 try {
2712 mPM.setPackageObbPath(packageName, path);
2713 } catch (RemoteException e) {
2714 // Should never happen!
2715 }
2716 }
2717
Dianne Hackborn21556372010-02-04 16:34:40 -08002718 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 private final IPackageManager mPM;
2720
2721 private static final Object sSync = new Object();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2723 = new HashMap<ResourceName, WeakReference<Drawable> >();
2724 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2725 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2726 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727}