summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2012-09-19 12:43:09 -0700
committerDianne Hackborn <hackbod@google.com>2012-09-19 12:43:09 -0700
commitaba0bed7a4f6301c6e3067fc799d8ef47aaca0b2 (patch)
tree55ac3c3a5276feafe8911522961ad0148b8a8607
parentbe38912262624b9c622d4baded4085b4b3350613 (diff)
downloadandroid_packages_apps_PackageInstaller-aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2.zip
android_packages_apps_PackageInstaller-aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2.tar.gz
android_packages_apps_PackageInstaller-aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2.tar.bz2
Allow side-loading of apps from other users.
This will allow applications to do the desired bypass of downloading and re-installing an app if it is already installed on the device for another user. Change-Id: Ib2bc0f39bc6b495af653560cf13cb8477413186d
-rw-r--r--AndroidManifest.xml2
-rwxr-xr-xsrc/com/android/packageinstaller/InstallAppProgress.java27
-rw-r--r--src/com/android/packageinstaller/PackageInstallerActivity.java61
3 files changed, 69 insertions, 21 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0bc6866..dfc1a6d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,6 +27,7 @@
<action android:name="android.intent.action.INSTALL_PACKAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
+ <data android:scheme="package" />
</intent-filter>
</activity>
<activity android:name=".InstallAppProgress"
@@ -37,7 +38,6 @@
android:excludeFromRecents="true"
android:theme="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DELETE" />
<action android:name="android.intent.action.UNINSTALL_PACKAGE" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/src/com/android/packageinstaller/InstallAppProgress.java b/src/com/android/packageinstaller/InstallAppProgress.java
index a2feacf..e281fd3 100755
--- a/src/com/android/packageinstaller/InstallAppProgress.java
+++ b/src/com/android/packageinstaller/InstallAppProgress.java
@@ -163,7 +163,7 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
mPackageURI = intent.getData();
final String scheme = mPackageURI.getScheme();
- if (scheme != null && !"file".equals(scheme)) {
+ if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) {
throw new IllegalArgumentException("unexpected scheme " + scheme);
}
@@ -227,8 +227,14 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
Log.w(TAG, "Replacing package:" + mAppInfo.packageName);
}
- final File sourceFile = new File(mPackageURI.getPath());
- PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, mAppInfo, sourceFile);
+ final PackageUtil.AppSnippet as;
+ if ("package".equals(mPackageURI.getScheme())) {
+ as = new PackageUtil.AppSnippet(pm.getApplicationLabel(mAppInfo),
+ pm.getApplicationIcon(mAppInfo));
+ } else {
+ final File sourceFile = new File(mPackageURI.getPath());
+ as = PackageUtil.getAppSnippet(this, mAppInfo, sourceFile);
+ }
mLabel = as.label;
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
mStatusTextView = (TextView)findViewById(R.id.center_text);
@@ -250,8 +256,19 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
referrer, null);
PackageInstallObserver observer = new PackageInstallObserver();
- pm.installPackageWithVerificationAndEncryption(mPackageURI, observer, installFlags,
- installerPackageName, verificationParams, null);
+ if ("package".equals(mPackageURI.getScheme())) {
+ try {
+ pm.installExistingPackage(mAppInfo.packageName);
+ observer.packageInstalled(mAppInfo.packageName,
+ PackageManager.INSTALL_SUCCEEDED);
+ } catch (PackageManager.NameNotFoundException e) {
+ observer.packageInstalled(mAppInfo.packageName,
+ PackageManager.INSTALL_FAILED_INVALID_APK);
+ }
+ } else {
+ pm.installPackageWithVerificationAndEncryption(mPackageURI, observer, installFlags,
+ installerPackageName, verificationParams, null);
+ }
}
@Override
diff --git a/src/com/android/packageinstaller/PackageInstallerActivity.java b/src/com/android/packageinstaller/PackageInstallerActivity.java
index 8cf9967..93a52df 100644
--- a/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -25,7 +25,9 @@ import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageUserState;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageParser;
import android.graphics.Rect;
@@ -66,7 +68,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
private Uri mReferrerURI;
private boolean localLOGV = false;
PackageManager mPm;
- PackageParser.Package mPkgInfo;
+ PackageInfo mPkgInfo;
ApplicationInfo mSourceInfo;
// ApplicationInfo object primarily used for already existing applications
@@ -438,12 +440,19 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
if (oldName != null && oldName.length > 0 && oldName[0] != null) {
pkgName = oldName[0];
- mPkgInfo.setPackageName(pkgName);
+ mPkgInfo.packageName = pkgName;
+ mPkgInfo.applicationInfo.packageName = pkgName;
}
// Check if package is already installed. display confirmation dialog if replacing pkg
try {
+ // This is a little convoluted because we want to get all uninstalled
+ // apps, but this may include apps with just data, and if it is just
+ // data we still want to count it as "installed".
mAppInfo = mPm.getApplicationInfo(pkgName,
PackageManager.GET_UNINSTALLED_PACKAGES);
+ if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ mAppInfo = null;
+ }
} catch (NameNotFoundException e) {
mAppInfo = null;
}
@@ -469,27 +478,49 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
mPm = getPackageManager();
final String scheme = mPackageURI.getScheme();
- if (scheme != null && !"file".equals(scheme)) {
- throw new IllegalArgumentException("unexpected scheme " + scheme);
+ if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) {
+ Log.w(TAG, "Unsupported scheme " + scheme);
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI);
+ return;
}
- final File sourceFile = new File(mPackageURI.getPath());
- mPkgInfo = PackageUtil.getPackageInfo(sourceFile);
-
- // Check for parse errors
- if (mPkgInfo == null) {
- Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
- showDialogInner(DLG_PACKAGE_ERROR);
- setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
- return;
+ final PackageUtil.AppSnippet as;
+ if ("package".equals(mPackageURI.getScheme())) {
+ try {
+ mPkgInfo = mPm.getPackageInfo(mPackageURI.getSchemeSpecificPart(),
+ PackageManager.GET_PERMISSIONS | PackageManager.GET_UNINSTALLED_PACKAGES);
+ } catch (NameNotFoundException e) {
+ }
+ if (mPkgInfo == null) {
+ Log.w(TAG, "Requested package " + mPackageURI.getScheme()
+ + " not available. Discontinuing installation");
+ showDialogInner(DLG_PACKAGE_ERROR);
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
+ return;
+ }
+ as = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo),
+ mPm.getApplicationIcon(mPkgInfo.applicationInfo));
+ } else {
+ final File sourceFile = new File(mPackageURI.getPath());
+ PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile);
+
+ // Check for parse errors
+ if (parsed == null) {
+ Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
+ showDialogInner(DLG_PACKAGE_ERROR);
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
+ return;
+ }
+ mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
+ PackageManager.GET_PERMISSIONS, 0, 0, null,
+ new PackageUserState());
+ as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
}
//set view
setContentView(R.layout.install_start);
mInstallConfirm = findViewById(R.id.install_confirm_panel);
mInstallConfirm.setVisibility(View.INVISIBLE);
- final PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(
- this, mPkgInfo.applicationInfo, sourceFile);
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
// Deal with install source.