blob: 54e391985ac8a8fada76f3c4606afa79b170d2a9 [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 -070021import com.google.android.collect.Maps;
22
23import org.xmlpull.v1.XmlPullParserException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.ContextWrapper;
30import android.content.IContentProvider;
31import android.content.Intent;
32import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070033import android.content.IIntentReceiver;
34import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.ReceiverCallNotAllowedException;
36import android.content.ServiceConnection;
37import android.content.SharedPreferences;
38import android.content.pm.ActivityInfo;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.ComponentInfo;
Dianne Hackborn49237342009-08-27 20:08:01 -070041import android.content.pm.FeatureInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.content.pm.IPackageDataObserver;
43import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.content.pm.IPackageInstallObserver;
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -080045import android.content.pm.IPackageMoveObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070047import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.content.pm.InstrumentationInfo;
49import android.content.pm.PackageInfo;
50import android.content.pm.PackageManager;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
53import android.content.pm.ProviderInfo;
54import android.content.pm.ResolveInfo;
55import android.content.pm.ServiceInfo;
56import android.content.res.AssetManager;
57import android.content.res.Resources;
58import android.content.res.XmlResourceParser;
59import android.database.sqlite.SQLiteDatabase;
60import android.database.sqlite.SQLiteDatabase.CursorFactory;
61import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.graphics.drawable.Drawable;
63import android.hardware.SensorManager;
64import android.location.ILocationManager;
65import android.location.LocationManager;
66import android.media.AudioManager;
67import android.net.ConnectivityManager;
68import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070069import android.net.ThrottleManager;
70import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.net.Uri;
72import android.net.wifi.IWifiManager;
73import android.net.wifi.WifiManager;
74import android.os.Binder;
75import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080076import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080077import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.os.FileUtils;
79import android.os.Handler;
80import android.os.IBinder;
81import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070082import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.PowerManager;
84import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070085import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.os.ServiceManager;
87import android.os.Vibrator;
88import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080089import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.telephony.TelephonyManager;
91import android.text.ClipboardManager;
92import android.util.AndroidRuntimeException;
93import android.util.Log;
94import android.view.ContextThemeWrapper;
95import android.view.LayoutInflater;
96import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070097import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070099import android.accounts.AccountManager;
100import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800101import android.app.admin.DevicePolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
Dan Egnorf18a01c2009-11-12 11:32:50 -0800103import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import java.io.File;
106import java.io.FileInputStream;
107import java.io.FileNotFoundException;
108import java.io.FileOutputStream;
109import java.io.IOException;
110import java.io.InputStream;
111import java.lang.ref.WeakReference;
112import java.util.ArrayList;
113import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700114import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import java.util.Iterator;
116import java.util.List;
117import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700118import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700119import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120import java.util.Map.Entry;
121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122class ReceiverRestrictedContext extends ContextWrapper {
123 ReceiverRestrictedContext(Context base) {
124 super(base);
125 }
126
127 @Override
128 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
129 return registerReceiver(receiver, filter, null, null);
130 }
131
132 @Override
133 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
134 String broadcastPermission, Handler scheduler) {
135 throw new ReceiverCallNotAllowedException(
136 "IntentReceiver components are not allowed to register to receive intents");
137 //ex.fillInStackTrace();
138 //Log.e("IntentReceiver", ex.getMessage(), ex);
139 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
140 // scheduler);
141 }
142
143 @Override
144 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
145 throw new ReceiverCallNotAllowedException(
146 "IntentReceiver components are not allowed to bind to services");
147 //ex.fillInStackTrace();
148 //Log.e("IntentReceiver", ex.getMessage(), ex);
149 //return mContext.bindService(service, interfaceName, conn, flags);
150 }
151}
152
153/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800154 * Common implementation of Context API, which provides the base
155 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800157class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700159 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private final static boolean DEBUG_ICONS = false;
161
162 private static final Object sSync = new Object();
163 private static AlarmManager sAlarmManager;
164 private static PowerManager sPowerManager;
165 private static ConnectivityManager sConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700166 private static ThrottleManager sThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 private static WifiManager sWifiManager;
168 private static LocationManager sLocationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
170 new HashMap<File, SharedPreferencesImpl>();
171
172 private AudioManager mAudioManager;
173 /*package*/ ActivityThread.PackageInfo mPackageInfo;
174 private Resources mResources;
175 /*package*/ ActivityThread mMainThread;
176 private Context mOuterContext;
177 private IBinder mActivityToken = null;
178 private ApplicationContentResolver mContentResolver;
179 private int mThemeResource = 0;
180 private Resources.Theme mTheme = null;
181 private PackageManager mPackageManager;
182 private NotificationManager mNotificationManager = null;
183 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700184 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 private Context mReceiverRestrictedContext = null;
186 private SearchManager mSearchManager = null;
187 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800188 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 private Vibrator mVibrator = null;
190 private LayoutInflater mLayoutInflater = null;
191 private StatusBarManager mStatusBarManager = null;
192 private TelephonyManager mTelephonyManager = null;
193 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700194 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700195 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800196 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800197 private DevicePolicyManager mDevicePolicyManager = null;
Tobias Haamel53332882010-02-18 16:15:43 -0800198 private UiModeManager mUiModeManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199
200 private final Object mSync = new Object();
201
202 private File mDatabasesDir;
203 private File mPreferencesDir;
204 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800206 private File mExternalFilesDir;
207 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 private static long sInstanceCount = 0;
210
211 private static final String[] EMPTY_FILE_LIST = {};
212
Carl Shapiro82fe5642010-02-24 00:14:23 -0800213 // For debug only
214 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 @Override
216 protected void finalize() throws Throwable {
217 super.finalize();
218 --sInstanceCount;
219 }
Carl Shapiro82fe5642010-02-24 00:14:23 -0800220 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
222 public static long getInstanceCount() {
223 return sInstanceCount;
224 }
225
226 @Override
227 public AssetManager getAssets() {
228 return mResources.getAssets();
229 }
230
231 @Override
232 public Resources getResources() {
233 return mResources;
234 }
235
236 @Override
237 public PackageManager getPackageManager() {
238 if (mPackageManager != null) {
239 return mPackageManager;
240 }
241
242 IPackageManager pm = ActivityThread.getPackageManager();
243 if (pm != null) {
244 // Doesn't matter if we make more than one instance.
245 return (mPackageManager = new ApplicationPackageManager(this, pm));
246 }
247
248 return null;
249 }
250
251 @Override
252 public ContentResolver getContentResolver() {
253 return mContentResolver;
254 }
255
256 @Override
257 public Looper getMainLooper() {
258 return mMainThread.getLooper();
259 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 @Override
262 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700263 return (mPackageInfo != null) ?
264 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 @Override
268 public void setTheme(int resid) {
269 mThemeResource = resid;
270 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 @Override
273 public Resources.Theme getTheme() {
274 if (mTheme == null) {
275 if (mThemeResource == 0) {
276 mThemeResource = com.android.internal.R.style.Theme;
277 }
278 mTheme = mResources.newTheme();
279 mTheme.applyStyle(mThemeResource, true);
280 }
281 return mTheme;
282 }
283
284 @Override
285 public ClassLoader getClassLoader() {
286 return mPackageInfo != null ?
287 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
288 }
289
290 @Override
291 public String getPackageName() {
292 if (mPackageInfo != null) {
293 return mPackageInfo.getPackageName();
294 }
295 throw new RuntimeException("Not supported in system context");
296 }
297
298 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700299 public ApplicationInfo getApplicationInfo() {
300 if (mPackageInfo != null) {
301 return mPackageInfo.getApplicationInfo();
302 }
303 throw new RuntimeException("Not supported in system context");
304 }
305
306 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 public String getPackageResourcePath() {
308 if (mPackageInfo != null) {
309 return mPackageInfo.getResDir();
310 }
311 throw new RuntimeException("Not supported in system context");
312 }
313
314 @Override
315 public String getPackageCodePath() {
316 if (mPackageInfo != null) {
317 return mPackageInfo.getAppDir();
318 }
319 throw new RuntimeException("Not supported in system context");
320 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 private static File makeBackupFile(File prefsFile) {
323 return new File(prefsFile.getPath() + ".bak");
324 }
325
Joe Onorato23ecae32009-06-10 17:07:15 -0700326 public File getSharedPrefsFile(String name) {
327 return makeFilename(getPreferencesDir(), name + ".xml");
328 }
329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 @Override
331 public SharedPreferences getSharedPreferences(String name, int mode) {
332 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700333 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 synchronized (sSharedPrefs) {
335 sp = sSharedPrefs.get(f);
336 if (sp != null && !sp.hasFileChanged()) {
337 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
338 return sp;
339 }
340 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 FileInputStream str = null;
343 File backup = makeBackupFile(f);
344 if (backup.exists()) {
345 f.delete();
346 backup.renameTo(f);
347 }
348
349 // Debugging
350 if (f.exists() && !f.canRead()) {
351 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
352 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 Map map = null;
355 if (f.exists() && f.canRead()) {
356 try {
357 str = new FileInputStream(f);
358 map = XmlUtils.readMapXml(str);
359 str.close();
360 } catch (org.xmlpull.v1.XmlPullParserException e) {
361 Log.w(TAG, "getSharedPreferences", e);
362 } catch (FileNotFoundException e) {
363 Log.w(TAG, "getSharedPreferences", e);
364 } catch (IOException e) {
365 Log.w(TAG, "getSharedPreferences", e);
366 }
367 }
368
369 synchronized (sSharedPrefs) {
370 if (sp != null) {
371 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
372 sp.replace(map);
373 } else {
374 sp = sSharedPrefs.get(f);
375 if (sp == null) {
376 sp = new SharedPreferencesImpl(f, mode, map);
377 sSharedPrefs.put(f, sp);
378 }
379 }
380 return sp;
381 }
382 }
383
384 private File getPreferencesDir() {
385 synchronized (mSync) {
386 if (mPreferencesDir == null) {
387 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
388 }
389 return mPreferencesDir;
390 }
391 }
392
393 @Override
394 public FileInputStream openFileInput(String name)
395 throws FileNotFoundException {
396 File f = makeFilename(getFilesDir(), name);
397 return new FileInputStream(f);
398 }
399
400 @Override
401 public FileOutputStream openFileOutput(String name, int mode)
402 throws FileNotFoundException {
403 final boolean append = (mode&MODE_APPEND) != 0;
404 File f = makeFilename(getFilesDir(), name);
405 try {
406 FileOutputStream fos = new FileOutputStream(f, append);
407 setFilePermissionsFromMode(f.getPath(), mode, 0);
408 return fos;
409 } catch (FileNotFoundException e) {
410 }
411
412 File parent = f.getParentFile();
413 parent.mkdir();
414 FileUtils.setPermissions(
415 parent.getPath(),
416 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
417 -1, -1);
418 FileOutputStream fos = new FileOutputStream(f, append);
419 setFilePermissionsFromMode(f.getPath(), mode, 0);
420 return fos;
421 }
422
423 @Override
424 public boolean deleteFile(String name) {
425 File f = makeFilename(getFilesDir(), name);
426 return f.delete();
427 }
428
429 @Override
430 public File getFilesDir() {
431 synchronized (mSync) {
432 if (mFilesDir == null) {
433 mFilesDir = new File(getDataDirFile(), "files");
434 }
435 if (!mFilesDir.exists()) {
436 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200437 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 return null;
439 }
440 FileUtils.setPermissions(
441 mFilesDir.getPath(),
442 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
443 -1, -1);
444 }
445 return mFilesDir;
446 }
447 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800450 public File getExternalFilesDir(String type) {
451 synchronized (mSync) {
452 if (mExternalFilesDir == null) {
453 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
454 getPackageName());
455 }
456 if (!mExternalFilesDir.exists()) {
457 try {
458 (new File(Environment.getExternalStorageAndroidDataDir(),
459 ".nomedia")).createNewFile();
460 } catch (IOException e) {
461 }
462 if (!mExternalFilesDir.mkdirs()) {
463 Log.w(TAG, "Unable to create external files directory");
464 return null;
465 }
466 }
467 if (type == null) {
468 return mExternalFilesDir;
469 }
470 File dir = new File(mExternalFilesDir, type);
471 if (!dir.exists()) {
472 if (!dir.mkdirs()) {
473 Log.w(TAG, "Unable to create external media directory " + dir);
474 return null;
475 }
476 }
477 return dir;
478 }
479 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200480
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800481 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 public File getCacheDir() {
483 synchronized (mSync) {
484 if (mCacheDir == null) {
485 mCacheDir = new File(getDataDirFile(), "cache");
486 }
487 if (!mCacheDir.exists()) {
488 if(!mCacheDir.mkdirs()) {
489 Log.w(TAG, "Unable to create cache directory");
490 return null;
491 }
492 FileUtils.setPermissions(
493 mCacheDir.getPath(),
494 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
495 -1, -1);
496 }
497 }
498 return mCacheDir;
499 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200500
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800501 @Override
502 public File getExternalCacheDir() {
503 synchronized (mSync) {
504 if (mExternalCacheDir == null) {
505 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
506 getPackageName());
507 }
508 if (!mExternalCacheDir.exists()) {
509 try {
510 (new File(Environment.getExternalStorageAndroidDataDir(),
511 ".nomedia")).createNewFile();
512 } catch (IOException e) {
513 }
514 if (!mExternalCacheDir.mkdirs()) {
515 Log.w(TAG, "Unable to create external cache directory");
516 return null;
517 }
518 }
519 return mExternalCacheDir;
520 }
521 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 @Override
524 public File getFileStreamPath(String name) {
525 return makeFilename(getFilesDir(), name);
526 }
527
528 @Override
529 public String[] fileList() {
530 final String[] list = getFilesDir().list();
531 return (list != null) ? list : EMPTY_FILE_LIST;
532 }
533
534 @Override
535 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800536 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
538 setFilePermissionsFromMode(f.getPath(), mode, 0);
539 return db;
540 }
541
542 @Override
543 public boolean deleteDatabase(String name) {
544 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800545 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 return f.delete();
547 } catch (Exception e) {
548 }
549 return false;
550 }
551
552 @Override
553 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800554 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 }
556
557 @Override
558 public String[] databaseList() {
559 final String[] list = getDatabasesDir().list();
560 return (list != null) ? list : EMPTY_FILE_LIST;
561 }
562
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 private File getDatabasesDir() {
565 synchronized (mSync) {
566 if (mDatabasesDir == null) {
567 mDatabasesDir = new File(getDataDirFile(), "databases");
568 }
569 if (mDatabasesDir.getPath().equals("databases")) {
570 mDatabasesDir = new File("/data/system");
571 }
572 return mDatabasesDir;
573 }
574 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 @Override
577 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700578 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 }
580
581 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700582 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700583 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 }
585
586 @Override
587 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700588 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 }
590
591 @Override
592 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700593 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595
596 @Override
597 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700598 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 }
600
601 @Override
602 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700603 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
605
606 @Override
607 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700608 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
610
611 @Override
612 public void startActivity(Intent intent) {
613 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
614 throw new AndroidRuntimeException(
615 "Calling startActivity() from outside of an Activity "
616 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
617 + " Is this really what you want?");
618 }
619 mMainThread.getInstrumentation().execStartActivity(
620 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
621 }
622
623 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700624 public void startIntentSender(IntentSender intent,
625 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
626 throws IntentSender.SendIntentException {
627 try {
628 String resolvedType = null;
629 if (fillInIntent != null) {
630 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
631 }
632 int result = ActivityManagerNative.getDefault()
633 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
634 fillInIntent, resolvedType, null, null,
635 0, flagsMask, flagsValues);
636 if (result == IActivityManager.START_CANCELED) {
637 throw new IntentSender.SendIntentException();
638 }
639 Instrumentation.checkStartActivityResult(result, null);
640 } catch (RemoteException e) {
641 }
642 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200643
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700644 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 public void sendBroadcast(Intent intent) {
646 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
647 try {
648 ActivityManagerNative.getDefault().broadcastIntent(
649 mMainThread.getApplicationThread(), intent, resolvedType, null,
650 Activity.RESULT_OK, null, null, null, false, false);
651 } catch (RemoteException e) {
652 }
653 }
654
655 @Override
656 public void sendBroadcast(Intent intent, String receiverPermission) {
657 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
658 try {
659 ActivityManagerNative.getDefault().broadcastIntent(
660 mMainThread.getApplicationThread(), intent, resolvedType, null,
661 Activity.RESULT_OK, null, null, receiverPermission, false, false);
662 } catch (RemoteException e) {
663 }
664 }
665
666 @Override
667 public void sendOrderedBroadcast(Intent intent,
668 String receiverPermission) {
669 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
670 try {
671 ActivityManagerNative.getDefault().broadcastIntent(
672 mMainThread.getApplicationThread(), intent, resolvedType, null,
673 Activity.RESULT_OK, null, null, receiverPermission, true, false);
674 } catch (RemoteException e) {
675 }
676 }
677
678 @Override
679 public void sendOrderedBroadcast(Intent intent,
680 String receiverPermission, BroadcastReceiver resultReceiver,
681 Handler scheduler, int initialCode, String initialData,
682 Bundle initialExtras) {
683 IIntentReceiver rd = null;
684 if (resultReceiver != null) {
685 if (mPackageInfo != null) {
686 if (scheduler == null) {
687 scheduler = mMainThread.getHandler();
688 }
689 rd = mPackageInfo.getReceiverDispatcher(
690 resultReceiver, getOuterContext(), scheduler,
691 mMainThread.getInstrumentation(), false);
692 } else {
693 if (scheduler == null) {
694 scheduler = mMainThread.getHandler();
695 }
696 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
697 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
698 }
699 }
700 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
701 try {
702 ActivityManagerNative.getDefault().broadcastIntent(
703 mMainThread.getApplicationThread(), intent, resolvedType, rd,
704 initialCode, initialData, initialExtras, receiverPermission,
705 true, false);
706 } catch (RemoteException e) {
707 }
708 }
709
710 @Override
711 public void sendStickyBroadcast(Intent intent) {
712 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
713 try {
714 ActivityManagerNative.getDefault().broadcastIntent(
715 mMainThread.getApplicationThread(), intent, resolvedType, null,
716 Activity.RESULT_OK, null, null, null, false, true);
717 } catch (RemoteException e) {
718 }
719 }
720
721 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700722 public void sendStickyOrderedBroadcast(Intent intent,
723 BroadcastReceiver resultReceiver,
724 Handler scheduler, int initialCode, String initialData,
725 Bundle initialExtras) {
726 IIntentReceiver rd = null;
727 if (resultReceiver != null) {
728 if (mPackageInfo != null) {
729 if (scheduler == null) {
730 scheduler = mMainThread.getHandler();
731 }
732 rd = mPackageInfo.getReceiverDispatcher(
733 resultReceiver, getOuterContext(), scheduler,
734 mMainThread.getInstrumentation(), false);
735 } else {
736 if (scheduler == null) {
737 scheduler = mMainThread.getHandler();
738 }
739 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
740 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
741 }
742 }
743 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
744 try {
745 ActivityManagerNative.getDefault().broadcastIntent(
746 mMainThread.getApplicationThread(), intent, resolvedType, rd,
747 initialCode, initialData, initialExtras, null,
748 true, true);
749 } catch (RemoteException e) {
750 }
751 }
752
753 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 public void removeStickyBroadcast(Intent intent) {
755 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
756 if (resolvedType != null) {
757 intent = new Intent(intent);
758 intent.setDataAndType(intent.getData(), resolvedType);
759 }
760 try {
761 ActivityManagerNative.getDefault().unbroadcastIntent(
762 mMainThread.getApplicationThread(), intent);
763 } catch (RemoteException e) {
764 }
765 }
766
767 @Override
768 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
769 return registerReceiver(receiver, filter, null, null);
770 }
771
772 @Override
773 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
774 String broadcastPermission, Handler scheduler) {
775 return registerReceiverInternal(receiver, filter, broadcastPermission,
776 scheduler, getOuterContext());
777 }
778
779 private Intent registerReceiverInternal(BroadcastReceiver receiver,
780 IntentFilter filter, String broadcastPermission,
781 Handler scheduler, Context context) {
782 IIntentReceiver rd = null;
783 if (receiver != null) {
784 if (mPackageInfo != null && context != null) {
785 if (scheduler == null) {
786 scheduler = mMainThread.getHandler();
787 }
788 rd = mPackageInfo.getReceiverDispatcher(
789 receiver, context, scheduler,
790 mMainThread.getInstrumentation(), true);
791 } else {
792 if (scheduler == null) {
793 scheduler = mMainThread.getHandler();
794 }
795 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700796 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 }
798 }
799 try {
800 return ActivityManagerNative.getDefault().registerReceiver(
801 mMainThread.getApplicationThread(),
802 rd, filter, broadcastPermission);
803 } catch (RemoteException e) {
804 return null;
805 }
806 }
807
808 @Override
809 public void unregisterReceiver(BroadcastReceiver receiver) {
810 if (mPackageInfo != null) {
811 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
812 getOuterContext(), receiver);
813 try {
814 ActivityManagerNative.getDefault().unregisterReceiver(rd);
815 } catch (RemoteException e) {
816 }
817 } else {
818 throw new RuntimeException("Not supported in system context");
819 }
820 }
821
822 @Override
823 public ComponentName startService(Intent service) {
824 try {
825 ComponentName cn = ActivityManagerNative.getDefault().startService(
826 mMainThread.getApplicationThread(), service,
827 service.resolveTypeIfNeeded(getContentResolver()));
828 if (cn != null && cn.getPackageName().equals("!")) {
829 throw new SecurityException(
830 "Not allowed to start service " + service
831 + " without permission " + cn.getClassName());
832 }
833 return cn;
834 } catch (RemoteException e) {
835 return null;
836 }
837 }
838
839 @Override
840 public boolean stopService(Intent service) {
841 try {
842 int res = ActivityManagerNative.getDefault().stopService(
843 mMainThread.getApplicationThread(), service,
844 service.resolveTypeIfNeeded(getContentResolver()));
845 if (res < 0) {
846 throw new SecurityException(
847 "Not allowed to stop service " + service);
848 }
849 return res != 0;
850 } catch (RemoteException e) {
851 return false;
852 }
853 }
854
855 @Override
856 public boolean bindService(Intent service, ServiceConnection conn,
857 int flags) {
858 IServiceConnection sd;
859 if (mPackageInfo != null) {
860 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
861 mMainThread.getHandler(), flags);
862 } else {
863 throw new RuntimeException("Not supported in system context");
864 }
865 try {
866 int res = ActivityManagerNative.getDefault().bindService(
867 mMainThread.getApplicationThread(), getActivityToken(),
868 service, service.resolveTypeIfNeeded(getContentResolver()),
869 sd, flags);
870 if (res < 0) {
871 throw new SecurityException(
872 "Not allowed to bind to service " + service);
873 }
874 return res != 0;
875 } catch (RemoteException e) {
876 return false;
877 }
878 }
879
880 @Override
881 public void unbindService(ServiceConnection conn) {
882 if (mPackageInfo != null) {
883 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
884 getOuterContext(), conn);
885 try {
886 ActivityManagerNative.getDefault().unbindService(sd);
887 } catch (RemoteException e) {
888 }
889 } else {
890 throw new RuntimeException("Not supported in system context");
891 }
892 }
893
894 @Override
895 public boolean startInstrumentation(ComponentName className,
896 String profileFile, Bundle arguments) {
897 try {
898 return ActivityManagerNative.getDefault().startInstrumentation(
899 className, profileFile, 0, arguments, null);
900 } catch (RemoteException e) {
901 // System has crashed, nothing we can do.
902 }
903 return false;
904 }
905
906 @Override
907 public Object getSystemService(String name) {
908 if (WINDOW_SERVICE.equals(name)) {
909 return WindowManagerImpl.getDefault();
910 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
911 synchronized (mSync) {
912 LayoutInflater inflater = mLayoutInflater;
913 if (inflater != null) {
914 return inflater;
915 }
916 mLayoutInflater = inflater =
917 PolicyManager.makeNewLayoutInflater(getOuterContext());
918 return inflater;
919 }
920 } else if (ACTIVITY_SERVICE.equals(name)) {
921 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700922 } else if (INPUT_METHOD_SERVICE.equals(name)) {
923 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 } else if (ALARM_SERVICE.equals(name)) {
925 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700926 } else if (ACCOUNT_SERVICE.equals(name)) {
927 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 } else if (POWER_SERVICE.equals(name)) {
929 return getPowerManager();
930 } else if (CONNECTIVITY_SERVICE.equals(name)) {
931 return getConnectivityManager();
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700932 } else if (THROTTLE_SERVICE.equals(name)) {
933 return getThrottleManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 } else if (WIFI_SERVICE.equals(name)) {
935 return getWifiManager();
936 } else if (NOTIFICATION_SERVICE.equals(name)) {
937 return getNotificationManager();
938 } else if (KEYGUARD_SERVICE.equals(name)) {
939 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700940 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
941 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 } else if (LOCATION_SERVICE.equals(name)) {
943 return getLocationManager();
944 } else if (SEARCH_SERVICE.equals(name)) {
945 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700946 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800948 } else if (STORAGE_SERVICE.equals(name)) {
949 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 } else if (VIBRATOR_SERVICE.equals(name)) {
951 return getVibrator();
952 } else if (STATUS_BAR_SERVICE.equals(name)) {
953 synchronized (mSync) {
954 if (mStatusBarManager == null) {
955 mStatusBarManager = new StatusBarManager(getOuterContext());
956 }
957 return mStatusBarManager;
958 }
959 } else if (AUDIO_SERVICE.equals(name)) {
960 return getAudioManager();
961 } else if (TELEPHONY_SERVICE.equals(name)) {
962 return getTelephonyManager();
963 } else if (CLIPBOARD_SERVICE.equals(name)) {
964 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700965 } else if (WALLPAPER_SERVICE.equals(name)) {
966 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700967 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800968 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800969 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
970 return getDevicePolicyManager();
Tobias Haamel69fb5742010-02-22 21:54:05 +0100971 } else if (UI_MODE_SERVICE.equals(name)) {
Tobias Haamel53332882010-02-18 16:15:43 -0800972 return getUiModeManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 }
974
975 return null;
976 }
977
Fred Quintana60307342009-03-24 22:48:12 -0700978 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700979 synchronized (mSync) {
980 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -0700981 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
982 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -0700983 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -0700984 }
Fred Quintanae00a3112009-09-22 15:13:30 -0700985 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -0700986 }
Fred Quintana60307342009-03-24 22:48:12 -0700987 }
988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 private ActivityManager getActivityManager() {
990 synchronized (mSync) {
991 if (mActivityManager == null) {
992 mActivityManager = new ActivityManager(getOuterContext(),
993 mMainThread.getHandler());
994 }
995 }
996 return mActivityManager;
997 }
998
999 private AlarmManager getAlarmManager() {
1000 synchronized (sSync) {
1001 if (sAlarmManager == null) {
1002 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1003 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1004 sAlarmManager = new AlarmManager(service);
1005 }
1006 }
1007 return sAlarmManager;
1008 }
1009
1010 private PowerManager getPowerManager() {
1011 synchronized (sSync) {
1012 if (sPowerManager == null) {
1013 IBinder b = ServiceManager.getService(POWER_SERVICE);
1014 IPowerManager service = IPowerManager.Stub.asInterface(b);
1015 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1016 }
1017 }
1018 return sPowerManager;
1019 }
1020
1021 private ConnectivityManager getConnectivityManager()
1022 {
1023 synchronized (sSync) {
1024 if (sConnectivityManager == null) {
1025 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1026 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1027 sConnectivityManager = new ConnectivityManager(service);
1028 }
1029 }
1030 return sConnectivityManager;
1031 }
1032
Irfan Sheriffc9b68512010-04-08 14:12:33 -07001033 private ThrottleManager getThrottleManager()
1034 {
1035 synchronized (sSync) {
1036 if (sThrottleManager == null) {
1037 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1038 IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1039 sThrottleManager = new ThrottleManager(service);
1040 }
1041 }
1042 return sThrottleManager;
1043 }
1044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 private WifiManager getWifiManager()
1046 {
1047 synchronized (sSync) {
1048 if (sWifiManager == null) {
1049 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1050 IWifiManager service = IWifiManager.Stub.asInterface(b);
1051 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1052 }
1053 }
1054 return sWifiManager;
1055 }
1056
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001057 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 synchronized (mSync) {
1059 if (mNotificationManager == null) {
1060 mNotificationManager = new NotificationManager(
1061 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1062 mMainThread.getHandler());
1063 }
1064 }
1065 return mNotificationManager;
1066 }
1067
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001068 private WallpaperManager getWallpaperManager() {
1069 synchronized (mSync) {
1070 if (mWallpaperManager == null) {
1071 mWallpaperManager = new WallpaperManager(getOuterContext(),
1072 mMainThread.getHandler());
1073 }
1074 }
1075 return mWallpaperManager;
1076 }
1077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 private TelephonyManager getTelephonyManager() {
1079 synchronized (mSync) {
1080 if (mTelephonyManager == null) {
1081 mTelephonyManager = new TelephonyManager(getOuterContext());
1082 }
1083 }
1084 return mTelephonyManager;
1085 }
1086
1087 private ClipboardManager getClipboardManager() {
1088 synchronized (mSync) {
1089 if (mClipboardManager == null) {
1090 mClipboardManager = new ClipboardManager(getOuterContext(),
1091 mMainThread.getHandler());
1092 }
1093 }
1094 return mClipboardManager;
1095 }
1096
1097 private LocationManager getLocationManager() {
1098 synchronized (sSync) {
1099 if (sLocationManager == null) {
1100 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1101 ILocationManager service = ILocationManager.Stub.asInterface(b);
1102 sLocationManager = new LocationManager(service);
1103 }
1104 }
1105 return sLocationManager;
1106 }
1107
1108 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 synchronized (mSync) {
1110 if (mSearchManager == null) {
1111 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1112 }
1113 }
1114 return mSearchManager;
1115 }
1116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 private SensorManager getSensorManager() {
1118 synchronized (mSync) {
1119 if (mSensorManager == null) {
1120 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1121 }
1122 }
1123 return mSensorManager;
1124 }
1125
San Mehatc9d81752010-02-01 10:23:27 -08001126 private StorageManager getStorageManager() {
1127 synchronized (mSync) {
1128 if (mStorageManager == null) {
1129 try {
1130 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1131 } catch (RemoteException rex) {
1132 Log.e(TAG, "Failed to create StorageManager", rex);
1133 mStorageManager = null;
1134 }
1135 }
1136 }
1137 return mStorageManager;
1138 }
1139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 private Vibrator getVibrator() {
1141 synchronized (mSync) {
1142 if (mVibrator == null) {
1143 mVibrator = new Vibrator();
1144 }
1145 }
1146 return mVibrator;
1147 }
Dan Egnor95240272009-10-27 18:23:39 -07001148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 private AudioManager getAudioManager()
1150 {
1151 if (mAudioManager == null) {
1152 mAudioManager = new AudioManager(this);
1153 }
1154 return mAudioManager;
1155 }
1156
Dan Egnorf18a01c2009-11-12 11:32:50 -08001157 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001158 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001159 if (mDropBoxManager == null) {
Dan Egnor95240272009-10-27 18:23:39 -07001160 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
Dan Egnorf18a01c2009-11-12 11:32:50 -08001161 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1162 mDropBoxManager = new DropBoxManager(service);
Dan Egnor95240272009-10-27 18:23:39 -07001163 }
1164 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001165 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001166 }
1167
Dianne Hackbornd6847842010-01-12 18:14:19 -08001168 private DevicePolicyManager getDevicePolicyManager() {
1169 synchronized (mSync) {
1170 if (mDevicePolicyManager == null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001171 mDevicePolicyManager = DevicePolicyManager.create(this,
Dianne Hackbornd6847842010-01-12 18:14:19 -08001172 mMainThread.getHandler());
1173 }
1174 }
1175 return mDevicePolicyManager;
1176 }
1177
Tobias Haamel53332882010-02-18 16:15:43 -08001178 private UiModeManager getUiModeManager() {
1179 synchronized (mSync) {
1180 if (mUiModeManager == null) {
1181 mUiModeManager = new UiModeManager();
1182 }
1183 }
1184 return mUiModeManager;
1185 }
1186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 @Override
1188 public int checkPermission(String permission, int pid, int uid) {
1189 if (permission == null) {
1190 throw new IllegalArgumentException("permission is null");
1191 }
1192
1193 if (!Process.supportsProcesses()) {
1194 return PackageManager.PERMISSION_GRANTED;
1195 }
1196 try {
1197 return ActivityManagerNative.getDefault().checkPermission(
1198 permission, pid, uid);
1199 } catch (RemoteException e) {
1200 return PackageManager.PERMISSION_DENIED;
1201 }
1202 }
1203
1204 @Override
1205 public int checkCallingPermission(String permission) {
1206 if (permission == null) {
1207 throw new IllegalArgumentException("permission is null");
1208 }
1209
1210 if (!Process.supportsProcesses()) {
1211 return PackageManager.PERMISSION_GRANTED;
1212 }
1213 int pid = Binder.getCallingPid();
1214 if (pid != Process.myPid()) {
1215 return checkPermission(permission, pid,
1216 Binder.getCallingUid());
1217 }
1218 return PackageManager.PERMISSION_DENIED;
1219 }
1220
1221 @Override
1222 public int checkCallingOrSelfPermission(String permission) {
1223 if (permission == null) {
1224 throw new IllegalArgumentException("permission is null");
1225 }
1226
1227 return checkPermission(permission, Binder.getCallingPid(),
1228 Binder.getCallingUid());
1229 }
1230
1231 private void enforce(
1232 String permission, int resultOfCheck,
1233 boolean selfToo, int uid, String message) {
1234 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1235 throw new SecurityException(
1236 (message != null ? (message + ": ") : "") +
1237 (selfToo
1238 ? "Neither user " + uid + " nor current process has "
1239 : "User " + uid + " does not have ") +
1240 permission +
1241 ".");
1242 }
1243 }
1244
1245 public void enforcePermission(
1246 String permission, int pid, int uid, String message) {
1247 enforce(permission,
1248 checkPermission(permission, pid, uid),
1249 false,
1250 uid,
1251 message);
1252 }
1253
1254 public void enforceCallingPermission(String permission, String message) {
1255 enforce(permission,
1256 checkCallingPermission(permission),
1257 false,
1258 Binder.getCallingUid(),
1259 message);
1260 }
1261
1262 public void enforceCallingOrSelfPermission(
1263 String permission, String message) {
1264 enforce(permission,
1265 checkCallingOrSelfPermission(permission),
1266 true,
1267 Binder.getCallingUid(),
1268 message);
1269 }
1270
1271 @Override
1272 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1273 try {
1274 ActivityManagerNative.getDefault().grantUriPermission(
1275 mMainThread.getApplicationThread(), toPackage, uri,
1276 modeFlags);
1277 } catch (RemoteException e) {
1278 }
1279 }
1280
1281 @Override
1282 public void revokeUriPermission(Uri uri, int modeFlags) {
1283 try {
1284 ActivityManagerNative.getDefault().revokeUriPermission(
1285 mMainThread.getApplicationThread(), uri,
1286 modeFlags);
1287 } catch (RemoteException e) {
1288 }
1289 }
1290
1291 @Override
1292 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1293 if (!Process.supportsProcesses()) {
1294 return PackageManager.PERMISSION_GRANTED;
1295 }
1296 try {
1297 return ActivityManagerNative.getDefault().checkUriPermission(
1298 uri, pid, uid, modeFlags);
1299 } catch (RemoteException e) {
1300 return PackageManager.PERMISSION_DENIED;
1301 }
1302 }
1303
1304 @Override
1305 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1306 if (!Process.supportsProcesses()) {
1307 return PackageManager.PERMISSION_GRANTED;
1308 }
1309 int pid = Binder.getCallingPid();
1310 if (pid != Process.myPid()) {
1311 return checkUriPermission(uri, pid,
1312 Binder.getCallingUid(), modeFlags);
1313 }
1314 return PackageManager.PERMISSION_DENIED;
1315 }
1316
1317 @Override
1318 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1319 return checkUriPermission(uri, Binder.getCallingPid(),
1320 Binder.getCallingUid(), modeFlags);
1321 }
1322
1323 @Override
1324 public int checkUriPermission(Uri uri, String readPermission,
1325 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001326 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1328 + readPermission + " writePermission=" + writePermission
1329 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1330 }
1331 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1332 if (readPermission == null
1333 || checkPermission(readPermission, pid, uid)
1334 == PackageManager.PERMISSION_GRANTED) {
1335 return PackageManager.PERMISSION_GRANTED;
1336 }
1337 }
1338 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1339 if (writePermission == null
1340 || checkPermission(writePermission, pid, uid)
1341 == PackageManager.PERMISSION_GRANTED) {
1342 return PackageManager.PERMISSION_GRANTED;
1343 }
1344 }
1345 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1346 : PackageManager.PERMISSION_DENIED;
1347 }
1348
1349 private String uriModeFlagToString(int uriModeFlags) {
1350 switch (uriModeFlags) {
1351 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1352 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1353 return "read and write";
1354 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1355 return "read";
1356 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1357 return "write";
1358 }
1359 throw new IllegalArgumentException(
1360 "Unknown permission mode flags: " + uriModeFlags);
1361 }
1362
1363 private void enforceForUri(
1364 int modeFlags, int resultOfCheck, boolean selfToo,
1365 int uid, Uri uri, String message) {
1366 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1367 throw new SecurityException(
1368 (message != null ? (message + ": ") : "") +
1369 (selfToo
1370 ? "Neither user " + uid + " nor current process has "
1371 : "User " + uid + " does not have ") +
1372 uriModeFlagToString(modeFlags) +
1373 " permission on " +
1374 uri +
1375 ".");
1376 }
1377 }
1378
1379 public void enforceUriPermission(
1380 Uri uri, int pid, int uid, int modeFlags, String message) {
1381 enforceForUri(
1382 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1383 false, uid, uri, message);
1384 }
1385
1386 public void enforceCallingUriPermission(
1387 Uri uri, int modeFlags, String message) {
1388 enforceForUri(
1389 modeFlags, checkCallingUriPermission(uri, modeFlags),
1390 false, Binder.getCallingUid(), uri, message);
1391 }
1392
1393 public void enforceCallingOrSelfUriPermission(
1394 Uri uri, int modeFlags, String message) {
1395 enforceForUri(
1396 modeFlags,
1397 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1398 Binder.getCallingUid(), uri, message);
1399 }
1400
1401 public void enforceUriPermission(
1402 Uri uri, String readPermission, String writePermission,
1403 int pid, int uid, int modeFlags, String message) {
1404 enforceForUri(modeFlags,
1405 checkUriPermission(
1406 uri, readPermission, writePermission, pid, uid,
1407 modeFlags),
1408 false,
1409 uid,
1410 uri,
1411 message);
1412 }
1413
1414 @Override
1415 public Context createPackageContext(String packageName, int flags)
1416 throws PackageManager.NameNotFoundException {
1417 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001418 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 }
1420
1421 ActivityThread.PackageInfo pi =
1422 mMainThread.getPackageInfo(packageName, flags);
1423 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001424 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001425 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001426 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 if (c.mResources != null) {
1428 return c;
1429 }
1430 }
1431
1432 // Should be a better exception.
1433 throw new PackageManager.NameNotFoundException(
1434 "Application package " + packageName + " not found");
1435 }
1436
Romain Guy870e09f2009-07-06 16:35:25 -07001437 @Override
1438 public boolean isRestricted() {
1439 return mRestricted;
1440 }
1441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 private File getDataDirFile() {
1443 if (mPackageInfo != null) {
1444 return mPackageInfo.getDataDirFile();
1445 }
1446 throw new RuntimeException("Not supported in system context");
1447 }
1448
1449 @Override
1450 public File getDir(String name, int mode) {
1451 name = "app_" + name;
1452 File file = makeFilename(getDataDirFile(), name);
1453 if (!file.exists()) {
1454 file.mkdir();
1455 setFilePermissionsFromMode(file.getPath(), mode,
1456 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1457 }
1458 return file;
1459 }
1460
Dianne Hackborn21556372010-02-04 16:34:40 -08001461 static ContextImpl createSystemContext(ActivityThread mainThread) {
1462 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 context.init(Resources.getSystem(), mainThread);
1464 return context;
1465 }
1466
Dianne Hackborn21556372010-02-04 16:34:40 -08001467 ContextImpl() {
Carl Shapiro82fe5642010-02-24 00:14:23 -08001468 // For debug only
1469 //++sInstanceCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 mOuterContext = this;
1471 }
1472
1473 /**
1474 * Create a new ApplicationContext from an existing one. The new one
1475 * works and operates the same as the one it is copying.
1476 *
1477 * @param context Existing application context.
1478 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001479 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 ++sInstanceCount;
1481 mPackageInfo = context.mPackageInfo;
1482 mResources = context.mResources;
1483 mMainThread = context.mMainThread;
1484 mContentResolver = context.mContentResolver;
1485 mOuterContext = this;
1486 }
1487
1488 final void init(ActivityThread.PackageInfo packageInfo,
1489 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001490 init(packageInfo, activityToken, mainThread, null);
1491 }
1492
1493 final void init(ActivityThread.PackageInfo packageInfo,
1494 IBinder activityToken, ActivityThread mainThread,
1495 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 mPackageInfo = packageInfo;
1497 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001498
Dianne Hackborn559a7872010-04-07 18:19:41 -07001499 if (mResources != null && container != null
1500 && container.getCompatibilityInfo().applicationScale !=
1501 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001502 if (DEBUG) {
1503 Log.d(TAG, "loaded context has different scaling. Using container's" +
1504 " compatiblity info:" + container.getDisplayMetrics());
1505 }
1506 mResources = mainThread.getTopLevelResources(
1507 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 mMainThread = mainThread;
1510 mContentResolver = new ApplicationContentResolver(this, mainThread);
1511
1512 setActivityToken(activityToken);
1513 }
1514
1515 final void init(Resources resources, ActivityThread mainThread) {
1516 mPackageInfo = null;
1517 mResources = resources;
1518 mMainThread = mainThread;
1519 mContentResolver = new ApplicationContentResolver(this, mainThread);
1520 }
1521
1522 final void scheduleFinalCleanup(String who, String what) {
1523 mMainThread.scheduleContextCleanup(this, who, what);
1524 }
1525
1526 final void performFinalCleanup(String who, String what) {
1527 //Log.i(TAG, "Cleanup up context: " + this);
1528 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1529 }
1530
1531 final Context getReceiverRestrictedContext() {
1532 if (mReceiverRestrictedContext != null) {
1533 return mReceiverRestrictedContext;
1534 }
1535 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1536 }
1537
1538 final void setActivityToken(IBinder token) {
1539 mActivityToken = token;
1540 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 final void setOuterContext(Context context) {
1543 mOuterContext = context;
1544 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 final Context getOuterContext() {
1547 return mOuterContext;
1548 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 final IBinder getActivityToken() {
1551 return mActivityToken;
1552 }
1553
1554 private static void setFilePermissionsFromMode(String name, int mode,
1555 int extraPermissions) {
1556 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1557 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1558 |extraPermissions;
1559 if ((mode&MODE_WORLD_READABLE) != 0) {
1560 perms |= FileUtils.S_IROTH;
1561 }
1562 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1563 perms |= FileUtils.S_IWOTH;
1564 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001565 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1567 + ", perms=0x" + Integer.toHexString(perms));
1568 }
1569 FileUtils.setPermissions(name, perms, -1, -1);
1570 }
1571
Oscar Montemayora8529f62009-11-18 10:14:20 -08001572 private File validateFilePath(String name, boolean createDirectory) {
1573 File dir;
1574 File f;
1575
1576 if (name.charAt(0) == File.separatorChar) {
1577 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1578 dir = new File(dirPath);
1579 name = name.substring(name.lastIndexOf(File.separatorChar));
1580 f = new File(dir, name);
1581 } else {
1582 dir = getDatabasesDir();
1583 f = makeFilename(dir, name);
1584 }
1585
1586 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1587 FileUtils.setPermissions(dir.getPath(),
1588 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1589 -1, -1);
1590 }
1591
1592 return f;
1593 }
1594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 private File makeFilename(File base, String name) {
1596 if (name.indexOf(File.separatorChar) < 0) {
1597 return new File(base, name);
1598 }
1599 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001600 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001601 }
1602
1603 // ----------------------------------------------------------------------
1604 // ----------------------------------------------------------------------
1605 // ----------------------------------------------------------------------
1606
1607 private static final class ApplicationContentResolver extends ContentResolver {
1608 public ApplicationContentResolver(Context context,
1609 ActivityThread mainThread)
1610 {
1611 super(context);
1612 mMainThread = mainThread;
1613 }
1614
1615 @Override
1616 protected IContentProvider acquireProvider(Context context, String name)
1617 {
1618 return mMainThread.acquireProvider(context, name);
1619 }
1620
1621 @Override
1622 public boolean releaseProvider(IContentProvider provider)
1623 {
1624 return mMainThread.releaseProvider(provider);
1625 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 private final ActivityThread mMainThread;
1628 }
1629
1630 // ----------------------------------------------------------------------
1631 // ----------------------------------------------------------------------
1632 // ----------------------------------------------------------------------
1633
1634 /*package*/
1635 static final class ApplicationPackageManager extends PackageManager {
1636 @Override
1637 public PackageInfo getPackageInfo(String packageName, int flags)
1638 throws NameNotFoundException {
1639 try {
1640 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1641 if (pi != null) {
1642 return pi;
1643 }
1644 } catch (RemoteException e) {
1645 throw new RuntimeException("Package manager has died", e);
1646 }
1647
1648 throw new NameNotFoundException(packageName);
1649 }
1650
Mihai Predaeae850c2009-05-13 10:13:48 +02001651 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001652 public String[] currentToCanonicalPackageNames(String[] names) {
1653 try {
1654 return mPM.currentToCanonicalPackageNames(names);
1655 } catch (RemoteException e) {
1656 throw new RuntimeException("Package manager has died", e);
1657 }
1658 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001659
Dianne Hackborn47096932010-02-11 15:57:09 -08001660 @Override
1661 public String[] canonicalToCurrentPackageNames(String[] names) {
1662 try {
1663 return mPM.canonicalToCurrentPackageNames(names);
1664 } catch (RemoteException e) {
1665 throw new RuntimeException("Package manager has died", e);
1666 }
1667 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001668
Dianne Hackborn47096932010-02-11 15:57:09 -08001669 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001670 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 // First see if the package has an INFO activity; the existence of
1672 // such an activity is implied to be the desired front-door for the
1673 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001674 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1675 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001676 intentToResolve.setPackage(packageName);
1677 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001680 if (resolveInfo == null) {
1681 // reuse the intent instance
1682 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1683 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001684 intentToResolve.setPackage(packageName);
1685 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001687 if (resolveInfo == null) {
1688 return null;
1689 }
1690 Intent intent = new Intent(Intent.ACTION_MAIN);
1691 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1692 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1693 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001696 @Override
1697 public int[] getPackageGids(String packageName)
1698 throws NameNotFoundException {
1699 try {
1700 int[] gids = mPM.getPackageGids(packageName);
1701 if (gids == null || gids.length > 0) {
1702 return gids;
1703 }
1704 } catch (RemoteException e) {
1705 throw new RuntimeException("Package manager has died", e);
1706 }
1707
1708 throw new NameNotFoundException(packageName);
1709 }
1710
1711 @Override
1712 public PermissionInfo getPermissionInfo(String name, int flags)
1713 throws NameNotFoundException {
1714 try {
1715 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1716 if (pi != null) {
1717 return pi;
1718 }
1719 } catch (RemoteException e) {
1720 throw new RuntimeException("Package manager has died", e);
1721 }
1722
1723 throw new NameNotFoundException(name);
1724 }
1725
1726 @Override
1727 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1728 throws NameNotFoundException {
1729 try {
1730 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1731 if (pi != null) {
1732 return pi;
1733 }
1734 } catch (RemoteException e) {
1735 throw new RuntimeException("Package manager has died", e);
1736 }
1737
1738 throw new NameNotFoundException(group);
1739 }
1740
1741 @Override
1742 public PermissionGroupInfo getPermissionGroupInfo(String name,
1743 int flags) throws NameNotFoundException {
1744 try {
1745 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1746 if (pgi != null) {
1747 return pgi;
1748 }
1749 } catch (RemoteException e) {
1750 throw new RuntimeException("Package manager has died", e);
1751 }
1752
1753 throw new NameNotFoundException(name);
1754 }
1755
1756 @Override
1757 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1758 try {
1759 return mPM.getAllPermissionGroups(flags);
1760 } catch (RemoteException e) {
1761 throw new RuntimeException("Package manager has died", e);
1762 }
1763 }
1764
1765 @Override
1766 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1767 throws NameNotFoundException {
1768 try {
1769 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1770 if (ai != null) {
1771 return ai;
1772 }
1773 } catch (RemoteException e) {
1774 throw new RuntimeException("Package manager has died", e);
1775 }
1776
1777 throw new NameNotFoundException(packageName);
1778 }
1779
1780 @Override
1781 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1782 throws NameNotFoundException {
1783 try {
1784 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1785 if (ai != null) {
1786 return ai;
1787 }
1788 } catch (RemoteException e) {
1789 throw new RuntimeException("Package manager has died", e);
1790 }
1791
1792 throw new NameNotFoundException(className.toString());
1793 }
1794
1795 @Override
1796 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1797 throws NameNotFoundException {
1798 try {
1799 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1800 if (ai != null) {
1801 return ai;
1802 }
1803 } catch (RemoteException e) {
1804 throw new RuntimeException("Package manager has died", e);
1805 }
1806
1807 throw new NameNotFoundException(className.toString());
1808 }
1809
1810 @Override
1811 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1812 throws NameNotFoundException {
1813 try {
1814 ServiceInfo si = mPM.getServiceInfo(className, flags);
1815 if (si != null) {
1816 return si;
1817 }
1818 } catch (RemoteException e) {
1819 throw new RuntimeException("Package manager has died", e);
1820 }
1821
1822 throw new NameNotFoundException(className.toString());
1823 }
1824
1825 @Override
1826 public String[] getSystemSharedLibraryNames() {
1827 try {
1828 return mPM.getSystemSharedLibraryNames();
1829 } catch (RemoteException e) {
1830 throw new RuntimeException("Package manager has died", e);
1831 }
1832 }
1833
1834 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001835 public FeatureInfo[] getSystemAvailableFeatures() {
1836 try {
1837 return mPM.getSystemAvailableFeatures();
1838 } catch (RemoteException e) {
1839 throw new RuntimeException("Package manager has died", e);
1840 }
1841 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001842
Dianne Hackborn49237342009-08-27 20:08:01 -07001843 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001844 public boolean hasSystemFeature(String name) {
1845 try {
1846 return mPM.hasSystemFeature(name);
1847 } catch (RemoteException e) {
1848 throw new RuntimeException("Package manager has died", e);
1849 }
1850 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001851
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001852 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 public int checkPermission(String permName, String pkgName) {
1854 try {
1855 return mPM.checkPermission(permName, pkgName);
1856 } catch (RemoteException e) {
1857 throw new RuntimeException("Package manager has died", e);
1858 }
1859 }
1860
1861 @Override
1862 public boolean addPermission(PermissionInfo info) {
1863 try {
1864 return mPM.addPermission(info);
1865 } catch (RemoteException e) {
1866 throw new RuntimeException("Package manager has died", e);
1867 }
1868 }
1869
1870 @Override
Dianne Hackbornd7c09682010-03-30 10:42:20 -07001871 public boolean addPermissionAsync(PermissionInfo info) {
1872 try {
1873 return mPM.addPermissionAsync(info);
1874 } catch (RemoteException e) {
1875 throw new RuntimeException("Package manager has died", e);
1876 }
1877 }
1878
1879 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 public void removePermission(String name) {
1881 try {
1882 mPM.removePermission(name);
1883 } catch (RemoteException e) {
1884 throw new RuntimeException("Package manager has died", e);
1885 }
1886 }
1887
1888 @Override
1889 public int checkSignatures(String pkg1, String pkg2) {
1890 try {
1891 return mPM.checkSignatures(pkg1, pkg2);
1892 } catch (RemoteException e) {
1893 throw new RuntimeException("Package manager has died", e);
1894 }
1895 }
1896
1897 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001898 public int checkSignatures(int uid1, int uid2) {
1899 try {
1900 return mPM.checkUidSignatures(uid1, uid2);
1901 } catch (RemoteException e) {
1902 throw new RuntimeException("Package manager has died", e);
1903 }
1904 }
1905
1906 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 public String[] getPackagesForUid(int uid) {
1908 try {
1909 return mPM.getPackagesForUid(uid);
1910 } catch (RemoteException e) {
1911 throw new RuntimeException("Package manager has died", e);
1912 }
1913 }
1914
1915 @Override
1916 public String getNameForUid(int uid) {
1917 try {
1918 return mPM.getNameForUid(uid);
1919 } catch (RemoteException e) {
1920 throw new RuntimeException("Package manager has died", e);
1921 }
1922 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001924 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001925 public int getUidForSharedUser(String sharedUserName)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001926 throws NameNotFoundException {
1927 try {
1928 int uid = mPM.getUidForSharedUser(sharedUserName);
1929 if(uid != -1) {
1930 return uid;
1931 }
1932 } catch (RemoteException e) {
1933 throw new RuntimeException("Package manager has died", e);
1934 }
1935 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1936 }
1937
1938 @Override
1939 public List<PackageInfo> getInstalledPackages(int flags) {
1940 try {
1941 return mPM.getInstalledPackages(flags);
1942 } catch (RemoteException e) {
1943 throw new RuntimeException("Package manager has died", e);
1944 }
1945 }
1946
1947 @Override
1948 public List<ApplicationInfo> getInstalledApplications(int flags) {
1949 try {
1950 return mPM.getInstalledApplications(flags);
1951 } catch (RemoteException e) {
1952 throw new RuntimeException("Package manager has died", e);
1953 }
1954 }
1955
1956 @Override
1957 public ResolveInfo resolveActivity(Intent intent, int flags) {
1958 try {
1959 return mPM.resolveIntent(
1960 intent,
1961 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1962 flags);
1963 } catch (RemoteException e) {
1964 throw new RuntimeException("Package manager has died", e);
1965 }
1966 }
1967
1968 @Override
1969 public List<ResolveInfo> queryIntentActivities(Intent intent,
1970 int flags) {
1971 try {
1972 return mPM.queryIntentActivities(
1973 intent,
1974 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1975 flags);
1976 } catch (RemoteException e) {
1977 throw new RuntimeException("Package manager has died", e);
1978 }
1979 }
1980
1981 @Override
1982 public List<ResolveInfo> queryIntentActivityOptions(
1983 ComponentName caller, Intent[] specifics, Intent intent,
1984 int flags) {
1985 final ContentResolver resolver = mContext.getContentResolver();
1986
1987 String[] specificTypes = null;
1988 if (specifics != null) {
1989 final int N = specifics.length;
1990 for (int i=0; i<N; i++) {
1991 Intent sp = specifics[i];
1992 if (sp != null) {
1993 String t = sp.resolveTypeIfNeeded(resolver);
1994 if (t != null) {
1995 if (specificTypes == null) {
1996 specificTypes = new String[N];
1997 }
1998 specificTypes[i] = t;
1999 }
2000 }
2001 }
2002 }
2003
2004 try {
2005 return mPM.queryIntentActivityOptions(caller, specifics,
2006 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2007 flags);
2008 } catch (RemoteException e) {
2009 throw new RuntimeException("Package manager has died", e);
2010 }
2011 }
2012
2013 @Override
2014 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2015 try {
2016 return mPM.queryIntentReceivers(
2017 intent,
2018 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2019 flags);
2020 } catch (RemoteException e) {
2021 throw new RuntimeException("Package manager has died", e);
2022 }
2023 }
2024
2025 @Override
2026 public ResolveInfo resolveService(Intent intent, int flags) {
2027 try {
2028 return mPM.resolveService(
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> queryIntentServices(Intent intent, int flags) {
2039 try {
2040 return mPM.queryIntentServices(
2041 intent,
2042 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2043 flags);
2044 } catch (RemoteException e) {
2045 throw new RuntimeException("Package manager has died", e);
2046 }
2047 }
2048
2049 @Override
2050 public ProviderInfo resolveContentProvider(String name,
2051 int flags) {
2052 try {
2053 return mPM.resolveContentProvider(name, flags);
2054 } catch (RemoteException e) {
2055 throw new RuntimeException("Package manager has died", e);
2056 }
2057 }
2058
2059 @Override
2060 public List<ProviderInfo> queryContentProviders(String processName,
2061 int uid, int flags) {
2062 try {
2063 return mPM.queryContentProviders(processName, uid, flags);
2064 } catch (RemoteException e) {
2065 throw new RuntimeException("Package manager has died", e);
2066 }
2067 }
2068
2069 @Override
2070 public InstrumentationInfo getInstrumentationInfo(
2071 ComponentName className, int flags)
2072 throws NameNotFoundException {
2073 try {
2074 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2075 className, flags);
2076 if (ii != null) {
2077 return ii;
2078 }
2079 } catch (RemoteException e) {
2080 throw new RuntimeException("Package manager has died", e);
2081 }
2082
2083 throw new NameNotFoundException(className.toString());
2084 }
2085
2086 @Override
2087 public List<InstrumentationInfo> queryInstrumentation(
2088 String targetPackage, int flags) {
2089 try {
2090 return mPM.queryInstrumentation(targetPackage, flags);
2091 } catch (RemoteException e) {
2092 throw new RuntimeException("Package manager has died", e);
2093 }
2094 }
2095
2096 @Override public Drawable getDrawable(String packageName, int resid,
2097 ApplicationInfo appInfo) {
2098 ResourceName name = new ResourceName(packageName, resid);
2099 Drawable dr = getCachedIcon(name);
2100 if (dr != null) {
2101 return dr;
2102 }
2103 if (appInfo == null) {
2104 try {
2105 appInfo = getApplicationInfo(packageName, 0);
2106 } catch (NameNotFoundException e) {
2107 return null;
2108 }
2109 }
2110 try {
2111 Resources r = getResourcesForApplication(appInfo);
2112 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002113 if (false) {
2114 RuntimeException e = new RuntimeException("here");
2115 e.fillInStackTrace();
2116 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2117 + " from package " + packageName
2118 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2119 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2120 e);
2121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2123 + Integer.toHexString(resid) + " from " + r
2124 + ": " + dr);
2125 putCachedIcon(name, dr);
2126 return dr;
2127 } catch (NameNotFoundException e) {
2128 Log.w("PackageManager", "Failure retrieving resources for"
2129 + appInfo.packageName);
2130 } catch (RuntimeException e) {
2131 // If an exception was thrown, fall through to return
2132 // default icon.
2133 Log.w("PackageManager", "Failure retrieving icon 0x"
2134 + Integer.toHexString(resid) + " in package "
2135 + packageName, e);
2136 }
2137 return null;
2138 }
2139
2140 @Override public Drawable getActivityIcon(ComponentName activityName)
2141 throws NameNotFoundException {
2142 return getActivityInfo(activityName, 0).loadIcon(this);
2143 }
2144
2145 @Override public Drawable getActivityIcon(Intent intent)
2146 throws NameNotFoundException {
2147 if (intent.getComponent() != null) {
2148 return getActivityIcon(intent.getComponent());
2149 }
2150
2151 ResolveInfo info = resolveActivity(
2152 intent, PackageManager.MATCH_DEFAULT_ONLY);
2153 if (info != null) {
2154 return info.activityInfo.loadIcon(this);
2155 }
2156
2157 throw new NameNotFoundException(intent.toURI());
2158 }
2159
2160 @Override public Drawable getDefaultActivityIcon() {
2161 return Resources.getSystem().getDrawable(
2162 com.android.internal.R.drawable.sym_def_app_icon);
2163 }
2164
2165 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002166 return info.loadIcon(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 }
2168
2169 @Override public Drawable getApplicationIcon(String packageName)
2170 throws NameNotFoundException {
2171 return getApplicationIcon(getApplicationInfo(packageName, 0));
2172 }
2173
2174 @Override public Resources getResourcesForActivity(
2175 ComponentName activityName) throws NameNotFoundException {
2176 return getResourcesForApplication(
2177 getActivityInfo(activityName, 0).applicationInfo);
2178 }
2179
2180 @Override public Resources getResourcesForApplication(
2181 ApplicationInfo app) throws NameNotFoundException {
2182 if (app.packageName.equals("system")) {
2183 return mContext.mMainThread.getSystemContext().getResources();
2184 }
2185 Resources r = mContext.mMainThread.getTopLevelResources(
2186 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002187 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188 if (r != null) {
2189 return r;
2190 }
2191 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2192 }
2193
2194 @Override public Resources getResourcesForApplication(
2195 String appPackageName) throws NameNotFoundException {
2196 return getResourcesForApplication(
2197 getApplicationInfo(appPackageName, 0));
2198 }
2199
2200 int mCachedSafeMode = -1;
2201 @Override public boolean isSafeMode() {
2202 try {
2203 if (mCachedSafeMode < 0) {
2204 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2205 }
2206 return mCachedSafeMode != 0;
2207 } catch (RemoteException e) {
2208 throw new RuntimeException("Package manager has died", e);
2209 }
2210 }
2211
2212 static void configurationChanged() {
2213 synchronized (sSync) {
2214 sIconCache.clear();
2215 sStringCache.clear();
2216 }
2217 }
2218
Dianne Hackborn21556372010-02-04 16:34:40 -08002219 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002220 IPackageManager pm) {
2221 mContext = context;
2222 mPM = pm;
2223 }
2224
2225 private Drawable getCachedIcon(ResourceName name) {
2226 synchronized (sSync) {
2227 WeakReference<Drawable> wr = sIconCache.get(name);
2228 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2229 + name + ": " + wr);
2230 if (wr != null) { // we have the activity
2231 Drawable dr = wr.get();
2232 if (dr != null) {
2233 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2234 + name + ": " + dr);
2235 return dr;
2236 }
2237 // our entry has been purged
2238 sIconCache.remove(name);
2239 }
2240 }
2241 return null;
2242 }
2243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 private void putCachedIcon(ResourceName name, Drawable dr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 synchronized (sSync) {
2246 sIconCache.put(name, new WeakReference<Drawable>(dr));
2247 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2248 + name + ": " + dr);
2249 }
2250 }
2251
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002252 static final void handlePackageBroadcast(int cmd, String[] pkgList,
2253 boolean hasPkgInfo) {
2254 boolean immediateGc = false;
2255 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2256 immediateGc = true;
2257 }
2258 if (pkgList != null && (pkgList.length > 0)) {
2259 boolean needCleanup = false;
2260 for (String ssp : pkgList) {
2261 synchronized (sSync) {
2262 if (sIconCache.size() > 0) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002263 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2264 while (it.hasNext()) {
2265 ResourceName nm = it.next();
2266 if (nm.packageName.equals(ssp)) {
2267 //Log.i(TAG, "Removing cached drawable for " + nm);
2268 it.remove();
2269 needCleanup = true;
2270 }
2271 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002272 }
2273 if (sStringCache.size() > 0) {
2274 Iterator<ResourceName> it = sStringCache.keySet().iterator();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002275 while (it.hasNext()) {
2276 ResourceName nm = it.next();
2277 if (nm.packageName.equals(ssp)) {
2278 //Log.i(TAG, "Removing cached string for " + nm);
2279 it.remove();
2280 needCleanup = true;
2281 }
2282 }
2283 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002284 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002285 }
2286 if (needCleanup || hasPkgInfo) {
2287 if (immediateGc) {
2288 // Schedule an immediate gc.
2289 Runtime.getRuntime().gc();
2290 } else {
2291 ActivityThread.currentActivityThread().scheduleGcIdler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 }
2293 }
2294 }
2295 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 private static final class ResourceName {
2298 final String packageName;
2299 final int iconId;
2300
2301 ResourceName(String _packageName, int _iconId) {
2302 packageName = _packageName;
2303 iconId = _iconId;
2304 }
2305
2306 ResourceName(ApplicationInfo aInfo, int _iconId) {
2307 this(aInfo.packageName, _iconId);
2308 }
2309
2310 ResourceName(ComponentInfo cInfo, int _iconId) {
2311 this(cInfo.applicationInfo.packageName, _iconId);
2312 }
2313
2314 ResourceName(ResolveInfo rInfo, int _iconId) {
2315 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2316 }
2317
2318 @Override
2319 public boolean equals(Object o) {
2320 if (this == o) return true;
2321 if (o == null || getClass() != o.getClass()) return false;
2322
2323 ResourceName that = (ResourceName) o;
2324
2325 if (iconId != that.iconId) return false;
2326 return !(packageName != null ?
2327 !packageName.equals(that.packageName) : that.packageName != null);
2328
2329 }
2330
2331 @Override
2332 public int hashCode() {
2333 int result;
2334 result = packageName.hashCode();
2335 result = 31 * result + iconId;
2336 return result;
2337 }
2338
2339 @Override
2340 public String toString() {
2341 return "{ResourceName " + packageName + " / " + iconId + "}";
2342 }
2343 }
2344
2345 private CharSequence getCachedString(ResourceName name) {
2346 synchronized (sSync) {
2347 WeakReference<CharSequence> wr = sStringCache.get(name);
2348 if (wr != null) { // we have the activity
2349 CharSequence cs = wr.get();
2350 if (cs != null) {
2351 return cs;
2352 }
2353 // our entry has been purged
2354 sStringCache.remove(name);
2355 }
2356 }
2357 return null;
2358 }
2359
2360 private void putCachedString(ResourceName name, CharSequence cs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361 synchronized (sSync) {
2362 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2363 }
2364 }
2365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 @Override
2367 public CharSequence getText(String packageName, int resid,
2368 ApplicationInfo appInfo) {
2369 ResourceName name = new ResourceName(packageName, resid);
2370 CharSequence text = getCachedString(name);
2371 if (text != null) {
2372 return text;
2373 }
2374 if (appInfo == null) {
2375 try {
2376 appInfo = getApplicationInfo(packageName, 0);
2377 } catch (NameNotFoundException e) {
2378 return null;
2379 }
2380 }
2381 try {
2382 Resources r = getResourcesForApplication(appInfo);
2383 text = r.getText(resid);
2384 putCachedString(name, text);
2385 return text;
2386 } catch (NameNotFoundException e) {
2387 Log.w("PackageManager", "Failure retrieving resources for"
2388 + appInfo.packageName);
2389 } catch (RuntimeException e) {
2390 // If an exception was thrown, fall through to return
2391 // default icon.
2392 Log.w("PackageManager", "Failure retrieving text 0x"
2393 + Integer.toHexString(resid) + " in package "
2394 + packageName, e);
2395 }
2396 return null;
2397 }
2398
2399 @Override
2400 public XmlResourceParser getXml(String packageName, int resid,
2401 ApplicationInfo appInfo) {
2402 if (appInfo == null) {
2403 try {
2404 appInfo = getApplicationInfo(packageName, 0);
2405 } catch (NameNotFoundException e) {
2406 return null;
2407 }
2408 }
2409 try {
2410 Resources r = getResourcesForApplication(appInfo);
2411 return r.getXml(resid);
2412 } catch (RuntimeException e) {
2413 // If an exception was thrown, fall through to return
2414 // default icon.
2415 Log.w("PackageManager", "Failure retrieving xml 0x"
2416 + Integer.toHexString(resid) + " in package "
2417 + packageName, e);
2418 } catch (NameNotFoundException e) {
2419 Log.w("PackageManager", "Failure retrieving resources for"
2420 + appInfo.packageName);
2421 }
2422 return null;
2423 }
2424
2425 @Override
2426 public CharSequence getApplicationLabel(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002427 return info.loadLabel(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002428 }
2429
2430 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002431 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2432 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002434 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002435 } catch (RemoteException e) {
2436 // Should never happen!
2437 }
2438 }
2439
2440 @Override
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -08002441 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2442 try {
2443 mPM.movePackage(packageName, observer, flags);
2444 } catch (RemoteException e) {
2445 // Should never happen!
2446 }
2447 }
2448
2449 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002450 public String getInstallerPackageName(String packageName) {
2451 try {
2452 return mPM.getInstallerPackageName(packageName);
2453 } catch (RemoteException e) {
2454 // Should never happen!
2455 }
2456 return null;
2457 }
2458
2459 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2461 try {
2462 mPM.deletePackage(packageName, observer, flags);
2463 } catch (RemoteException e) {
2464 // Should never happen!
2465 }
2466 }
2467 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002468 public void clearApplicationUserData(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002469 IPackageDataObserver observer) {
2470 try {
2471 mPM.clearApplicationUserData(packageName, observer);
2472 } catch (RemoteException e) {
2473 // Should never happen!
2474 }
2475 }
2476 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002477 public void deleteApplicationCacheFiles(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 IPackageDataObserver observer) {
2479 try {
2480 mPM.deleteApplicationCacheFiles(packageName, observer);
2481 } catch (RemoteException e) {
2482 // Should never happen!
2483 }
2484 }
2485 @Override
2486 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2487 try {
2488 mPM.freeStorageAndNotify(idealStorageSize, observer);
2489 } catch (RemoteException e) {
2490 // Should never happen!
2491 }
2492 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002495 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002497 mPM.freeStorage(freeStorageSize, pi);
2498 } catch (RemoteException e) {
2499 // Should never happen!
2500 }
2501 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002504 public void getPackageSizeInfo(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002505 IPackageStatsObserver observer) {
2506 try {
2507 mPM.getPackageSizeInfo(packageName, observer);
2508 } catch (RemoteException e) {
2509 // Should never happen!
2510 }
2511 }
2512 @Override
2513 public void addPackageToPreferred(String packageName) {
2514 try {
2515 mPM.addPackageToPreferred(packageName);
2516 } catch (RemoteException e) {
2517 // Should never happen!
2518 }
2519 }
2520
2521 @Override
2522 public void removePackageFromPreferred(String packageName) {
2523 try {
2524 mPM.removePackageFromPreferred(packageName);
2525 } catch (RemoteException e) {
2526 // Should never happen!
2527 }
2528 }
2529
2530 @Override
2531 public List<PackageInfo> getPreferredPackages(int flags) {
2532 try {
2533 return mPM.getPreferredPackages(flags);
2534 } catch (RemoteException e) {
2535 // Should never happen!
2536 }
2537 return new ArrayList<PackageInfo>();
2538 }
2539
2540 @Override
2541 public void addPreferredActivity(IntentFilter filter,
2542 int match, ComponentName[] set, ComponentName activity) {
2543 try {
2544 mPM.addPreferredActivity(filter, match, set, activity);
2545 } catch (RemoteException e) {
2546 // Should never happen!
2547 }
2548 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002551 public void replacePreferredActivity(IntentFilter filter,
2552 int match, ComponentName[] set, ComponentName activity) {
2553 try {
2554 mPM.replacePreferredActivity(filter, match, set, activity);
2555 } catch (RemoteException e) {
2556 // Should never happen!
2557 }
2558 }
2559
2560 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 public void clearPackagePreferredActivities(String packageName) {
2562 try {
2563 mPM.clearPackagePreferredActivities(packageName);
2564 } catch (RemoteException e) {
2565 // Should never happen!
2566 }
2567 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 @Override
2570 public int getPreferredActivities(List<IntentFilter> outFilters,
2571 List<ComponentName> outActivities, String packageName) {
2572 try {
2573 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2574 } catch (RemoteException e) {
2575 // Should never happen!
2576 }
2577 return 0;
2578 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002580 @Override
2581 public void setComponentEnabledSetting(ComponentName componentName,
2582 int newState, int flags) {
2583 try {
2584 mPM.setComponentEnabledSetting(componentName, newState, flags);
2585 } catch (RemoteException e) {
2586 // Should never happen!
2587 }
2588 }
2589
2590 @Override
2591 public int getComponentEnabledSetting(ComponentName componentName) {
2592 try {
2593 return mPM.getComponentEnabledSetting(componentName);
2594 } catch (RemoteException e) {
2595 // Should never happen!
2596 }
2597 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2598 }
2599
2600 @Override
2601 public void setApplicationEnabledSetting(String packageName,
2602 int newState, int flags) {
2603 try {
2604 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2605 } catch (RemoteException e) {
2606 // Should never happen!
2607 }
2608 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002610 @Override
2611 public int getApplicationEnabledSetting(String packageName) {
2612 try {
2613 return mPM.getApplicationEnabledSetting(packageName);
2614 } catch (RemoteException e) {
2615 // Should never happen!
2616 }
2617 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2618 }
2619
Dianne Hackborn21556372010-02-04 16:34:40 -08002620 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 private final IPackageManager mPM;
2622
2623 private static final Object sSync = new Object();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002624 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2625 = new HashMap<ResourceName, WeakReference<Drawable> >();
2626 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2627 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2628 }
2629
2630 // ----------------------------------------------------------------------
2631 // ----------------------------------------------------------------------
2632 // ----------------------------------------------------------------------
2633
2634 private static final class SharedPreferencesImpl implements SharedPreferences {
2635
2636 private final File mFile;
2637 private final File mBackupFile;
2638 private final int mMode;
2639 private Map mMap;
2640 private final FileStatus mFileStatus = new FileStatus();
2641 private long mTimestamp;
2642
The Android Open Source Project10592532009-03-18 17:39:46 -07002643 private static final Object mContent = new Object();
2644 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645
2646 SharedPreferencesImpl(
2647 File file, int mode, Map initialContents) {
2648 mFile = file;
2649 mBackupFile = makeBackupFile(file);
2650 mMode = mode;
2651 mMap = initialContents != null ? initialContents : new HashMap();
2652 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2653 mTimestamp = mFileStatus.mtime;
2654 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002655 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 }
2657
2658 public boolean hasFileChanged() {
2659 synchronized (this) {
2660 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2661 return true;
2662 }
2663 return mTimestamp != mFileStatus.mtime;
2664 }
2665 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 public void replace(Map newContents) {
2668 if (newContents != null) {
2669 synchronized (this) {
2670 mMap = newContents;
2671 }
2672 }
2673 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2676 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002677 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 }
2679 }
2680
2681 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2682 synchronized(this) {
2683 mListeners.remove(listener);
2684 }
2685 }
2686
2687 public Map<String, ?> getAll() {
2688 synchronized(this) {
2689 //noinspection unchecked
2690 return new HashMap(mMap);
2691 }
2692 }
2693
2694 public String getString(String key, String defValue) {
2695 synchronized (this) {
2696 String v = (String)mMap.get(key);
2697 return v != null ? v : defValue;
2698 }
2699 }
2700
2701 public int getInt(String key, int defValue) {
2702 synchronized (this) {
2703 Integer v = (Integer)mMap.get(key);
2704 return v != null ? v : defValue;
2705 }
2706 }
2707 public long getLong(String key, long defValue) {
2708 synchronized (this) {
2709 Long v = (Long) mMap.get(key);
2710 return v != null ? v : defValue;
2711 }
2712 }
2713 public float getFloat(String key, float defValue) {
2714 synchronized (this) {
2715 Float v = (Float)mMap.get(key);
2716 return v != null ? v : defValue;
2717 }
2718 }
2719 public boolean getBoolean(String key, boolean defValue) {
2720 synchronized (this) {
2721 Boolean v = (Boolean)mMap.get(key);
2722 return v != null ? v : defValue;
2723 }
2724 }
2725
2726 public boolean contains(String key) {
2727 synchronized (this) {
2728 return mMap.containsKey(key);
2729 }
2730 }
2731
2732 public final class EditorImpl implements Editor {
2733 private final Map<String, Object> mModified = Maps.newHashMap();
2734 private boolean mClear = false;
2735
2736 public Editor putString(String key, String value) {
2737 synchronized (this) {
2738 mModified.put(key, value);
2739 return this;
2740 }
2741 }
2742 public Editor putInt(String key, int value) {
2743 synchronized (this) {
2744 mModified.put(key, value);
2745 return this;
2746 }
2747 }
2748 public Editor putLong(String key, long value) {
2749 synchronized (this) {
2750 mModified.put(key, value);
2751 return this;
2752 }
2753 }
2754 public Editor putFloat(String key, float value) {
2755 synchronized (this) {
2756 mModified.put(key, value);
2757 return this;
2758 }
2759 }
2760 public Editor putBoolean(String key, boolean value) {
2761 synchronized (this) {
2762 mModified.put(key, value);
2763 return this;
2764 }
2765 }
2766
2767 public Editor remove(String key) {
2768 synchronized (this) {
2769 mModified.put(key, this);
2770 return this;
2771 }
2772 }
2773
2774 public Editor clear() {
2775 synchronized (this) {
2776 mClear = true;
2777 return this;
2778 }
2779 }
2780
2781 public boolean commit() {
2782 boolean returnValue;
2783
2784 boolean hasListeners;
2785 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002786 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002787
2788 synchronized (SharedPreferencesImpl.this) {
2789 hasListeners = mListeners.size() > 0;
2790 if (hasListeners) {
2791 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002792 listeners =
2793 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002794 }
2795
2796 synchronized (this) {
2797 if (mClear) {
2798 mMap.clear();
2799 mClear = false;
2800 }
2801
The Android Open Source Project10592532009-03-18 17:39:46 -07002802 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 String k = e.getKey();
2804 Object v = e.getValue();
2805 if (v == this) {
2806 mMap.remove(k);
2807 } else {
2808 mMap.put(k, v);
2809 }
2810
2811 if (hasListeners) {
2812 keysModified.add(k);
2813 }
2814 }
2815
2816 mModified.clear();
2817 }
2818
2819 returnValue = writeFileLocked();
2820 }
2821
2822 if (hasListeners) {
2823 for (int i = keysModified.size() - 1; i >= 0; i--) {
2824 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002825 for (OnSharedPreferenceChangeListener listener : listeners) {
2826 if (listener != null) {
2827 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002829 }
2830 }
2831 }
2832
2833 return returnValue;
2834 }
2835 }
2836
2837 public Editor edit() {
2838 return new EditorImpl();
2839 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002841 private FileOutputStream createFileOutputStream(File file) {
2842 FileOutputStream str = null;
2843 try {
2844 str = new FileOutputStream(file);
2845 } catch (FileNotFoundException e) {
2846 File parent = file.getParentFile();
2847 if (!parent.mkdir()) {
2848 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2849 return null;
2850 }
2851 FileUtils.setPermissions(
2852 parent.getPath(),
2853 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2854 -1, -1);
2855 try {
2856 str = new FileOutputStream(file);
2857 } catch (FileNotFoundException e2) {
2858 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2859 }
2860 }
2861 return str;
2862 }
2863
2864 private boolean writeFileLocked() {
2865 // Rename the current file so it may be used as a backup during the next read
2866 if (mFile.exists()) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002867 if (!mBackupFile.exists()) {
2868 if (!mFile.renameTo(mBackupFile)) {
2869 Log.e(TAG, "Couldn't rename file " + mFile
2870 + " to backup file " + mBackupFile);
2871 return false;
2872 }
2873 } else {
2874 mFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 }
2876 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 // Attempt to write the file, delete the backup and return true as atomically as
2879 // possible. If any exception occurs, delete the new file; next time we will restore
2880 // from the backup.
2881 try {
2882 FileOutputStream str = createFileOutputStream(mFile);
2883 if (str == null) {
2884 return false;
2885 }
2886 XmlUtils.writeMapXml(mMap, str);
2887 str.close();
2888 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2889 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2890 mTimestamp = mFileStatus.mtime;
2891 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002892
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002893 // Writing was successful, delete the backup file if there is one.
2894 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002895 return true;
2896 } catch (XmlPullParserException e) {
2897 Log.w(TAG, "writeFileLocked: Got exception:", e);
2898 } catch (IOException e) {
2899 Log.w(TAG, "writeFileLocked: Got exception:", e);
2900 }
2901 // Clean up an unsuccessfully written file
2902 if (mFile.exists()) {
2903 if (!mFile.delete()) {
2904 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2905 }
2906 }
2907 return false;
2908 }
2909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910}