Replace hidden APIs with their publicly avaiable variants
In order to make PackageInstaller an updatable app, we need to migrate
it away from any hidden APIs and have it depend only on publicly
available APIs or SystemApis.
Test: atest CtsPackageInstallTestCases
Bug: 239722738
Change-Id: Ia9a9ae03ff81fed441fba2d662b1a671cf7b369e
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index fe640ad..fd982f5 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -39,12 +39,13 @@
certificate: "platform",
privileged: true,
- platform_apis: true,
+ platform_apis: false,
+ sdk_version: "system_current",
rename_resources_package: false,
-
static_libs: [
"xz-java",
"androidx.leanback_leanback",
+ "androidx.annotation_annotation",
],
}
@@ -56,7 +57,8 @@
certificate: "platform",
privileged: true,
- platform_apis: true,
+ platform_apis: false,
+ sdk_version: "system_current",
rename_resources_package: false,
overrides: ["PackageInstaller"],
@@ -75,13 +77,15 @@
certificate: "platform",
privileged: true,
- platform_apis: true,
+ platform_apis: false,
+ sdk_version: "system_current",
rename_resources_package: false,
overrides: ["PackageInstaller"],
static_libs: [
"xz-java",
"androidx.leanback_leanback",
+ "androidx.annotation_annotation",
],
aaptflags: ["--product tv"],
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
index 33e5231..4c5875b 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
@@ -16,11 +16,12 @@
package com.android.packageinstaller;
-import android.annotation.Nullable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
+import androidx.annotation.Nullable;
+
import java.io.File;
/**
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java b/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java
index 3a94fdc..71401ee 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java
@@ -16,8 +16,6 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller;
@@ -27,6 +25,9 @@
import android.util.SparseArray;
import android.util.Xml;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java
index c70d7db..be8eabb 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java
@@ -16,11 +16,12 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import androidx.annotation.NonNull;
+
/**
* Receives install events and perists them using a {@link EventResultPersister}.
*/
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java
index 54105bb..3505cfb 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java
@@ -16,7 +16,6 @@
package com.android.packageinstaller;
-import android.annotation.Nullable;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -32,7 +31,7 @@
import android.util.Log;
import android.view.View;
-import com.android.internal.app.AlertActivity;
+import androidx.annotation.Nullable;
import java.io.File;
@@ -79,6 +78,8 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setFinishOnTouchOutside(true);
+
int statusCode = getIntent().getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index 3aa8dbf..c71f380 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -16,28 +16,22 @@
package com.android.packageinstaller;
-import static android.content.pm.PackageInstaller.SessionParams.UID_UNKNOWN;
-
-import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInstaller;
+import android.content.pm.PackageInstaller.InstallInfo;
import android.content.pm.PackageManager;
-import android.content.pm.parsing.ApkLiteParseUtils;
-import android.content.pm.parsing.PackageLite;
-import android.content.pm.parsing.result.ParseResult;
-import android.content.pm.parsing.result.ParseTypeImpl;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Process;
import android.util.Log;
import android.view.View;
import android.widget.Button;
-import com.android.internal.app.AlertActivity;
-import com.android.internal.content.InstallLocationUtils;
+import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileInputStream;
@@ -139,34 +133,30 @@
params.setOriginatingUri(getIntent()
.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI));
params.setOriginatingUid(getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
- UID_UNKNOWN));
+ Process.INVALID_UID));
params.setInstallerPackageName(getIntent().getStringExtra(
Intent.EXTRA_INSTALLER_PACKAGE_NAME));
params.setInstallReason(PackageManager.INSTALL_REASON_USER);
File file = new File(mPackageURI.getPath());
try {
- final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
- final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
- input.reset(), file, /* flags */ 0);
- if (result.isError()) {
- Log.e(LOG_TAG, "Cannot parse package " + file + ". Assuming defaults.");
- Log.e(LOG_TAG,
- "Cannot calculate installed size " + file + ". Try only apk size.");
+ final InstallInfo result = getPackageManager().getPackageInstaller()
+ .getInstallInfo(file, 0);
+ params.setAppPackageName(result.getPackageName());
+ params.setInstallLocation(result.getInstallLocation());
+ try {
+ params.setSize(result.calculateInstalledSize(params));
+ } catch (IOException e) {
+ e.printStackTrace();
params.setSize(file.length());
- } else {
- final PackageLite pkg = result.getResult();
- params.setAppPackageName(pkg.getPackageName());
- params.setInstallLocation(pkg.getInstallLocation());
- params.setSize(InstallLocationUtils.calculateInstalledSize(pkg,
- params.abiOverride));
}
- } catch (IOException e) {
+ } catch (PackageInstaller.PackageParsingException e) {
+
+ Log.e(LOG_TAG, "Cannot parse package " + file + ". Assuming defaults.", e);
Log.e(LOG_TAG,
"Cannot calculate installed size " + file + ". Try only apk size.");
params.setSize(file.length());
}
-
try {
mInstallId = InstallEventReceiver
.addObserver(this, EventResultPersister.GENERATE_NEW_ID,
@@ -318,6 +308,7 @@
try (InputStream in = new FileInputStream(file)) {
long sizeBytes = file.length();
+ long totalRead = 0;
try (OutputStream out = session
.openWrite("PackageInstaller", 0, sizeBytes)) {
byte[] buffer = new byte[1024 * 1024];
@@ -336,8 +327,9 @@
out.write(buffer, 0, numRead);
if (sizeBytes > 0) {
- float fraction = ((float) numRead / (float) sizeBytes);
- session.addProgress(fraction);
+ totalRead += numRead;
+ float fraction = ((float) totalRead / (float) sizeBytes);
+ session.setStagingProgress(fraction);
}
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
index b6b8837..68de2f6 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
@@ -16,7 +16,6 @@
package com.android.packageinstaller;
-import android.annotation.Nullable;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -31,7 +30,7 @@
import android.util.Log;
import android.view.View;
-import com.android.internal.app.AlertActivity;
+import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileOutputStream;
@@ -58,6 +57,7 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setFinishOnTouchOutside(true);
mAlert.setIcon(R.drawable.ic_file_download);
mAlert.setTitle(getString(R.string.app_name_unknown));
mAlert.setView(R.layout.install_content_view);
@@ -123,7 +123,8 @@
* Show an error message and set result as error.
*/
private void showError() {
- (new ErrorDialog()).showAllowingStateLoss(getFragmentManager(), "error");
+ getFragmentManager().beginTransaction()
+ .add(new ErrorDialog(), "error").commitAllowingStateLoss();
Intent result = new Intent();
result.putExtra(Intent.EXTRA_INSTALL_RESULT,
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index 88c1036..7338e64 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -19,26 +19,25 @@
import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.Activity;
-import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.os.RemoteException;
+import android.os.Process;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.util.Arrays;
/**
@@ -80,12 +79,11 @@
final ApplicationInfo sourceInfo = getSourceInfo(callingPackage);
final int originatingUid = getOriginatingUid(sourceInfo);
boolean isTrustedSource = false;
- if (sourceInfo != null
- && (sourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
+ if (sourceInfo != null && sourceInfo.isPrivilegedApp()) {
isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false);
}
- if (!isTrustedSource && originatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
+ if (!isTrustedSource && originatingUid != Process.INVALID_UID) {
final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid);
if (targetSdkVersion < 0) {
Log.w(LOG_TAG, "Cannot get target sdk version for uid " + originatingUid);
@@ -99,6 +97,10 @@
}
}
+ if (sessionId != -1 && !isCallerSessionOwner(originatingUid, sessionId)) {
+ mAbortInstall = true;
+ }
+
final String installerPackageNameFromIntent = getIntent().getStringExtra(
Intent.EXTRA_INSTALLER_PACKAGE_NAME);
if (installerPackageNameFromIntent != null) {
@@ -208,30 +210,27 @@
}
/**
- * Get the originating uid if possible, or
- * {@link android.content.pm.PackageInstaller.SessionParams#UID_UNKNOWN} if not available
+ * Get the originating uid if possible, or {@link Process#INVALID_UID} if not available
*
* @param sourceInfo The source of this installation
- * @return The UID of the installation source or UID_UNKNOWN
+ * @return The UID of the installation source or INVALID_UID
*/
private int getOriginatingUid(@Nullable ApplicationInfo sourceInfo) {
// The originating uid from the intent. We only trust/use this if it comes from either
// the document manager app or the downloads provider
final int uidFromIntent = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
- PackageInstaller.SessionParams.UID_UNKNOWN);
+ Process.INVALID_UID);
final int callingUid;
if (sourceInfo != null) {
callingUid = sourceInfo.uid;
} else {
- try {
- callingUid = ActivityManager.getService()
- .getLaunchedFromUid(getActivityToken());
- } catch (RemoteException ex) {
+ callingUid = getLaunchedFromUid();
+ if (callingUid == Process.INVALID_UID) {
// Cannot reach ActivityManager. Aborting install.
Log.e(LOG_TAG, "Could not determine the launching uid.");
mAbortInstall = true;
- return PackageInstaller.SessionParams.UID_UNKNOWN;
+ return Process.INVALID_UID;
}
}
if (checkPermission(Manifest.permission.MANAGE_DOCUMENTS, -1, callingUid)
@@ -253,7 +252,8 @@
return false;
}
final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo;
- return (appInfo.isSystemApp() && uid == appInfo.uid);
+ return ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ && uid == appInfo.uid);
}
@NonNull
@@ -268,8 +268,14 @@
try {
return mPackageManager.canPackageQuery(callingPackage, targetPackage);
- } catch (NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException e) {
return false;
}
}
+
+ private boolean isCallerSessionOwner(int originatingUid, int sessionId) {
+ PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
+ int installerUid = packageInstaller.getSessionInfo(sessionId).getInstallerUid();
+ return (originatingUid == Process.ROOT_UID) || (originatingUid == installerUid);
+ }
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
index 38c06dd..73c03a5 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
@@ -16,7 +16,6 @@
package com.android.packageinstaller;
-import android.annotation.Nullable;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
@@ -30,7 +29,7 @@
import android.view.View;
import android.widget.Button;
-import com.android.internal.app.AlertActivity;
+import androidx.annotation.Nullable;
import java.io.File;
import java.util.List;
@@ -54,6 +53,8 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setFinishOnTouchOutside(true);
+
if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
// Return result if requested
Intent result = new Intent();
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java
index eea12ec..228a9f5 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java
@@ -16,7 +16,6 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -24,7 +23,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
@@ -32,8 +30,11 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.NonNull;
+
/**
* A util class that handle and post new app installed notifications.
*/
@@ -107,8 +108,8 @@
@NonNull String packageName) {
CharSequence label = appInfo.loadSafeLabel(context.getPackageManager(),
DEFAULT_MAX_LABEL_SIZE_PX,
- PackageItemInfo.SAFE_LABEL_FLAG_TRIM
- | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString();
+ TextUtils.SAFE_STRING_FLAG_TRIM
+ | TextUtils.SAFE_STRING_FLAG_FIRST_LINE).toString();
if (label != null) {
return label.toString();
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index fa93670..ead3839 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -21,11 +21,8 @@
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.StringRes;
import android.app.Activity;
import android.app.AlertDialog;
-import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -36,24 +33,26 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Process;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
-import com.android.internal.app.AlertActivity;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
import java.io.File;
import java.util.ArrayList;
@@ -86,13 +85,12 @@
private Uri mPackageURI;
private Uri mOriginatingURI;
private Uri mReferrerURI;
- private int mOriginatingUid = PackageInstaller.SessionParams.UID_UNKNOWN;
+ private int mOriginatingUid = Process.INVALID_UID;
private String mOriginatingPackage; // The package name corresponding to #mOriginatingUid
private int mActivityResultCode = Activity.RESULT_CANCELED;
private final boolean mLocalLOGV = false;
PackageManager mPm;
- IPackageManager mIpm;
AppOpsManager mAppOpsManager;
UserManager mUserManager;
PackageInstaller mInstaller;
@@ -166,7 +164,8 @@
DialogFragment newDialog = createDialog(id);
if (newDialog != null) {
- newDialog.showAllowingStateLoss(getFragmentManager(), "dialog");
+ getFragmentManager().beginTransaction()
+ .add(newDialog, "dialog").commitAllowingStateLoss();
}
}
@@ -211,9 +210,9 @@
// Log the fact that the app is requesting an install, and is now allowed to do it
// (before this point we could only log that it's requesting an install, but isn't
// allowed to do it yet).
- int appOpCode =
- AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
- mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid, mOriginatingPackage,
+ String appOpStr =
+ AppOpsManager.permissionToOp(Manifest.permission.REQUEST_INSTALL_PACKAGES);
+ mAppOpsManager.noteOpNoThrow(appOpStr, mOriginatingUid, mOriginatingPackage,
mCallingAttributionTag,
"Successfully started package installation activity");
@@ -250,12 +249,9 @@
private boolean isInstallRequestFromUnknownSource(Intent intent) {
if (mCallingPackage != null && intent.getBooleanExtra(
Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) {
- if (mSourceInfo != null) {
- if ((mSourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
- != 0) {
- // Privileged apps can bypass unknown sources check if they want.
- return false;
- }
+ if (mSourceInfo != null && mSourceInfo.isPrivilegedApp()) {
+ // Privileged apps can bypass unknown sources check if they want.
+ return false;
}
}
return true;
@@ -305,7 +301,7 @@
@Override
protected void onCreate(Bundle icicle) {
- if (mLocalLOGV) Log.i(TAG, "creating for user " + getUserId());
+ if (mLocalLOGV) Log.i(TAG, "creating for user " + UserHandle.myUserId());
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
super.onCreate(null);
@@ -316,7 +312,6 @@
setFinishOnTouchOutside(true);
mPm = getPackageManager();
- mIpm = AppGlobals.getPackageManager();
mAppOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
mInstaller = mPm.getPackageInstaller();
mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
@@ -328,8 +323,8 @@
mCallingAttributionTag = intent.getStringExtra(EXTRA_CALLING_ATTRIBUTION_TAG);
mSourceInfo = intent.getParcelableExtra(EXTRA_ORIGINAL_SOURCE_INFO);
mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID,
- PackageInstaller.SessionParams.UID_UNKNOWN);
- mOriginatingPackage = (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN)
+ Process.INVALID_UID);
+ mOriginatingPackage = (mOriginatingUid != Process.INVALID_UID)
? getPackageNameForUid(mOriginatingUid) : null;
final Object packageSource;
@@ -547,15 +542,15 @@
return;
}
// Shouldn't use static constant directly, see b/65534401.
- final int appOpCode =
- AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
- final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid,
+ final String appOpStr =
+ AppOpsManager.permissionToOp(Manifest.permission.REQUEST_INSTALL_PACKAGES);
+ final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpStr, mOriginatingUid,
mOriginatingPackage, mCallingAttributionTag,
"Started package installation activity");
if (mLocalLOGV) Log.i(TAG, "handleUnknownSources(): appMode=" + appOpMode);
switch (appOpMode) {
case AppOpsManager.MODE_DEFAULT:
- mAppOpsManager.setMode(appOpCode, mOriginatingUid,
+ mAppOpsManager.setMode(appOpStr, mOriginatingUid,
mOriginatingPackage, AppOpsManager.MODE_ERRORED);
// fall through
case AppOpsManager.MODE_ERRORED:
@@ -588,8 +583,8 @@
switch (scheme) {
case SCHEME_PACKAGE: {
- for (UserInfo info : mUserManager.getUsers()) {
- PackageManager pmForUser = createContextAsUser(info.getUserHandle(), 0)
+ for (UserHandle handle : mUserManager.getUserHandles(true)) {
+ PackageManager pmForUser = createContextAsUser(handle, 0)
.getPackageManager();
try {
if (pmForUser.canPackageQuery(mCallingPackage, packageName)) {
@@ -645,9 +640,9 @@
* @return {@code true} iff the installer could be set up
*/
private boolean processSessionInfo(@NonNull SessionInfo info) {
- mPkgInfo = generateStubPackageInfo(info.appPackageName);
- mAppSnippet = new PackageUtil.AppSnippet(info.appLabel,
- info.appIcon != null ? new BitmapDrawable(getResources(), info.appIcon)
+ mPkgInfo = generateStubPackageInfo(info.getAppPackageName());
+ mAppSnippet = new PackageUtil.AppSnippet(info.getAppLabel(),
+ info.getAppIcon() != null ? new BitmapDrawable(getResources(), info.getAppIcon())
: getPackageManager().getDefaultActivityIcon());
return true;
}
@@ -693,7 +688,7 @@
if (mReferrerURI != null) {
newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
}
- if (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
+ if (mOriginatingUid != Process.INVALID_UID) {
newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
}
if (installerPackageName != null) {
@@ -829,7 +824,7 @@
if (isDestroyed()) {
return;
}
- getMainThreadHandler().postDelayed(() -> {
+ new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (!isDestroyed()) {
startActivity(getIntent().addFlags(FLAG_ACTIVITY_REORDER_TO_FRONT));
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
index f5570df..698159f 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
@@ -17,14 +17,11 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
@@ -33,6 +30,9 @@
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.io.File;
/**
@@ -131,16 +131,15 @@
public static AppSnippet getAppSnippet(
Activity pContext, ApplicationInfo appInfo, File sourceFile) {
final String archiveFilePath = sourceFile.getAbsolutePath();
- Resources pRes = pContext.getResources();
- AssetManager assmgr = new AssetManager();
- assmgr.addAssetPath(archiveFilePath);
- Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
+ PackageManager pm = pContext.getPackageManager();
+ appInfo.publicSourceDir = archiveFilePath;
+
CharSequence label = null;
// Try to load the label from the package's resources. If an app has not explicitly
// specified any label, just use the package name.
if (appInfo.labelRes != 0) {
try {
- label = res.getText(appInfo.labelRes);
+ label = appInfo.loadLabel(pm);
} catch (Resources.NotFoundException e) {
}
}
@@ -154,7 +153,7 @@
try {
if (appInfo.icon != 0) {
try {
- icon = res.getDrawable(appInfo.icon);
+ icon = appInfo.loadIcon(pm);
} catch (Resources.NotFoundException e) {
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java b/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java
index f77318c..afb2ea4 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java
@@ -16,13 +16,14 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import java.io.File;
import java.io.IOException;
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java
index c3e9c23..1fb66b5 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java
@@ -16,11 +16,12 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import androidx.annotation.NonNull;
+
/**
* Receives uninstall events and persists them using a {@link EventResultPersister}.
*/
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java
index 973ab89..0025b91 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java
@@ -16,29 +16,27 @@
package com.android.packageinstaller;
-import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.admin.IDevicePolicyManager;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.graphics.drawable.Icon;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
+import androidx.annotation.NonNull;
+
import java.util.List;
/**
@@ -94,28 +92,24 @@
switch (legacyStatus) {
case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: {
- IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
- ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
// Find out if the package is an active admin for some non-current user.
- int myUserId = UserHandle.myUserId();
- UserInfo otherBlockingUser = null;
- for (UserInfo user : userManager.getUsers()) {
+ UserHandle myUserHandle = Process.myUserHandle();
+ UserHandle otherBlockingUserHandle = null;
+ for (UserHandle otherUserHandle : userManager.getUserHandles(true)) {
// We only catch the case when the user in question is neither the
// current user nor its profile.
- if (isProfileOfOrSame(userManager, myUserId, user.id)) {
+ if (isProfileOfOrSame(userManager, myUserHandle, otherUserHandle)) {
continue;
}
-
- try {
- if (dpm.packageHasActiveAdmins(appInfo.packageName, user.id)) {
- otherBlockingUser = user;
- break;
- }
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Failed to talk to package manager", e);
+ DevicePolicyManager dpm =
+ context.createContextAsUser(otherUserHandle, 0)
+ .getSystemService(DevicePolicyManager.class);
+ if (dpm.packageHasActiveAdmins(appInfo.packageName)) {
+ otherBlockingUserHandle = otherUserHandle;
+ break;
}
}
- if (otherBlockingUser == null) {
+ if (otherBlockingUserHandle == null) {
Log.d(LOG_TAG, "Uninstall failed because " + appInfo.packageName
+ " is a device admin");
@@ -124,46 +118,42 @@
R.string.uninstall_failed_device_policy_manager));
} else {
Log.d(LOG_TAG, "Uninstall failed because " + appInfo.packageName
- + " is a device admin of user " + otherBlockingUser);
+ + " is a device admin of user " + otherBlockingUserHandle);
+ String userName =
+ context.createContextAsUser(otherBlockingUserHandle, 0)
+ .getSystemService(UserManager.class).getUserName();
setBigText(uninstallFailedNotification, String.format(context.getString(
R.string.uninstall_failed_device_policy_manager_of_user),
- otherBlockingUser.name));
+ userName));
}
break;
}
case PackageManager.DELETE_FAILED_OWNER_BLOCKED: {
- IPackageManager packageManager = IPackageManager.Stub.asInterface(
- ServiceManager.getService("package"));
-
- List<UserInfo> users = userManager.getUsers();
- int blockingUserId = UserHandle.USER_NULL;
- for (int i = 0; i < users.size(); ++i) {
- final UserInfo user = users.get(i);
- try {
- if (packageManager.getBlockUninstallForUser(appInfo.packageName,
- user.id)) {
- blockingUserId = user.id;
- break;
- }
- } catch (RemoteException e) {
- // Shouldn't happen.
- Log.e(LOG_TAG, "Failed to talk to package manager", e);
+ PackageManager packageManager = context.getPackageManager();
+ List<UserHandle> userHandles = userManager.getUserHandles(true);
+ UserHandle otherBlockingUserHandle = null;
+ for (int i = 0; i < userHandles.size(); ++i) {
+ final UserHandle handle = userHandles.get(i);
+ if (packageManager.getBlockUninstallForUser(appInfo.packageName,
+ handle.getIdentifier())) {
+ otherBlockingUserHandle = handle;
+ break;
}
}
- int myUserId = UserHandle.myUserId();
- if (isProfileOfOrSame(userManager, myUserId, blockingUserId)) {
+ UserHandle myUserHandle = Process.myUserHandle();
+ if (isProfileOfOrSame(userManager, myUserHandle, otherBlockingUserHandle)) {
addDeviceManagerButton(context, uninstallFailedNotification);
} else {
addManageUsersButton(context, uninstallFailedNotification);
}
- if (blockingUserId == UserHandle.USER_NULL) {
+ if (otherBlockingUserHandle == null) {
Log.d(LOG_TAG,
"Uninstall failed for " + appInfo.packageName + " with code "
+ returnCode + " no blocking user");
- } else if (blockingUserId == UserHandle.USER_SYSTEM) {
+ } else if (otherBlockingUserHandle == UserHandle.SYSTEM) {
setBigText(uninstallFailedNotification,
context.getString(R.string.uninstall_blocked_device_owner));
} else {
@@ -200,18 +190,18 @@
* Is a profile part of a user?
*
* @param userManager The user manager
- * @param userId The id of the user
- * @param profileId The id of the profile
+ * @param userHandle The handle of the user
+ * @param profileHandle The handle of the profile
*
* @return If the profile is part of the user or the profile parent of the user
*/
- private boolean isProfileOfOrSame(@NonNull UserManager userManager, int userId, int profileId) {
- if (userId == profileId) {
+ private boolean isProfileOfOrSame(UserManager userManager, UserHandle userHandle,
+ UserHandle profileHandle) {
+ if (userHandle.equals(profileHandle)) {
return true;
}
-
- UserInfo parentUser = userManager.getProfileParent(profileId);
- return parentUser != null && parentUser.id == userId;
+ return userManager.getProfileParent(profileHandle) != null
+ && userManager.getProfileParent(profileHandle).equals(userHandle);
}
/**
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
index 1485352..258b6f0 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
@@ -16,9 +16,7 @@
package com.android.packageinstaller;
-import android.annotation.Nullable;
import android.app.Activity;
-import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -40,6 +38,8 @@
import android.util.Log;
import android.widget.Toast;
+import androidx.annotation.Nullable;
+
/**
* Start an uninstallation, show a dialog while uninstalling and return result to the caller.
*/
@@ -119,15 +119,10 @@
int flags = allUsers ? PackageManager.DELETE_ALL_USERS : 0;
flags |= keepData ? PackageManager.DELETE_KEEP_DATA : 0;
- try {
- ActivityThread.getPackageManager().getPackageInstaller().uninstall(
- new VersionedPackage(mAppInfo.packageName,
- PackageManager.VERSION_CODE_HIGHEST),
- getPackageName(), flags, pendingIntent.getIntentSender(),
- user.getIdentifier());
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
+ getPackageManager().getPackageInstaller().uninstall(
+ new VersionedPackage(mAppInfo.packageName,
+ PackageManager.VERSION_CODE_HIGHEST),
+ flags, pendingIntent.getIntentSender());
} else {
mUninstallId = savedInstanceState.getInt(UNINSTALL_ID);
UninstallEventReceiver.addObserver(this, mUninstallId, this);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
index 0198168..9bfb83c 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
@@ -22,12 +22,7 @@
import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.StringRes;
import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ActivityThread;
-import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.DialogFragment;
import android.app.Fragment;
@@ -37,12 +32,10 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDeleteObserver2;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
@@ -51,12 +44,15 @@
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.Process;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
import com.android.packageinstaller.handheld.ErrorDialogFragment;
import com.android.packageinstaller.handheld.UninstallAlertDialogFragment;
import com.android.packageinstaller.television.ErrorFragment;
@@ -94,44 +90,8 @@
// be stale, if e.g. the app was uninstalled while the activity was destroyed.
super.onCreate(null);
- try {
- int callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken());
-
- String callingPackage = getPackageNameForUid(callingUid);
- if (callingPackage == null) {
- Log.e(TAG, "Package not found for originating uid " + callingUid);
- setResult(Activity.RESULT_FIRST_USER);
- finish();
- return;
- } else {
- AppOpsManager appOpsManager = (AppOpsManager) getSystemService(
- Context.APP_OPS_SERVICE);
- if (appOpsManager.noteOpNoThrow(
- AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, callingUid, callingPackage)
- != MODE_ALLOWED) {
- Log.e(TAG, "Install from uid " + callingUid + " disallowed by AppOps");
- setResult(Activity.RESULT_FIRST_USER);
- finish();
- return;
- }
- }
-
- if (getMaxTargetSdkVersionForUid(this, callingUid)
- >= Build.VERSION_CODES.P && AppGlobals.getPackageManager().checkUidPermission(
- Manifest.permission.REQUEST_DELETE_PACKAGES, callingUid)
- != PackageManager.PERMISSION_GRANTED
- && AppGlobals.getPackageManager().checkUidPermission(
- Manifest.permission.DELETE_PACKAGES, callingUid)
- != PackageManager.PERMISSION_GRANTED) {
- Log.e(TAG, "Uid " + callingUid + " does not have "
- + Manifest.permission.REQUEST_DELETE_PACKAGES + " or "
- + Manifest.permission.DELETE_PACKAGES);
-
- setResult(Activity.RESULT_FIRST_USER);
- finish();
- return;
- }
- } catch (RemoteException ex) {
+ int callingUid = getLaunchedFromUid();
+ if (callingUid == Process.INVALID_UID) {
// Cannot reach Package/ActivityManager. Aborting uninstall.
Log.e(TAG, "Could not determine the launching uid.");
@@ -140,6 +100,38 @@
return;
}
+ String callingPackage = getPackageNameForUid(callingUid);
+ if (callingPackage == null) {
+ Log.e(TAG, "Package not found for originating uid " + callingUid);
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ } else {
+ AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
+ if (appOpsManager.noteOpNoThrow(
+ AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, callingUid, callingPackage)
+ != MODE_ALLOWED) {
+ Log.e(TAG, "Install from uid " + callingUid + " disallowed by AppOps");
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ }
+ }
+
+ if (getMaxTargetSdkVersionForUid(this, callingUid) >= Build.VERSION_CODES.P
+ && getBaseContext().checkPermission(Manifest.permission.REQUEST_DELETE_PACKAGES,
+ 0 /* random value for pid */, callingUid) != PackageManager.PERMISSION_GRANTED
+ && getBaseContext().checkPermission(Manifest.permission.DELETE_PACKAGES,
+ 0 /* random value for pid */, callingUid) != PackageManager.PERMISSION_GRANTED) {
+ Log.e(TAG, "Uid " + callingUid + " does not have "
+ + Manifest.permission.REQUEST_DELETE_PACKAGES + " or "
+ + Manifest.permission.DELETE_PACKAGES);
+
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ }
+
// Get intent information.
// We expect an intent with URI of the form package://<packageName>#<className>
// className is optional; if specified, it is the activity the user chose to uninstall
@@ -157,25 +149,24 @@
return;
}
- final IPackageManager pm = IPackageManager.Stub.asInterface(
- ServiceManager.getService("package"));
+ PackageManager pm = getPackageManager();
+ UserManager userManager = getBaseContext().getSystemService(UserManager.class);
mDialogInfo = new DialogInfo();
mDialogInfo.allUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
- if (mDialogInfo.allUsers && !UserManager.get(this).isAdminUser()) {
+ if (mDialogInfo.allUsers && !userManager.isAdminUser()) {
Log.e(TAG, "Only admin user can request uninstall for all users");
showUserIsNotAllowed();
return;
}
mDialogInfo.user = intent.getParcelableExtra(Intent.EXTRA_USER);
if (mDialogInfo.user == null) {
- mDialogInfo.user = android.os.Process.myUserHandle();
+ mDialogInfo.user = Process.myUserHandle();
} else {
- UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
List<UserHandle> profiles = userManager.getUserProfiles();
if (!profiles.contains(mDialogInfo.user)) {
- Log.e(TAG, "User " + android.os.Process.myUserHandle() + " can't request uninstall "
+ Log.e(TAG, "User " + Process.myUserHandle() + " can't request uninstall "
+ "for user " + mDialogInfo.user);
showUserIsNotAllowed();
return;
@@ -186,8 +177,8 @@
try {
mDialogInfo.appInfo = pm.getApplicationInfo(mPackageName,
- PackageManager.MATCH_ANY_USER, mDialogInfo.user.getIdentifier());
- } catch (RemoteException e) {
+ PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_ANY_USER));
+ } catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to get packageName. Package manager is dead?");
}
@@ -202,9 +193,9 @@
if (className != null) {
try {
mDialogInfo.activityInfo = pm.getActivityInfo(
- new ComponentName(mPackageName, className), 0,
- mDialogInfo.user.getIdentifier());
- } catch (RemoteException e) {
+ new ComponentName(mPackageName, className),
+ PackageManager.ComponentInfoFlags.of(0));
+ } catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to get className. Package manager is dead?");
// Continue as the ActivityInfo isn't critical.
}
@@ -366,11 +357,10 @@
int flags = mDialogInfo.allUsers ? PackageManager.DELETE_ALL_USERS : 0;
flags |= keepData ? PackageManager.DELETE_KEEP_DATA : 0;
- ActivityThread.getPackageManager().getPackageInstaller().uninstall(
+ getPackageManager().getPackageInstaller().uninstall(
new VersionedPackage(mDialogInfo.appInfo.packageName,
PackageManager.VERSION_CODE_HIGHEST),
- getPackageName(), flags, pendingIntent.getIntentSender(),
- mDialogInfo.user.getIdentifier());
+ flags, pendingIntent.getIntentSender());
} catch (Exception e) {
notificationManager.cancel(uninstallId);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
index a1bc992..21f4be0 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -16,10 +16,10 @@
package com.android.packageinstaller.handheld;
+import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
+import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
import static android.text.format.Formatter.formatFileSize;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -29,7 +29,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
@@ -41,6 +40,9 @@
import android.widget.CheckBox;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.packageinstaller.R;
import com.android.packageinstaller.UninstallerActivity;
@@ -91,11 +93,11 @@
long appDataSize = 0;
if (user == null) {
- List<UserInfo> users = userManager.getUsers();
+ List<UserHandle> userHandles = userManager.getUserHandles(true);
- int numUsers = users.size();
+ int numUsers = userHandles.size();
for (int i = 0; i < numUsers; i++) {
- appDataSize += getAppDataSizeForUser(pkg, UserHandle.of(users.get(i).id));
+ appDataSize += getAppDataSizeForUser(pkg, userHandles.get(i));
}
} else {
appDataSize = getAppDataSizeForUser(pkg, user);
@@ -128,7 +130,7 @@
final boolean isUpdate =
((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
final UserHandle myUserHandle = Process.myUserHandle();
- UserManager userManager = UserManager.get(getActivity());
+ UserManager userManager = getContext().getSystemService(UserManager.class);
if (isUpdate) {
if (isSingleUser(userManager)) {
messageBuilder.append(getString(R.string.uninstall_update_text));
@@ -139,20 +141,25 @@
if (dialogInfo.allUsers && !isSingleUser(userManager)) {
messageBuilder.append(getString(R.string.uninstall_application_text_all_users));
} else if (!dialogInfo.user.equals(myUserHandle)) {
- UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier());
- if (userInfo.isManagedProfile()
- && userInfo.profileGroupId == myUserHandle.getIdentifier()) {
+ int userId = dialogInfo.user.getIdentifier();
+ UserManager customUserManager = getContext()
+ .createContextAsUser(UserHandle.of(userId), 0)
+ .getSystemService(UserManager.class);
+ String userName = customUserManager.getUserName();
+
+ if (customUserManager.isUserOfType(USER_TYPE_PROFILE_MANAGED)
+ && customUserManager.isSameProfileGroup(dialogInfo.user, myUserHandle)) {
messageBuilder.append(
getString(R.string.uninstall_application_text_current_user_work_profile,
- userInfo.name));
- } else if (userInfo.isCloneProfile()
- && userInfo.profileGroupId == myUserHandle.getIdentifier()) {
+ userName));
+ } else if (customUserManager.isUserOfType(USER_TYPE_PROFILE_CLONE)
+ && customUserManager.isSameProfileGroup(dialogInfo.user, myUserHandle)) {
isClonedApp = true;
messageBuilder.append(getString(
R.string.uninstall_application_text_current_user_clone_profile));
} else {
messageBuilder.append(
- getString(R.string.uninstall_application_text_user, userInfo.name));
+ getString(R.string.uninstall_application_text_user, userName));
}
} else if (isCloneProfile(myUserHandle)) {
isClonedApp = true;
@@ -238,8 +245,8 @@
// Check if another instance of given package exists in clone user profile.
if (cloneUser != null) {
try {
- if (getContext().getPackageManager()
- .getPackageUidAsUser(packageName, cloneUser.getIdentifier()) > 0) {
+ if (getContext().getPackageManager().getPackageUidAsUser(packageName,
+ PackageManager.PackageInfoFlags.of(0), cloneUser.getIdentifier()) > 0) {
return true;
}
} catch (PackageManager.NameNotFoundException e) {
@@ -273,7 +280,6 @@
*/
private boolean isSingleUser(UserManager userManager) {
final int userCount = userManager.getUserCount();
- return userCount == 1
- || (UserManager.isSplitSystemUser() && userCount == 2);
+ return userCount == 1 || (UserManager.isHeadlessSystemUserMode() && userCount == 2);
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
index 2d241ca..5c5720a 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
@@ -16,10 +16,11 @@
package com.android.packageinstaller.television;
+import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
@@ -63,7 +64,7 @@
final boolean isUpdate =
((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
final UserHandle myUserHandle = Process.myUserHandle();
- UserManager userManager = UserManager.get(getActivity());
+ UserManager userManager = getContext().getSystemService(UserManager.class);
if (isUpdate) {
if (isSingleUser(userManager)) {
messageBuilder.append(getString(R.string.uninstall_update_text));
@@ -74,15 +75,21 @@
if (dialogInfo.allUsers && !isSingleUser(userManager)) {
messageBuilder.append(getString(R.string.uninstall_application_text_all_users));
} else if (!dialogInfo.user.equals(myUserHandle)) {
- UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier());
- if (userInfo.isManagedProfile()
- && userInfo.profileGroupId == myUserHandle.getIdentifier()) {
+ int userId = dialogInfo.user.getIdentifier();
+ UserManager customUserManager = getContext()
+ .createContextAsUser(UserHandle.of(userId), 0)
+ .getSystemService(UserManager.class);
+ String userName = customUserManager.getUserName();
+
+ if (customUserManager.isUserOfType(USER_TYPE_PROFILE_MANAGED)
+ && customUserManager.isSameProfileGroup(dialogInfo.user, myUserHandle)) {
+
messageBuilder.append(
getString(R.string.uninstall_application_text_current_user_work_profile,
- userInfo.name));
+ userName));
} else {
messageBuilder.append(
- getString(R.string.uninstall_application_text_user, userInfo.name));
+ getString(R.string.uninstall_application_text_user, userName));
}
} else {
messageBuilder.append(getString(R.string.uninstall_application_text));
@@ -126,7 +133,6 @@
*/
private boolean isSingleUser(UserManager userManager) {
final int userCount = userManager.getUserCount();
- return userCount == 1
- || (UserManager.isSplitSystemUser() && userCount == 2);
+ return userCount == 1 || (UserManager.isHeadlessSystemUserMode() && userCount == 2);
}
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java
index a4f217c..7e76dd4 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java
@@ -17,24 +17,22 @@
package com.android.packageinstaller.television;
import android.app.Activity;
-import android.app.admin.IDevicePolicyManager;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageDeleteObserver2;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
@@ -139,37 +137,34 @@
// Update the status text
final String statusText;
+ Context ctx = getBaseContext();
switch (msg.arg1) {
case PackageManager.DELETE_SUCCEEDED:
statusText = getString(R.string.uninstall_done);
// Show a Toast and finish the activity
- Context ctx = getBaseContext();
Toast.makeText(ctx, statusText, Toast.LENGTH_LONG).show();
setResultAndFinish();
return;
case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: {
UserManager userManager =
(UserManager) getSystemService(Context.USER_SERVICE);
- IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
- ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
// Find out if the package is an active admin for some non-current user.
- int myUserId = UserHandle.myUserId();
- UserInfo otherBlockingUser = null;
- for (UserInfo user : userManager.getUsers()) {
+ UserHandle myUserHandle = Process.myUserHandle();
+ UserHandle otherBlockingUserHandle = null;
+ for (UserHandle otherUserHandle : userManager.getUserHandles(true)) {
// We only catch the case when the user in question is neither the
// current user nor its profile.
- if (isProfileOfOrSame(userManager, myUserId, user.id)) continue;
-
- try {
- if (dpm.packageHasActiveAdmins(packageName, user.id)) {
- otherBlockingUser = user;
- break;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to talk to package manager", e);
+ if (isProfileOfOrSame(userManager, myUserHandle, otherUserHandle)) {
+ continue;
+ }
+ DevicePolicyManager dpm = ctx.createContextAsUser(otherUserHandle, 0)
+ .getSystemService(DevicePolicyManager.class);
+ if (dpm.packageHasActiveAdmins(packageName)) {
+ otherBlockingUserHandle = otherUserHandle;
+ break;
}
}
- if (otherBlockingUser == null) {
+ if (otherBlockingUserHandle == null) {
Log.d(TAG, "Uninstall failed because " + packageName
+ " is a device admin");
getProgressFragment().setDeviceManagerButtonVisible(true);
@@ -177,45 +172,41 @@
R.string.uninstall_failed_device_policy_manager);
} else {
Log.d(TAG, "Uninstall failed because " + packageName
- + " is a device admin of user " + otherBlockingUser);
+ + " is a device admin of user " + otherBlockingUserHandle);
getProgressFragment().setDeviceManagerButtonVisible(false);
+ String userName = ctx.createContextAsUser(otherBlockingUserHandle, 0)
+ .getSystemService(UserManager.class).getUserName();
statusText = String.format(
getString(R.string.uninstall_failed_device_policy_manager_of_user),
- otherBlockingUser.name);
+ userName);
}
break;
}
case PackageManager.DELETE_FAILED_OWNER_BLOCKED: {
UserManager userManager =
(UserManager) getSystemService(Context.USER_SERVICE);
- IPackageManager packageManager = IPackageManager.Stub.asInterface(
- ServiceManager.getService("package"));
- List<UserInfo> users = userManager.getUsers();
- int blockingUserId = UserHandle.USER_NULL;
- for (int i = 0; i < users.size(); ++i) {
- final UserInfo user = users.get(i);
- try {
- if (packageManager.getBlockUninstallForUser(packageName,
- user.id)) {
- blockingUserId = user.id;
- break;
- }
- } catch (RemoteException e) {
- // Shouldn't happen.
- Log.e(TAG, "Failed to talk to package manager", e);
+ PackageManager packageManager = ctx.getPackageManager();
+ List<UserHandle> userHandles = userManager.getUserHandles(true);
+ UserHandle otherBlockingUserHandle = null;
+ for (int i = 0; i < userHandles.size(); ++i) {
+ final UserHandle handle = userHandles.get(i);
+ if (packageManager.getBlockUninstallForUser(packageName,
+ handle.getIdentifier())) {
+ otherBlockingUserHandle = handle;
+ break;
}
}
- int myUserId = UserHandle.myUserId();
- if (isProfileOfOrSame(userManager, myUserId, blockingUserId)) {
+ UserHandle myUserHandle = Process.myUserHandle();
+ if (isProfileOfOrSame(userManager, myUserHandle, otherBlockingUserHandle)) {
getProgressFragment().setDeviceManagerButtonVisible(true);
} else {
getProgressFragment().setDeviceManagerButtonVisible(false);
getProgressFragment().setUsersButtonVisible(true);
}
// TODO: b/25442806
- if (blockingUserId == UserHandle.USER_SYSTEM) {
+ if (otherBlockingUserHandle == UserHandle.SYSTEM) {
statusText = getString(R.string.uninstall_blocked_device_owner);
- } else if (blockingUserId == UserHandle.USER_NULL) {
+ } else if (otherBlockingUserHandle == null) {
Log.d(TAG, "Uninstall failed for " + packageName + " with code "
+ msg.arg1 + " no blocking user");
statusText = getString(R.string.uninstall_failed);
@@ -239,12 +230,13 @@
}
}
- private boolean isProfileOfOrSame(UserManager userManager, int userId, int profileId) {
- if (userId == profileId) {
+ private boolean isProfileOfOrSame(UserManager userManager, UserHandle userHandle,
+ UserHandle profileHandle) {
+ if (userHandle.equals(profileHandle)) {
return true;
}
- UserInfo parentUser = userManager.getProfileParent(profileId);
- return parentUser != null && parentUser.id == userId;
+ return userManager.getProfileParent(profileHandle) != null
+ && userManager.getProfileParent(profileHandle).equals(userHandle);
}
@Override
@@ -278,7 +270,7 @@
mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
if (user == null) {
- user = android.os.Process.myUserHandle();
+ user = Process.myUserHandle();
}
PackageDeleteObserver observer = new PackageDeleteObserver();
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java
index af6d9c5..c2d95b2 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java
@@ -16,7 +16,6 @@
package com.android.packageinstaller.television;
-import android.annotation.Nullable;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
@@ -28,6 +27,8 @@
import android.widget.Button;
import android.widget.TextView;
+import androidx.annotation.Nullable;
+
import com.android.packageinstaller.PackageUtil;
import com.android.packageinstaller.R;
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
index 063d789..8dd691d 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
@@ -265,7 +265,7 @@
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(action);
mContext.registerReceiver(broadcastReceiver, intentFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
+ Context.RECEIVER_EXPORTED);
// Create a matching PendingIntent and use it to generate the IntentSender
Intent broadcastIntent = new Intent(action);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
index 06b1c16..34234f5 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
@@ -211,7 +211,6 @@
}
final PackageManager pm = getPackageManager();
File tempFile = null;
- int installFlags = 0;
PowerManager.WakeLock lock = getLock(this.getApplicationContext());
boolean messageSent = false;
try {
@@ -220,17 +219,14 @@
existingPkgInfo = pm.getPackageInfo(packageName,
PackageManager.MATCH_ANY_USER | PackageManager.GET_PERMISSIONS);
if (existingPkgInfo != null) {
- installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Replacing package:" + packageName);
+ }
}
} catch (PackageManager.NameNotFoundException e) {
// Ignore this exception. We could not find the package, will treat as a new
// installation.
}
- if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Replacing package:" + packageName);
- }
- }
// TODO(28021618): This was left as a temp file due to the fact that this code is being
// deprecated and that we need the bare minimum to continue working moving forward
// If this code is used as reference, this permission logic might want to be