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

Commit d0f47278 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix role granting flow."

parents ace9dc2d b295ac47
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.SystemService;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -189,7 +190,7 @@ public final class RoleManager {
    @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
    @SystemApi
    public List<String> getRoleHolders(@NonNull String roleName) {
        return getRoleHoldersAsUser(roleName, UserHandle.of(UserHandle.getCallingUserId()));
        return getRoleHoldersAsUser(roleName, Process.myUserHandle());
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -93,8 +93,8 @@ public abstract class RoleControllerService extends Service {
            @Override
            public void onGrantDefaultRoles(IRoleManagerCallback callback) {
                Preconditions.checkNotNull(callback, "callback cannot be null");
                RoleControllerService.this.onGrantDefaultRoles(
                        new RoleManagerCallbackDelegate(callback));
                RoleControllerService.this.onGrantDefaultRoles(new RoleManagerCallbackDelegate(
                        callback));
            }
        };
    }
+1 −1
Original line number Diff line number Diff line
@@ -2467,7 +2467,7 @@
         {@link android.content.pm.PackageManager#addPackageToPreferred}
         for details. -->
    <permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"
        android:protectionLevel="signature|verifier" />
        android:protectionLevel="signature|installer|verifier" />

    <!-- Allows an application to receive the
         {@link android.content.Intent#ACTION_BOOT_COMPLETED} that is
+7 −1
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ public class RemoteRoleControllerService {
            private final IRoleManagerCallback mCallback;

            @NonNull
            private final Runnable mTimeoutRunnable = () -> notifyCallback(false);
            private final Runnable mTimeoutRunnable = this::notifyTimeout;

            private boolean mCallbackNotified;

@@ -243,6 +243,12 @@ public class RemoteRoleControllerService {
                }
            }

            @WorkerThread
            private void notifyTimeout() {
                Slog.e(LOG_TAG, "Call timed out, calling onFailure()");
                notifyCallback(false);
            }

            @WorkerThread
            private void notifyCallback(boolean success) {
                if (mCallbackNotified) {
+40 −31
Original line number Diff line number Diff line
@@ -67,13 +67,13 @@ public class RoleUserState {
    private final int mUserId;

    @GuardedBy("RoleManagerService.mLock")
    private int mVersion = VERSION_UNDEFINED;
    private int mVersion;

    /**
     * Maps role names to its holders' package names. The values should never be null.
     */
    @GuardedBy("RoleManagerService.mLock")
    private ArrayMap<String, ArraySet<String>> mRoles = null;
    private ArrayMap<String, ArraySet<String>> mRoles;

    @GuardedBy("RoleManagerService.mLock")
    private boolean mDestroyed;
@@ -146,6 +146,8 @@ public class RoleUserState {
        throwIfDestroyedLocked();
        ArraySet<String> roleHolders = mRoles.get(roleName);
        if (roleHolders == null) {
            Slog.e(LOG_TAG, "Cannot add role holder for unknown role, role: " + roleName
                    + ", package: " + packageName);
            return false;
        }
        roleHolders.add(packageName);
@@ -167,6 +169,8 @@ public class RoleUserState {
        throwIfDestroyedLocked();
        ArraySet<String> roleHolders = mRoles.get(roleName);
        if (roleHolders == null) {
            Slog.e(LOG_TAG, "Cannot remove role holder for unknown role, role: " + roleName
                    + ", package: " + packageName);
            return false;
        }
        roleHolders.remove(packageName);
@@ -194,10 +198,10 @@ public class RoleUserState {

    @WorkerThread
    private void writeSync(int version, @NonNull ArrayMap<String, ArraySet<String>> roles) {
        AtomicFile destination = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
        AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
        FileOutputStream out = null;
        try {
            out = destination.startWrite();
            out = atomicFile.startWrite();

            XmlSerializer serializer = Xml.newSerializer();
            serializer.setOutput(out, StandardCharsets.UTF_8.name());
@@ -208,11 +212,12 @@ public class RoleUserState {
            serializeRoles(serializer, version, roles);

            serializer.endDocument();
            destination.finishWrite(out);
        } catch (Throwable t) {
            // Any error while writing is fatal.
            Slog.wtf(LOG_TAG, "Failed to write roles file, restoring backup", t);
            destination.failWrite(out);
            atomicFile.finishWrite(out);
        } catch (IllegalArgumentException | IllegalStateException | IOException e) {
            Slog.wtf(LOG_TAG, "Failed to write roles.xml, restoring backup", e);
            if (out != null) {
                atomicFile.failWrite(out);
            }
        } finally {
            IoUtils.closeQuietly(out);
        }
@@ -251,37 +256,34 @@ public class RoleUserState {
    @GuardedBy("RoleManagerService.mLock")
    public void readSyncLocked() {
        if (mRoles != null) {
            throw new IllegalStateException("This RoleUserState has already read the XML file");
        }
        File file = getFile(mUserId);
        FileInputStream in;
        try {
            in = new AtomicFile(file).openRead();
        } catch (FileNotFoundException e) {
            Slog.i(LOG_TAG, "No roles file found");
            return;
            throw new IllegalStateException("This RoleUserState has already read the roles.xml");
        }

        try {
        File file = getFile(mUserId);
        try (FileInputStream in = new AtomicFile(file).openRead()) {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(in, null);
            parseXmlLocked(parser);
        } catch (FileNotFoundException e) {
            Slog.i(LOG_TAG, "roles.xml not found");
            mRoles = new ArrayMap<>();
            mVersion = VERSION_UNDEFINED;
        } catch (XmlPullParserException | IOException e) {
            throw new IllegalStateException("Failed to parse roles file: " + file , e);
        } finally {
            IoUtils.closeQuietly(in);
            throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
        }
    }

    private void parseXmlLocked(@NonNull XmlPullParser parser) throws IOException,
            XmlPullParserException {
        int outerDepth = parser.getDepth();
        int type;
        int depth;
        int innerDepth = parser.getDepth() + 1;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
                continue;
            }

            if (parser.getName().equals(TAG_ROLES)) {
                parseRolesLocked(parser);
                return;
@@ -293,13 +295,16 @@ public class RoleUserState {
            XmlPullParserException {
        mVersion = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION));
        mRoles = new ArrayMap<>();
        int outerDepth = parser.getDepth();

        int type;
        int depth;
        int innerDepth = parser.getDepth() + 1;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
                continue;
            }

            if (parser.getName().equals(TAG_ROLE)) {
                String roleName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
                ArraySet<String> roleHolders = parseRoleHoldersLocked(parser);
@@ -312,18 +317,22 @@ public class RoleUserState {
    private ArraySet<String> parseRoleHoldersLocked(@NonNull XmlPullParser parser)
            throws IOException, XmlPullParserException {
        ArraySet<String> roleHolders = new ArraySet<>();
        int outerDepth = parser.getDepth();

        int type;
        int depth;
        int innerDepth = parser.getDepth() + 1;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
                continue;
            }

            if (parser.getName().equals(TAG_HOLDER)) {
                String roleHolder = parser.getAttributeValue(null, ATTRIBUTE_NAME);
                roleHolders.add(roleHolder);
            }
        }

        return roleHolders;
    }