summaryrefslogtreecommitdiffstats
path: root/core/java/android/content/pm
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/content/pm')
-rwxr-xr-xcore/java/android/content/pm/ActivityInfo.aidl20
-rw-r--r--core/java/android/content/pm/ActivityInfo.java353
-rwxr-xr-xcore/java/android/content/pm/ApplicationInfo.aidl20
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java310
-rw-r--r--core/java/android/content/pm/ComponentInfo.java138
-rwxr-xr-xcore/java/android/content/pm/ConfigurationInfo.java119
-rwxr-xr-xcore/java/android/content/pm/IPackageDataObserver.aidl28
-rw-r--r--core/java/android/content/pm/IPackageDeleteObserver.aidl28
-rw-r--r--core/java/android/content/pm/IPackageInstallObserver.aidl27
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl269
-rwxr-xr-xcore/java/android/content/pm/IPackageStatsObserver.aidl30
-rwxr-xr-xcore/java/android/content/pm/InstrumentationInfo.aidl20
-rw-r--r--core/java/android/content/pm/InstrumentationInfo.java98
-rwxr-xr-xcore/java/android/content/pm/PackageInfo.aidl20
-rw-r--r--core/java/android/content/pm/PackageInfo.java199
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java191
-rw-r--r--core/java/android/content/pm/PackageManager.java1646
-rw-r--r--core/java/android/content/pm/PackageParser.java2352
-rwxr-xr-xcore/java/android/content/pm/PackageStats.aidl20
-rwxr-xr-xcore/java/android/content/pm/PackageStats.java63
-rwxr-xr-xcore/java/android/content/pm/PermissionGroupInfo.aidl20
-rw-r--r--core/java/android/content/pm/PermissionGroupInfo.java108
-rwxr-xr-xcore/java/android/content/pm/PermissionInfo.aidl20
-rw-r--r--core/java/android/content/pm/PermissionInfo.java156
-rwxr-xr-xcore/java/android/content/pm/ProviderInfo.aidl20
-rw-r--r--core/java/android/content/pm/ProviderInfo.java129
-rwxr-xr-xcore/java/android/content/pm/ResolveInfo.aidl20
-rw-r--r--core/java/android/content/pm/ResolveInfo.java280
-rwxr-xr-xcore/java/android/content/pm/ServiceInfo.aidl20
-rw-r--r--core/java/android/content/pm/ServiceInfo.java56
-rwxr-xr-xcore/java/android/content/pm/Signature.aidl20
-rw-r--r--core/java/android/content/pm/Signature.java158
-rw-r--r--core/java/android/content/pm/package.html7
33 files changed, 6965 insertions, 0 deletions
diff --git a/core/java/android/content/pm/ActivityInfo.aidl b/core/java/android/content/pm/ActivityInfo.aidl
new file mode 100755
index 0000000..dd90302
--- /dev/null
+++ b/core/java/android/content/pm/ActivityInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable ActivityInfo;
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
new file mode 100644
index 0000000..85d877a
--- /dev/null
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -0,0 +1,353 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Printer;
+
+/**
+ * Information you can retrieve about a particular application
+ * activity or receiver. This corresponds to information collected
+ * from the AndroidManifest.xml's <activity> and
+ * <receiver> tags.
+ */
+public class ActivityInfo extends ComponentInfo
+ implements Parcelable {
+ /**
+ * A style resource identifier (in the package's resources) of this
+ * activity's theme. From the "theme" attribute or, if not set, 0.
+ */
+ public int theme;
+
+ /**
+ * Constant corresponding to <code>standard</code> in
+ * the {@link android.R.attr#launchMode} attribute.
+ */
+ public static final int LAUNCH_MULTIPLE = 0;
+ /**
+ * Constant corresponding to <code>singleTop</code> in
+ * the {@link android.R.attr#launchMode} attribute.
+ */
+ public static final int LAUNCH_SINGLE_TOP = 1;
+ /**
+ * Constant corresponding to <code>singleTask</code> in
+ * the {@link android.R.attr#launchMode} attribute.
+ */
+ public static final int LAUNCH_SINGLE_TASK = 2;
+ /**
+ * Constant corresponding to <code>singleInstance</code> in
+ * the {@link android.R.attr#launchMode} attribute.
+ */
+ public static final int LAUNCH_SINGLE_INSTANCE = 3;
+ /**
+ * The launch mode style requested by the activity. From the
+ * {@link android.R.attr#launchMode} attribute, one of
+ * {@link #LAUNCH_MULTIPLE},
+ * {@link #LAUNCH_SINGLE_TOP}, {@link #LAUNCH_SINGLE_TASK}, or
+ * {@link #LAUNCH_SINGLE_INSTANCE}.
+ */
+ public int launchMode;
+
+ /**
+ * Optional name of a permission required to be able to access this
+ * Activity. From the "permission" attribute.
+ */
+ public String permission;
+
+ /**
+ * The affinity this activity has for another task in the system. The
+ * string here is the name of the task, often the package name of the
+ * overall package. If null, the activity has no affinity. Set from the
+ * {@link android.R.attr#taskAffinity} attribute.
+ */
+ public String taskAffinity;
+
+ /**
+ * If this is an activity alias, this is the real activity class to run
+ * for it. Otherwise, this is null.
+ */
+ public String targetActivity;
+
+ /**
+ * Bit in {@link #flags} indicating whether this activity is able to
+ * run in multiple processes. If
+ * true, the system may instantiate it in the some process as the
+ * process starting it in order to conserve resources. If false, the
+ * default, it always runs in {@link #processName}. Set from the
+ * {@link android.R.attr#multiprocess} attribute.
+ */
+ public static final int FLAG_MULTIPROCESS = 0x0001;
+ /**
+ * Bit in {@link #flags} indicating that, when the activity's task is
+ * relaunched from home, this activity should be finished.
+ * Set from the
+ * {@link android.R.attr#finishOnTaskLaunch} attribute.
+ */
+ public static final int FLAG_FINISH_ON_TASK_LAUNCH = 0x0002;
+ /**
+ * Bit in {@link #flags} indicating that, when the activity is the root
+ * of a task, that task's stack should be cleared each time the user
+ * re-launches it from home. As a result, the user will always
+ * return to the original activity at the top of the task.
+ * This flag only applies to activities that
+ * are used to start the root of a new task. Set from the
+ * {@link android.R.attr#clearTaskOnLaunch} attribute.
+ */
+ public static final int FLAG_CLEAR_TASK_ON_LAUNCH = 0x0004;
+ /**
+ * Bit in {@link #flags} indicating that, when the activity is the root
+ * of a task, that task's stack should never be cleared when it is
+ * relaunched from home. Set from the
+ * {@link android.R.attr#alwaysRetainTaskState} attribute.
+ */
+ public static final int FLAG_ALWAYS_RETAIN_TASK_STATE = 0x0008;
+ /**
+ * Bit in {@link #flags} indicating that the activity's state
+ * is not required to be saved, so that if there is a failure the
+ * activity will not be removed from the activity stack. Set from the
+ * {@link android.R.attr#stateNotNeeded} attribute.
+ */
+ public static final int FLAG_STATE_NOT_NEEDED = 0x0010;
+ /**
+ * Bit in {@link #flags} that indicates that the activity should not
+ * appear in the list of recently launched activities. Set from the
+ * {@link android.R.attr#excludeFromRecents} attribute.
+ */
+ public static final int FLAG_EXCLUDE_FROM_RECENTS = 0x0020;
+ /**
+ * Bit in {@link #flags} that indicates that the activity can be moved
+ * between tasks based on its task affinity. Set from the
+ * {@link android.R.attr#allowTaskReparenting} attribute.
+ */
+ public static final int FLAG_ALLOW_TASK_REPARENTING = 0x0040;
+ /**
+ * Bit in {@link #flags} indicating that, when the user navigates away
+ * from an activity, it should be finished.
+ * Set from the
+ * {@link android.R.attr#noHistory} attribute.
+ */
+ public static final int FLAG_NO_HISTORY = 0x0080;
+ /**
+ * Options that have been set in the activity declaration in the
+ * manifest: {@link #FLAG_MULTIPROCESS},
+ * {@link #FLAG_FINISH_ON_TASK_LAUNCH}, {@link #FLAG_CLEAR_TASK_ON_LAUNCH},
+ * {@link #FLAG_ALWAYS_RETAIN_TASK_STATE},
+ * {@link #FLAG_STATE_NOT_NEEDED}, {@link #FLAG_EXCLUDE_FROM_RECENTS},
+ * {@link #FLAG_ALLOW_TASK_REPARENTING}, {@link #FLAG_NO_HISTORY}.
+ */
+ public int flags;
+
+ /**
+ * Constant corresponding to <code>unspecified</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_UNSPECIFIED = -1;
+ /**
+ * Constant corresponding to <code>landscape</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_LANDSCAPE = 0;
+ /**
+ * Constant corresponding to <code>portrait</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_PORTRAIT = 1;
+ /**
+ * Constant corresponding to <code>user</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_USER = 2;
+ /**
+ * Constant corresponding to <code>behind</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_BEHIND = 3;
+ /**
+ * Constant corresponding to <code>sensor</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_SENSOR = 4;
+
+ /**
+ * Constant corresponding to <code>sensor</code> in
+ * the {@link android.R.attr#screenOrientation} attribute.
+ */
+ public static final int SCREEN_ORIENTATION_NOSENSOR = 5;
+ /**
+ * The preferred screen orientation this activity would like to run in.
+ * From the {@link android.R.attr#screenOrientation} attribute, one of
+ * {@link #SCREEN_ORIENTATION_UNSPECIFIED},
+ * {@link #SCREEN_ORIENTATION_LANDSCAPE},
+ * {@link #SCREEN_ORIENTATION_PORTRAIT},
+ * {@link #SCREEN_ORIENTATION_USER},
+ * {@link #SCREEN_ORIENTATION_BEHIND},
+ * {@link #SCREEN_ORIENTATION_SENSOR},
+ * {@link #SCREEN_ORIENTATION_NOSENSOR}.
+ */
+ public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the IMSI MCC. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_MCC = 0x0001;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the IMSI MNC. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_MNC = 0x0002;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the locale. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_LOCALE = 0x0004;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the touchscreen type. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_TOUCHSCREEN = 0x0008;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the keyboard type. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_KEYBOARD = 0x0010;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the keyboard being hidden/exposed.
+ * Set from the {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_KEYBOARD_HIDDEN = 0x0020;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the navigation type. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_NAVIGATION = 0x0040;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the screen orientation. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_ORIENTATION = 0x0080;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the font scaling factor. Set from the
+ * {@link android.R.attr#configChanges} attribute. This is
+ * not a core resource configutation, but a higher-level value, so its
+ * constant starts at the high bits.
+ */
+ public static final int CONFIG_FONT_SCALE = 0x40000000;
+
+ /**
+ * Bit mask of kinds of configuration changes that this activity
+ * can handle itself (without being restarted by the system).
+ * Contains any combination of {@link #CONFIG_FONT_SCALE},
+ * {@link #CONFIG_MCC}, {@link #CONFIG_MNC},
+ * {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN},
+ * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, and
+ * {@link #CONFIG_ORIENTATION}. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public int configChanges;
+
+ /**
+ * The desired soft input mode for this activity's main window.
+ * Set from the {@link android.R.attr#windowSoftInputMode} attribute
+ * in the activity's manifest. May be any of the same values allowed
+ * for {@link android.view.WindowManager.LayoutParams#softInputMode
+ * WindowManager.LayoutParams.softInputMode}. If 0 (unspecified),
+ * the mode from the theme will be used.
+ */
+ public int softInputMode;
+
+ public ActivityInfo() {
+ }
+
+ public ActivityInfo(ActivityInfo orig) {
+ super(orig);
+ theme = orig.theme;
+ launchMode = orig.launchMode;
+ permission = orig.permission;
+ taskAffinity = orig.taskAffinity;
+ targetActivity = orig.targetActivity;
+ flags = orig.flags;
+ screenOrientation = orig.screenOrientation;
+ configChanges = orig.configChanges;
+ softInputMode = orig.softInputMode;
+ }
+
+ /**
+ * Return the theme resource identifier to use for this activity. If
+ * the activity defines a theme, that is used; else, the application
+ * theme is used.
+ *
+ * @return The theme associated with this activity.
+ */
+ public final int getThemeResource() {
+ return theme != 0 ? theme : applicationInfo.theme;
+ }
+
+ public void dump(Printer pw, String prefix) {
+ super.dumpFront(pw, prefix);
+ pw.println(prefix + "permission=" + permission);
+ pw.println(prefix + "taskAffinity=" + taskAffinity
+ + " targetActivity=" + targetActivity);
+ pw.println(prefix + "launchMode=" + launchMode
+ + " flags=0x" + Integer.toHexString(flags)
+ + " theme=0x" + Integer.toHexString(theme));
+ pw.println(prefix + "screenOrientation=" + screenOrientation
+ + " configChanges=0x" + Integer.toHexString(configChanges)
+ + " softInputMode=0x" + Integer.toHexString(softInputMode));
+ super.dumpBack(pw, prefix);
+ }
+
+ public String toString() {
+ return "ActivityInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + name + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeInt(theme);
+ dest.writeInt(launchMode);
+ dest.writeString(permission);
+ dest.writeString(taskAffinity);
+ dest.writeString(targetActivity);
+ dest.writeInt(flags);
+ dest.writeInt(screenOrientation);
+ dest.writeInt(configChanges);
+ dest.writeInt(softInputMode);
+ }
+
+ public static final Parcelable.Creator<ActivityInfo> CREATOR
+ = new Parcelable.Creator<ActivityInfo>() {
+ public ActivityInfo createFromParcel(Parcel source) {
+ return new ActivityInfo(source);
+ }
+ public ActivityInfo[] newArray(int size) {
+ return new ActivityInfo[size];
+ }
+ };
+
+ private ActivityInfo(Parcel source) {
+ super(source);
+ theme = source.readInt();
+ launchMode = source.readInt();
+ permission = source.readString();
+ taskAffinity = source.readString();
+ targetActivity = source.readString();
+ flags = source.readInt();
+ screenOrientation = source.readInt();
+ configChanges = source.readInt();
+ softInputMode = source.readInt();
+ }
+}
diff --git a/core/java/android/content/pm/ApplicationInfo.aidl b/core/java/android/content/pm/ApplicationInfo.aidl
new file mode 100755
index 0000000..006d1bd
--- /dev/null
+++ b/core/java/android/content/pm/ApplicationInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable ApplicationInfo;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
new file mode 100644
index 0000000..8d727ed
--- /dev/null
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -0,0 +1,310 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Printer;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Information you can retrieve about a particular application. This
+ * corresponds to information collected from the AndroidManifest.xml's
+ * &lt;application&gt; tag.
+ */
+public class ApplicationInfo extends PackageItemInfo implements Parcelable {
+
+ /**
+ * Default task affinity of all activities in this application. See
+ * {@link ActivityInfo#taskAffinity} for more information. This comes
+ * from the "taskAffinity" attribute.
+ */
+ public String taskAffinity;
+
+ /**
+ * Optional name of a permission required to be able to access this
+ * application's components. From the "permission" attribute.
+ */
+ public String permission;
+
+ /**
+ * The name of the process this application should run in. From the
+ * "process" attribute or, if not set, the same as
+ * <var>packageName</var>.
+ */
+ public String processName;
+
+ /**
+ * Class implementing the Application object. From the "class"
+ * attribute.
+ */
+ public String className;
+
+ /**
+ * A style resource identifier (in the package's resources) of the
+ * description of an application. From the "description" attribute
+ * or, if not set, 0.
+ */
+ public int descriptionRes;
+
+ /**
+ * A style resource identifier (in the package's resources) of the
+ * default visual theme of the application. From the "theme" attribute
+ * or, if not set, 0.
+ */
+ public int theme;
+
+ /**
+ * Class implementing the Application's manage space
+ * functionality. From the "manageSpaceActivity"
+ * attribute. This is an optional attribute and will be null if
+ * application's dont specify it in their manifest
+ */
+ public String manageSpaceActivityName;
+
+ /**
+ * Value for {@link #flags}: if set, this application is installed in the
+ * device's system image.
+ */
+ public static final int FLAG_SYSTEM = 1<<0;
+
+ /**
+ * Value for {@link #flags}: set to true if this application would like to
+ * allow debugging of its
+ * code, even when installed on a non-development system. Comes
+ * from {@link android.R.styleable#AndroidManifestApplication_debuggable
+ * android:debuggable} of the &lt;application&gt; tag.
+ */
+ public static final int FLAG_DEBUGGABLE = 1<<1;
+
+ /**
+ * Value for {@link #flags}: set to true if this application has code
+ * associated with it. Comes
+ * from {@link android.R.styleable#AndroidManifestApplication_hasCode
+ * android:hasCode} of the &lt;application&gt; tag.
+ */
+ public static final int FLAG_HAS_CODE = 1<<2;
+
+ /**
+ * Value for {@link #flags}: set to true if this application is persistent.
+ * Comes from {@link android.R.styleable#AndroidManifestApplication_persistent
+ * android:persistent} of the &lt;application&gt; tag.
+ */
+ public static final int FLAG_PERSISTENT = 1<<3;
+
+ /**
+ * Value for {@link #flags}: set to true iif this application holds the
+ * {@link android.Manifest.permission#FACTORY_TEST} permission and the
+ * device is running in factory test mode.
+ */
+ public static final int FLAG_FACTORY_TEST = 1<<4;
+
+ /**
+ * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
+ * Comes from {@link android.R.styleable#AndroidManifestApplication_allowTaskReparenting
+ * android:allowTaskReparenting} of the &lt;application&gt; tag.
+ */
+ public static final int FLAG_ALLOW_TASK_REPARENTING = 1<<5;
+
+ /**
+ * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
+ * Comes from {@link android.R.styleable#AndroidManifestApplication_allowClearUserData
+ * android:allowClearUserData} of the &lt;application&gt; tag.
+ */
+ public static final int FLAG_ALLOW_CLEAR_USER_DATA = 1<<6;
+
+
+ /**
+ * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
+ * {@hide}
+ */
+ public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
+
+ /**
+ * Flags associated with the application. Any combination of
+ * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
+ * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
+ * {@link #FLAG_ALLOW_TASK_REPARENTING}
+ * {@link #FLAG_ALLOW_CLEAR_USER_DATA}.
+ */
+ public int flags = 0;
+
+ /**
+ * Full path to the location of this package.
+ */
+ public String sourceDir;
+
+ /**
+ * Full path to the location of the publicly available parts of this package (i.e. the resources
+ * and manifest). For non-forward-locked apps this will be the same as {@link #sourceDir).
+ */
+ public String publicSourceDir;
+
+ /**
+ * Paths to all shared libraries this application is linked against. This
+ * field is only set if the {@link PackageManager#GET_SHARED_LIBRARY_FILES
+ * PackageManager.GET_SHARED_LIBRARY_FILES} flag was used when retrieving
+ * the structure.
+ */
+ public String[] sharedLibraryFiles;
+
+ /**
+ * Full path to a directory assigned to the package for its persistent
+ * data.
+ */
+ public String dataDir;
+
+ /**
+ * The kernel user-ID that has been assigned to this application;
+ * currently this is not a unique ID (multiple applications can have
+ * the same uid).
+ */
+ public int uid;
+
+ /**
+ * When false, indicates that all components within this application are
+ * considered disabled, regardless of their individually set enabled status.
+ */
+ public boolean enabled = true;
+
+ public void dump(Printer pw, String prefix) {
+ super.dumpFront(pw, prefix);
+ pw.println(prefix + "className=" + className);
+ pw.println(prefix + "permission=" + permission
+ + " uid=" + uid);
+ pw.println(prefix + "taskAffinity=" + taskAffinity);
+ pw.println(prefix + "theme=0x" + Integer.toHexString(theme));
+ pw.println(prefix + "flags=0x" + Integer.toHexString(flags)
+ + " processName=" + processName);
+ pw.println(prefix + "sourceDir=" + sourceDir);
+ pw.println(prefix + "publicSourceDir=" + publicSourceDir);
+ pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
+ pw.println(prefix + "dataDir=" + dataDir);
+ pw.println(prefix + "enabled=" + enabled);
+ pw.println(prefix+"manageSpaceActivityName="+manageSpaceActivityName);
+ pw.println(prefix+"description=0x"+Integer.toHexString(descriptionRes));
+ super.dumpBack(pw, prefix);
+ }
+
+ public static class DisplayNameComparator
+ implements Comparator<ApplicationInfo> {
+ public DisplayNameComparator(PackageManager pm) {
+ mPM = pm;
+ }
+
+ public final int compare(ApplicationInfo aa, ApplicationInfo ab) {
+ CharSequence sa = mPM.getApplicationLabel(aa);
+ if (sa == null) {
+ sa = aa.packageName;
+ }
+ CharSequence sb = mPM.getApplicationLabel(ab);
+ if (sb == null) {
+ sb = ab.packageName;
+ }
+
+ return sCollator.compare(sa.toString(), sb.toString());
+ }
+
+ private final Collator sCollator = Collator.getInstance();
+ private PackageManager mPM;
+ }
+
+ public ApplicationInfo() {
+ }
+
+ public ApplicationInfo(ApplicationInfo orig) {
+ super(orig);
+ taskAffinity = orig.taskAffinity;
+ permission = orig.permission;
+ processName = orig.processName;
+ className = orig.className;
+ theme = orig.theme;
+ flags = orig.flags;
+ sourceDir = orig.sourceDir;
+ publicSourceDir = orig.publicSourceDir;
+ sharedLibraryFiles = orig.sharedLibraryFiles;
+ dataDir = orig.dataDir;
+ uid = orig.uid;
+ enabled = orig.enabled;
+ manageSpaceActivityName = orig.manageSpaceActivityName;
+ descriptionRes = orig.descriptionRes;
+ }
+
+
+ public String toString() {
+ return "ApplicationInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + packageName + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeString(taskAffinity);
+ dest.writeString(permission);
+ dest.writeString(processName);
+ dest.writeString(className);
+ dest.writeInt(theme);
+ dest.writeInt(flags);
+ dest.writeString(sourceDir);
+ dest.writeString(publicSourceDir);
+ dest.writeStringArray(sharedLibraryFiles);
+ dest.writeString(dataDir);
+ dest.writeInt(uid);
+ dest.writeInt(enabled ? 1 : 0);
+ dest.writeString(manageSpaceActivityName);
+ dest.writeInt(descriptionRes);
+ }
+
+ public static final Parcelable.Creator<ApplicationInfo> CREATOR
+ = new Parcelable.Creator<ApplicationInfo>() {
+ public ApplicationInfo createFromParcel(Parcel source) {
+ return new ApplicationInfo(source);
+ }
+ public ApplicationInfo[] newArray(int size) {
+ return new ApplicationInfo[size];
+ }
+ };
+
+ private ApplicationInfo(Parcel source) {
+ super(source);
+ taskAffinity = source.readString();
+ permission = source.readString();
+ processName = source.readString();
+ className = source.readString();
+ theme = source.readInt();
+ flags = source.readInt();
+ sourceDir = source.readString();
+ publicSourceDir = source.readString();
+ sharedLibraryFiles = source.readStringArray();
+ dataDir = source.readString();
+ uid = source.readInt();
+ enabled = source.readInt() != 0;
+ manageSpaceActivityName = source.readString();
+ descriptionRes = source.readInt();
+ }
+
+ /**
+ * Retrieve the textual description of the application. This
+ * will call back on the given PackageManager to load the description from
+ * the application.
+ *
+ * @param pm A PackageManager from which the label can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a CharSequence containing the application's description.
+ * If there is no description, null is returned.
+ */
+ public CharSequence loadDescription(PackageManager pm) {
+ if (descriptionRes != 0) {
+ CharSequence label = pm.getText(packageName, descriptionRes, null);
+ if (label != null) {
+ return label;
+ }
+ }
+ return null;
+ }
+}
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
new file mode 100644
index 0000000..73c9244
--- /dev/null
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -0,0 +1,138 @@
+package android.content.pm;
+
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.util.Printer;
+
+/**
+ * Base class containing information common to all application components
+ * ({@link ActivityInfo}, {@link ServiceInfo}). This class is not intended
+ * to be used by itself; it is simply here to share common definitions
+ * between all application components. As such, it does not itself
+ * implement Parcelable, but does provide convenience methods to assist
+ * in the implementation of Parcelable in subclasses.
+ */
+public class ComponentInfo extends PackageItemInfo {
+ /**
+ * Global information about the application/package this component is a
+ * part of.
+ */
+ public ApplicationInfo applicationInfo;
+
+ /**
+ * The name of the process this component should run in.
+ * From the "android:process" attribute or, if not set, the same
+ * as <var>applicationInfo.processName</var>.
+ */
+ public String processName;
+
+ /**
+ * Indicates whether or not this component may be instantiated. Note that this value can be
+ * overriden by the one in its parent {@link ApplicationInfo}.
+ */
+ public boolean enabled = true;
+
+ /**
+ * Set to true if this component is available for use by other applications.
+ * Comes from {@link android.R.attr#exported android:exported} of the
+ * &lt;activity&gt;, &lt;receiver&gt;, &lt;service&gt;, or
+ * &lt;provider&gt; tag.
+ */
+ public boolean exported = false;
+
+ public ComponentInfo() {
+ }
+
+ public ComponentInfo(ComponentInfo orig) {
+ super(orig);
+ applicationInfo = orig.applicationInfo;
+ processName = orig.processName;
+ enabled = orig.enabled;
+ exported = orig.exported;
+ }
+
+ @Override public CharSequence loadLabel(PackageManager pm) {
+ if (nonLocalizedLabel != null) {
+ return nonLocalizedLabel;
+ }
+ ApplicationInfo ai = applicationInfo;
+ CharSequence label;
+ if (labelRes != 0) {
+ label = pm.getText(packageName, labelRes, ai);
+ if (label != null) {
+ return label;
+ }
+ }
+ if (ai.nonLocalizedLabel != null) {
+ return ai.nonLocalizedLabel;
+ }
+ if (ai.labelRes != 0) {
+ label = pm.getText(packageName, ai.labelRes, ai);
+ if (label != null) {
+ return label;
+ }
+ }
+ return name;
+ }
+
+ @Override public Drawable loadIcon(PackageManager pm) {
+ ApplicationInfo ai = applicationInfo;
+ Drawable dr;
+ if (icon != 0) {
+ dr = pm.getDrawable(packageName, icon, ai);
+ if (dr != null) {
+ return dr;
+ }
+ }
+ if (ai.icon != 0) {
+ dr = pm.getDrawable(packageName, ai.icon, ai);
+ if (dr != null) {
+ return dr;
+ }
+ }
+ return pm.getDefaultActivityIcon();
+ }
+
+ /**
+ * Return the icon resource identifier to use for this component. If
+ * the component defines an icon, that is used; else, the application
+ * icon is used.
+ *
+ * @return The icon associated with this component.
+ */
+ public final int getIconResource() {
+ return icon != 0 ? icon : applicationInfo.icon;
+ }
+
+ protected void dumpFront(Printer pw, String prefix) {
+ super.dumpFront(pw, prefix);
+ pw.println(prefix + "enabled=" + enabled + " exported=" + exported
+ + " processName=" + processName);
+ }
+
+ protected void dumpBack(Printer pw, String prefix) {
+ if (applicationInfo != null) {
+ pw.println(prefix + "ApplicationInfo:");
+ applicationInfo.dump(pw, prefix + " ");
+ } else {
+ pw.println(prefix + "ApplicationInfo: null");
+ }
+ super.dumpBack(pw, prefix);
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ applicationInfo.writeToParcel(dest, parcelableFlags);
+ dest.writeString(processName);
+ dest.writeInt(enabled ? 1 : 0);
+ dest.writeInt(exported ? 1 : 0);
+ }
+
+ protected ComponentInfo(Parcel source) {
+ super(source);
+ applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source);
+ processName = source.readString();
+ enabled = (source.readInt() != 0);
+ exported = (source.readInt() != 0);
+ }
+}
diff --git a/core/java/android/content/pm/ConfigurationInfo.java b/core/java/android/content/pm/ConfigurationInfo.java
new file mode 100755
index 0000000..dcc7463
--- /dev/null
+++ b/core/java/android/content/pm/ConfigurationInfo.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information you can retrieve about hardware configuration preferences
+ * declared by an application. This corresponds to information collected from the
+ * AndroidManifest.xml's &lt;uses-configuration&gt; tags.
+ */
+public class ConfigurationInfo implements Parcelable {
+ /**
+ * The kind of touch screen attached to the device.
+ * One of: {@link android.content.res.Configuration#TOUCHSCREEN_NOTOUCH},
+ * {@link android.content.res.Configuration#TOUCHSCREEN_STYLUS},
+ * {@link android.content.res.Configuration#TOUCHSCREEN_FINGER}.
+ */
+ public int reqTouchScreen;
+
+ /**
+ * Application's input method preference.
+ * One of: {@link android.content.res.Configuration#KEYBOARD_UNDEFINED},
+ * {@link android.content.res.Configuration#KEYBOARD_NOKEYS},
+ * {@link android.content.res.Configuration#KEYBOARD_QWERTY},
+ * {@link android.content.res.Configuration#KEYBOARD_12KEY}
+ */
+ public int reqKeyboardType;
+
+ /**
+ * A flag indicating whether any keyboard is available.
+ * one of: {@link android.content.res.Configuration#NAVIGATION_UNDEFINED},
+ * {@link android.content.res.Configuration#NAVIGATION_DPAD},
+ * {@link android.content.res.Configuration#NAVIGATION_TRACKBALL},
+ * {@link android.content.res.Configuration#NAVIGATION_WHEEL}
+ */
+ public int reqNavigation;
+
+ /**
+ * Value for {@link #reqInputFeatures}: if set, indicates that the application
+ * requires a hard keyboard
+ */
+ public static final int INPUT_FEATURE_HARD_KEYBOARD = 0x00000001;
+
+ /**
+ * Value for {@link #reqInputFeatures}: if set, indicates that the application
+ * requires a five way navigation device
+ */
+ public static final int INPUT_FEATURE_FIVE_WAY_NAV = 0x00000002;
+
+ /**
+ * Flags associated with the input features. Any combination of
+ * {@link #INPUT_FEATURE_HARD_KEYBOARD},
+ * {@link #INPUT_FEATURE_FIVE_WAY_NAV}
+ */
+ public int reqInputFeatures = 0;
+
+ public ConfigurationInfo() {
+ }
+
+ public ConfigurationInfo(ConfigurationInfo orig) {
+ reqTouchScreen = orig.reqTouchScreen;
+ reqKeyboardType = orig.reqKeyboardType;
+ reqNavigation = orig.reqNavigation;
+ reqInputFeatures = orig.reqInputFeatures;
+ }
+
+ public String toString() {
+ return "ApplicationHardwarePreferences{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + ", touchscreen = " + reqTouchScreen + "}"
+ + ", inputMethod = " + reqKeyboardType + "}"
+ + ", navigation = " + reqNavigation + "}"
+ + ", reqInputFeatures = " + reqInputFeatures + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ dest.writeInt(reqTouchScreen);
+ dest.writeInt(reqKeyboardType);
+ dest.writeInt(reqNavigation);
+ dest.writeInt(reqInputFeatures);
+ }
+
+ public static final Creator<ConfigurationInfo> CREATOR =
+ new Creator<ConfigurationInfo>() {
+ public ConfigurationInfo createFromParcel(Parcel source) {
+ return new ConfigurationInfo(source);
+ }
+ public ConfigurationInfo[] newArray(int size) {
+ return new ConfigurationInfo[size];
+ }
+ };
+
+ private ConfigurationInfo(Parcel source) {
+ reqTouchScreen = source.readInt();
+ reqKeyboardType = source.readInt();
+ reqNavigation = source.readInt();
+ reqInputFeatures = source.readInt();
+ }
+}
diff --git a/core/java/android/content/pm/IPackageDataObserver.aidl b/core/java/android/content/pm/IPackageDataObserver.aidl
new file mode 100755
index 0000000..d010ee4
--- /dev/null
+++ b/core/java/android/content/pm/IPackageDataObserver.aidl
@@ -0,0 +1,28 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+/**
+ * API for package data change related callbacks from the Package Manager.
+ * Some usage scenarios include deletion of cache directory, generate
+ * statistics related to code, data, cache usage(TODO)
+ * {@hide}
+ */
+oneway interface IPackageDataObserver {
+ void onRemoveCompleted(in String packageName, boolean succeeded);
+}
diff --git a/core/java/android/content/pm/IPackageDeleteObserver.aidl b/core/java/android/content/pm/IPackageDeleteObserver.aidl
new file mode 100644
index 0000000..bc16b3e
--- /dev/null
+++ b/core/java/android/content/pm/IPackageDeleteObserver.aidl
@@ -0,0 +1,28 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+/**
+ * API for deletion callbacks from the Package Manager.
+ *
+ * {@hide}
+ */
+oneway interface IPackageDeleteObserver {
+ void packageDeleted(in boolean succeeded);
+}
+
diff --git a/core/java/android/content/pm/IPackageInstallObserver.aidl b/core/java/android/content/pm/IPackageInstallObserver.aidl
new file mode 100644
index 0000000..e83bbc6
--- /dev/null
+++ b/core/java/android/content/pm/IPackageInstallObserver.aidl
@@ -0,0 +1,27 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+/**
+ * API for installation callbacks from the Package Manager.
+ *
+ */
+oneway interface IPackageInstallObserver {
+ void packageInstalled(in String packageName, int returnCode);
+}
+
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
new file mode 100644
index 0000000..d3f6f3c
--- /dev/null
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -0,0 +1,269 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.net.Uri;
+import android.app.PendingIntent;
+
+/**
+ * See {@link PackageManager} for documentation on most of the APIs
+ * here.
+ *
+ * {@hide}
+ */
+interface IPackageManager {
+ PackageInfo getPackageInfo(String packageName, int flags);
+ int getPackageUid(String packageName);
+ int[] getPackageGids(String packageName);
+
+ PermissionInfo getPermissionInfo(String name, int flags);
+
+ List<PermissionInfo> queryPermissionsByGroup(String group, int flags);
+
+ PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
+
+ List<PermissionGroupInfo> getAllPermissionGroups(int flags);
+
+ ApplicationInfo getApplicationInfo(String packageName, int flags);
+
+ ActivityInfo getActivityInfo(in ComponentName className, int flags);
+
+ ActivityInfo getReceiverInfo(in ComponentName className, int flags);
+
+ ServiceInfo getServiceInfo(in ComponentName className, int flags);
+
+ int checkPermission(String permName, String pkgName);
+
+ int checkUidPermission(String permName, int uid);
+
+ boolean addPermission(in PermissionInfo info);
+
+ void removePermission(String name);
+
+ int checkSignatures(String pkg1, String pkg2);
+
+ String[] getPackagesForUid(int uid);
+
+ String getNameForUid(int uid);
+
+ int getUidForSharedUser(String sharedUserName);
+
+ ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags);
+
+ List<ResolveInfo> queryIntentActivities(in Intent intent,
+ String resolvedType, int flags);
+
+ List<ResolveInfo> queryIntentActivityOptions(
+ in ComponentName caller, in Intent[] specifics,
+ in String[] specificTypes, in Intent intent,
+ String resolvedType, int flags);
+
+ List<ResolveInfo> queryIntentReceivers(in Intent intent,
+ String resolvedType, int flags);
+
+ ResolveInfo resolveService(in Intent intent,
+ String resolvedType, int flags);
+
+ List<ResolveInfo> queryIntentServices(in Intent intent,
+ String resolvedType, int flags);
+
+ List<PackageInfo> getInstalledPackages(int flags);
+
+ List<ApplicationInfo> getInstalledApplications(int flags);
+
+ /**
+ * Retrieve all applications that are marked as persistent.
+ *
+ * @return A List&lt;applicationInfo> containing one entry for each persistent
+ * application.
+ */
+ List<ApplicationInfo> getPersistentApplications(int flags);
+
+ ProviderInfo resolveContentProvider(String name, int flags);
+
+ /**
+ * Retrieve sync information for all content providers.
+ *
+ * @param outNames Filled in with a list of the root names of the content
+ * providers that can sync.
+ * @param outInfo Filled in with a list of the ProviderInfo for each
+ * name in 'outNames'.
+ */
+ void querySyncProviders(inout List<String> outNames,
+ inout List<ProviderInfo> outInfo);
+
+ List<ProviderInfo> queryContentProviders(
+ String processName, int uid, int flags);
+
+ InstrumentationInfo getInstrumentationInfo(
+ in ComponentName className, int flags);
+
+ List<InstrumentationInfo> queryInstrumentation(
+ String targetPackage, int flags);
+
+ /**
+ * Install a package.
+ *
+ * @param packageURI The location of the package file to install.
+ * @param observer a callback to use to notify when the package installation in finished.
+ * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
+ * {@link #REPLACE_EXISITING_PACKAGE}
+ */
+ void installPackage(in Uri packageURI, IPackageInstallObserver observer, int flags);
+
+ /**
+ * Delete a package.
+ *
+ * @param packageName The fully qualified name of the package to delete.
+ * @param observer a callback to use to notify when the package deletion in finished.
+ * @param flags - possible values: {@link #DONT_DELETE_DATA}
+ */
+ void deletePackage(in String packageName, IPackageDeleteObserver observer, int flags);
+
+ void addPackageToPreferred(String packageName);
+
+ void removePackageFromPreferred(String packageName);
+
+ List<PackageInfo> getPreferredPackages(int flags);
+
+ void addPreferredActivity(in IntentFilter filter, int match,
+ in ComponentName[] set, in ComponentName activity);
+ void clearPackagePreferredActivities(String packageName);
+ int getPreferredActivities(out List<IntentFilter> outFilters,
+ out List<ComponentName> outActivities, String packageName);
+
+ /**
+ * As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}.
+ */
+ void setComponentEnabledSetting(in ComponentName componentName,
+ in int newState, in int flags);
+
+ /**
+ * As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}.
+ */
+ int getComponentEnabledSetting(in ComponentName componentName);
+
+ /**
+ * As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.
+ */
+ void setApplicationEnabledSetting(in String packageName, in int newState, int flags);
+
+ /**
+ * As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}.
+ */
+ int getApplicationEnabledSetting(in String packageName);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param observer call back used to notify when
+ * the operation is completed
+ */
+ void freeStorageAndNotify(in long freeStorageSize,
+ IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param opFinishedIntent PendingIntent call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ */
+ void freeStorage(in long freeStorageSize,
+ in PendingIntent opFinishedIntent);
+
+ /**
+ * Delete all the cache files in an applications cache directory
+ * @param packageName The package name of the application whose cache
+ * files need to be deleted
+ * @param observer a callback used to notify when the deletion is finished.
+ */
+ void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer);
+
+ /**
+ * Clear the user data directory of an application.
+ * @param packageName The package name of the application whose cache
+ * files need to be deleted
+ * @param observer a callback used to notify when the operation is completed.
+ */
+ void clearApplicationUserData(in String packageName, IPackageDataObserver observer);
+
+ /**
+ * Get package statistics including the code, data and cache size for
+ * an already installed package
+ * @param packageName The package name of the application
+ * @param observer a callback to use to notify when the asynchronous
+ * retrieval of information is complete.
+ */
+ void getPackageSizeInfo(in String packageName, IPackageStatsObserver observer);
+
+ /**
+ * Get a list of shared libraries that are available on the
+ * system.
+ */
+ String[] getSystemSharedLibraryNames();
+
+ void enterSafeMode();
+ boolean isSafeMode();
+ void systemReady();
+ boolean hasSystemUidErrors();
+}
diff --git a/core/java/android/content/pm/IPackageStatsObserver.aidl b/core/java/android/content/pm/IPackageStatsObserver.aidl
new file mode 100755
index 0000000..ede4d1d
--- /dev/null
+++ b/core/java/android/content/pm/IPackageStatsObserver.aidl
@@ -0,0 +1,30 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+import android.content.pm.PackageStats;
+/**
+ * API for package data change related callbacks from the Package Manager.
+ * Some usage scenarios include deletion of cache directory, generate
+ * statistics related to code, data, cache usage(TODO)
+ * {@hide}
+ */
+oneway interface IPackageStatsObserver {
+
+ void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
+}
diff --git a/core/java/android/content/pm/InstrumentationInfo.aidl b/core/java/android/content/pm/InstrumentationInfo.aidl
new file mode 100755
index 0000000..3d847ae
--- /dev/null
+++ b/core/java/android/content/pm/InstrumentationInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable InstrumentationInfo;
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
new file mode 100644
index 0000000..30ca002
--- /dev/null
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -0,0 +1,98 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Information you can retrieve about a particular piece of test
+ * instrumentation. This corresponds to information collected
+ * from the AndroidManifest.xml's &lt;instrumentation&gt; tag.
+ */
+public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
+ /**
+ * The name of the application package being instrumented. From the
+ * "package" attribute.
+ */
+ public String targetPackage;
+
+ /**
+ * Full path to the location of this package.
+ */
+ public String sourceDir;
+
+ /**
+ * Full path to the location of the publicly available parts of this package (i.e. the resources
+ * and manifest). For non-forward-locked apps this will be the same as {@link #sourceDir).
+ */
+ public String publicSourceDir;
+ /**
+ * Full path to a directory assigned to the package for its persistent
+ * data.
+ */
+ public String dataDir;
+
+ /**
+ * Specifies whether or not this instrumentation will handle profiling.
+ */
+ public boolean handleProfiling;
+
+ /** Specifies whether or not to run this instrumentation as a functional test */
+ public boolean functionalTest;
+
+ public InstrumentationInfo() {
+ }
+
+ public InstrumentationInfo(InstrumentationInfo orig) {
+ super(orig);
+ targetPackage = orig.targetPackage;
+ sourceDir = orig.sourceDir;
+ publicSourceDir = orig.publicSourceDir;
+ dataDir = orig.dataDir;
+ handleProfiling = orig.handleProfiling;
+ functionalTest = orig.functionalTest;
+ }
+
+ public String toString() {
+ return "InstrumentationInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + packageName + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeString(targetPackage);
+ dest.writeString(sourceDir);
+ dest.writeString(publicSourceDir);
+ dest.writeString(dataDir);
+ dest.writeInt((handleProfiling == false) ? 0 : 1);
+ dest.writeInt((functionalTest == false) ? 0 : 1);
+ }
+
+ public static final Parcelable.Creator<InstrumentationInfo> CREATOR
+ = new Parcelable.Creator<InstrumentationInfo>() {
+ public InstrumentationInfo createFromParcel(Parcel source) {
+ return new InstrumentationInfo(source);
+ }
+ public InstrumentationInfo[] newArray(int size) {
+ return new InstrumentationInfo[size];
+ }
+ };
+
+ private InstrumentationInfo(Parcel source) {
+ super(source);
+ targetPackage = source.readString();
+ sourceDir = source.readString();
+ publicSourceDir = source.readString();
+ dataDir = source.readString();
+ handleProfiling = source.readInt() != 0;
+ functionalTest = source.readInt() != 0;
+ }
+}
diff --git a/core/java/android/content/pm/PackageInfo.aidl b/core/java/android/content/pm/PackageInfo.aidl
new file mode 100755
index 0000000..35e2322
--- /dev/null
+++ b/core/java/android/content/pm/PackageInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable PackageInfo;
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
new file mode 100644
index 0000000..d9326f2
--- /dev/null
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -0,0 +1,199 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Overall information about the contents of a package. This corresponds
+ * to all of the information collected from AndroidManifest.xml.
+ */
+public class PackageInfo implements Parcelable {
+ /**
+ * The name of this package. From the &lt;manifest&gt; tag's "name"
+ * attribute.
+ */
+ public String packageName;
+
+ /**
+ * The version number of this package, as specified by the &lt;manifest&gt;
+ * tag's {@link android.R.styleable#AndroidManifest_versionCode versionCode}
+ * attribute.
+ */
+ public int versionCode;
+
+ /**
+ * The version name of this package, as specified by the &lt;manifest&gt;
+ * tag's {@link android.R.styleable#AndroidManifest_versionName versionName}
+ * attribute.
+ */
+ public String versionName;
+
+ /**
+ * The shared user ID name of this package, as specified by the &lt;manifest&gt;
+ * tag's {@link android.R.styleable#AndroidManifest_sharedUserId sharedUserId}
+ * attribute.
+ */
+ public String sharedUserId;
+
+ /**
+ * The shared user ID label of this package, as specified by the &lt;manifest&gt;
+ * tag's {@link android.R.styleable#AndroidManifest_sharedUserLabel sharedUserLabel}
+ * attribute.
+ */
+ public int sharedUserLabel;
+
+ /**
+ * Information collected from the &lt;application&gt; tag, or null if
+ * there was none.
+ */
+ public ApplicationInfo applicationInfo;
+
+ /**
+ * All kernel group-IDs that have been assigned to this package.
+ * This is only filled in if the flag {@link PackageManager#GET_GIDS} was set.
+ */
+ public int[] gids;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestActivity
+ * &lt;activity&gt;} tags included under &lt;application&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_ACTIVITIES} was set.
+ */
+ public ActivityInfo[] activities;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestReceiver
+ * &lt;receiver&gt;} tags included under &lt;application&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_RECEIVERS} was set.
+ */
+ public ActivityInfo[] receivers;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestService
+ * &lt;service&gt;} tags included under &lt;application&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_SERVICES} was set.
+ */
+ public ServiceInfo[] services;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestProvider
+ * &lt;provider&gt;} tags included under &lt;application&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_PROVIDERS} was set.
+ */
+ public ProviderInfo[] providers;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestInstrumentation
+ * &lt;instrumentation&gt;} tags included under &lt;manifest&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_INSTRUMENTATION} was set.
+ */
+ public InstrumentationInfo[] instrumentation;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestPermission
+ * &lt;permission&gt;} tags included under &lt;manifest&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_PERMISSIONS} was set.
+ */
+ public PermissionInfo[] permissions;
+
+ /**
+ * Array of all {@link android.R.styleable#AndroidManifestUsesPermission
+ * &lt;uses-permission&gt;} tags included under &lt;manifest&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_PERMISSIONS} was set. This list includes
+ * all permissions requested, even those that were not granted or known
+ * by the system at install time.
+ */
+ public String[] requestedPermissions;
+
+ /**
+ * Array of all signatures read from the package file. This is only filled
+ * in if the flag {@link PackageManager#GET_SIGNATURES} was set.
+ */
+ public Signature[] signatures;
+
+ /**
+ * Application specified preferred configuration
+ * {@link android.R.styleable#AndroidManifestUsesConfiguration
+ * &lt;uses-configuration&gt;} tags included under &lt;manifest&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_CONFIGURATIONS} was set.
+ */
+ public ConfigurationInfo[] configPreferences;
+
+ public PackageInfo() {
+ }
+
+ public String toString() {
+ return "PackageInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + packageName + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ dest.writeString(packageName);
+ dest.writeInt(versionCode);
+ dest.writeString(versionName);
+ dest.writeString(sharedUserId);
+ dest.writeInt(sharedUserLabel);
+ if (applicationInfo != null) {
+ dest.writeInt(1);
+ applicationInfo.writeToParcel(dest, parcelableFlags);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeIntArray(gids);
+ dest.writeTypedArray(activities, parcelableFlags);
+ dest.writeTypedArray(receivers, parcelableFlags);
+ dest.writeTypedArray(services, parcelableFlags);
+ dest.writeTypedArray(providers, parcelableFlags);
+ dest.writeTypedArray(instrumentation, parcelableFlags);
+ dest.writeTypedArray(permissions, parcelableFlags);
+ dest.writeStringArray(requestedPermissions);
+ dest.writeTypedArray(signatures, parcelableFlags);
+ dest.writeTypedArray(configPreferences, parcelableFlags);
+ }
+
+ public static final Parcelable.Creator<PackageInfo> CREATOR
+ = new Parcelable.Creator<PackageInfo>() {
+ public PackageInfo createFromParcel(Parcel source) {
+ return new PackageInfo(source);
+ }
+
+ public PackageInfo[] newArray(int size) {
+ return new PackageInfo[size];
+ }
+ };
+
+ private PackageInfo(Parcel source) {
+ packageName = source.readString();
+ versionCode = source.readInt();
+ versionName = source.readString();
+ sharedUserId = source.readString();
+ sharedUserLabel = source.readInt();
+ int hasApp = source.readInt();
+ if (hasApp != 0) {
+ applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source);
+ }
+ gids = source.createIntArray();
+ activities = source.createTypedArray(ActivityInfo.CREATOR);
+ receivers = source.createTypedArray(ActivityInfo.CREATOR);
+ services = source.createTypedArray(ServiceInfo.CREATOR);
+ providers = source.createTypedArray(ProviderInfo.CREATOR);
+ instrumentation = source.createTypedArray(InstrumentationInfo.CREATOR);
+ permissions = source.createTypedArray(PermissionInfo.CREATOR);
+ requestedPermissions = source.createStringArray();
+ signatures = source.createTypedArray(Signature.CREATOR);
+ configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
+ }
+}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
new file mode 100644
index 0000000..46e7ca4
--- /dev/null
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -0,0 +1,191 @@
+package android.content.pm;
+
+import android.content.res.XmlResourceParser;
+
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.text.TextUtils;
+import android.util.Printer;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Base class containing information common to all package items held by
+ * the package manager. This provides a very common basic set of attributes:
+ * a label, icon, and meta-data. This class is not intended
+ * to be used by itself; it is simply here to share common definitions
+ * between all items returned by the package manager. As such, it does not
+ * itself implement Parcelable, but does provide convenience methods to assist
+ * in the implementation of Parcelable in subclasses.
+ */
+public class PackageItemInfo {
+ /**
+ * Public name of this item. From the "android:name" attribute.
+ */
+ public String name;
+
+ /**
+ * Name of the package that this item is in.
+ */
+ public String packageName;
+
+ /**
+ * A string resource identifier (in the package's resources) of this
+ * component's label. From the "label" attribute or, if not set, 0.
+ */
+ public int labelRes;
+
+ /**
+ * The string provided in the AndroidManifest file, if any. You
+ * probably don't want to use this. You probably want
+ * {@link PackageManager#getApplicationLabel}
+ */
+ public CharSequence nonLocalizedLabel;
+
+ /**
+ * A drawable resource identifier (in the package's resources) of this
+ * component's icon. From the "icon" attribute or, if not set, 0.
+ */
+ public int icon;
+
+ /**
+ * Additional meta-data associated with this component. This field
+ * will only be filled in if you set the
+ * {@link PackageManager#GET_META_DATA} flag when requesting the info.
+ */
+ public Bundle metaData;
+
+ public PackageItemInfo() {
+ }
+
+ public PackageItemInfo(PackageItemInfo orig) {
+ name = orig.name;
+ packageName = orig.packageName;
+ labelRes = orig.labelRes;
+ nonLocalizedLabel = orig.nonLocalizedLabel;
+ icon = orig.icon;
+ metaData = orig.metaData;
+ }
+
+ /**
+ * Retrieve the current textual label associated with this item. This
+ * will call back on the given PackageManager to load the label from
+ * the application.
+ *
+ * @param pm A PackageManager from which the label can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a CharSequence containing the item's label. If the
+ * item does not have a label, its name is returned.
+ */
+ public CharSequence loadLabel(PackageManager pm) {
+ if (nonLocalizedLabel != null) {
+ return nonLocalizedLabel;
+ }
+ if (labelRes != 0) {
+ CharSequence label = pm.getText(packageName, labelRes, null);
+ if (label != null) {
+ return label;
+ }
+ }
+ if(name != null) {
+ return name;
+ }
+ return packageName;
+ }
+
+ /**
+ * Retrieve the current graphical icon associated with this item. This
+ * will call back on the given PackageManager to load the icon from
+ * the application.
+ *
+ * @param pm A PackageManager from which the icon can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the item's icon. If the
+ * item does not have an icon, the default activity icon is returned.
+ */
+ public Drawable loadIcon(PackageManager pm) {
+ if (icon != 0) {
+ Drawable dr = pm.getDrawable(packageName, icon, null);
+ if (dr != null) {
+ return dr;
+ }
+ }
+ return pm.getDefaultActivityIcon();
+ }
+
+ /**
+ * Load an XML resource attached to the meta-data of this item. This will
+ * retrieved the name meta-data entry, and if defined call back on the
+ * given PackageManager to load its XML file from the application.
+ *
+ * @param pm A PackageManager from which the XML can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ * @param name Name of the meta-date you would like to load.
+ *
+ * @return Returns an XmlPullParser you can use to parse the XML file
+ * assigned as the given meta-data. If the meta-data name is not defined
+ * or the XML resource could not be found, null is returned.
+ */
+ public XmlResourceParser loadXmlMetaData(PackageManager pm, String name) {
+ if (metaData != null) {
+ int resid = metaData.getInt(name);
+ if (resid != 0) {
+ return pm.getXml(packageName, resid, null);
+ }
+ }
+ return null;
+ }
+
+ protected void dumpFront(Printer pw, String prefix) {
+ pw.println(prefix + "name=" + name);
+ pw.println(prefix + "packageName=" + packageName);
+ pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
+ + " nonLocalizedLabel=" + nonLocalizedLabel
+ + " icon=0x" + Integer.toHexString(icon));
+ }
+
+ protected void dumpBack(Printer pw, String prefix) {
+ // no back here
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ dest.writeString(name);
+ dest.writeString(packageName);
+ dest.writeInt(labelRes);
+ TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
+ dest.writeInt(icon);
+ dest.writeBundle(metaData);
+ }
+
+ protected PackageItemInfo(Parcel source) {
+ name = source.readString();
+ packageName = source.readString();
+ labelRes = source.readInt();
+ nonLocalizedLabel
+ = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ icon = source.readInt();
+ metaData = source.readBundle();
+ }
+
+ public static class DisplayNameComparator
+ implements Comparator<PackageItemInfo> {
+ public DisplayNameComparator(PackageManager pm) {
+ mPM = pm;
+ }
+
+ public final int compare(PackageItemInfo aa, PackageItemInfo ab) {
+ CharSequence sa = aa.loadLabel(mPM);
+ if (sa == null) sa = aa.name;
+ CharSequence sb = ab.loadLabel(mPM);
+ if (sb == null) sb = ab.name;
+ return sCollator.compare(sa.toString(), sb.toString());
+ }
+
+ private final Collator sCollator = Collator.getInstance();
+ private PackageManager mPM;
+ }
+}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
new file mode 100644
index 0000000..7287d9c
--- /dev/null
+++ b/core/java/android/content/pm/PackageManager.java
@@ -0,0 +1,1646 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.util.AndroidException;
+import android.util.DisplayMetrics;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Class for retrieving various kinds of information related to the application
+ * packages that are currently installed on the device.
+ *
+ * You can find this class through {@link Context#getPackageManager}.
+ */
+public abstract class PackageManager {
+
+ /**
+ * This exception is thrown when a given package, application, or component
+ * name can not be found.
+ */
+ public static class NameNotFoundException extends AndroidException {
+ public NameNotFoundException() {
+ }
+
+ public NameNotFoundException(String name) {
+ super(name);
+ }
+ }
+
+ /**
+ * {@link PackageInfo} flag: return information about
+ * activities in the package in {@link PackageInfo#activities}.
+ */
+ public static final int GET_ACTIVITIES = 0x00000001;
+
+ /**
+ * {@link PackageInfo} flag: return information about
+ * intent receivers in the package in
+ * {@link PackageInfo#receivers}.
+ */
+ public static final int GET_RECEIVERS = 0x00000002;
+
+ /**
+ * {@link PackageInfo} flag: return information about
+ * services in the package in {@link PackageInfo#services}.
+ */
+ public static final int GET_SERVICES = 0x00000004;
+
+ /**
+ * {@link PackageInfo} flag: return information about
+ * content providers in the package in
+ * {@link PackageInfo#providers}.
+ */
+ public static final int GET_PROVIDERS = 0x00000008;
+
+ /**
+ * {@link PackageInfo} flag: return information about
+ * instrumentation in the package in
+ * {@link PackageInfo#instrumentation}.
+ */
+ public static final int GET_INSTRUMENTATION = 0x00000010;
+
+ /**
+ * {@link PackageInfo} flag: return information about the
+ * intent filters supported by the activity.
+ */
+ public static final int GET_INTENT_FILTERS = 0x00000020;
+
+ /**
+ * {@link PackageInfo} flag: return information about the
+ * signatures included in the package.
+ */
+ public static final int GET_SIGNATURES = 0x00000040;
+
+ /**
+ * {@link ResolveInfo} flag: return the IntentFilter that
+ * was matched for a particular ResolveInfo in
+ * {@link ResolveInfo#filter}.
+ */
+ public static final int GET_RESOLVED_FILTER = 0x00000040;
+
+ /**
+ * {@link ComponentInfo} flag: return the {@link ComponentInfo#metaData}
+ * data {@link android.os.Bundle}s that are associated with a component.
+ * This applies for any API returning a ComponentInfo subclass.
+ */
+ public static final int GET_META_DATA = 0x00000080;
+
+ /**
+ * {@link PackageInfo} flag: return the
+ * {@link PackageInfo#gids group ids} that are associated with an
+ * application.
+ * This applies for any API returning an PackageInfo class, either
+ * directly or nested inside of another.
+ */
+ public static final int GET_GIDS = 0x00000100;
+
+ /**
+ * {@link PackageInfo} flag: include disabled components in the returned info.
+ */
+ public static final int GET_DISABLED_COMPONENTS = 0x00000200;
+
+ /**
+ * {@link ApplicationInfo} flag: return the
+ * {@link ApplicationInfo#sharedLibraryFiles paths to the shared libraries}
+ * that are associated with an application.
+ * This applies for any API returning an ApplicationInfo class, either
+ * directly or nested inside of another.
+ */
+ public static final int GET_SHARED_LIBRARY_FILES = 0x00000400;
+
+ /**
+ * {@link ProviderInfo} flag: return the
+ * {@link ProviderInfo#uriPermissionPatterns URI permission patterns}
+ * that are associated with a content provider.
+ * This applies for any API returning an ProviderInfo class, either
+ * directly or nested inside of another.
+ */
+ public static final int GET_URI_PERMISSION_PATTERNS = 0x00000800;
+ /**
+ * {@link PackageInfo} flag: return information about
+ * permissions in the package in
+ * {@link PackageInfo#permissions}.
+ */
+ public static final int GET_PERMISSIONS = 0x00001000;
+
+ /**
+ * Flag parameter to retrieve all applications(even uninstalled ones) with data directories.
+ * This state could have resulted if applications have been deleted with flag
+ * DONT_DELETE_DATA
+ * with a possibility of being replaced or reinstalled in future
+ */
+ public static final int GET_UNINSTALLED_PACKAGES = 0x00002000;
+
+ /**
+ * {@link PackageInfo} flag: return information about
+ * hardware preferences
+ * {@link PackageInfo#configPreferences}
+ */
+ public static final int GET_CONFIGURATIONS = 0x00004000;
+
+ /**
+ * Permission check result: this is returned by {@link #checkPermission}
+ * if the permission has been granted to the given package.
+ */
+ public static final int PERMISSION_GRANTED = 0;
+
+ /**
+ * Permission check result: this is returned by {@link #checkPermission}
+ * if the permission has not been granted to the given package.
+ */
+ public static final int PERMISSION_DENIED = -1;
+
+ /**
+ * Signature check result: this is returned by {@link #checkSignatures}
+ * if the two packages have a matching signature.
+ */
+ public static final int SIGNATURE_MATCH = 0;
+
+ /**
+ * Signature check result: this is returned by {@link #checkSignatures}
+ * if neither of the two packages is signed.
+ */
+ public static final int SIGNATURE_NEITHER_SIGNED = 1;
+
+ /**
+ * Signature check result: this is returned by {@link #checkSignatures}
+ * if the first package is not signed, but the second is.
+ */
+ public static final int SIGNATURE_FIRST_NOT_SIGNED = -1;
+
+ /**
+ * Signature check result: this is returned by {@link #checkSignatures}
+ * if the second package is not signed, but the first is.
+ */
+ public static final int SIGNATURE_SECOND_NOT_SIGNED = -2;
+
+ /**
+ * Signature check result: this is returned by {@link #checkSignatures}
+ * if both packages are signed but there is no matching signature.
+ */
+ public static final int SIGNATURE_NO_MATCH = -3;
+
+ /**
+ * Signature check result: this is returned by {@link #checkSignatures}
+ * if either of the given package names are not valid.
+ */
+ public static final int SIGNATURE_UNKNOWN_PACKAGE = -4;
+
+ /**
+ * Resolution and querying flag: if set, only filters that support the
+ * {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for
+ * matching. This is a synonym for including the CATEGORY_DEFAULT in your
+ * supplied Intent.
+ */
+ public static final int MATCH_DEFAULT_ONLY = 0x00010000;
+
+ public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;
+ public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;
+ public static final int COMPONENT_ENABLED_STATE_DISABLED = 2;
+
+ /**
+ * Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to
+ * indicate that this package should be installed as forward locked, i.e. only the app itself
+ * should have access to it's code and non-resource assets.
+ */
+ public static final int FORWARD_LOCK_PACKAGE = 0x00000001;
+
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that you want to replace an already
+ * installed package, if one exists
+ */
+ public static final int REPLACE_EXISTING_PACKAGE = 0x00000002;
+
+ /**
+ * Flag parameter for
+ * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
+ * that you don't want to kill the app containing the component. Be careful when you set this
+ * since changing component states can make the containing application's behavior unpredictable.
+ */
+ public static final int DONT_KILL_APP = 0x00000001;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success.
+ */
+ public static final int INSTALL_SUCCEEDED = 1;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package is
+ * already installed.
+ */
+ public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package archive
+ * file is invalid.
+ */
+ public static final int INSTALL_FAILED_INVALID_APK = -2;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the URI passed in
+ * is invalid.
+ */
+ public static final int INSTALL_FAILED_INVALID_URI = -3;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package manager
+ * service found that the device didn't have enough storage space to install the app
+ */
+ public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if a
+ * package is already installed with the same name.
+ */
+ public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the requested shared user does not exist.
+ */
+ public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * a previously installed package of the same name has a different signature
+ * than the new package (and the old package's data was not removed).
+ */
+ public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package is requested a shared user which is already installed on the
+ * device and does not have matching signature.
+ */
+ public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package uses a shared library that is not available.
+ */
+ public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package uses a shared library that is not available.
+ */
+ public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package failed while optimizing and validating its dex files,
+ * either because there was not enough storage or the validation failed.
+ */
+ public static final int INSTALL_FAILED_DEXOPT = -11;
+
+ /**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the new package failed because the current SDK version is older than
+ * that required by the package.
+ */
+ public static final int INSTALL_FAILED_OLDER_SDK = -12;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser was given a path that is not a file, or does not end with the expected
+ * '.apk' extension.
+ */
+ public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser was unable to retrieve the AndroidManifest.xml file.
+ */
+ public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser encountered an unexpected exception.
+ */
+ public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser did not find any certificates in the .apk.
+ */
+ public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser found inconsistent certificates on the files in the .apk.
+ */
+ public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser encountered a CertificateEncodingException in one of the
+ * files in the .apk.
+ */
+ public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser encountered a bad or missing package name in the manifest.
+ */
+ public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser encountered a bad shared user id name in the manifest.
+ */
+ public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser encountered some structural problem in the manifest.
+ */
+ public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
+
+ /**
+ * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the parser did not find any actionable tags (instrumentation or application)
+ * in the manifest.
+ */
+ public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
+
+ /**
+ * Indicates the state of installation. Used by PackageManager to
+ * figure out incomplete installations. Say a package is being installed
+ * (the state is set to PKG_INSTALL_INCOMPLETE) and remains so till
+ * the package installation is successful or unsuccesful lin which case
+ * the PackageManager will no longer maintain state information associated
+ * with the package. If some exception(like device freeze or battery being
+ * pulled out) occurs during installation of a package, the PackageManager
+ * needs this information to clean up the previously failed installation.
+ */
+ public static final int PKG_INSTALL_INCOMPLETE = 0;
+ public static final int PKG_INSTALL_COMPLETE = 1;
+
+ /**
+ * Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
+ * package's data directory.
+ *
+ * @hide
+ */
+ public static final int DONT_DELETE_DATA = 0x00000001;
+
+ /**
+ * Retrieve overall information about an application package that is
+ * installed on the system.
+ *
+ * <p>Throws {@link NameNotFoundException} if a package with the given
+ * name can not be found on the system.
+ *
+ * @param packageName The full name (i.e. com.google.apps.contacts) of the
+ * desired package.
+
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_ACTIVITIES},
+ * {@link #GET_GIDS},
+ * {@link #GET_CONFIGURATIONS},
+ * {@link #GET_INSTRUMENTATION},
+ * {@link #GET_PERMISSIONS},
+ * {@link #GET_PROVIDERS},
+ * {@link #GET_RECEIVERS},
+ * {@link #GET_SERVICES},
+ * {@link #GET_SIGNATURES},
+ * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
+ *
+ * @return Returns a PackageInfo object containing information about the package.
+ * If flag GET_UNINSTALLED_PACKAGES is set and if the package is not
+ * found in the list of installed applications, the package information is
+ * retrieved from the list of uninstalled applications(which includes
+ * installed applications as well as applications
+ * with data directory ie applications which had been
+ * deleted with DONT_DELTE_DATA flag set).
+ *
+ * @see #GET_ACTIVITIES
+ * @see #GET_GIDS
+ * @see #GET_CONFIGURATIONS
+ * @see #GET_INSTRUMENTATION
+ * @see #GET_PERMISSIONS
+ * @see #GET_PROVIDERS
+ * @see #GET_RECEIVERS
+ * @see #GET_SERVICES
+ * @see #GET_SIGNATURES
+ * @see #GET_UNINSTALLED_PACKAGES
+ *
+ */
+ public abstract PackageInfo getPackageInfo(String packageName, int flags)
+ throws NameNotFoundException;
+
+ /**
+ * Return a "good" intent to launch a front-door activity in a package,
+ * for use for example to implement an "open" button when browsing through
+ * packages. The current implementation will look first for a main
+ * activity in the category {@link Intent#CATEGORY_INFO}, next for a
+ * main activity in the category {@link Intent#CATEGORY_LAUNCHER}, or return
+ * null if neither are found.
+ *
+ * <p>Throws {@link NameNotFoundException} if a package with the given
+ * name can not be found on the system.
+ *
+ * @param packageName The name of the package to inspect.
+ *
+ * @return Returns either a fully-qualified Intent that can be used to
+ * launch the main activity in the package, or null if the package does
+ * not contain such an activity.
+ */
+ public abstract Intent getLaunchIntentForPackage(String packageName)
+ throws NameNotFoundException;
+
+ /**
+ * Return an array of all of the secondary group-ids that have been
+ * assigned to a package.
+ *
+ * <p>Throws {@link NameNotFoundException} if a package with the given
+ * name can not be found on the system.
+ *
+ * @param packageName The full name (i.e. com.google.apps.contacts) of the
+ * desired package.
+ *
+ * @return Returns an int array of the assigned gids, or null if there
+ * are none.
+ */
+ public abstract int[] getPackageGids(String packageName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve all of the information we know about a particular permission.
+ *
+ * <p>Throws {@link NameNotFoundException} if a permission with the given
+ * name can not be found on the system.
+ *
+ * @param name The fully qualified name (i.e. com.google.permission.LOGIN)
+ * of the permission you are interested in.
+ * @param flags Additional option flags. Use {@link #GET_META_DATA} to
+ * retrieve any meta-data associated with the permission.
+ *
+ * @return Returns a {@link PermissionInfo} containing information about the
+ * permission.
+ */
+ public abstract PermissionInfo getPermissionInfo(String name, int flags)
+ throws NameNotFoundException;
+
+ /**
+ * Query for all of the permissions associated with a particular group.
+ *
+ * <p>Throws {@link NameNotFoundException} if the given group does not
+ * exist.
+ *
+ * @param group The fully qualified name (i.e. com.google.permission.LOGIN)
+ * of the permission group you are interested in. Use null to
+ * find all of the permissions not associated with a group.
+ * @param flags Additional option flags. Use {@link #GET_META_DATA} to
+ * retrieve any meta-data associated with the permissions.
+ *
+ * @return Returns a list of {@link PermissionInfo} containing information
+ * about all of the permissions in the given group.
+ */
+ public abstract List<PermissionInfo> queryPermissionsByGroup(String group,
+ int flags) throws NameNotFoundException;
+
+ /**
+ * Retrieve all of the information we know about a particular group of
+ * permissions.
+ *
+ * <p>Throws {@link NameNotFoundException} if a permission group with the given
+ * name can not be found on the system.
+ *
+ * @param name The fully qualified name (i.e. com.google.permission_group.APPS)
+ * of the permission you are interested in.
+ * @param flags Additional option flags. Use {@link #GET_META_DATA} to
+ * retrieve any meta-data associated with the permission group.
+ *
+ * @return Returns a {@link PermissionGroupInfo} containing information
+ * about the permission.
+ */
+ public abstract PermissionGroupInfo getPermissionGroupInfo(String name,
+ int flags) throws NameNotFoundException;
+
+ /**
+ * Retrieve all of the known permission groups in the system.
+ *
+ * @param flags Additional option flags. Use {@link #GET_META_DATA} to
+ * retrieve any meta-data associated with the permission group.
+ *
+ * @return Returns a list of {@link PermissionGroupInfo} containing
+ * information about all of the known permission groups.
+ */
+ public abstract List<PermissionGroupInfo> getAllPermissionGroups(int flags);
+
+ /**
+ * Retrieve all of the information we know about a particular
+ * package/application.
+ *
+ * <p>Throws {@link NameNotFoundException} if an application with the given
+ * package name can not be found on the system.
+ *
+ * @param packageName The full name (i.e. com.google.apps.contacts) of an
+ * application.
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
+ *
+ * @return {@link ApplicationInfo} Returns ApplicationInfo object containing
+ * information about the package.
+ * If flag GET_UNINSTALLED_PACKAGES is set and if the package is not
+ * found in the list of installed applications,
+ * the application information is retrieved from the
+ * list of uninstalled applications(which includes
+ * installed applications as well as applications
+ * with data directory ie applications which had been
+ * deleted with DONT_DELTE_DATA flag set).
+ *
+ * @see #GET_META_DATA
+ * @see #GET_SHARED_LIBRARY_FILES
+ * @see #GET_UNINSTALLED_PACKAGES
+ */
+ public abstract ApplicationInfo getApplicationInfo(String packageName,
+ int flags) throws NameNotFoundException;
+
+ /**
+ * Retrieve all of the information we know about a particular activity
+ * class.
+ *
+ * <p>Throws {@link NameNotFoundException} if an activity with the given
+ * class name can not be found on the system.
+ *
+ * @param className The full name (i.e.
+ * com.google.apps.contacts.ContactsList) of an Activity
+ * class.
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * to modify the data (in ApplicationInfo) returned.
+ *
+ * @return {@link ActivityInfo} containing information about the activity.
+ *
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_META_DATA
+ * @see #GET_SHARED_LIBRARY_FILES
+ */
+ public abstract ActivityInfo getActivityInfo(ComponentName className,
+ int flags) throws NameNotFoundException;
+
+ /**
+ * Retrieve all of the information we know about a particular receiver
+ * class.
+ *
+ * <p>Throws {@link NameNotFoundException} if a receiver with the given
+ * class name can not be found on the system.
+ *
+ * @param className The full name (i.e.
+ * com.google.apps.contacts.CalendarAlarm) of a Receiver
+ * class.
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * to modify the data returned.
+ *
+ * @return {@link ActivityInfo} containing information about the receiver.
+ *
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_META_DATA
+ * @see #GET_SHARED_LIBRARY_FILES
+ */
+ public abstract ActivityInfo getReceiverInfo(ComponentName className,
+ int flags) throws NameNotFoundException;
+
+ /**
+ * Retrieve all of the information we know about a particular service
+ * class.
+ *
+ * <p>Throws {@link NameNotFoundException} if a service with the given
+ * class name can not be found on the system.
+ *
+ * @param className The full name (i.e.
+ * com.google.apps.media.BackgroundPlayback) of a Service
+ * class.
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * to modify the data returned.
+ *
+ * @return ServiceInfo containing information about the service.
+ *
+ * @see #GET_META_DATA
+ * @see #GET_SHARED_LIBRARY_FILES
+ */
+ public abstract ServiceInfo getServiceInfo(ComponentName className,
+ int flags) throws NameNotFoundException;
+
+ /**
+ * Return a List of all packages that are installed
+ * on the device.
+ *
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_ACTIVITIES},
+ * {@link #GET_GIDS},
+ * {@link #GET_CONFIGURATIONS},
+ * {@link #GET_INSTRUMENTATION},
+ * {@link #GET_PERMISSIONS},
+ * {@link #GET_PROVIDERS},
+ * {@link #GET_RECEIVERS},
+ * {@link #GET_SERVICES},
+ * {@link #GET_SIGNATURES},
+ * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
+ *
+ * @return A List of PackageInfo objects, one for each package that is
+ * installed on the device. In the unlikely case of there being no
+ * installed packages, an empty list is returned.
+ * If flag GET_UNINSTALLED_PACKAGES is set, a list of all
+ * applications including those deleted with DONT_DELETE_DATA
+ * (partially installed apps with data directory) will be returned.
+ *
+ * @see #GET_ACTIVITIES
+ * @see #GET_GIDS
+ * @see #GET_CONFIGURATIONS
+ * @see #GET_INSTRUMENTATION
+ * @see #GET_PERMISSIONS
+ * @see #GET_PROVIDERS
+ * @see #GET_RECEIVERS
+ * @see #GET_SERVICES
+ * @see #GET_SIGNATURES
+ * @see #GET_UNINSTALLED_PACKAGES
+ *
+ */
+ public abstract List<PackageInfo> getInstalledPackages(int flags);
+
+ /**
+ * Check whether a particular package has been granted a particular
+ * permission.
+ *
+ * @param permName The name of the permission you are checking for,
+ * @param pkgName The name of the package you are checking against.
+ *
+ * @return If the package has the permission, PERMISSION_GRANTED is
+ * returned. If it does not have the permission, PERMISSION_DENIED
+ * is returned.
+ *
+ * @see #PERMISSION_GRANTED
+ * @see #PERMISSION_DENIED
+ */
+ public abstract int checkPermission(String permName, String pkgName);
+
+ /**
+ * Add a new dynamic permission to the system. For this to work, your
+ * package must have defined a permission tree through the
+ * {@link android.R.styleable#AndroidManifestPermissionTree
+ * &lt;permission-tree&gt;} tag in its manifest. A package can only add
+ * permissions to trees that were defined by either its own package or
+ * another with the same user id; a permission is in a tree if it
+ * matches the name of the permission tree + ".": for example,
+ * "com.foo.bar" is a member of the permission tree "com.foo".
+ *
+ * <p>It is good to make your permission tree name descriptive, because you
+ * are taking possession of that entire set of permission names. Thus, it
+ * must be under a domain you control, with a suffix that will not match
+ * any normal permissions that may be declared in any applications that
+ * are part of that domain.
+ *
+ * <p>New permissions must be added before
+ * any .apks are installed that use those permissions. Permissions you
+ * add through this method are remembered across reboots of the device.
+ * If the given permission already exists, the info you supply here
+ * will be used to update it.
+ *
+ * @param info Description of the permission to be added.
+ *
+ * @return Returns true if a new permission was created, false if an
+ * existing one was updated.
+ *
+ * @throws SecurityException if you are not allowed to add the
+ * given permission name.
+ *
+ * @see #removePermission(String)
+ */
+ public abstract boolean addPermission(PermissionInfo info);
+
+ /**
+ * Removes a permission that was previously added with
+ * {@link #addPermission(PermissionInfo)}. The same ownership rules apply
+ * -- you are only allowed to remove permissions that you are allowed
+ * to add.
+ *
+ * @param name The name of the permission to remove.
+ *
+ * @throws SecurityException if you are not allowed to remove the
+ * given permission name.
+ *
+ * @see #addPermission(PermissionInfo)
+ */
+ public abstract void removePermission(String name);
+
+ /**
+ * Compare the signatures of two packages to determine if the same
+ * signature appears in both of them. If they do contain the same
+ * signature, then they are allowed special privileges when working
+ * with each other: they can share the same user-id, run instrumentation
+ * against each other, etc.
+ *
+ * @param pkg1 First package name whose signature will be compared.
+ * @param pkg2 Second package name whose signature will be compared.
+ * @return Returns an integer indicating whether there is a matching
+ * signature: the value is >= 0 if there is a match (or neither package
+ * is signed), or < 0 if there is not a match. The match result can be
+ * further distinguished with the success (>= 0) constants
+ * {@link #SIGNATURE_MATCH}, {@link #SIGNATURE_NEITHER_SIGNED}; or
+ * failure (< 0) constants {@link #SIGNATURE_FIRST_NOT_SIGNED},
+ * {@link #SIGNATURE_SECOND_NOT_SIGNED}, {@link #SIGNATURE_NO_MATCH},
+ * or {@link #SIGNATURE_UNKNOWN_PACKAGE}.
+ *
+ * @see #SIGNATURE_MATCH
+ * @see #SIGNATURE_NEITHER_SIGNED
+ * @see #SIGNATURE_FIRST_NOT_SIGNED
+ * @see #SIGNATURE_SECOND_NOT_SIGNED
+ * @see #SIGNATURE_NO_MATCH
+ * @see #SIGNATURE_UNKNOWN_PACKAGE
+ */
+ public abstract int checkSignatures(String pkg1, String pkg2);
+
+ /**
+ * Retrieve the names of all packages that are associated with a particular
+ * user id. In most cases, this will be a single package name, the package
+ * that has been assigned that user id. Where there are multiple packages
+ * sharing the same user id through the "sharedUserId" mechanism, all
+ * packages with that id will be returned.
+ *
+ * @param uid The user id for which you would like to retrieve the
+ * associated packages.
+ *
+ * @return Returns an array of one or more packages assigned to the user
+ * id, or null if there are no known packages with the given id.
+ */
+ public abstract String[] getPackagesForUid(int uid);
+
+ /**
+ * Retrieve the official name associated with a user id. This name is
+ * guaranteed to never change, though it is possibly for the underlying
+ * user id to be changed. That is, if you are storing information about
+ * user ids in persistent storage, you should use the string returned
+ * by this function instead of the raw user-id.
+ *
+ * @param uid The user id for which you would like to retrieve a name.
+ * @return Returns a unique name for the given user id, or null if the
+ * user id is not currently assigned.
+ */
+ public abstract String getNameForUid(int uid);
+
+ /**
+ * Return the user id associated with a shared user name. Multiple
+ * applications can specify a shared user name in their manifest and thus
+ * end up using a common uid. This might be used for new applications
+ * that use an existing shared user name and need to know the uid of the
+ * shared user.
+ *
+ * @param sharedUserName The shared user name whose uid is to be retrieved.
+ * @return Returns the uid associated with the shared user, or NameNotFoundException
+ * if the shared user name is not being used by any installed packages
+ * @hide
+ */
+ public abstract int getUidForSharedUser(String sharedUserName)
+ throws NameNotFoundException;
+
+ /**
+ * Return a List of all application packages that are installed on the
+ * device. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all
+ * applications including those deleted with DONT_DELETE_DATA(partially
+ * installed apps with data directory) will be returned.
+ *
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+ * {link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
+ *
+ * @return A List of ApplicationInfo objects, one for each application that
+ * is installed on the device. In the unlikely case of there being
+ * no installed applications, an empty list is returned.
+ * If flag GET_UNINSTALLED_PACKAGES is set, a list of all
+ * applications including those deleted with DONT_DELETE_DATA
+ * (partially installed apps with data directory) will be returned.
+ *
+ * @see #GET_META_DATA
+ * @see #GET_SHARED_LIBRARY_FILES
+ * @see #GET_UNINSTALLED_PACKAGES
+ */
+ public abstract List<ApplicationInfo> getInstalledApplications(int flags);
+
+ /**
+ * Get a list of shared libraries that are available on the
+ * system.
+ *
+ * @return An array of shared library names that are
+ * available on the system, or null if none are installed.
+ *
+ */
+ public abstract String[] getSystemSharedLibraryNames();
+
+ /**
+ * Determine the best action to perform for a given Intent. This is how
+ * {@link Intent#resolveActivity} finds an activity if a class has not
+ * been explicitly specified.
+ *
+ * @param intent An intent containing all of the desired specification
+ * (action, data, type, category, and/or component).
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ *
+ * @return Returns a ResolveInfo containing the final activity intent that
+ * was determined to be the best action. Returns null if no
+ * matching activity was found.
+ *
+ * @see #MATCH_DEFAULT_ONLY
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_RESOLVED_FILTER
+ */
+ public abstract ResolveInfo resolveActivity(Intent intent, int flags);
+
+ /**
+ * Retrieve all activities that can be performed for the given intent.
+ *
+ * @param intent The desired intent as per resolveActivity().
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ *
+ * @return A List<ResolveInfo> containing one entry for each matching
+ * Activity. These are ordered from best to worst match -- that
+ * is, the first item in the list is what is returned by
+ * resolveActivity(). If there are no matching activities, an empty
+ * list is returned.
+ *
+ * @see #MATCH_DEFAULT_ONLY
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_RESOLVED_FILTER
+ */
+ public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
+ int flags);
+
+ /**
+ * Retrieve a set of activities that should be presented to the user as
+ * similar options. This is like {@link #queryIntentActivities}, except it
+ * also allows you to supply a list of more explicit Intents that you would
+ * like to resolve to particular options, and takes care of returning the
+ * final ResolveInfo list in a reasonable order, with no duplicates, based
+ * on those inputs.
+ *
+ * @param caller The class name of the activity that is making the
+ * request. This activity will never appear in the output
+ * list. Can be null.
+ * @param specifics An array of Intents that should be resolved to the
+ * first specific results. Can be null.
+ * @param intent The desired intent as per resolveActivity().
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ *
+ * @return A List<ResolveInfo> containing one entry for each matching
+ * Activity. These are ordered first by all of the intents resolved
+ * in <var>specifics</var> and then any additional activities that
+ * can handle <var>intent</var> but did not get included by one of
+ * the <var>specifics</var> intents. If there are no matching
+ * activities, an empty list is returned.
+ *
+ * @see #MATCH_DEFAULT_ONLY
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_RESOLVED_FILTER
+ */
+ public abstract List<ResolveInfo> queryIntentActivityOptions(
+ ComponentName caller, Intent[] specifics, Intent intent, int flags);
+
+ /**
+ * Retrieve all receivers that can handle a broadcast of the given intent.
+ *
+ * @param intent The desired intent as per resolveActivity().
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ *
+ * @return A List<ResolveInfo> containing one entry for each matching
+ * Receiver. These are ordered from first to last in priority. If
+ * there are no matching receivers, an empty list is returned.
+ *
+ * @see #MATCH_DEFAULT_ONLY
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_RESOLVED_FILTER
+ */
+ public abstract List<ResolveInfo> queryBroadcastReceivers(Intent intent,
+ int flags);
+
+ /**
+ * Determine the best service to handle for a given Intent.
+ *
+ * @param intent An intent containing all of the desired specification
+ * (action, data, type, category, and/or component).
+ * @param flags Additional option flags.
+ *
+ * @return Returns a ResolveInfo containing the final service intent that
+ * was determined to be the best action. Returns null if no
+ * matching service was found.
+ *
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_RESOLVED_FILTER
+ */
+ public abstract ResolveInfo resolveService(Intent intent, int flags);
+
+ /**
+ * Retrieve all services that can match the given intent.
+ *
+ * @param intent The desired intent as per resolveService().
+ * @param flags Additional option flags.
+ *
+ * @return A List<ResolveInfo> containing one entry for each matching
+ * ServiceInfo. These are ordered from best to worst match -- that
+ * is, the first item in the list is what is returned by
+ * resolveService(). If there are no matching services, an empty
+ * list is returned.
+ *
+ * @see #GET_INTENT_FILTERS
+ * @see #GET_RESOLVED_FILTER
+ */
+ public abstract List<ResolveInfo> queryIntentServices(Intent intent,
+ int flags);
+
+ /**
+ * Find a single content provider by its base path name.
+ *
+ * @param name The name of the provider to find.
+ * @param flags Additional option flags. Currently should always be 0.
+ *
+ * @return ContentProviderInfo Information about the provider, if found,
+ * else null.
+ */
+ public abstract ProviderInfo resolveContentProvider(String name,
+ int flags);
+
+ /**
+ * Retrieve content provider information.
+ *
+ * <p><em>Note: unlike most other methods, an empty result set is indicated
+ * by a null return instead of an empty list.</em>
+ *
+ * @param processName If non-null, limits the returned providers to only
+ * those that are hosted by the given process. If null,
+ * all content providers are returned.
+ * @param uid If <var>processName</var> is non-null, this is the required
+ * uid owning the requested content providers.
+ * @param flags Additional option flags. Currently should always be 0.
+ *
+ * @return A List<ContentProviderInfo> containing one entry for each
+ * content provider either patching <var>processName</var> or, if
+ * <var>processName</var> is null, all known content providers.
+ * <em>If there are no matching providers, null is returned.</em>
+ */
+ public abstract List<ProviderInfo> queryContentProviders(
+ String processName, int uid, int flags);
+
+ /**
+ * Retrieve all of the information we know about a particular
+ * instrumentation class.
+ *
+ * <p>Throws {@link NameNotFoundException} if instrumentation with the
+ * given class name can not be found on the system.
+ *
+ * @param className The full name (i.e.
+ * com.google.apps.contacts.InstrumentList) of an
+ * Instrumentation class.
+ * @param flags Additional option flags. Currently should always be 0.
+ *
+ * @return InstrumentationInfo containing information about the
+ * instrumentation.
+ */
+ public abstract InstrumentationInfo getInstrumentationInfo(
+ ComponentName className, int flags) throws NameNotFoundException;
+
+ /**
+ * Retrieve information about available instrumentation code. May be used
+ * to retrieve either all instrumentation code, or only the code targeting
+ * a particular package.
+ *
+ * @param targetPackage If null, all instrumentation is returned; only the
+ * instrumentation targeting this package name is
+ * returned.
+ * @param flags Additional option flags. Currently should always be 0.
+ *
+ * @return A List<InstrumentationInfo> containing one entry for each
+ * matching available Instrumentation. Returns an empty list if
+ * there is no instrumentation available for the given package.
+ */
+ public abstract List<InstrumentationInfo> queryInstrumentation(
+ String targetPackage, int flags);
+
+ /**
+ * Retrieve an image from a package. This is a low-level API used by
+ * the various package manager info structures (such as
+ * {@link ComponentInfo} to implement retrieval of their associated
+ * icon.
+ *
+ * @param packageName The name of the package that this icon is coming from.
+ * Can not be null.
+ * @param resid The resource identifier of the desired image. Can not be 0.
+ * @param appInfo Overall information about <var>packageName</var>. This
+ * may be null, in which case the application information will be retrieved
+ * for you if needed; if you already have this information around, it can
+ * be much more efficient to supply it here.
+ *
+ * @return Returns a Drawable holding the requested image. Returns null if
+ * an image could not be found for any reason.
+ */
+ public abstract Drawable getDrawable(String packageName, int resid,
+ ApplicationInfo appInfo);
+
+ /**
+ * Retrieve the icon associated with an activity. Given the full name of
+ * an activity, retrieves the information about it and calls
+ * {@link ComponentInfo#loadIcon ComponentInfo.loadIcon()} to return its icon.
+ * If the activity can not be found, NameNotFoundException is thrown.
+ *
+ * @param activityName Name of the activity whose icon is to be retrieved.
+ *
+ * @return Returns the image of the icon, or the default activity icon if
+ * it could not be found. Does not return null.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * activity could not be loaded.
+ *
+ * @see #getActivityIcon(Intent)
+ */
+ public abstract Drawable getActivityIcon(ComponentName activityName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the icon associated with an Intent. If intent.getClassName() is
+ * set, this simply returns the result of
+ * getActivityIcon(intent.getClassName()). Otherwise it resolves the intent's
+ * component and returns the icon associated with the resolved component.
+ * If intent.getClassName() can not be found or the Intent can not be resolved
+ * to a component, NameNotFoundException is thrown.
+ *
+ * @param intent The intent for which you would like to retrieve an icon.
+ *
+ * @return Returns the image of the icon, or the default activity icon if
+ * it could not be found. Does not return null.
+ * @throws NameNotFoundException Thrown if the resources for application
+ * matching the given intent could not be loaded.
+ *
+ * @see #getActivityIcon(ComponentName)
+ */
+ public abstract Drawable getActivityIcon(Intent intent)
+ throws NameNotFoundException;
+
+ /**
+ * Return the generic icon for an activity that is used when no specific
+ * icon is defined.
+ *
+ * @return Drawable Image of the icon.
+ */
+ public abstract Drawable getDefaultActivityIcon();
+
+ /**
+ * Retrieve the icon associated with an application. If it has not defined
+ * an icon, the default app icon is returned. Does not return null.
+ *
+ * @param info Information about application being queried.
+ *
+ * @return Returns the image of the icon, or the default application icon
+ * if it could not be found.
+ *
+ * @see #getApplicationIcon(String)
+ */
+ public abstract Drawable getApplicationIcon(ApplicationInfo info);
+
+ /**
+ * Retrieve the icon associated with an application. Given the name of the
+ * application's package, retrieves the information about it and calls
+ * getApplicationIcon() to return its icon. If the application can not be
+ * found, NameNotFoundException is thrown.
+ *
+ * @param packageName Name of the package whose application icon is to be
+ * retrieved.
+ *
+ * @return Returns the image of the icon, or the default application icon
+ * if it could not be found. Does not return null.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded.
+ *
+ * @see #getApplicationIcon(ApplicationInfo)
+ */
+ public abstract Drawable getApplicationIcon(String packageName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve text from a package. This is a low-level API used by
+ * the various package manager info structures (such as
+ * {@link ComponentInfo} to implement retrieval of their associated
+ * labels and other text.
+ *
+ * @param packageName The name of the package that this text is coming from.
+ * Can not be null.
+ * @param resid The resource identifier of the desired text. Can not be 0.
+ * @param appInfo Overall information about <var>packageName</var>. This
+ * may be null, in which case the application information will be retrieved
+ * for you if needed; if you already have this information around, it can
+ * be much more efficient to supply it here.
+ *
+ * @return Returns a CharSequence holding the requested text. Returns null
+ * if the text could not be found for any reason.
+ */
+ public abstract CharSequence getText(String packageName, int resid,
+ ApplicationInfo appInfo);
+
+ /**
+ * Retrieve an XML file from a package. This is a low-level API used to
+ * retrieve XML meta data.
+ *
+ * @param packageName The name of the package that this xml is coming from.
+ * Can not be null.
+ * @param resid The resource identifier of the desired xml. Can not be 0.
+ * @param appInfo Overall information about <var>packageName</var>. This
+ * may be null, in which case the application information will be retrieved
+ * for you if needed; if you already have this information around, it can
+ * be much more efficient to supply it here.
+ *
+ * @return Returns an XmlPullParser allowing you to parse out the XML
+ * data. Returns null if the xml resource could not be found for any
+ * reason.
+ */
+ public abstract XmlResourceParser getXml(String packageName, int resid,
+ ApplicationInfo appInfo);
+
+ /**
+ * Return the label to use for this application.
+ *
+ * @return Returns the label associated with this application, or null if
+ * it could not be found for any reason.
+ * @param info The application to get the label of
+ */
+ public abstract CharSequence getApplicationLabel(ApplicationInfo info);
+
+ /**
+ * Retrieve the resources associated with an activity. Given the full
+ * name of an activity, retrieves the information about it and calls
+ * getResources() to return its application's resources. If the activity
+ * can not be found, NameNotFoundException is thrown.
+ *
+ * @param activityName Name of the activity whose resources are to be
+ * retrieved.
+ *
+ * @return Returns the application's Resources.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded.
+ *
+ * @see #getResourcesForApplication(ApplicationInfo)
+ */
+ public abstract Resources getResourcesForActivity(ComponentName activityName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the resources for an application. Throws NameNotFoundException
+ * if the package is no longer installed.
+ *
+ * @param app Information about the desired application.
+ *
+ * @return Returns the application's Resources.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded (most likely because it was uninstalled).
+ */
+ public abstract Resources getResourcesForApplication(ApplicationInfo app)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the resources associated with an application. Given the full
+ * package name of an application, retrieves the information about it and
+ * calls getResources() to return its application's resources. If the
+ * appPackageName can not be found, NameNotFoundException is thrown.
+ *
+ * @param appPackageName Package name of the application whose resources
+ * are to be retrieved.
+ *
+ * @return Returns the application's Resources.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded.
+ *
+ * @see #getResourcesForApplication(ApplicationInfo)
+ */
+ public abstract Resources getResourcesForApplication(String appPackageName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve overall information about an application package defined
+ * in a package archive file
+ *
+ * @param archiveFilePath The path to the archive file
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_ACTIVITIES},
+ * {@link #GET_GIDS},
+ * {@link #GET_CONFIGURATIONS},
+ * {@link #GET_INSTRUMENTATION},
+ * {@link #GET_PERMISSIONS},
+ * {@link #GET_PROVIDERS},
+ * {@link #GET_RECEIVERS},
+ * {@link #GET_SERVICES},
+ * {@link #GET_SIGNATURES}, to modify the data returned.
+ *
+ * @return Returns the information about the package. Returns
+ * null if the package could not be successfully parsed.
+ *
+ * @see #GET_ACTIVITIES
+ * @see #GET_GIDS
+ * @see #GET_CONFIGURATIONS
+ * @see #GET_INSTRUMENTATION
+ * @see #GET_PERMISSIONS
+ * @see #GET_PROVIDERS
+ * @see #GET_RECEIVERS
+ * @see #GET_SERVICES
+ * @see #GET_SIGNATURES
+ *
+ */
+ public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
+ PackageParser packageParser = new PackageParser(archiveFilePath);
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setToDefaults();
+ final File sourceFile = new File(archiveFilePath);
+ PackageParser.Package pkg = packageParser.parsePackage(
+ sourceFile, archiveFilePath, metrics, 0);
+ if (pkg == null) {
+ return null;
+ }
+ return PackageParser.generatePackageInfo(pkg, null, flags);
+ }
+
+ /**
+ * Install a package. Since this may take a little while, the result will
+ * be posted back to the given observer. An installation will fail if the calling context
+ * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
+ * package named in the package file's manifest is already installed, or if there's no space
+ * available on the device.
+ *
+ * @param packageURI The location of the package file to install. This can be a 'file:' or a
+ * 'content:' URI.
+ * @param observer An observer callback to get notified when the package installation is
+ * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
+ * called when that happens. observer may be null to indicate that no callback is desired.
+ * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
+ * {@link #REPLACE_EXISTING_PACKAGE}
+ *
+ * @see #installPackage(android.net.Uri)
+ */
+ public abstract void installPackage(
+ Uri packageURI, IPackageInstallObserver observer, int flags);
+
+ /**
+ * Attempts to delete a package. Since this may take a little while, the result will
+ * be posted back to the given observer. A deletion will fail if the calling context
+ * lacks the {@link android.Manifest.permission#DELETE_PACKAGES} permission, if the
+ * named package cannot be found, or if the named package is a "system package".
+ * (TODO: include pointer to documentation on "system packages")
+ *
+ * @param packageName The name of the package to delete
+ * @param observer An observer callback to get notified when the package deletion is
+ * complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be
+ * called when that happens. observer may be null to indicate that no callback is desired.
+ * @param flags - possible values: {@link #DONT_DELETE_DATA}
+ *
+ * @hide
+ */
+ public abstract void deletePackage(
+ String packageName, IPackageDeleteObserver observer, int flags);
+ /**
+ * Attempts to clear the user data directory of an application.
+ * Since this may take a little while, the result will
+ * be posted back to the given observer. A deletion will fail if the
+ * named package cannot be found, or if the named package is a "system package".
+ *
+ * @param packageName The name of the package
+ * @param observer An observer callback to get notified when the operation is finished
+ * {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
+ * will be called when that happens. observer may be null to indicate that
+ * no callback is desired.
+ *
+ * @hide
+ */
+ public abstract void clearApplicationUserData(String packageName,
+ IPackageDataObserver observer);
+ /**
+ * Attempts to delete the cache files associated with an application.
+ * Since this may take a little while, the result will
+ * be posted back to the given observer. A deletion will fail if the calling context
+ * lacks the {@link android.Manifest.permission#DELETE_CACHE_FILES} permission, if the
+ * named package cannot be found, or if the named package is a "system package".
+ *
+ * @param packageName The name of the package to delete
+ * @param observer An observer callback to get notified when the cache file deletion
+ * is complete.
+ * {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
+ * will be called when that happens. observer may be null to indicate that
+ * no callback is desired.
+ *
+ * @hide
+ */
+ public abstract void deleteApplicationCacheFiles(String packageName,
+ IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param observer call back used to notify when
+ * the operation is completed
+ *
+ * @hide
+ */
+ public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param opFinishedIntent PendingIntent call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ *
+ * @hide
+ */
+ public abstract void freeStorage(long freeStorageSize, PendingIntent opFinishedIntent);
+
+ /**
+ * Retrieve the size information for a package.
+ * Since this may take a little while, the result will
+ * be posted back to the given observer. The calling context
+ * should have the {@link android.Manifest.permission#GET_PACKAGE_SIZE} permission.
+ *
+ * @param packageName The name of the package whose size information is to be retrieved
+ * @param observer An observer callback to get notified when the operation
+ * is complete.
+ * {@link android.content.pm.IPackageStatsObserver#onGetStatsCompleted(PackageStats, boolean)}
+ * The observer's callback is invoked with a PackageStats object(containing the
+ * code, data and cache sizes of the package) and a boolean value representing
+ * the status of the operation. observer may be null to indicate that
+ * no callback is desired.
+ *
+ * @hide
+ */
+ public abstract void getPackageSizeInfo(String packageName,
+ IPackageStatsObserver observer);
+
+ /**
+ * Install a package.
+ *
+ * @param packageURI The location of the package file to install
+ *
+ * @see #installPackage(android.net.Uri, IPackageInstallObserver, int)
+ */
+ public void installPackage(Uri packageURI) {
+ installPackage(packageURI, null, 0);
+ }
+
+ /**
+ * Add a new package to the list of preferred packages. This new package
+ * will be added to the front of the list (removed from its current location
+ * if already listed), meaning it will now be preferred over all other
+ * packages when resolving conflicts.
+ *
+ * @param packageName The package name of the new package to make preferred.
+ */
+ public abstract void addPackageToPreferred(String packageName);
+
+ /**
+ * Remove a package from the list of preferred packages. If it was on
+ * the list, it will no longer be preferred over other packages.
+ *
+ * @param packageName The package name to remove.
+ */
+ public abstract void removePackageFromPreferred(String packageName);
+
+ /**
+ * Retrieve the list of all currently configured preferred packages. The
+ * first package on the list is the most preferred, the last is the
+ * least preferred.
+ *
+ * @param flags Additional option flags. Use any combination of
+ * {@link #GET_ACTIVITIES},
+ * {@link #GET_GIDS},
+ * {@link #GET_CONFIGURATIONS},
+ * {@link #GET_INSTRUMENTATION},
+ * {@link #GET_PERMISSIONS},
+ * {@link #GET_PROVIDERS},
+ * {@link #GET_RECEIVERS},
+ * {@link #GET_SERVICES},
+ * {@link #GET_SIGNATURES}, to modify the data returned.
+ *
+ * @return Returns a list of PackageInfo objects describing each
+ * preferred application, in order of preference.
+ *
+ * @see #GET_ACTIVITIES
+ * @see #GET_GIDS
+ * @see #GET_CONFIGURATIONS
+ * @see #GET_INSTRUMENTATION
+ * @see #GET_PERMISSIONS
+ * @see #GET_PROVIDERS
+ * @see #GET_RECEIVERS
+ * @see #GET_SERVICES
+ * @see #GET_SIGNATURES
+ */
+ public abstract List<PackageInfo> getPreferredPackages(int flags);
+
+ /**
+ * Add a new preferred activity mapping to the system. This will be used
+ * to automatically select the given activity component when
+ * {@link Context#startActivity(Intent) Context.startActivity()} finds
+ * multiple matching activities and also matches the given filter.
+ *
+ * @param filter The set of intents under which this activity will be
+ * made preferred.
+ * @param match The IntentFilter match category that this preference
+ * applies to.
+ * @param set The set of activities that the user was picking from when
+ * this preference was made.
+ * @param activity The component name of the activity that is to be
+ * preferred.
+ */
+ public abstract void addPreferredActivity(IntentFilter filter, int match,
+ ComponentName[] set, ComponentName activity);
+
+ /**
+ * Remove all preferred activity mappings, previously added with
+ * {@link #addPreferredActivity}, from the
+ * system whose activities are implemented in the given package name.
+ *
+ * @param packageName The name of the package whose preferred activity
+ * mappings are to be removed.
+ */
+ public abstract void clearPackagePreferredActivities(String packageName);
+
+ /**
+ * Retrieve all preferred activities, previously added with
+ * {@link #addPreferredActivity}, that are
+ * currently registered with the system.
+ *
+ * @param outFilters A list in which to place the filters of all of the
+ * preferred activities, or null for none.
+ * @param outActivities A list in which to place the component names of
+ * all of the preferred activities, or null for none.
+ * @param packageName An option package in which you would like to limit
+ * the list. If null, all activities will be returned; if non-null, only
+ * those activities in the given package are returned.
+ *
+ * @return Returns the total number of registered preferred activities
+ * (the number of distinct IntentFilter records, not the number of unique
+ * activity components) that were found.
+ */
+ public abstract int getPreferredActivities(List<IntentFilter> outFilters,
+ List<ComponentName> outActivities, String packageName);
+
+ /**
+ * Set the enabled setting for a package component (activity, receiver, service, provider).
+ * This setting will override any enabled state which may have been set by the component in its
+ * manifest.
+ *
+ * @param componentName The component to enable
+ * @param newState The new enabled state for the component. The legal values for this state
+ * are:
+ * {@link #COMPONENT_ENABLED_STATE_ENABLED},
+ * {@link #COMPONENT_ENABLED_STATE_DISABLED}
+ * and
+ * {@link #COMPONENT_ENABLED_STATE_DEFAULT}
+ * The last one removes the setting, thereby restoring the component's state to
+ * whatever was set in it's manifest (or enabled, by default).
+ * @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
+ */
+ public abstract void setComponentEnabledSetting(ComponentName componentName,
+ int newState, int flags);
+
+
+ /**
+ * Return the the enabled setting for a package component (activity,
+ * receiver, service, provider). This returns the last value set by
+ * {@link #setComponentEnabledSetting(ComponentName, int, int)}; in most
+ * cases this value will be {@link #COMPONENT_ENABLED_STATE_DEFAULT} since
+ * the value originally specified in the manifest has not been modified.
+ *
+ * @param componentName The component to retrieve.
+ * @return Returns the current enabled state for the component. May
+ * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
+ * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
+ * {@link #COMPONENT_ENABLED_STATE_DEFAULT}. The last one means the
+ * component's enabled state is based on the original information in
+ * the manifest as found in {@link ComponentInfo}.
+ */
+ public abstract int getComponentEnabledSetting(ComponentName componentName);
+
+ /**
+ * Set the enabled setting for an application
+ * This setting will override any enabled state which may have been set by the application in
+ * its manifest. It also overrides the enabled state set in the manifest for any of the
+ * application's components. It does not override any enabled state set by
+ * {@link #setComponentEnabledSetting} for any of the application's components.
+ *
+ * @param packageName The package name of the application to enable
+ * @param newState The new enabled state for the component. The legal values for this state
+ * are:
+ * {@link #COMPONENT_ENABLED_STATE_ENABLED},
+ * {@link #COMPONENT_ENABLED_STATE_DISABLED}
+ * and
+ * {@link #COMPONENT_ENABLED_STATE_DEFAULT}
+ * The last one removes the setting, thereby restoring the applications's state to
+ * whatever was set in its manifest (or enabled, by default).
+ * @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
+ */
+ public abstract void setApplicationEnabledSetting(String packageName,
+ int newState, int flags);
+
+ /**
+ * Return the the enabled setting for an application. This returns
+ * the last value set by
+ * {@link #setApplicationEnabledSetting(String, int, int)}; in most
+ * cases this value will be {@link #COMPONENT_ENABLED_STATE_DEFAULT} since
+ * the value originally specified in the manifest has not been modified.
+ *
+ * @param packageName The component to retrieve.
+ * @return Returns the current enabled state for the component. May
+ * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
+ * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
+ * {@link #COMPONENT_ENABLED_STATE_DEFAULT}. The last one means the
+ * application's enabled state is based on the original information in
+ * the manifest as found in {@link ComponentInfo}.
+ */
+ public abstract int getApplicationEnabledSetting(String packageName);
+
+ /**
+ * Return whether the device has been booted into safe mode.
+ */
+ public abstract boolean isSafeMode();
+}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
new file mode 100644
index 0000000..4ae8b08
--- /dev/null
+++ b/core/java/android/content/pm/PackageParser.java
@@ -0,0 +1,2352 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
+import android.os.PatternMatcher;
+import android.util.AttributeSet;
+import android.util.Config;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
+import com.android.internal.util.XmlUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Package archive parsing
+ *
+ * {@hide}
+ */
+public class PackageParser {
+
+ private String mArchiveSourcePath;
+ private String[] mSeparateProcesses;
+ private int mSdkVersion;
+
+ private int mParseError = PackageManager.INSTALL_SUCCEEDED;
+
+ private static final Object mSync = new Object();
+ private static WeakReference<byte[]> mReadBuffer;
+
+ /** If set to true, we will only allow package files that exactly match
+ * the DTD. Otherwise, we try to get as much from the package as we
+ * can without failing. This should normally be set to false, to
+ * support extensions to the DTD in future versions. */
+ private static final boolean RIGID_PARSER = false;
+
+ private static final String TAG = "PackageParser";
+
+ public PackageParser(String archiveSourcePath) {
+ mArchiveSourcePath = archiveSourcePath;
+ }
+
+ public void setSeparateProcesses(String[] procs) {
+ mSeparateProcesses = procs;
+ }
+
+ public void setSdkVersion(int sdkVersion) {
+ mSdkVersion = sdkVersion;
+ }
+
+ private static final boolean isPackageFilename(String name) {
+ return name.endsWith(".apk");
+ }
+
+ /**
+ * Generate and return the {@link PackageInfo} for a parsed package.
+ *
+ * @param p the parsed package.
+ * @param flags indicating which optional information is included.
+ */
+ public static PackageInfo generatePackageInfo(PackageParser.Package p,
+ int gids[], int flags) {
+
+ PackageInfo pi = new PackageInfo();
+ pi.packageName = p.packageName;
+ pi.versionCode = p.mVersionCode;
+ pi.versionName = p.mVersionName;
+ pi.sharedUserId = p.mSharedUserId;
+ pi.sharedUserLabel = p.mSharedUserLabel;
+ pi.applicationInfo = p.applicationInfo;
+ if ((flags&PackageManager.GET_GIDS) != 0) {
+ pi.gids = gids;
+ }
+ if ((flags&PackageManager.GET_CONFIGURATIONS) != 0) {
+ int N = p.configPreferences.size();
+ if (N > 0) {
+ pi.configPreferences = new ConfigurationInfo[N];
+ for (int i=0; i<N; i++) {
+ pi.configPreferences[i] = p.configPreferences.get(i);
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_ACTIVITIES) != 0) {
+ int N = p.activities.size();
+ if (N > 0) {
+ pi.activities = new ActivityInfo[N];
+ for (int i=0; i<N; i++) {
+ final Activity activity = p.activities.get(i);
+ if (activity.info.enabled
+ || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
+ pi.activities[i] = generateActivityInfo(p.activities.get(i), flags);
+ }
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_RECEIVERS) != 0) {
+ int N = p.receivers.size();
+ if (N > 0) {
+ pi.receivers = new ActivityInfo[N];
+ for (int i=0; i<N; i++) {
+ final Activity activity = p.receivers.get(i);
+ if (activity.info.enabled
+ || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
+ pi.receivers[i] = generateActivityInfo(p.receivers.get(i), flags);
+ }
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_SERVICES) != 0) {
+ int N = p.services.size();
+ if (N > 0) {
+ pi.services = new ServiceInfo[N];
+ for (int i=0; i<N; i++) {
+ final Service service = p.services.get(i);
+ if (service.info.enabled
+ || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
+ pi.services[i] = generateServiceInfo(p.services.get(i), flags);
+ }
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_PROVIDERS) != 0) {
+ int N = p.providers.size();
+ if (N > 0) {
+ pi.providers = new ProviderInfo[N];
+ for (int i=0; i<N; i++) {
+ final Provider provider = p.providers.get(i);
+ if (provider.info.enabled
+ || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
+ pi.providers[i] = generateProviderInfo(p.providers.get(i), flags);
+ }
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_INSTRUMENTATION) != 0) {
+ int N = p.instrumentation.size();
+ if (N > 0) {
+ pi.instrumentation = new InstrumentationInfo[N];
+ for (int i=0; i<N; i++) {
+ pi.instrumentation[i] = generateInstrumentationInfo(
+ p.instrumentation.get(i), flags);
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_PERMISSIONS) != 0) {
+ int N = p.permissions.size();
+ if (N > 0) {
+ pi.permissions = new PermissionInfo[N];
+ for (int i=0; i<N; i++) {
+ pi.permissions[i] = generatePermissionInfo(p.permissions.get(i), flags);
+ }
+ }
+ N = p.requestedPermissions.size();
+ if (N > 0) {
+ pi.requestedPermissions = new String[N];
+ for (int i=0; i<N; i++) {
+ pi.requestedPermissions[i] = p.requestedPermissions.get(i);
+ }
+ }
+ }
+ if ((flags&PackageManager.GET_SIGNATURES) != 0) {
+ int N = p.mSignatures.length;
+ if (N > 0) {
+ pi.signatures = new Signature[N];
+ System.arraycopy(p.mSignatures, 0, pi.signatures, 0, N);
+ }
+ }
+ return pi;
+ }
+
+ private Certificate[] loadCertificates(JarFile jarFile, JarEntry je,
+ byte[] readBuffer) {
+ try {
+ // We must read the stream for the JarEntry to retrieve
+ // its certificates.
+ InputStream is = jarFile.getInputStream(je);
+ while (is.read(readBuffer, 0, readBuffer.length) != -1) {
+ // not using
+ }
+ is.close();
+ return je != null ? je.getCertificates() : null;
+ } catch (IOException e) {
+ Log.w(TAG, "Exception reading " + je.getName() + " in "
+ + jarFile.getName(), e);
+ }
+ return null;
+ }
+
+ public final static int PARSE_IS_SYSTEM = 0x0001;
+ public final static int PARSE_CHATTY = 0x0002;
+ public final static int PARSE_MUST_BE_APK = 0x0004;
+ public final static int PARSE_IGNORE_PROCESSES = 0x0008;
+
+ public int getParseError() {
+ return mParseError;
+ }
+
+ public Package parsePackage(File sourceFile, String destFileName,
+ DisplayMetrics metrics, int flags) {
+ mParseError = PackageManager.INSTALL_SUCCEEDED;
+
+ mArchiveSourcePath = sourceFile.getPath();
+ if (!sourceFile.isFile()) {
+ Log.w(TAG, "Skipping dir: " + mArchiveSourcePath);
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
+ return null;
+ }
+ if (!isPackageFilename(sourceFile.getName())
+ && (flags&PARSE_MUST_BE_APK) != 0) {
+ if ((flags&PARSE_IS_SYSTEM) == 0) {
+ // We expect to have non-.apk files in the system dir,
+ // so don't warn about them.
+ Log.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);
+ }
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
+ return null;
+ }
+
+ if ((flags&PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
+ TAG, "Scanning package: " + mArchiveSourcePath);
+
+ XmlResourceParser parser = null;
+ AssetManager assmgr = null;
+ boolean assetError = true;
+ try {
+ assmgr = new AssetManager();
+ if(assmgr.addAssetPath(mArchiveSourcePath) != 0) {
+ parser = assmgr.openXmlResourceParser("AndroidManifest.xml");
+ assetError = false;
+ } else {
+ Log.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Unable to read AndroidManifest.xml of "
+ + mArchiveSourcePath, e);
+ }
+ if(assetError) {
+ if (assmgr != null) assmgr.close();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
+ return null;
+ }
+ String[] errorText = new String[1];
+ Package pkg = null;
+ Exception errorException = null;
+ try {
+ // XXXX todo: need to figure out correct configuration.
+ Resources res = new Resources(assmgr, metrics, null);
+ pkg = parsePackage(res, parser, flags, errorText);
+ } catch (Exception e) {
+ errorException = e;
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
+ }
+
+
+ if (pkg == null) {
+ if (errorException != null) {
+ Log.w(TAG, mArchiveSourcePath, errorException);
+ } else {
+ Log.w(TAG, mArchiveSourcePath + " (at "
+ + parser.getPositionDescription()
+ + "): " + errorText[0]);
+ }
+ parser.close();
+ assmgr.close();
+ if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ }
+ return null;
+ }
+
+ parser.close();
+ assmgr.close();
+
+ pkg.applicationInfo.sourceDir = destFileName;
+ pkg.applicationInfo.publicSourceDir = destFileName;
+ pkg.mSignatures = null;
+
+ return pkg;
+ }
+
+ public boolean collectCertificates(Package pkg, int flags) {
+ pkg.mSignatures = null;
+
+ WeakReference<byte[]> readBufferRef;
+ byte[] readBuffer = null;
+ synchronized (mSync) {
+ readBufferRef = mReadBuffer;
+ if (readBufferRef != null) {
+ mReadBuffer = null;
+ readBuffer = readBufferRef.get();
+ }
+ if (readBuffer == null) {
+ readBuffer = new byte[8192];
+ readBufferRef = new WeakReference<byte[]>(readBuffer);
+ }
+ }
+
+ try {
+ JarFile jarFile = new JarFile(mArchiveSourcePath);
+
+ Certificate[] certs = null;
+
+ if ((flags&PARSE_IS_SYSTEM) != 0) {
+ // If this package comes from the system image, then we
+ // can trust it... we'll just use the AndroidManifest.xml
+ // to retrieve its signatures, not validating all of the
+ // files.
+ JarEntry jarEntry = jarFile.getJarEntry("AndroidManifest.xml");
+ certs = loadCertificates(jarFile, jarEntry, readBuffer);
+ if (certs == null) {
+ Log.e(TAG, "Package " + pkg.packageName
+ + " has no certificates at entry "
+ + jarEntry.getName() + "; ignoring!");
+ jarFile.close();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
+ return false;
+ }
+ if (false) {
+ Log.i(TAG, "File " + mArchiveSourcePath + ": entry=" + jarEntry
+ + " certs=" + (certs != null ? certs.length : 0));
+ if (certs != null) {
+ final int N = certs.length;
+ for (int i=0; i<N; i++) {
+ Log.i(TAG, " Public key: "
+ + certs[i].getPublicKey().getEncoded()
+ + " " + certs[i].getPublicKey());
+ }
+ }
+ }
+
+ } else {
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry je = (JarEntry)entries.nextElement();
+ if (je.isDirectory()) continue;
+ if (je.getName().startsWith("META-INF/")) continue;
+ Certificate[] localCerts = loadCertificates(jarFile, je,
+ readBuffer);
+ if (false) {
+ Log.i(TAG, "File " + mArchiveSourcePath + " entry " + je.getName()
+ + ": certs=" + certs + " ("
+ + (certs != null ? certs.length : 0) + ")");
+ }
+ if (localCerts == null) {
+ Log.e(TAG, "Package " + pkg.packageName
+ + " has no certificates at entry "
+ + je.getName() + "; ignoring!");
+ jarFile.close();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
+ return false;
+ } else if (certs == null) {
+ certs = localCerts;
+ } else {
+ // Ensure all certificates match.
+ for (int i=0; i<certs.length; i++) {
+ boolean found = false;
+ for (int j=0; j<localCerts.length; j++) {
+ if (certs[i] != null &&
+ certs[i].equals(localCerts[j])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found || certs.length != localCerts.length) {
+ Log.e(TAG, "Package " + pkg.packageName
+ + " has mismatched certificates at entry "
+ + je.getName() + "; ignoring!");
+ jarFile.close();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+ return false;
+ }
+ }
+ }
+ }
+ }
+ jarFile.close();
+
+ synchronized (mSync) {
+ mReadBuffer = readBufferRef;
+ }
+
+ if (certs != null && certs.length > 0) {
+ final int N = certs.length;
+ pkg.mSignatures = new Signature[certs.length];
+ for (int i=0; i<N; i++) {
+ pkg.mSignatures[i] = new Signature(
+ certs[i].getEncoded());
+ }
+ } else {
+ Log.e(TAG, "Package " + pkg.packageName
+ + " has no certificates; ignoring!");
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
+ return false;
+ }
+ } catch (CertificateEncodingException e) {
+ Log.w(TAG, "Exception reading " + mArchiveSourcePath, e);
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
+ return false;
+ } catch (IOException e) {
+ Log.w(TAG, "Exception reading " + mArchiveSourcePath, e);
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
+ return false;
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Exception reading " + mArchiveSourcePath, e);
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
+ return false;
+ }
+
+ return true;
+ }
+
+ public static String parsePackageName(String packageFilePath, int flags) {
+ XmlResourceParser parser = null;
+ AssetManager assmgr = null;
+ try {
+ assmgr = new AssetManager();
+ int cookie = assmgr.addAssetPath(packageFilePath);
+ parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
+ } catch (Exception e) {
+ if (assmgr != null) assmgr.close();
+ Log.w(TAG, "Unable to read AndroidManifest.xml of "
+ + packageFilePath, e);
+ return null;
+ }
+ AttributeSet attrs = parser;
+ String errors[] = new String[1];
+ String packageName = null;
+ try {
+ packageName = parsePackageName(parser, attrs, flags, errors);
+ } catch (IOException e) {
+ Log.w(TAG, packageFilePath, e);
+ } catch (XmlPullParserException e) {
+ Log.w(TAG, packageFilePath, e);
+ } finally {
+ if (parser != null) parser.close();
+ if (assmgr != null) assmgr.close();
+ }
+ if (packageName == null) {
+ Log.e(TAG, "parsePackageName error: " + errors[0]);
+ return null;
+ }
+ return packageName;
+ }
+
+ private static String validateName(String name, boolean requiresSeparator) {
+ final int N = name.length();
+ boolean hasSep = false;
+ boolean front = true;
+ for (int i=0; i<N; i++) {
+ final char c = name.charAt(i);
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ front = false;
+ continue;
+ }
+ if (!front) {
+ if ((c >= '0' && c <= '9') || c == '_') {
+ continue;
+ }
+ }
+ if (c == '.') {
+ hasSep = true;
+ front = true;
+ continue;
+ }
+ return "bad character '" + c + "'";
+ }
+ return hasSep || !requiresSeparator
+ ? null : "must have at least one '.' separator";
+ }
+
+ private static String parsePackageName(XmlPullParser parser,
+ AttributeSet attrs, int flags, String[] outError)
+ throws IOException, XmlPullParserException {
+
+ int type;
+ while ((type=parser.next()) != parser.START_TAG
+ && type != parser.END_DOCUMENT) {
+ ;
+ }
+
+ if (type != parser.START_TAG) {
+ outError[0] = "No start tag found";
+ return null;
+ }
+ if ((flags&PARSE_CHATTY) != 0 && Config.LOGV) Log.v(
+ TAG, "Root element name: '" + parser.getName() + "'");
+ if (!parser.getName().equals("manifest")) {
+ outError[0] = "No <manifest> tag";
+ return null;
+ }
+ String pkgName = attrs.getAttributeValue(null, "package");
+ if (pkgName == null || pkgName.length() == 0) {
+ outError[0] = "<manifest> does not specify package";
+ return null;
+ }
+ String nameError = validateName(pkgName, true);
+ if (nameError != null && !"android".equals(pkgName)) {
+ outError[0] = "<manifest> specifies bad package name \""
+ + pkgName + "\": " + nameError;
+ return null;
+ }
+
+ return pkgName.intern();
+ }
+
+ /**
+ * Temporary.
+ */
+ static public Signature stringToSignature(String str) {
+ final int N = str.length();
+ byte[] sig = new byte[N];
+ for (int i=0; i<N; i++) {
+ sig[i] = (byte)str.charAt(i);
+ }
+ return new Signature(sig);
+ }
+
+ private Package parsePackage(
+ Resources res, XmlResourceParser parser, int flags, String[] outError)
+ throws XmlPullParserException, IOException {
+ AttributeSet attrs = parser;
+
+ String pkgName = parsePackageName(parser, attrs, flags, outError);
+ if (pkgName == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
+ return null;
+ }
+ int type;
+
+ final Package pkg = new Package(pkgName);
+ pkg.mSystem = (flags&PARSE_IS_SYSTEM) != 0;
+ boolean foundApp = false;
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifest);
+ pkg.mVersionCode = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
+ pkg.mVersionName = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifest_versionName);
+ if (pkg.mVersionName != null) {
+ pkg.mVersionName = pkg.mVersionName.intern();
+ }
+ String str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifest_sharedUserId);
+ if (str != null) {
+ String nameError = validateName(str, true);
+ if (nameError != null && !"android".equals(pkgName)) {
+ outError[0] = "<manifest> specifies bad sharedUserId name \""
+ + str + "\": " + nameError;
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
+ return null;
+ }
+ pkg.mSharedUserId = str.intern();
+ pkg.mSharedUserLabel = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
+ }
+ sa.recycle();
+
+ final int innerDepth = parser.getDepth();
+
+ int outerDepth = parser.getDepth();
+ while ((type=parser.next()) != parser.END_DOCUMENT
+ && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == parser.END_TAG || type == parser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals("application")) {
+ if (foundApp) {
+ if (RIGID_PARSER) {
+ outError[0] = "<manifest> has more than one <application>";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ } else {
+ Log.w(TAG, "<manifest> has more than one <application>");
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+
+ foundApp = true;
+ if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
+ return null;
+ }
+ } else if (tagName.equals("permission-group")) {
+ if (parsePermissionGroup(pkg, res, parser, attrs, outError) == null) {
+ return null;
+ }
+ } else if (tagName.equals("permission")) {
+ if (parsePermission(pkg, res, parser, attrs, outError) == null) {
+ return null;
+ }
+ } else if (tagName.equals("permission-tree")) {
+ if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
+ return null;
+ }
+ } else if (tagName.equals("uses-permission")) {
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestUsesPermission);
+
+ String name = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
+
+ sa.recycle();
+
+ if (name != null && !pkg.requestedPermissions.contains(name)) {
+ pkg.requestedPermissions.add(name);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+
+ } else if (tagName.equals("uses-configuration")) {
+ ConfigurationInfo cPref = new ConfigurationInfo();
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestUsesConfiguration);
+ cPref.reqTouchScreen = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
+ Configuration.TOUCHSCREEN_UNDEFINED);
+ cPref.reqKeyboardType = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType,
+ Configuration.KEYBOARD_UNDEFINED);
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard,
+ false)) {
+ cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
+ }
+ cPref.reqNavigation = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqNavigation,
+ Configuration.NAVIGATION_UNDEFINED);
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav,
+ false)) {
+ cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
+ }
+ sa.recycle();
+ pkg.configPreferences.add(cPref);
+
+ XmlUtils.skipCurrentTag(parser);
+
+ } else if (tagName.equals("uses-sdk")) {
+ if (mSdkVersion > 0) {
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestUsesSdk);
+
+ int vers = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion, 0);
+
+ sa.recycle();
+
+ if (vers > mSdkVersion) {
+ outError[0] = "Requires newer sdk version #" + vers
+ + " (current version is #" + mSdkVersion + ")";
+ mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
+ return null;
+ }
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+
+ } else if (tagName.equals("instrumentation")) {
+ if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) {
+ return null;
+ }
+ } else if (tagName.equals("eat-comment")) {
+ // Just skip this tag
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else if (RIGID_PARSER) {
+ outError[0] = "Bad element under <manifest>: "
+ + parser.getName();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ } else {
+ Log.w(TAG, "Bad element under <manifest>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+
+ if (!foundApp && pkg.instrumentation.size() == 0) {
+ outError[0] = "<manifest> does not contain an <application> or <instrumentation>";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
+ }
+
+ if (pkg.usesLibraries.size() > 0) {
+ pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
+ pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
+ }
+
+ return pkg;
+ }
+
+ private static String buildClassName(String pkg, CharSequence clsSeq,
+ String[] outError) {
+ if (clsSeq == null || clsSeq.length() <= 0) {
+ outError[0] = "Empty class name in package " + pkg;
+ return null;
+ }
+ String cls = clsSeq.toString();
+ char c = cls.charAt(0);
+ if (c == '.') {
+ return (pkg + cls).intern();
+ }
+ if (cls.indexOf('.') < 0) {
+ StringBuilder b = new StringBuilder(pkg);
+ b.append('.');
+ b.append(cls);
+ return b.toString().intern();
+ }
+ if (c >= 'a' && c <= 'z') {
+ return cls.intern();
+ }
+ outError[0] = "Bad class name " + cls + " in package " + pkg;
+ return null;
+ }
+
+ private static String buildCompoundName(String pkg,
+ CharSequence procSeq, String type, String[] outError) {
+ String proc = procSeq.toString();
+ char c = proc.charAt(0);
+ if (pkg != null && c == ':') {
+ if (proc.length() < 2) {
+ outError[0] = "Bad " + type + " name " + proc + " in package " + pkg
+ + ": must be at least two characters";
+ return null;
+ }
+ String subName = proc.substring(1);
+ String nameError = validateName(subName, false);
+ if (nameError != null) {
+ outError[0] = "Invalid " + type + " name " + proc + " in package "
+ + pkg + ": " + nameError;
+ return null;
+ }
+ return (pkg + proc).intern();
+ }
+ String nameError = validateName(proc, true);
+ if (nameError != null && !"system".equals(proc)) {
+ outError[0] = "Invalid " + type + " name " + proc + " in package "
+ + pkg + ": " + nameError;
+ return null;
+ }
+ return proc.intern();
+ }
+
+ private static String buildProcessName(String pkg, String defProc,
+ CharSequence procSeq, int flags, String[] separateProcesses,
+ String[] outError) {
+ if ((flags&PARSE_IGNORE_PROCESSES) != 0 && !"system".equals(procSeq)) {
+ return defProc != null ? defProc : pkg;
+ }
+ if (separateProcesses != null) {
+ for (int i=separateProcesses.length-1; i>=0; i--) {
+ String sp = separateProcesses[i];
+ if (sp.equals(pkg) || sp.equals(defProc) || sp.equals(procSeq)) {
+ return pkg;
+ }
+ }
+ }
+ if (procSeq == null || procSeq.length() <= 0) {
+ return defProc;
+ }
+ return buildCompoundName(pkg, procSeq, "package", outError);
+ }
+
+ private static String buildTaskAffinityName(String pkg, String defProc,
+ CharSequence procSeq, String[] outError) {
+ if (procSeq == null) {
+ return defProc;
+ }
+ if (procSeq.length() <= 0) {
+ return null;
+ }
+ return buildCompoundName(pkg, procSeq, "taskAffinity", outError);
+ }
+
+ private PermissionGroup parsePermissionGroup(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, String[] outError)
+ throws XmlPullParserException, IOException {
+ PermissionGroup perm = new PermissionGroup(owner);
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup);
+
+ if (!parsePackageItemInfo(owner, perm.info, outError,
+ "<permission-group>", sa,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_label,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon)) {
+ sa.recycle();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ perm.info.descriptionRes = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_description,
+ 0);
+
+ sa.recycle();
+
+ if (!parseAllMetaData(res, parser, attrs, "<permission-group>", perm,
+ outError)) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ owner.permissionGroups.add(perm);
+
+ return perm;
+ }
+
+ private Permission parsePermission(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, String[] outError)
+ throws XmlPullParserException, IOException {
+ Permission perm = new Permission(owner);
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestPermission);
+
+ if (!parsePackageItemInfo(owner, perm.info, outError,
+ "<permission>", sa,
+ com.android.internal.R.styleable.AndroidManifestPermission_name,
+ com.android.internal.R.styleable.AndroidManifestPermission_label,
+ com.android.internal.R.styleable.AndroidManifestPermission_icon)) {
+ sa.recycle();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ perm.info.group = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestPermission_permissionGroup);
+ if (perm.info.group != null) {
+ perm.info.group = perm.info.group.intern();
+ }
+
+ perm.info.descriptionRes = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestPermission_description,
+ 0);
+
+ perm.info.protectionLevel = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestPermission_protectionLevel,
+ PermissionInfo.PROTECTION_NORMAL);
+
+ sa.recycle();
+
+ if (perm.info.protectionLevel == -1) {
+ outError[0] = "<permission> does not specify protectionLevel";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ if (!parseAllMetaData(res, parser, attrs, "<permission>", perm,
+ outError)) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ owner.permissions.add(perm);
+
+ return perm;
+ }
+
+ private Permission parsePermissionTree(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, String[] outError)
+ throws XmlPullParserException, IOException {
+ Permission perm = new Permission(owner);
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree);
+
+ if (!parsePackageItemInfo(owner, perm.info, outError,
+ "<permission-tree>", sa,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_name,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_label,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_icon)) {
+ sa.recycle();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ sa.recycle();
+
+ int index = perm.info.name.indexOf('.');
+ if (index > 0) {
+ index = perm.info.name.indexOf('.', index+1);
+ }
+ if (index < 0) {
+ outError[0] = "<permission-tree> name has less than three segments: "
+ + perm.info.name;
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ perm.info.descriptionRes = 0;
+ perm.info.protectionLevel = PermissionInfo.PROTECTION_NORMAL;
+ perm.tree = true;
+
+ if (!parseAllMetaData(res, parser, attrs, "<permission-tree>", perm,
+ outError)) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ owner.permissions.add(perm);
+
+ return perm;
+ }
+
+ private Instrumentation parseInstrumentation(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, String[] outError)
+ throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation);
+
+ Instrumentation a = new Instrumentation(owner);
+
+ if (!parsePackageItemInfo(owner, a.info, outError, "<instrumentation>", sa,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_name,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_label,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_icon)) {
+ sa.recycle();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ a.component = new ComponentName(owner.applicationInfo.packageName,
+ a.info.name);
+
+ String str;
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_targetPackage);
+ a.info.targetPackage = str != null ? str.intern() : null;
+
+ a.info.handleProfiling = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_handleProfiling,
+ false);
+
+ a.info.functionalTest = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_functionalTest,
+ false);
+
+ sa.recycle();
+
+ if (a.info.targetPackage == null) {
+ outError[0] = "<instrumentation> does not specify targetPackage";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ if (!parseAllMetaData(res, parser, attrs, "<instrumentation>", a,
+ outError)) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+
+ owner.instrumentation.add(a);
+
+ return a;
+ }
+
+ private boolean parseApplication(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+ throws XmlPullParserException, IOException {
+ final ApplicationInfo ai = owner.applicationInfo;
+ final String pkgName = owner.applicationInfo.packageName;
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestApplication);
+
+ String name = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestApplication_name);
+ if (name != null) {
+ ai.className = buildClassName(pkgName, name, outError);
+ if (ai.className == null) {
+ sa.recycle();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+ }
+
+ String manageSpaceActivity = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity);
+ if (manageSpaceActivity != null) {
+ ai.manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity,
+ outError);
+ }
+
+ TypedValue v = sa.peekValue(
+ com.android.internal.R.styleable.AndroidManifestApplication_label);
+ if (v != null && (ai.labelRes=v.resourceId) == 0) {
+ ai.nonLocalizedLabel = v.coerceToString();
+ }
+
+ ai.icon = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
+ ai.theme = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
+ ai.descriptionRes = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestApplication_description, 0);
+
+ if ((flags&PARSE_IS_SYSTEM) != 0) {
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_persistent,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
+ }
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_debuggable,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_hasCode,
+ true)) {
+ ai.flags |= ApplicationInfo.FLAG_HAS_CODE;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_allowTaskReparenting,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_allowClearUserData,
+ true)) {
+ ai.flags |= ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
+ }
+
+ String str;
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestApplication_permission);
+ ai.permission = (str != null && str.length() > 0) ? str.intern() : null;
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity);
+ ai.taskAffinity = buildTaskAffinityName(ai.packageName, ai.packageName,
+ str, outError);
+
+ if (outError[0] == null) {
+ ai.processName = buildProcessName(ai.packageName, null, sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestApplication_process),
+ flags, mSeparateProcesses, outError);
+
+ ai.enabled = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);
+ }
+
+ sa.recycle();
+
+ if (outError[0] != null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ final int innerDepth = parser.getDepth();
+
+ int type;
+ while ((type=parser.next()) != parser.END_DOCUMENT
+ && (type != parser.END_TAG || parser.getDepth() > innerDepth)) {
+ if (type == parser.END_TAG || type == parser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals("activity")) {
+ Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false);
+ if (a == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ owner.activities.add(a);
+
+ } else if (tagName.equals("receiver")) {
+ Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true);
+ if (a == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ owner.receivers.add(a);
+
+ } else if (tagName.equals("service")) {
+ Service s = parseService(owner, res, parser, attrs, flags, outError);
+ if (s == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ owner.services.add(s);
+
+ } else if (tagName.equals("provider")) {
+ Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
+ if (p == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ owner.providers.add(p);
+
+ } else if (tagName.equals("activity-alias")) {
+ Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError, false);
+ if (a == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ owner.activities.add(a);
+
+ } else if (parser.getName().equals("meta-data")) {
+ // note: application meta-data is stored off to the side, so it can
+ // remain null in the primary copy (we like to avoid extra copies because
+ // it can be large)
+ if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
+ outError)) == null) {
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ } else if (tagName.equals("uses-library")) {
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestUsesLibrary);
+
+ String lname = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestUsesLibrary_name);
+
+ sa.recycle();
+
+ if (lname != null && !owner.usesLibraries.contains(lname)) {
+ owner.usesLibraries.add(lname);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "Unknown element under <application>: " + tagName);
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "Bad element under <application>: " + tagName;
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
+ String[] outError, String tag, TypedArray sa,
+ int nameRes, int labelRes, int iconRes) {
+ String name = sa.getNonResourceString(nameRes);
+ if (name == null) {
+ outError[0] = tag + " does not specify android:name";
+ return false;
+ }
+
+ outInfo.name
+ = buildClassName(owner.applicationInfo.packageName, name, outError);
+ if (outInfo.name == null) {
+ return false;
+ }
+
+ int iconVal = sa.getResourceId(iconRes, 0);
+ if (iconVal != 0) {
+ outInfo.icon = iconVal;
+ outInfo.nonLocalizedLabel = null;
+ }
+
+ TypedValue v = sa.peekValue(labelRes);
+ if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
+ outInfo.nonLocalizedLabel = v.coerceToString();
+ }
+
+ outInfo.packageName = owner.packageName;
+
+ return true;
+ }
+
+ private boolean parseComponentInfo(Package owner, int flags,
+ ComponentInfo outInfo, String[] outError, String tag, TypedArray sa,
+ int nameRes, int labelRes, int iconRes, int processRes,
+ int enabledRes) {
+ if (!parsePackageItemInfo(owner, outInfo, outError, tag, sa,
+ nameRes, labelRes, iconRes)) {
+ return false;
+ }
+
+ if (processRes != 0) {
+ outInfo.processName = buildProcessName(owner.applicationInfo.packageName,
+ owner.applicationInfo.processName, sa.getNonResourceString(processRes),
+ flags, mSeparateProcesses, outError);
+ }
+ outInfo.enabled = sa.getBoolean(enabledRes, true);
+
+ return outError[0] == null;
+ }
+
+ private Activity parseActivity(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, int flags, String[] outError,
+ boolean receiver) throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestActivity);
+
+ Activity a = new Activity(owner);
+
+ if (!parseComponentInfo(owner, flags, a.info, outError,
+ receiver ? "<receiver>" : "<activity>", sa,
+ com.android.internal.R.styleable.AndroidManifestActivity_name,
+ com.android.internal.R.styleable.AndroidManifestActivity_label,
+ com.android.internal.R.styleable.AndroidManifestActivity_icon,
+ com.android.internal.R.styleable.AndroidManifestActivity_process,
+ com.android.internal.R.styleable.AndroidManifestActivity_enabled)) {
+ sa.recycle();
+ return null;
+ }
+
+ final boolean setExported = sa.hasValue(
+ com.android.internal.R.styleable.AndroidManifestActivity_exported);
+ if (setExported) {
+ a.info.exported = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_exported, false);
+ }
+
+ a.component = new ComponentName(owner.applicationInfo.packageName,
+ a.info.name);
+
+ a.info.theme = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestActivity_theme, 0);
+
+ String str;
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestActivity_permission);
+ if (str == null) {
+ a.info.permission = owner.applicationInfo.permission;
+ } else {
+ a.info.permission = str.length() > 0 ? str.toString().intern() : null;
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestActivity_taskAffinity);
+ a.info.taskAffinity = buildTaskAffinityName(owner.applicationInfo.packageName,
+ owner.applicationInfo.taskAffinity, str, outError);
+
+ a.info.flags = 0;
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_multiprocess,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_MULTIPROCESS;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_finishOnTaskLaunch,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_clearTaskOnLaunch,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_noHistory,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_alwaysRetainTaskState,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_stateNotNeeded,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_STATE_NOT_NEEDED;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_excludeFromRecents,
+ false)) {
+ a.info.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+ }
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivity_allowTaskReparenting,
+ (owner.applicationInfo.flags&ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) != 0)) {
+ a.info.flags |= ActivityInfo.FLAG_ALLOW_TASK_REPARENTING;
+ }
+
+ if (!receiver) {
+ a.info.launchMode = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestActivity_launchMode,
+ ActivityInfo.LAUNCH_MULTIPLE);
+ a.info.screenOrientation = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestActivity_screenOrientation,
+ ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+ a.info.configChanges = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestActivity_configChanges,
+ 0);
+ a.info.softInputMode = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestActivity_windowSoftInputMode,
+ 0);
+ } else {
+ a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+ a.info.configChanges = 0;
+ }
+
+ sa.recycle();
+
+ if (outError[0] != null) {
+ return null;
+ }
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("intent-filter")) {
+ ActivityIntentInfo intent = new ActivityIntentInfo(a);
+ if (!parseIntent(res, parser, attrs, flags, intent, outError, !receiver)) {
+ return null;
+ }
+ if (intent.countActions() == 0) {
+ Log.w(TAG, "Intent filter for activity " + intent
+ + " defines no actions");
+ } else {
+ a.intents.add(intent);
+ }
+ } else if (parser.getName().equals("meta-data")) {
+ if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
+ outError)) == null) {
+ return null;
+ }
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ if (receiver) {
+ Log.w(TAG, "Unknown element under <receiver>: " + parser.getName());
+ } else {
+ Log.w(TAG, "Unknown element under <activity>: " + parser.getName());
+ }
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ if (receiver) {
+ outError[0] = "Bad element under <receiver>: " + parser.getName();
+ } else {
+ outError[0] = "Bad element under <activity>: " + parser.getName();
+ }
+ return null;
+ }
+ }
+
+ if (!setExported) {
+ a.info.exported = a.intents.size() > 0;
+ }
+
+ return a;
+ }
+
+ private Activity parseActivityAlias(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, int flags, String[] outError,
+ boolean receiver) throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias);
+
+ String targetActivity = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity);
+ if (targetActivity == null) {
+ outError[0] = "<activity-alias> does not specify android:targetActivity";
+ sa.recycle();
+ return null;
+ }
+
+ targetActivity = buildClassName(owner.applicationInfo.packageName,
+ targetActivity, outError);
+ if (targetActivity == null) {
+ sa.recycle();
+ return null;
+ }
+
+ Activity a = new Activity(owner);
+ Activity target = null;
+
+ final int NA = owner.activities.size();
+ for (int i=0; i<NA; i++) {
+ Activity t = owner.activities.get(i);
+ if (targetActivity.equals(t.info.name)) {
+ target = t;
+ break;
+ }
+ }
+
+ if (target == null) {
+ outError[0] = "<activity-alias> target activity " + targetActivity
+ + " not found in manifest";
+ sa.recycle();
+ return null;
+ }
+
+ a.info.targetActivity = targetActivity;
+
+ a.info.configChanges = target.info.configChanges;
+ a.info.flags = target.info.flags;
+ a.info.icon = target.info.icon;
+ a.info.labelRes = target.info.labelRes;
+ a.info.launchMode = target.info.launchMode;
+ a.info.nonLocalizedLabel = target.info.nonLocalizedLabel;
+ a.info.processName = target.info.processName;
+ a.info.screenOrientation = target.info.screenOrientation;
+ a.info.taskAffinity = target.info.taskAffinity;
+ a.info.theme = target.info.theme;
+
+ if (!parseComponentInfo(owner, flags, a.info, outError,
+ receiver ? "<receiver>" : "<activity>", sa,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_name,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
+ 0,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_enabled)) {
+ sa.recycle();
+ return null;
+ }
+
+ final boolean setExported = sa.hasValue(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_exported);
+ if (setExported) {
+ a.info.exported = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_exported, false);
+ }
+
+ a.component = new ComponentName(owner.applicationInfo.packageName,
+ a.info.name);
+
+ String str;
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_permission);
+ if (str != null) {
+ a.info.permission = str.length() > 0 ? str.toString().intern() : null;
+ }
+
+ sa.recycle();
+
+ if (outError[0] != null) {
+ return null;
+ }
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("intent-filter")) {
+ ActivityIntentInfo intent = new ActivityIntentInfo(a);
+ if (!parseIntent(res, parser, attrs, flags, intent, outError, true)) {
+ return null;
+ }
+ if (intent.countActions() == 0) {
+ Log.w(TAG, "Intent filter for activity alias " + intent
+ + " defines no actions");
+ } else {
+ a.intents.add(intent);
+ }
+ } else if (parser.getName().equals("meta-data")) {
+ if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
+ outError)) == null) {
+ return null;
+ }
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "Unknown element under <activity-alias>: " + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ outError[0] = "Bad element under <activity-alias>: " + parser.getName();
+ return null;
+ }
+ }
+
+ if (!setExported) {
+ a.info.exported = a.intents.size() > 0;
+ }
+
+ return a;
+ }
+
+ private Provider parseProvider(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+ throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestProvider);
+
+ Provider p = new Provider(owner);
+
+ if (!parseComponentInfo(owner, flags, p.info, outError, "<provider>", sa,
+ com.android.internal.R.styleable.AndroidManifestProvider_name,
+ com.android.internal.R.styleable.AndroidManifestProvider_label,
+ com.android.internal.R.styleable.AndroidManifestProvider_icon,
+ com.android.internal.R.styleable.AndroidManifestProvider_process,
+ com.android.internal.R.styleable.AndroidManifestProvider_enabled)) {
+ sa.recycle();
+ return null;
+ }
+
+ p.info.exported = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestProvider_exported, true);
+
+ p.component = new ComponentName(owner.applicationInfo.packageName,
+ p.info.name);
+
+ String cpname = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestProvider_authorities);
+
+ p.info.isSyncable = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestProvider_syncable,
+ false);
+
+ String permission = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestProvider_permission);
+ String str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestProvider_readPermission);
+ if (str == null) {
+ str = permission;
+ }
+ if (str == null) {
+ p.info.readPermission = owner.applicationInfo.permission;
+ } else {
+ p.info.readPermission =
+ str.length() > 0 ? str.toString().intern() : null;
+ }
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestProvider_writePermission);
+ if (str == null) {
+ str = permission;
+ }
+ if (str == null) {
+ p.info.writePermission = owner.applicationInfo.permission;
+ } else {
+ p.info.writePermission =
+ str.length() > 0 ? str.toString().intern() : null;
+ }
+
+ p.info.grantUriPermissions = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestProvider_grantUriPermissions,
+ false);
+
+ p.info.multiprocess = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestProvider_multiprocess,
+ false);
+
+ p.info.initOrder = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestProvider_initOrder,
+ 0);
+
+ sa.recycle();
+
+ if (cpname == null) {
+ outError[0] = "<provider> does not incude authorities attribute";
+ return null;
+ }
+ p.info.authority = cpname.intern();
+
+ if (!parseProviderTags(res, parser, attrs, p, outError)) {
+ return null;
+ }
+
+ return p;
+ }
+
+ private boolean parseProviderTags(Resources res,
+ XmlPullParser parser, AttributeSet attrs,
+ Provider outInfo, String[] outError)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("meta-data")) {
+ if ((outInfo.metaData=parseMetaData(res, parser, attrs,
+ outInfo.metaData, outError)) == null) {
+ return false;
+ }
+ } else if (parser.getName().equals("grant-uri-permission")) {
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission);
+
+ PatternMatcher pa = null;
+
+ String str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission_path);
+ if (str != null) {
+ pa = new PatternMatcher(str, PatternMatcher.PATTERN_LITERAL);
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPrefix);
+ if (str != null) {
+ pa = new PatternMatcher(str, PatternMatcher.PATTERN_PREFIX);
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPattern);
+ if (str != null) {
+ pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+
+ sa.recycle();
+
+ if (pa != null) {
+ if (outInfo.info.uriPermissionPatterns == null) {
+ outInfo.info.uriPermissionPatterns = new PatternMatcher[1];
+ outInfo.info.uriPermissionPatterns[0] = pa;
+ } else {
+ final int N = outInfo.info.uriPermissionPatterns.length;
+ PatternMatcher[] newp = new PatternMatcher[N+1];
+ System.arraycopy(outInfo.info.uriPermissionPatterns, 0, newp, 0, N);
+ newp[N] = pa;
+ outInfo.info.uriPermissionPatterns = newp;
+ }
+ outInfo.info.grantUriPermissions = true;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "Unknown element under <provider>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ outError[0] = "Bad element under <provider>: "
+ + parser.getName();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private Service parseService(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+ throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestService);
+
+ Service s = new Service(owner);
+
+ if (!parseComponentInfo(owner, flags, s.info, outError, "<service>", sa,
+ com.android.internal.R.styleable.AndroidManifestService_name,
+ com.android.internal.R.styleable.AndroidManifestService_label,
+ com.android.internal.R.styleable.AndroidManifestService_icon,
+ com.android.internal.R.styleable.AndroidManifestService_process,
+ com.android.internal.R.styleable.AndroidManifestService_enabled)) {
+ sa.recycle();
+ return null;
+ }
+
+ final boolean setExported = sa.hasValue(
+ com.android.internal.R.styleable.AndroidManifestService_exported);
+ if (setExported) {
+ s.info.exported = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestService_exported, false);
+ }
+
+ s.component = new ComponentName(owner.applicationInfo.packageName,
+ s.info.name);
+
+ String str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestService_permission);
+ if (str == null) {
+ s.info.permission = owner.applicationInfo.permission;
+ } else {
+ s.info.permission = str.length() > 0 ? str.toString().intern() : null;
+ }
+
+ sa.recycle();
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("intent-filter")) {
+ ServiceIntentInfo intent = new ServiceIntentInfo(s);
+ if (!parseIntent(res, parser, attrs, flags, intent, outError, false)) {
+ return null;
+ }
+
+ s.intents.add(intent);
+ } else if (parser.getName().equals("meta-data")) {
+ if ((s.metaData=parseMetaData(res, parser, attrs, s.metaData,
+ outError)) == null) {
+ return null;
+ }
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "Unknown element under <service>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ outError[0] = "Bad element under <service>: "
+ + parser.getName();
+ return null;
+ }
+ }
+
+ if (!setExported) {
+ s.info.exported = s.intents.size() > 0;
+ }
+
+ return s;
+ }
+
+ private boolean parseAllMetaData(Resources res,
+ XmlPullParser parser, AttributeSet attrs, String tag,
+ Component outInfo, String[] outError)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("meta-data")) {
+ if ((outInfo.metaData=parseMetaData(res, parser, attrs,
+ outInfo.metaData, outError)) == null) {
+ return false;
+ }
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "Unknown element under " + tag + ": "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ outError[0] = "Bad element under " + tag + ": "
+ + parser.getName();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private Bundle parseMetaData(Resources res,
+ XmlPullParser parser, AttributeSet attrs,
+ Bundle data, String[] outError)
+ throws XmlPullParserException, IOException {
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestMetaData);
+
+ if (data == null) {
+ data = new Bundle();
+ }
+
+ String name = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestMetaData_name);
+ if (name == null) {
+ outError[0] = "<meta-data> requires an android:name attribute";
+ sa.recycle();
+ return null;
+ }
+
+ boolean success = true;
+
+ TypedValue v = sa.peekValue(
+ com.android.internal.R.styleable.AndroidManifestMetaData_resource);
+ if (v != null && v.resourceId != 0) {
+ //Log.i(TAG, "Meta data ref " + name + ": " + v);
+ data.putInt(name, v.resourceId);
+ } else {
+ v = sa.peekValue(
+ com.android.internal.R.styleable.AndroidManifestMetaData_value);
+ //Log.i(TAG, "Meta data " + name + ": " + v);
+ if (v != null) {
+ if (v.type == TypedValue.TYPE_STRING) {
+ CharSequence cs = v.coerceToString();
+ data.putString(name, cs != null ? cs.toString() : null);
+ } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
+ data.putBoolean(name, v.data != 0);
+ } else if (v.type >= TypedValue.TYPE_FIRST_INT
+ && v.type <= TypedValue.TYPE_LAST_INT) {
+ data.putInt(name, v.data);
+ } else if (v.type == TypedValue.TYPE_FLOAT) {
+ data.putFloat(name, v.getFloat());
+ } else {
+ if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "<meta-data> only supports string, integer, float, color, boolean, and resource reference types");
+ } else {
+ outError[0] = "<meta-data> only supports string, integer, float, color, boolean, and resource reference types";
+ data = null;
+ }
+ }
+ } else {
+ outError[0] = "<meta-data> requires an android:value or android:resource attribute";
+ data = null;
+ }
+ }
+
+ sa.recycle();
+
+ XmlUtils.skipCurrentTag(parser);
+
+ return data;
+ }
+
+ private static final String ANDROID_RESOURCES
+ = "http://schemas.android.com/apk/res/android";
+
+ private boolean parseIntent(Resources res,
+ XmlPullParser parser, AttributeSet attrs, int flags,
+ IntentInfo outInfo, String[] outError, boolean isActivity)
+ throws XmlPullParserException, IOException {
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestIntentFilter);
+
+ int priority = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);
+ if (priority > 0 && isActivity && (flags&PARSE_IS_SYSTEM) == 0) {
+ Log.w(TAG, "Activity with priority > 0, forcing to 0 at "
+ + parser.getPositionDescription());
+ priority = 0;
+ }
+ outInfo.setPriority(priority);
+
+ TypedValue v = sa.peekValue(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_label);
+ if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
+ outInfo.nonLocalizedLabel = v.coerceToString();
+ }
+
+ outInfo.icon = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);
+
+ sa.recycle();
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type=parser.next()) != parser.END_DOCUMENT
+ && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == parser.END_TAG || type == parser.TEXT) {
+ continue;
+ }
+
+ String nodeName = parser.getName();
+ if (nodeName.equals("action")) {
+ String value = attrs.getAttributeValue(
+ ANDROID_RESOURCES, "name");
+ if (value == null || value == "") {
+ outError[0] = "No value supplied for <android:name>";
+ return false;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ outInfo.addAction(value);
+ } else if (nodeName.equals("category")) {
+ String value = attrs.getAttributeValue(
+ ANDROID_RESOURCES, "name");
+ if (value == null || value == "") {
+ outError[0] = "No value supplied for <android:name>";
+ return false;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ outInfo.addCategory(value);
+
+ } else if (nodeName.equals("data")) {
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestData);
+
+ String str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_mimeType);
+ if (str != null) {
+ try {
+ outInfo.addDataType(str);
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ outError[0] = e.toString();
+ sa.recycle();
+ return false;
+ }
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_scheme);
+ if (str != null) {
+ outInfo.addDataScheme(str);
+ }
+
+ String host = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_host);
+ String port = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_port);
+ if (host != null) {
+ outInfo.addDataAuthority(host, port);
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_path);
+ if (str != null) {
+ outInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL);
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_pathPrefix);
+ if (str != null) {
+ outInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX);
+ }
+
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestData_pathPattern);
+ if (str != null) {
+ outInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+
+ sa.recycle();
+ XmlUtils.skipCurrentTag(parser);
+ } else if (!RIGID_PARSER) {
+ Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
+ Log.w(TAG, "Unknown element under <intent-filter>: " + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ } else {
+ outError[0] = "Bad element under <intent-filter>: " + parser.getName();
+ return false;
+ }
+ }
+
+ outInfo.hasDefault = outInfo.hasCategory(Intent.CATEGORY_DEFAULT);
+ if (false) {
+ String cats = "";
+ Iterator<String> it = outInfo.categoriesIterator();
+ while (it != null && it.hasNext()) {
+ cats += " " + it.next();
+ }
+ System.out.println("Intent d=" +
+ outInfo.hasDefault + ", cat=" + cats);
+ }
+
+ return true;
+ }
+
+ public final static class Package {
+ public final String packageName;
+
+ // For now we only support one application per package.
+ public final ApplicationInfo applicationInfo = new ApplicationInfo();
+
+ public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
+ public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
+ public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
+ public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
+ public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
+ public final ArrayList<Service> services = new ArrayList<Service>(0);
+ public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
+
+ public final ArrayList<String> requestedPermissions = new ArrayList<String>();
+
+ public final ArrayList<String> usesLibraries = new ArrayList<String>();
+ public String[] usesLibraryFiles = null;
+
+ // We store the application meta-data independently to avoid multiple unwanted references
+ public Bundle mAppMetaData = null;
+
+ // If this is a 3rd party app, this is the path of the zip file.
+ public String mPath;
+
+ // True if this package is part of the system image.
+ public boolean mSystem;
+
+ // The version code declared for this package.
+ public int mVersionCode;
+
+ // The version name declared for this package.
+ public String mVersionName;
+
+ // The shared user id that this package wants to use.
+ public String mSharedUserId;
+
+ // The shared user label that this package wants to use.
+ public int mSharedUserLabel;
+
+ // Signatures that were read from the package.
+ public Signature mSignatures[];
+
+ // For use by package manager service for quick lookup of
+ // preferred up order.
+ public int mPreferredOrder = 0;
+
+ // Additional data supplied by callers.
+ public Object mExtras;
+
+ /*
+ * Applications hardware preferences
+ */
+ public final ArrayList<ConfigurationInfo> configPreferences =
+ new ArrayList<ConfigurationInfo>();
+
+ public Package(String _name) {
+ packageName = _name;
+ applicationInfo.packageName = _name;
+ applicationInfo.uid = -1;
+ }
+
+ public String toString() {
+ return "Package{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + packageName + "}";
+ }
+ }
+
+ public static class Component<II extends IntentInfo> {
+ public final Package owner;
+ public final ArrayList<II> intents = new ArrayList<II>(0);
+ public ComponentName component;
+ public Bundle metaData;
+
+ public Component(Package _owner) {
+ owner = _owner;
+ }
+
+ public Component(Component<II> clone) {
+ owner = clone.owner;
+ metaData = clone.metaData;
+ }
+ }
+
+ public final static class Permission extends Component<IntentInfo> {
+ public final PermissionInfo info;
+ public boolean tree;
+ public PermissionGroup group;
+
+ public Permission(Package _owner) {
+ super(_owner);
+ info = new PermissionInfo();
+ }
+
+ public Permission(Package _owner, PermissionInfo _info) {
+ super(_owner);
+ info = _info;
+ }
+
+ public String toString() {
+ return "Permission{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + info.name + "}";
+ }
+ }
+
+ public final static class PermissionGroup extends Component<IntentInfo> {
+ public final PermissionGroupInfo info;
+
+ public PermissionGroup(Package _owner) {
+ super(_owner);
+ info = new PermissionGroupInfo();
+ }
+
+ public PermissionGroup(Package _owner, PermissionGroupInfo _info) {
+ super(_owner);
+ info = _info;
+ }
+
+ public String toString() {
+ return "PermissionGroup{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + info.name + "}";
+ }
+ }
+
+ private static boolean copyNeeded(int flags, Package p, Bundle metaData) {
+ if ((flags & PackageManager.GET_META_DATA) != 0
+ && (metaData != null || p.mAppMetaData != null)) {
+ return true;
+ }
+ if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0
+ && p.usesLibraryFiles != null) {
+ return true;
+ }
+ return false;
+ }
+
+ public static ApplicationInfo generateApplicationInfo(Package p, int flags) {
+ if (p == null) return null;
+ if (!copyNeeded(flags, p, null)) {
+ return p.applicationInfo;
+ }
+
+ // Make shallow copy so we can store the metadata/libraries safely
+ ApplicationInfo ai = new ApplicationInfo(p.applicationInfo);
+ if ((flags & PackageManager.GET_META_DATA) != 0) {
+ ai.metaData = p.mAppMetaData;
+ }
+ if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0) {
+ ai.sharedLibraryFiles = p.usesLibraryFiles;
+ }
+ return ai;
+ }
+
+ public static final PermissionInfo generatePermissionInfo(
+ Permission p, int flags) {
+ if (p == null) return null;
+ if ((flags&PackageManager.GET_META_DATA) == 0) {
+ return p.info;
+ }
+ PermissionInfo pi = new PermissionInfo(p.info);
+ pi.metaData = p.metaData;
+ return pi;
+ }
+
+ public static final PermissionGroupInfo generatePermissionGroupInfo(
+ PermissionGroup pg, int flags) {
+ if (pg == null) return null;
+ if ((flags&PackageManager.GET_META_DATA) == 0) {
+ return pg.info;
+ }
+ PermissionGroupInfo pgi = new PermissionGroupInfo(pg.info);
+ pgi.metaData = pg.metaData;
+ return pgi;
+ }
+
+ public final static class Activity extends Component<ActivityIntentInfo> {
+ public final ActivityInfo info =
+ new ActivityInfo();
+
+ public Activity(Package _owner) {
+ super(_owner);
+ info.applicationInfo = owner.applicationInfo;
+ }
+
+ public String toString() {
+ return "Activity{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + component.flattenToString() + "}";
+ }
+ }
+
+ public static final ActivityInfo generateActivityInfo(Activity a,
+ int flags) {
+ if (a == null) return null;
+ if (!copyNeeded(flags, a.owner, a.metaData)) {
+ return a.info;
+ }
+ // Make shallow copies so we can store the metadata safely
+ ActivityInfo ai = new ActivityInfo(a.info);
+ ai.metaData = a.metaData;
+ ai.applicationInfo = generateApplicationInfo(a.owner, flags);
+ return ai;
+ }
+
+ public final static class Service extends Component<ServiceIntentInfo> {
+ public final ServiceInfo info =
+ new ServiceInfo();
+
+ public Service(Package _owner) {
+ super(_owner);
+ info.applicationInfo = owner.applicationInfo;
+ }
+
+ public String toString() {
+ return "Service{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + component.flattenToString() + "}";
+ }
+ }
+
+ public static final ServiceInfo generateServiceInfo(Service s, int flags) {
+ if (s == null) return null;
+ if (!copyNeeded(flags, s.owner, s.metaData)) {
+ return s.info;
+ }
+ // Make shallow copies so we can store the metadata safely
+ ServiceInfo si = new ServiceInfo(s.info);
+ si.metaData = s.metaData;
+ si.applicationInfo = generateApplicationInfo(s.owner, flags);
+ return si;
+ }
+
+ public final static class Provider extends Component {
+ public final ProviderInfo info;
+ public boolean syncable;
+
+ public Provider(Package _owner) {
+ super(_owner);
+ info = new ProviderInfo();
+ info.applicationInfo = owner.applicationInfo;
+ syncable = false;
+ }
+
+ public Provider(Provider existingProvider) {
+ super(existingProvider);
+ this.info = existingProvider.info;
+ this.syncable = existingProvider.syncable;
+ }
+
+ public String toString() {
+ return "Provider{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + info.name + "}";
+ }
+ }
+
+ public static final ProviderInfo generateProviderInfo(Provider p,
+ int flags) {
+ if (p == null) return null;
+ if (!copyNeeded(flags, p.owner, p.metaData)
+ && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0
+ || p.info.uriPermissionPatterns == null)) {
+ return p.info;
+ }
+ // Make shallow copies so we can store the metadata safely
+ ProviderInfo pi = new ProviderInfo(p.info);
+ pi.metaData = p.metaData;
+ if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
+ pi.uriPermissionPatterns = null;
+ }
+ pi.applicationInfo = generateApplicationInfo(p.owner, flags);
+ return pi;
+ }
+
+ public final static class Instrumentation extends Component {
+ public final InstrumentationInfo info =
+ new InstrumentationInfo();
+
+ public Instrumentation(Package _owner) {
+ super(_owner);
+ }
+
+ public String toString() {
+ return "Instrumentation{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + component.flattenToString() + "}";
+ }
+ }
+
+ public static final InstrumentationInfo generateInstrumentationInfo(
+ Instrumentation i, int flags) {
+ if (i == null) return null;
+ if ((flags&PackageManager.GET_META_DATA) == 0) {
+ return i.info;
+ }
+ InstrumentationInfo ii = new InstrumentationInfo(i.info);
+ ii.metaData = i.metaData;
+ return ii;
+ }
+
+ public static class IntentInfo extends IntentFilter {
+ public boolean hasDefault;
+ public int labelRes;
+ public CharSequence nonLocalizedLabel;
+ public int icon;
+ }
+
+ public final static class ActivityIntentInfo extends IntentInfo {
+ public final Activity activity;
+
+ public ActivityIntentInfo(Activity _activity) {
+ activity = _activity;
+ }
+
+ public String toString() {
+ return "ActivityIntentInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + activity.info.name + "}";
+ }
+ }
+
+ public final static class ServiceIntentInfo extends IntentInfo {
+ public final Service service;
+
+ public ServiceIntentInfo(Service _service) {
+ service = _service;
+ }
+
+ public String toString() {
+ return "ServiceIntentInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + service.info.name + "}";
+ }
+ }
+}
diff --git a/core/java/android/content/pm/PackageStats.aidl b/core/java/android/content/pm/PackageStats.aidl
new file mode 100755
index 0000000..8c9786f
--- /dev/null
+++ b/core/java/android/content/pm/PackageStats.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable PackageStats;
diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java
new file mode 100755
index 0000000..66c6efd
--- /dev/null
+++ b/core/java/android/content/pm/PackageStats.java
@@ -0,0 +1,63 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * implementation of PackageStats associated with a
+ * application package.
+ */
+public class PackageStats implements Parcelable {
+ public String packageName;
+ public long codeSize;
+ public long dataSize;
+ public long cacheSize;
+
+ public static final Parcelable.Creator<PackageStats> CREATOR
+ = new Parcelable.Creator<PackageStats>() {
+ public PackageStats createFromParcel(Parcel in) {
+ return new PackageStats(in);
+ }
+
+ public PackageStats[] newArray(int size) {
+ return new PackageStats[size];
+ }
+ };
+
+ public String toString() {
+ return "PackageStats{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + packageName + "}";
+ }
+
+ public PackageStats(String pkgName) {
+ packageName = pkgName;
+ }
+
+ public PackageStats(Parcel source) {
+ packageName = source.readString();
+ codeSize = source.readLong();
+ dataSize = source.readLong();
+ cacheSize = source.readLong();
+ }
+
+ public PackageStats(PackageStats pStats) {
+ packageName = pStats.packageName;
+ codeSize = pStats.codeSize;
+ dataSize = pStats.dataSize;
+ cacheSize = pStats.cacheSize;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags){
+ dest.writeString(packageName);
+ dest.writeLong(codeSize);
+ dest.writeLong(dataSize);
+ dest.writeLong(cacheSize);
+ }
+}
diff --git a/core/java/android/content/pm/PermissionGroupInfo.aidl b/core/java/android/content/pm/PermissionGroupInfo.aidl
new file mode 100755
index 0000000..9f215f1
--- /dev/null
+++ b/core/java/android/content/pm/PermissionGroupInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable PermissionGroupInfo;
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
new file mode 100644
index 0000000..02eb816
--- /dev/null
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Information you can retrieve about a particular security permission
+ * group known to the system. This corresponds to information collected from the
+ * AndroidManifest.xml's &lt;permission-group&gt; tags.
+ */
+public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
+ /**
+ * A string resource identifier (in the package's resources) of this
+ * permission's description. From the "description" attribute or,
+ * if not set, 0.
+ */
+ public int descriptionRes;
+
+ /**
+ * The description string provided in the AndroidManifest file, if any. You
+ * probably don't want to use this, since it will be null if the description
+ * is in a resource. You probably want
+ * {@link PermissionInfo#loadDescription} instead.
+ */
+ public CharSequence nonLocalizedDescription;
+
+ public PermissionGroupInfo() {
+ }
+
+ public PermissionGroupInfo(PermissionGroupInfo orig) {
+ super(orig);
+ descriptionRes = orig.descriptionRes;
+ nonLocalizedDescription = orig.nonLocalizedDescription;
+ }
+
+ /**
+ * Retrieve the textual description of this permission. This
+ * will call back on the given PackageManager to load the description from
+ * the application.
+ *
+ * @param pm A PackageManager from which the label can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a CharSequence containing the permission's description.
+ * If there is no description, null is returned.
+ */
+ public CharSequence loadDescription(PackageManager pm) {
+ if (nonLocalizedDescription != null) {
+ return nonLocalizedDescription;
+ }
+ if (descriptionRes != 0) {
+ CharSequence label = pm.getText(packageName, descriptionRes, null);
+ if (label != null) {
+ return label;
+ }
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "PermissionGroupInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + name + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeInt(descriptionRes);
+ TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
+ }
+
+ public static final Creator<PermissionGroupInfo> CREATOR =
+ new Creator<PermissionGroupInfo>() {
+ public PermissionGroupInfo createFromParcel(Parcel source) {
+ return new PermissionGroupInfo(source);
+ }
+ public PermissionGroupInfo[] newArray(int size) {
+ return new PermissionGroupInfo[size];
+ }
+ };
+
+ private PermissionGroupInfo(Parcel source) {
+ super(source);
+ descriptionRes = source.readInt();
+ nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ }
+}
diff --git a/core/java/android/content/pm/PermissionInfo.aidl b/core/java/android/content/pm/PermissionInfo.aidl
new file mode 100755
index 0000000..5a7d4f4
--- /dev/null
+++ b/core/java/android/content/pm/PermissionInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable PermissionInfo;
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
new file mode 100644
index 0000000..3cc884b
--- /dev/null
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Information you can retrieve about a particular security permission
+ * known to the system. This corresponds to information collected from the
+ * AndroidManifest.xml's &lt;permission&gt; tags.
+ */
+public class PermissionInfo extends PackageItemInfo implements Parcelable {
+ /**
+ * A normal application value for {@link #protectionLevel}, corresponding
+ * to the <code>normal</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_NORMAL = 0;
+
+ /**
+ * Dangerous value for {@link #protectionLevel}, corresponding
+ * to the <code>dangerous</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_DANGEROUS = 1;
+
+ /**
+ * System-level value for {@link #protectionLevel}, corresponding
+ * to the <code>signature</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_SIGNATURE = 2;
+
+ /**
+ * System-level value for {@link #protectionLevel}, corresponding
+ * to the <code>signatureOrSystem</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
+
+ /**
+ * The group this permission is a part of, as per
+ * {@link android.R.attr#permissionGroup}.
+ */
+ public String group;
+
+ /**
+ * A string resource identifier (in the package's resources) of this
+ * permission's description. From the "description" attribute or,
+ * if not set, 0.
+ */
+ public int descriptionRes;
+
+ /**
+ * The description string provided in the AndroidManifest file, if any. You
+ * probably don't want to use this, since it will be null if the description
+ * is in a resource. You probably want
+ * {@link PermissionInfo#loadDescription} instead.
+ */
+ public CharSequence nonLocalizedDescription;
+
+ /**
+ * The level of access this permission is protecting, as per
+ * {@link android.R.attr#protectionLevel}. Values may be
+ * {@link #PROTECTION_NORMAL}, {@link #PROTECTION_DANGEROUS}, or
+ * {@link #PROTECTION_SIGNATURE}.
+ */
+ public int protectionLevel;
+
+ public PermissionInfo() {
+ }
+
+ public PermissionInfo(PermissionInfo orig) {
+ super(orig);
+ group = orig.group;
+ descriptionRes = orig.descriptionRes;
+ protectionLevel = orig.protectionLevel;
+ nonLocalizedDescription = orig.nonLocalizedDescription;
+ }
+
+ /**
+ * Retrieve the textual description of this permission. This
+ * will call back on the given PackageManager to load the description from
+ * the application.
+ *
+ * @param pm A PackageManager from which the label can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a CharSequence containing the permission's description.
+ * If there is no description, null is returned.
+ */
+ public CharSequence loadDescription(PackageManager pm) {
+ if (nonLocalizedDescription != null) {
+ return nonLocalizedDescription;
+ }
+ if (descriptionRes != 0) {
+ CharSequence label = pm.getText(packageName, descriptionRes, null);
+ if (label != null) {
+ return label;
+ }
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "PermissionInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + name + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeString(group);
+ dest.writeInt(descriptionRes);
+ dest.writeInt(protectionLevel);
+ TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
+ }
+
+ public static final Creator<PermissionInfo> CREATOR =
+ new Creator<PermissionInfo>() {
+ public PermissionInfo createFromParcel(Parcel source) {
+ return new PermissionInfo(source);
+ }
+ public PermissionInfo[] newArray(int size) {
+ return new PermissionInfo[size];
+ }
+ };
+
+ private PermissionInfo(Parcel source) {
+ super(source);
+ group = source.readString();
+ descriptionRes = source.readInt();
+ protectionLevel = source.readInt();
+ nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ }
+}
diff --git a/core/java/android/content/pm/ProviderInfo.aidl b/core/java/android/content/pm/ProviderInfo.aidl
new file mode 100755
index 0000000..18fbc8a
--- /dev/null
+++ b/core/java/android/content/pm/ProviderInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable ProviderInfo;
diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java
new file mode 100644
index 0000000..b67ddf6
--- /dev/null
+++ b/core/java/android/content/pm/ProviderInfo.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PatternMatcher;
+
+/**
+ * Holds information about a specific
+ * {@link android.content.ContentProvider content provider}. This is returned by
+ * {@link android.content.pm.PackageManager#resolveContentProvider(java.lang.String, int)
+ * PackageManager.resolveContentProvider()}.
+ */
+public final class ProviderInfo extends ComponentInfo
+ implements Parcelable {
+ /** The name provider is published under content:// */
+ public String authority = null;
+
+ /** Optional permission required for read-only access this content
+ * provider. */
+ public String readPermission = null;
+
+ /** Optional permission required for read/write access this content
+ * provider. */
+ public String writePermission = null;
+
+ /** If true, additional permissions to specific Uris in this content
+ * provider can be granted, as per the
+ * {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
+ * grantUriPermissions} attribute.
+ */
+ public boolean grantUriPermissions = false;
+
+ /**
+ * If non-null, these are the patterns that are allowed for granting URI
+ * permissions. Any URI that does not match one of these patterns will not
+ * allowed to be granted. If null, all URIs are allowed. The
+ * {@link PackageManager#GET_URI_PERMISSION_PATTERNS
+ * PackageManager.GET_URI_PERMISSION_PATTERNS} flag must be specified for
+ * this field to be filled in.
+ */
+ public PatternMatcher[] uriPermissionPatterns = null;
+
+ /** If true, this content provider allows multiple instances of itself
+ * to run in different process. If false, a single instances is always
+ * run in {@link #processName}. */
+ public boolean multiprocess = false;
+
+ /** Used to control initialization order of single-process providers
+ * running in the same process. Higher goes first. */
+ public int initOrder = 0;
+
+ /** Whether or not this provider is syncable. */
+ public boolean isSyncable = false;
+
+ public ProviderInfo() {
+ }
+
+ public ProviderInfo(ProviderInfo orig) {
+ super(orig);
+ authority = orig.authority;
+ readPermission = orig.readPermission;
+ writePermission = orig.writePermission;
+ grantUriPermissions = orig.grantUriPermissions;
+ uriPermissionPatterns = orig.uriPermissionPatterns;
+ multiprocess = orig.multiprocess;
+ initOrder = orig.initOrder;
+ isSyncable = orig.isSyncable;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override public void writeToParcel(Parcel out, int parcelableFlags) {
+ super.writeToParcel(out, parcelableFlags);
+ out.writeString(authority);
+ out.writeString(readPermission);
+ out.writeString(writePermission);
+ out.writeInt(grantUriPermissions ? 1 : 0);
+ out.writeTypedArray(uriPermissionPatterns, parcelableFlags);
+ out.writeInt(multiprocess ? 1 : 0);
+ out.writeInt(initOrder);
+ out.writeInt(isSyncable ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator<ProviderInfo> CREATOR
+ = new Parcelable.Creator<ProviderInfo>() {
+ public ProviderInfo createFromParcel(Parcel in) {
+ return new ProviderInfo(in);
+ }
+
+ public ProviderInfo[] newArray(int size) {
+ return new ProviderInfo[size];
+ }
+ };
+
+ public String toString() {
+ return "ContentProviderInfo{name=" + authority + " className=" + name
+ + " isSyncable=" + (isSyncable ? "true" : "false") + "}";
+ }
+
+ private ProviderInfo(Parcel in) {
+ super(in);
+ authority = in.readString();
+ readPermission = in.readString();
+ writePermission = in.readString();
+ grantUriPermissions = in.readInt() != 0;
+ uriPermissionPatterns = in.createTypedArray(PatternMatcher.CREATOR);
+ multiprocess = in.readInt() != 0;
+ initOrder = in.readInt();
+ isSyncable = in.readInt() != 0;
+ }
+}
diff --git a/core/java/android/content/pm/ResolveInfo.aidl b/core/java/android/content/pm/ResolveInfo.aidl
new file mode 100755
index 0000000..b4e7f8b
--- /dev/null
+++ b/core/java/android/content/pm/ResolveInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable ResolveInfo;
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
new file mode 100644
index 0000000..ee49c02
--- /dev/null
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -0,0 +1,280 @@
+package android.content.pm;
+
+import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Printer;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Information that is returned from resolving an intent
+ * against an IntentFilter. This partially corresponds to
+ * information collected from the AndroidManifest.xml's
+ * &lt;intent&gt; tags.
+ */
+public class ResolveInfo implements Parcelable {
+ /**
+ * The activity that corresponds to this resolution match, if this
+ * resolution is for an activity. One and only one of this and
+ * serviceInfo must be non-null.
+ */
+ public ActivityInfo activityInfo;
+
+ /**
+ * The service that corresponds to this resolution match, if this
+ * resolution is for a service. One and only one of this and
+ * activityInfo must be non-null.
+ */
+ public ServiceInfo serviceInfo;
+
+ /**
+ * The IntentFilter that was matched for this ResolveInfo.
+ */
+ public IntentFilter filter;
+
+ /**
+ * The declared priority of this match. Comes from the "priority"
+ * attribute or, if not set, defaults to 0. Higher values are a higher
+ * priority.
+ */
+ public int priority;
+
+ /**
+ * Order of result according to the user's preference. If the user
+ * has not set a preference for this result, the value is 0; higher
+ * values are a higher priority.
+ */
+ public int preferredOrder;
+
+ /**
+ * The system's evaluation of how well the activity matches the
+ * IntentFilter. This is a match constant, a combination of
+ * {@link IntentFilter#MATCH_CATEGORY_MASK IntentFilter.MATCH_CATEGORY_MASK}
+ * and {@link IntentFilter#MATCH_ADJUSTMENT_MASK IntentFiler.MATCH_ADJUSTMENT_MASK}.
+ */
+ public int match;
+
+ /**
+ * Only set when returned by
+ * {@link PackageManager#queryIntentActivityOptions}, this tells you
+ * which of the given specific intents this result came from. 0 is the
+ * first in the list, < 0 means it came from the generic Intent query.
+ */
+ public int specificIndex = -1;
+
+ /**
+ * This filter has specified the Intent.CATEGORY_DEFAULT, meaning it
+ * would like to be considered a default action that the user can
+ * perform on this data.
+ */
+ public boolean isDefault;
+
+ /**
+ * A string resource identifier (in the package's resources) of this
+ * match's label. From the "label" attribute or, if not set, 0.
+ */
+ public int labelRes;
+
+ /**
+ * The actual string retrieve from <var>labelRes</var> or null if none
+ * was provided.
+ */
+ public CharSequence nonLocalizedLabel;
+
+ /**
+ * A drawable resource identifier (in the package's resources) of this
+ * match's icon. From the "icon" attribute or, if not set, 0.
+ */
+ public int icon;
+
+ /**
+ * Retrieve the current textual label associated with this resolution. This
+ * will call back on the given PackageManager to load the label from
+ * the application.
+ *
+ * @param pm A PackageManager from which the label can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a CharSequence containing the resolutions's label. If the
+ * item does not have a label, its name is returned.
+ */
+ public CharSequence loadLabel(PackageManager pm) {
+ if (nonLocalizedLabel != null) {
+ return nonLocalizedLabel;
+ }
+ ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
+ ApplicationInfo ai = ci.applicationInfo;
+ CharSequence label;
+ if (labelRes != 0) {
+ label = pm.getText(ci.packageName, labelRes, ai);
+ if (label != null) {
+ return label;
+ }
+ }
+ return ci.loadLabel(pm);
+ }
+
+ /**
+ * Retrieve the current graphical icon associated with this resolution. This
+ * will call back on the given PackageManager to load the icon from
+ * the application.
+ *
+ * @param pm A PackageManager from which the icon can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the resolution's icon. If the
+ * item does not have an icon, the default activity icon is returned.
+ */
+ public Drawable loadIcon(PackageManager pm) {
+ ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
+ ApplicationInfo ai = ci.applicationInfo;
+ Drawable dr;
+ if (icon != 0) {
+ dr = pm.getDrawable(ci.packageName, icon, ai);
+ if (dr != null) {
+ return dr;
+ }
+ }
+ return ci.loadIcon(pm);
+ }
+
+ /**
+ * Return the icon resource identifier to use for this match. If the
+ * match defines an icon, that is used; else if the activity defines
+ * an icon, that is used; else, the application icon is used.
+ *
+ * @return The icon associated with this match.
+ */
+ public final int getIconResource() {
+ if (icon != 0) return icon;
+ if (activityInfo != null) return activityInfo.getIconResource();
+ if (serviceInfo != null) return serviceInfo.getIconResource();
+ return 0;
+ }
+
+ public void dump(Printer pw, String prefix) {
+ if (filter != null) {
+ pw.println(prefix + "Filter:");
+ filter.dump(pw, prefix + " ");
+ } else {
+ pw.println(prefix + "Filter: null");
+ }
+ pw.println(prefix + "priority=" + priority
+ + " preferredOrder=" + preferredOrder
+ + " match=0x" + Integer.toHexString(match)
+ + " specificIndex=" + specificIndex
+ + " isDefault=" + isDefault);
+ pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
+ + " nonLocalizedLabel=" + nonLocalizedLabel
+ + " icon=0x" + Integer.toHexString(icon));
+ if (activityInfo != null) {
+ pw.println(prefix + "ActivityInfo:");
+ activityInfo.dump(pw, prefix + " ");
+ } else if (serviceInfo != null) {
+ pw.println(prefix + "ServiceInfo:");
+ // TODO
+ //serviceInfo.dump(pw, prefix + " ");
+ }
+ }
+
+ public ResolveInfo() {
+ }
+
+ public String toString() {
+ ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
+ return "ResolveInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + ci.name + " p=" + priority + " o="
+ + preferredOrder + " m=0x" + Integer.toHexString(match) + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ if (activityInfo != null) {
+ dest.writeInt(1);
+ activityInfo.writeToParcel(dest, parcelableFlags);
+ } else if (serviceInfo != null) {
+ dest.writeInt(2);
+ serviceInfo.writeToParcel(dest, parcelableFlags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (filter != null) {
+ dest.writeInt(1);
+ filter.writeToParcel(dest, parcelableFlags);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(priority);
+ dest.writeInt(preferredOrder);
+ dest.writeInt(match);
+ dest.writeInt(specificIndex);
+ dest.writeInt(labelRes);
+ TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
+ dest.writeInt(icon);
+ }
+
+ public static final Creator<ResolveInfo> CREATOR
+ = new Creator<ResolveInfo>() {
+ public ResolveInfo createFromParcel(Parcel source) {
+ return new ResolveInfo(source);
+ }
+ public ResolveInfo[] newArray(int size) {
+ return new ResolveInfo[size];
+ }
+ };
+
+ private ResolveInfo(Parcel source) {
+ switch (source.readInt()) {
+ case 1:
+ activityInfo = ActivityInfo.CREATOR.createFromParcel(source);
+ serviceInfo = null;
+ break;
+ case 2:
+ serviceInfo = ServiceInfo.CREATOR.createFromParcel(source);
+ activityInfo = null;
+ break;
+ default:
+ activityInfo = null;
+ serviceInfo = null;
+ break;
+ }
+ if (source.readInt() != 0) {
+ filter = IntentFilter.CREATOR.createFromParcel(source);
+ }
+ priority = source.readInt();
+ preferredOrder = source.readInt();
+ match = source.readInt();
+ specificIndex = source.readInt();
+ labelRes = source.readInt();
+ nonLocalizedLabel
+ = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ icon = source.readInt();
+ }
+
+ public static class DisplayNameComparator
+ implements Comparator<ResolveInfo> {
+ public DisplayNameComparator(PackageManager pm) {
+ mPM = pm;
+ }
+
+ public final int compare(ResolveInfo a, ResolveInfo b) {
+ CharSequence sa = a.loadLabel(mPM);
+ if (sa == null) sa = a.activityInfo.name;
+ CharSequence sb = b.loadLabel(mPM);
+ if (sb == null) sb = b.activityInfo.name;
+
+ return sCollator.compare(sa.toString(), sb.toString());
+ }
+
+ private final Collator sCollator = Collator.getInstance();
+ private PackageManager mPM;
+ }
+}
diff --git a/core/java/android/content/pm/ServiceInfo.aidl b/core/java/android/content/pm/ServiceInfo.aidl
new file mode 100755
index 0000000..5ddae1a
--- /dev/null
+++ b/core/java/android/content/pm/ServiceInfo.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable ServiceInfo;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
new file mode 100644
index 0000000..b60650c
--- /dev/null
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -0,0 +1,56 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information you can retrieve about a particular application
+ * service. This corresponds to information collected from the
+ * AndroidManifest.xml's &lt;service&gt; tags.
+ */
+public class ServiceInfo extends ComponentInfo
+ implements Parcelable {
+ /**
+ * Optional name of a permission required to be able to access this
+ * Service. From the "permission" attribute.
+ */
+ public String permission;
+
+ public ServiceInfo() {
+ }
+
+ public ServiceInfo(ServiceInfo orig) {
+ super(orig);
+ permission = orig.permission;
+ }
+
+ public String toString() {
+ return "ServiceInfo{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + name + "}";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ super.writeToParcel(dest, parcelableFlags);
+ dest.writeString(permission);
+ }
+
+ public static final Creator<ServiceInfo> CREATOR =
+ new Creator<ServiceInfo>() {
+ public ServiceInfo createFromParcel(Parcel source) {
+ return new ServiceInfo(source);
+ }
+ public ServiceInfo[] newArray(int size) {
+ return new ServiceInfo[size];
+ }
+ };
+
+ private ServiceInfo(Parcel source) {
+ super(source);
+ permission = source.readString();
+ }
+}
diff --git a/core/java/android/content/pm/Signature.aidl b/core/java/android/content/pm/Signature.aidl
new file mode 100755
index 0000000..3a0d775
--- /dev/null
+++ b/core/java/android/content/pm/Signature.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/WindowManager.aidl
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable Signature;
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
new file mode 100644
index 0000000..1bb3857
--- /dev/null
+++ b/core/java/android/content/pm/Signature.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * Opaque, immutable representation of a signature associated with an
+ * application package.
+ */
+public class Signature implements Parcelable {
+ private final byte[] mSignature;
+ private int mHashCode;
+ private boolean mHaveHashCode;
+ private String mString;
+
+ /**
+ * Create Signature from an existing raw byte array.
+ */
+ public Signature(byte[] signature) {
+ mSignature = signature.clone();
+ }
+
+ /**
+ * Create Signature from a text representation previously returned by
+ * {@link #toChars} or {@link #toCharsString()}.
+ */
+ public Signature(String text) {
+ final int N = text.length()/2;
+ byte[] sig = new byte[N];
+ for (int i=0; i<N; i++) {
+ char c = text.charAt(i*2);
+ byte b = (byte)(
+ (c >= 'a' ? (c - 'a' + 10) : (c - '0'))<<4);
+ c = text.charAt(i*2 + 1);
+ b |= (byte)(c >= 'a' ? (c - 'a' + 10) : (c - '0'));
+ sig[i] = b;
+ }
+ mSignature = sig;
+ }
+
+ /**
+ * Encode the Signature as ASCII text.
+ */
+ public char[] toChars() {
+ return toChars(null, null);
+ }
+
+ /**
+ * Encode the Signature as ASCII text in to an existing array.
+ *
+ * @param existingArray Existing char array or null.
+ * @param outLen Output parameter for the number of characters written in
+ * to the array.
+ * @return Returns either <var>existingArray</var> if it was large enough
+ * to hold the ASCII representation, or a newly created char[] array if
+ * needed.
+ */
+ public char[] toChars(char[] existingArray, int[] outLen) {
+ byte[] sig = mSignature;
+ final int N = sig.length;
+ final int N2 = N*2;
+ char[] text = existingArray == null || N2 > existingArray.length
+ ? new char[N2] : existingArray;
+ for (int j=0; j<N; j++) {
+ byte v = sig[j];
+ int d = (v>>4)&0xf;
+ text[j*2] = (char)(d >= 10 ? ('a' + d - 10) : ('0' + d));
+ d = v&0xf;
+ text[j*2+1] = (char)(d >= 10 ? ('a' + d - 10) : ('0' + d));
+ }
+ if (outLen != null) outLen[0] = N;
+ return text;
+ }
+
+ /**
+ * Return the result of {@link #toChars()} as a String. This result is
+ * cached so future calls will return the same String.
+ */
+ public String toCharsString() {
+ if (mString != null) return mString;
+ String str = new String(toChars());
+ mString = str;
+ return mString;
+ }
+
+ /**
+ * @return the contents of this signature as a byte array.
+ */
+ public byte[] toByteArray() {
+ byte[] bytes = new byte[mSignature.length];
+ System.arraycopy(mSignature, 0, bytes, 0, mSignature.length);
+ return bytes;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ try {
+ if (obj != null) {
+ Signature other = (Signature)obj;
+ return Arrays.equals(mSignature, other.mSignature);
+ }
+ } catch (ClassCastException e) {
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (mHaveHashCode) {
+ return mHashCode;
+ }
+ mHashCode = Arrays.hashCode(mSignature);
+ mHaveHashCode = true;
+ return mHashCode;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ dest.writeByteArray(mSignature);
+ }
+
+ public static final Parcelable.Creator<Signature> CREATOR
+ = new Parcelable.Creator<Signature>() {
+ public Signature createFromParcel(Parcel source) {
+ return new Signature(source);
+ }
+
+ public Signature[] newArray(int size) {
+ return new Signature[size];
+ }
+ };
+
+ private Signature(Parcel source) {
+ mSignature = source.createByteArray();
+ }
+}
diff --git a/core/java/android/content/pm/package.html b/core/java/android/content/pm/package.html
new file mode 100644
index 0000000..766b7dd
--- /dev/null
+++ b/core/java/android/content/pm/package.html
@@ -0,0 +1,7 @@
+<HTML>
+<BODY>
+Contains classes for accessing information about an
+application package, including information about its activities,
+permissions, services, signatures, and providers.
+</BODY>
+</HTML> \ No newline at end of file