Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc28cb37 authored by Doris Ling's avatar Doris Ling
Browse files

Fix crash when primary user select app installed by secondary user.

- PackageManager.getPackageInfo() can return null. When trying to check
the app permission info, check for null package info and only process
the permission info when package info is available.
- Update usage of PackageManager.MATCH_UNINSTALLED_PACKAGES to
PackageManager.MATCH_ANY_USER, as the implementation for querying
packages for other users have been changed.
- Add PackageManager APIs used by AppStateAppOpsBridge to
IPackageManagerWrapper for test purpose.
- Change UserManager.get() to Context.getSystemService() to fix test
failure.

Change-Id: I52de924618aa252ffaae02b8f06ebe5b1d0def61
Fix: 37409266
Test: make RunSettingsRoboTests
parent 83392792
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ public abstract class AppCounter extends AsyncTask<Void, Void, Integer> {

    public AppCounter(Context context, PackageManagerWrapper packageManager) {
        mPm = packageManager;
        mUm = UserManager.get(context);
        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
    }

    @Override
+24 −14
Original line number Diff line number Diff line
@@ -19,12 +19,12 @@ import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AppOpsManager.PackageOps;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
@@ -46,7 +46,7 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge {

    private static final String TAG = "AppStateAppOpsBridge";

    private final IPackageManager mIPackageManager;
    private final IPackageManagerWrapper mIPackageManager;
    private final UserManager mUserManager;
    private final List<UserHandle> mProfiles;
    private final AppOpsManager mAppOpsManager;
@@ -56,9 +56,16 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge {

    public AppStateAppOpsBridge(Context context, ApplicationsState appState, Callback callback,
            int appOpsOpCode, String[] permissions) {
        this(context, appState, callback, appOpsOpCode, permissions,
            new IPackageManagerWrapperImpl(AppGlobals.getPackageManager()));
    }

    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    AppStateAppOpsBridge(Context context, ApplicationsState appState, Callback callback,
            int appOpsOpCode, String[] permissions, IPackageManagerWrapper packageManager) {
        super(appState, callback);
        mContext = context;
        mIPackageManager = AppGlobals.getPackageManager();
        mIPackageManager = packageManager;
        mUserManager = UserManager.get(context);
        mProfiles = mUserManager.getUserProfiles();
        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
@@ -92,8 +99,9 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge {
                .getUserId(uid)));
        try {
            permissionState.packageInfo = mIPackageManager.getPackageInfo(pkg,
                    PackageManager.GET_PERMISSIONS | PackageManager.MATCH_UNINSTALLED_PACKAGES,
                    PackageManager.GET_PERMISSIONS | PackageManager.MATCH_ANY_USER,
                    permissionState.userHandle.getIdentifier());
            if (permissionState.packageInfo != null) {
                // Check static permission state (whatever that is declared in package manifest)
                String[] requestedPermissions = permissionState.packageInfo.requestedPermissions;
                int[] permissionFlags = permissionState.packageInfo.requestedPermissionsFlags;
@@ -101,13 +109,15 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge {
                    for (int i = 0; i < requestedPermissions.length; i++) {
                        if (doesAnyPermissionMatch(requestedPermissions[i], mPermissions)) {
                            permissionState.permissionDeclared = true;
                        if ((permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
                            if ((permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED)
                                    != 0) {
                                permissionState.staticPermissionGranted = true;
                                break;
                            }
                        }
                    }
                }
            }
            // Check app op state.
            List<PackageOps> ops = mAppOpsManager.getOpsForPackage(uid, pkg, mAppOpsOpCodes);
            if (ops != null && ops.size() > 0 && ops.get(0).getOps().size() > 0) {
+31 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.settings.applications;

import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;

@@ -41,4 +43,33 @@ public interface IPackageManagerWrapper {
     * @see android.content.pm.IPackageManager#findPersistentPreferredActivity
     */
    ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) throws RemoteException;

    /**
     * Calls {@code IPackageManager.getPackageInfo()}.
     *
     * @see android.content.pm.IPackageManager#getPackageInfo
     */
    PackageInfo getPackageInfo(String packageName, int flags, int userId) throws RemoteException;

    /**
     * Calls {@code IPackageManager.getAppOpPermissionPackages()}.
     *
     * @see android.content.pm.IPackageManager#getAppOpPermissionPackages
     */
    String[] getAppOpPermissionPackages(String permissionName) throws RemoteException;

    /**
     * Calls {@code IPackageManager.isPackageAvailable()}.
     *
     * @see android.content.pm.IPackageManager#isPackageAvailable
     */
    boolean isPackageAvailable(String packageName, int userId) throws RemoteException;

    /**
     * Calls {@code IPackageManager.getPackagesHoldingPermissions()}.
     *
     * @see android.content.pm.IPackageManager#getPackagesHoldingPermissions
     */
    ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
        String[] permissions, int flags, int userId) throws RemoteException;
}
+25 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.settings.applications;

import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;

@@ -39,4 +41,27 @@ public class IPackageManagerWrapperImpl implements IPackageManagerWrapper {
            throws RemoteException {
        return mPms.findPersistentPreferredActivity(intent, userId);
    }

    @Override
    public PackageInfo getPackageInfo(String packageName, int flags, int userId)
            throws RemoteException {
        return mPms.getPackageInfo(packageName, flags, userId);
    }

    @Override
    public String[] getAppOpPermissionPackages(String permissionName) throws RemoteException {
        return mPms.getAppOpPermissionPackages(permissionName);
    }

    @Override
    public boolean isPackageAvailable(String packageName, int userId) throws RemoteException {
        return mPms.isPackageAvailable(packageName, userId);
    }

    @Override
    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
        String[] permissions, int flags, int userId) throws RemoteException {
        return mPms.getPackagesHoldingPermissions(permissions, flags, userId);
    }

}
+1 −1
Original line number Diff line number Diff line
@@ -500,7 +500,7 @@ public class RunningState {
                si.mRunningService = service;
                try {
                    si.mServiceInfo = ActivityThread.getPackageManager().getServiceInfo(
                            service.service, PackageManager.MATCH_UNINSTALLED_PACKAGES,
                            service.service, PackageManager.MATCH_ANY_USER,
                            UserHandle.getUserId(service.uid));

                    if (si.mServiceInfo == null) {
Loading