summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-08-09 19:35:56 -0700
committerDianne Hackborn <hackbod@google.com>2011-08-10 17:30:19 -0700
commit9e9721266feafdf16786b94f6fac4c06220cd422 (patch)
tree9f3de81d278b82453b86a96e84fdcbed49a780f4
parent315ced0cc2ac2f654d2aea3ee78bf9e289c5389d (diff)
downloadandroid_packages_apps_PackageInstaller-9e9721266feafdf16786b94f6fac4c06220cd422.tar.gz
android_packages_apps_PackageInstaller-9e9721266feafdf16786b94f6fac4c06220cd422.tar.bz2
android_packages_apps_PackageInstaller-9e9721266feafdf16786b94f6fac4c06220cd422.zip
Implement new extended install/uninstall options.
Change-Id: I60374f937ca3ccf454480b196a7eb4e36d67fe86
-rw-r--r--AndroidManifest.xml16
-rw-r--r--res/values/strings.xml5
-rwxr-xr-xsrc/com/android/packageinstaller/InstallAppProgress.java12
-rw-r--r--src/com/android/packageinstaller/PackageInstallerActivity.java84
-rw-r--r--src/com/android/packageinstaller/RemoveReceiver.java42
-rwxr-xr-xsrc/com/android/packageinstaller/UninstallAppProgress.java10
-rwxr-xr-xsrc/com/android/packageinstaller/UninstallerActivity.java6
7 files changed, 167 insertions, 8 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a24b0e1f..a0fc6cd6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,11 +17,18 @@
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.INSTALL_PACKAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" />
<data android:scheme="file" />
<data android:mimeType="application/vnd.android.package-archive" />
</intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.INSTALL_PACKAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="content" />
+ <data android:scheme="file" />
+ </intent-filter>
</activity>
<activity android:name=".InstallAppProgress"
android:configChanges="orientation|keyboardHidden">
@@ -32,6 +39,7 @@
<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" />
<data android:scheme="package" />
</intent-filter>
@@ -39,5 +47,13 @@
<activity android:name=".UninstallAppProgress"
android:configChanges="orientation|keyboardHidden">
</activity>
+ <!--
+ <receiver android:name=".RemoveReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
+ <data android:scheme="package" />
+ </intent-filter>
+ </receiver>
+ -->
</application>
</manifest>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d8749782..9dadd510 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -57,6 +57,11 @@
<string name="unknown_apps_dlg_text" product="default">For security, your phone is set to block installation of applications not obtained from Android Market.</string>
<string name="ok">OK</string>
<string name="settings">Settings</string>
+ <!-- Title of dialog asking user if they would allow an application to be an install source. -->
+ <string name="allow_source_dlg_title">Allow new source for apps?</string>
+ <!-- Message of dialog asking user if they would allow an application to be an install source. -->
+ <string name="allow_source_dlg_text"><xliff:g id="app_name">%1$s</xliff:g> wants to install other apps.\n\nAllow
+ this now and in the future?</string>
<string name="manage_applications">Manage applications</string>
<string name="dlg_app_replacement_title">Replace application</string>
<string name="dlg_app_replacement_statement">The application you are installing will replace another application.\n\nAll previous user data will be saved.</string>
diff --git a/src/com/android/packageinstaller/InstallAppProgress.java b/src/com/android/packageinstaller/InstallAppProgress.java
index 08a6d1dd..a1c07952 100755
--- a/src/com/android/packageinstaller/InstallAppProgress.java
+++ b/src/com/android/packageinstaller/InstallAppProgress.java
@@ -30,8 +30,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.net.Uri;
import android.os.Bundle;
@@ -39,7 +37,6 @@ import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
-import android.view.Window;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -74,6 +71,15 @@ public class InstallAppProgress extends Activity implements View.OnClickListener
public void handleMessage(Message msg) {
switch (msg.what) {
case INSTALL_COMPLETE:
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1);
+ setResult(msg.arg1 == PackageManager.INSTALL_SUCCEEDED
+ ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER,
+ result);
+ finish();
+ return;
+ }
// Update the status text
mProgressBar.setVisibility(View.INVISIBLE);
// Show the ok button
diff --git a/src/com/android/packageinstaller/PackageInstallerActivity.java b/src/com/android/packageinstaller/PackageInstallerActivity.java
index 8a009617..d4591601 100644
--- a/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -19,9 +19,11 @@ package com.android.packageinstaller;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -51,7 +53,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
private Uri mPackageURI;
private boolean localLOGV = false;
PackageManager mPm;
- private PackageParser.Package mPkgInfo;
+ PackageParser.Package mPkgInfo;
+ ApplicationInfo mSourceInfo;
// ApplicationInfo object primarily used for already existing applications
private ApplicationInfo mAppInfo = null;
@@ -62,6 +65,8 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
private Button mOk;
private Button mCancel;
+ static final String PREFS_ALLOWED_SOURCES = "allowed_sources";
+
// Dialog identifiers used in showDialog
private static final int DLG_BASE = 0;
private static final int DLG_REPLACE_APP = DLG_BASE + 1;
@@ -69,6 +74,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
private static final int DLG_PACKAGE_ERROR = DLG_BASE + 3;
private static final int DLG_OUT_OF_SPACE = DLG_BASE + 4;
private static final int DLG_INSTALL_ERROR = DLG_BASE + 5;
+ private static final int DLG_ALLOW_SOURCE = DLG_BASE + 6;
private void startInstallConfirm() {
LinearLayout permsSection = (LinearLayout) mInstallConfirm.findViewById(R.id.permissions_section);
@@ -116,6 +122,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, "Canceling installation");
+ setResult(RESULT_CANCELED);
finish();
}})
.setMessage(msgId)
@@ -189,6 +196,28 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
.setMessage(dlgText1)
.setOnCancelListener(this)
.create();
+ case DLG_ALLOW_SOURCE:
+ CharSequence appTitle2 = mPm.getApplicationLabel(mSourceInfo);
+ String dlgText2 = getString(R.string.allow_source_dlg_text,
+ appTitle2.toString());
+ return new AlertDialog.Builder(this)
+ .setTitle(R.string.allow_source_dlg_title)
+ .setMessage(dlgText2)
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ setResult(RESULT_CANCELED);
+ finish();
+ }})
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ SharedPreferences prefs = getSharedPreferences(PREFS_ALLOWED_SOURCES,
+ Context.MODE_PRIVATE);
+ prefs.edit().putBoolean(mSourceInfo.packageName, true).apply();
+ startInstallConfirm();
+ }
+ })
+ .setOnCancelListener(this)
+ .create();
}
return null;
}
@@ -222,7 +251,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
} catch (NameNotFoundException e) {
mAppInfo = null;
}
- if (mAppInfo == null) {
+ if (mAppInfo == null || getIntent().getBooleanExtra(Intent.EXTRA_ALLOW_REPLACE, false)) {
startInstallConfirm();
} else {
if(localLOGV) Log.i(TAG, "Replacing existing package:"+
@@ -230,7 +259,14 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
showDialogInner(DLG_REPLACE_APP);
}
}
-
+
+ void setPmResult(int pmResult) {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, pmResult);
+ setResult(pmResult == PackageManager.INSTALL_SUCCEEDED
+ ? RESULT_OK : RESULT_FIRST_USER, result);
+ }
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -244,6 +280,7 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
if(mPkgInfo == null) {
Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
showDialogInner(DLG_PACKAGE_ERROR);
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
return;
}
@@ -254,8 +291,40 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this,
mPkgInfo.applicationInfo, mPackageURI);
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
- //check setting
- if(!isInstallingUnknownAppsAllowed()) {
+
+ // Deal with install source.
+ String callerPackage = getCallingPackage();
+ if (callerPackage != null && intent.getBooleanExtra(
+ Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) {
+ try {
+ mSourceInfo = mPm.getApplicationInfo(callerPackage, 0);
+ if (mSourceInfo != null) {
+ if ((mSourceInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
+ // System apps don't need to be approved.
+ initiateInstall();
+ return;
+ }
+ /* for now this is disabled, since the user would need to
+ * have enabled the global "unknown sources" setting in the
+ * first place in order to get here.
+ SharedPreferences prefs = getSharedPreferences(PREFS_ALLOWED_SOURCES,
+ Context.MODE_PRIVATE);
+ if (prefs.getBoolean(mSourceInfo.packageName, false)) {
+ // User has already allowed this one.
+ initiateInstall();
+ return;
+ }
+ //ask user to enable setting first
+ showDialogInner(DLG_ALLOW_SOURCE);
+ return;
+ */
+ }
+ } catch (NameNotFoundException e) {
+ }
+ }
+
+ // Check unknown sources.
+ if (!isInstallingUnknownAppsAllowed()) {
//ask user to enable setting first
showDialogInner(DLG_UNKNOWN_APPS);
return;
@@ -280,11 +349,16 @@ public class PackageInstallerActivity extends Activity implements OnCancelListen
if (installerPackageName != null) {
newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
}
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ }
if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
startActivity(newIntent);
finish();
} else if(v == mCancel) {
// Cancel and finish
+ setResult(RESULT_CANCELED);
finish();
}
}
diff --git a/src/com/android/packageinstaller/RemoveReceiver.java b/src/com/android/packageinstaller/RemoveReceiver.java
new file mode 100644
index 00000000..7d8064dd
--- /dev/null
+++ b/src/com/android/packageinstaller/RemoveReceiver.java
@@ -0,0 +1,42 @@
+/*
+**
+** 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 com.android.packageinstaller;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+
+public class RemoveReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+ if (pkg != null) {
+ SharedPreferences prefs = context.getSharedPreferences(
+ PackageInstallerActivity.PREFS_ALLOWED_SOURCES,
+ Context.MODE_PRIVATE);
+ if (prefs.getBoolean(pkg, false)) {
+ prefs.edit().remove(pkg).apply();
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/packageinstaller/UninstallAppProgress.java b/src/com/android/packageinstaller/UninstallAppProgress.java
index b4d71476..3dfa80f3 100755
--- a/src/com/android/packageinstaller/UninstallAppProgress.java
+++ b/src/com/android/packageinstaller/UninstallAppProgress.java
@@ -56,6 +56,16 @@ public class UninstallAppProgress extends Activity implements OnClickListener {
public void handleMessage(Message msg) {
switch (msg.what) {
case UNINSTALL_COMPLETE:
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1);
+ setResult(msg.arg1 == PackageManager.DELETE_SUCCEEDED
+ ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER,
+ result);
+ finish();
+ return;
+ }
+
mResultCode = msg.arg1;
final String packageName = (String) msg.obj;
diff --git a/src/com/android/packageinstaller/UninstallerActivity.java b/src/com/android/packageinstaller/UninstallerActivity.java
index d215894b..5a312973 100755
--- a/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/src/com/android/packageinstaller/UninstallerActivity.java
@@ -71,6 +71,7 @@ public class UninstallerActivity extends Activity implements OnClickListener,
.setNeutralButton(getString(R.string.dlg_ok),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
+ setResult(Activity.RESULT_FIRST_USER);
finish();
}})
.create();
@@ -87,6 +88,7 @@ public class UninstallerActivity extends Activity implements OnClickListener,
.setNeutralButton(getString(R.string.dlg_ok),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
+ setResult(Activity.RESULT_FIRST_USER);
finish();
}})
.create();
@@ -98,6 +100,10 @@ public class UninstallerActivity extends Activity implements OnClickListener,
Intent newIntent = new Intent(Intent.ACTION_VIEW);
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
mAppInfo);
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ }
newIntent.setClass(this, UninstallAppProgress.class);
startActivity(newIntent);
finish();