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

Commit 5f5d4f60 authored by Winson's avatar Winson
Browse files

Check installed and enabled state for package domain approval

If the package isn't installed or isn't enabled for a user, it cannot
be approved for that user.

Also hooks into package uninstall for a single user to remove the
domain state for that package for that user.

Bug: 183226822

Test: atest DomainVerificationManagerApiTest#getOwnersForDomain
Test: atest com.android.server.pm.test.verify.domain

Change-Id: I04942e1491d470fdd41e99f207bbf85baae87d4c
parent efdf07b6
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.pm.overlay.OverlayPaths;
import android.content.pm.parsing.ParsingPackageRead;
import android.content.pm.parsing.component.ParsedMainComponent;
import android.os.BaseBundle;
import android.os.Debug;
@@ -53,7 +54,6 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

@@ -310,6 +310,20 @@ public class PackageUserState {
        return result;
    }

    public boolean isPackageEnabled(@NonNull ParsingPackageRead pkg) {
        switch (this.enabled) {
            case COMPONENT_ENABLED_STATE_ENABLED:
                return true;
            case COMPONENT_ENABLED_STATE_DISABLED:
            case COMPONENT_ENABLED_STATE_DISABLED_USER:
            case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
                return false;
            default:
            case COMPONENT_ENABLED_STATE_DEFAULT:
                return pkg.isEnabled();
        }
    }

    public boolean isEnabled(ComponentInfo componentInfo, int flags) {
        return isEnabled(componentInfo.applicationInfo.enabled, componentInfo.enabled,
                componentInfo.name, flags);
+1 −0
Original line number Diff line number Diff line
@@ -21759,6 +21759,7 @@ public class PackageManagerService extends IPackageManager.Stub
            clearPackagePreferredActivities(ps.name, nextUserId);
            mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs,
                    nextUserId);
            mDomainVerificationManager.clearPackageForUser(ps.name, nextUserId);
        }
        if (outInfo != null) {
+5 −0
Original line number Diff line number Diff line
@@ -227,6 +227,11 @@ public interface DomainVerificationManagerInternal {
     */
    void clearPackage(@NonNull String packageName);

    /**
     * Remove all state for the given package for the given user.
     */
    void clearPackageForUser(@NonNull String packageName, @UserIdInt int userId);

    /**
     * Delete all the state for a user. This can be because the user has been removed from the
     * device, or simply that the state for a user should be deleted.
+32 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.Intent;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageUserState;
import android.content.pm.ResolveInfo;
import android.content.pm.parsing.component.ParsedActivity;
import android.content.pm.verify.domain.DomainOwner;
@@ -1042,6 +1043,21 @@ public class DomainVerificationService extends SystemService
    public void clearPackage(@NonNull String packageName) {
        synchronized (mLock) {
            mAttachedPkgStates.remove(packageName);
            mSettings.removePackage(packageName);
        }

        mConnection.scheduleWriteSettings();
    }

    @Override
    public void clearPackageForUser(@NonNull String packageName, @UserIdInt int userId) {
        synchronized (mLock) {
            final DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
            if (pkgState != null) {
                pkgState.removeUser(userId);
            }

            mSettings.removePackageForUser(packageName, userId);
        }

        mConnection.scheduleWriteSettings();
@@ -1544,6 +1560,22 @@ public class DomainVerificationService extends SystemService
        String packageName = pkgSetting.getName();
        final AndroidPackage pkg = pkgSetting.getPkg();

        final PackageUserState pkgUserState = pkgSetting.readUserState(userId);
        if (pkgUserState == null) {
            if (DEBUG_APPROVAL) {
                debugApproval(packageName, debugObject, userId, false,
                        "PackageUserState unavailable");
            }
            return APPROVAL_LEVEL_NONE;
        }

        if (!pkgUserState.installed || !pkgUserState.isPackageEnabled(pkg)) {
            if (DEBUG_APPROVAL) {
                debugApproval(packageName, debugObject, userId, false, "package not enabled");
            }
            return APPROVAL_LEVEL_NONE;
        }

        // Should never be null, but if it is, skip this and assume that v2 is enabled
        if (pkg != null && !DomainVerificationUtils.isChangeEnabled(mPlatformCompat, pkg,
                SETTINGS_API_V2)) {
+33 −9
Original line number Diff line number Diff line
@@ -241,7 +241,30 @@ class DomainVerificationSettings {
        }
    }

    public void removePackage(@NonNull String packageName) {
        synchronized (mLock) {
            mPendingPkgStates.remove(packageName);
            mRestoredPkgStates.remove(packageName);
        }
    }

    public void removePackageForUser(@NonNull String packageName, @UserIdInt int userId) {
        synchronized (mLock) {
            final DomainVerificationPkgState pendingPkgState = mPendingPkgStates.get(packageName);
            if (pendingPkgState != null) {
                pendingPkgState.removeUser(userId);
            }
            // TODO(b/170746586): Restored assumes user IDs match, which is probably not the case
            //  on a new device
            final DomainVerificationPkgState restoredPkgState = mRestoredPkgStates.get(packageName);
            if (restoredPkgState != null) {
                restoredPkgState.removeUser(userId);
            }
        }
    }

    public void removeUser(@UserIdInt int userId) {
        synchronized (mLock) {
            int pendingSize = mPendingPkgStates.size();
            for (int index = 0; index < pendingSize; index++) {
                mPendingPkgStates.valueAt(index).removeUser(userId);
@@ -254,6 +277,7 @@ class DomainVerificationSettings {
                mRestoredPkgStates.valueAt(index).removeUser(userId);
            }
        }
    }

    @Nullable
    public DomainVerificationPkgState removePendingState(@NonNull String pkgName) {
Loading