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

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

Merge "Add RoleControllerManager for role controller service."

parents a091cc2d a4959e56
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ java_defaults {
        "core/java/android/app/prediction/IPredictionCallback.aidl",
        "core/java/android/app/prediction/IPredictionManager.aidl",
        "core/java/android/app/role/IOnRoleHoldersChangedListener.aidl",
        "core/java/android/app/role/IRoleController.aidl",
        "core/java/android/app/role/IRoleManager.aidl",
        "core/java/android/app/role/IRoleManagerCallback.aidl",
        "core/java/android/app/slice/ISliceManager.aidl",
@@ -275,7 +276,6 @@ java_defaults {
        "core/java/android/os/storage/IStorageShutdownObserver.aidl",
        "core/java/android/os/storage/IObbActionListener.aidl",
        "core/java/android/permission/IPermissionController.aidl",
        "core/java/android/rolecontrollerservice/IRoleControllerService.aidl",
        ":keystore_aidl",
        "core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl",
        "core/java/android/service/appprediction/IPredictionService.aidl",
+11 −15
Original line number Diff line number Diff line
@@ -1116,6 +1116,17 @@ package android.app.role {
    method public void onRoleHoldersChanged(@NonNull String, @NonNull android.os.UserHandle);
  }
  public abstract class RoleControllerService extends android.app.Service {
    ctor public RoleControllerService();
    method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
    method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
    method public abstract void onClearRoleHolders(@NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
    method public abstract void onGrantDefaultRoles(@NonNull android.app.role.RoleManagerCallback);
    method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
    method public abstract void onSmsKillSwitchToggled(boolean);
    field public static final String SERVICE_INTERFACE = "android.app.role.RoleControllerService";
  }
  public final class RoleManager {
    method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
@@ -6177,21 +6188,6 @@ package android.provider {
}
package android.rolecontrollerservice {
  public abstract class RoleControllerService extends android.app.Service {
    ctor public RoleControllerService();
    method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
    method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
    method public abstract void onClearRoleHolders(@NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
    method public abstract void onGrantDefaultRoles(@NonNull android.app.role.RoleManagerCallback);
    method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
    method public abstract void onSmsKillSwitchToggled(boolean);
    field public static final String SERVICE_INTERFACE = "android.rolecontrollerservice.RoleControllerService";
  }
}
package android.security.keystore {
  public abstract class AttestationUtils {
+9 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.app.contentsuggestions.IContentSuggestionsManager;
import android.app.job.IJobScheduler;
import android.app.job.JobScheduler;
import android.app.prediction.AppPredictionManager;
import android.app.role.RoleControllerManager;
import android.app.role.RoleManager;
import android.app.slice.SliceManager;
import android.app.timedetector.TimeDetector;
@@ -1243,6 +1244,14 @@ final class SystemServiceRegistry {
                        return new RoleManager(ctx.getOuterContext());
                    }});

        registerService(Context.ROLE_CONTROLLER_SERVICE, RoleControllerManager.class,
                new CachedServiceFetcher<RoleControllerManager>() {
                    @Override
                    public RoleControllerManager createService(ContextImpl ctx)
                            throws ServiceNotFoundException {
                        return new RoleControllerManager(ctx.getOuterContext());
                    }});

        registerService(Context.ROLLBACK_SERVICE, RollbackManager.class,
                new CachedServiceFetcher<RollbackManager>() {
                    @Override
+5 −5
Original line number Diff line number Diff line
@@ -14,14 +14,16 @@
 * limitations under the License.
 */

package android.rolecontrollerservice;
package android.app.role;

import android.app.role.IRoleManagerCallback;

/**
 * @hide
 */
oneway interface IRoleControllerService {
oneway interface IRoleController {

    void onGrantDefaultRoles(in IRoleManagerCallback callback);

    void onAddRoleHolder(in String roleName, in String packageName, int flags,
                         in IRoleManagerCallback callback);
@@ -31,7 +33,5 @@ oneway interface IRoleControllerService {

    void onClearRoleHolders(in String roleName, int flags, in IRoleManagerCallback callback);

    void onGrantDefaultRoles(in IRoleManagerCallback callback);

    void onSmsKillSwitchToggled(boolean smsRestrictionEnabled);
    void onSmsKillSwitchToggled(boolean enabled);
}
+474 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.app.role;

import android.annotation.NonNull;
import android.annotation.SystemService;
import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
import com.android.internal.infra.AbstractRemoteService;

/**
 * Interface for communicating with the role controller.
 *
 * @hide
 */
@SystemService(Context.ROLE_CONTROLLER_SERVICE)
public class RoleControllerManager {

    private static final String LOG_TAG = RoleControllerManager.class.getSimpleName();

    private static final Object sRemoteServicesLock = new Object();
    /**
     * Global remote services (per user) used by all {@link RoleControllerManager managers}.
     */
    @GuardedBy("sRemoteServicesLock")
    private static final SparseArray<RemoteService> sRemoteServices = new SparseArray<>();

    @NonNull
    private final RemoteService mRemoteService;

    public RoleControllerManager(@NonNull Context context, @NonNull Handler handler) {
        synchronized (sRemoteServicesLock) {
            int userId = context.getUserId();
            RemoteService remoteService = sRemoteServices.get(userId);
            if (remoteService == null) {
                Intent intent = new Intent(RoleControllerService.SERVICE_INTERFACE);
                PackageManager packageManager = context.getPackageManager();
                intent.setPackage(packageManager.getPermissionControllerPackageName());
                ResolveInfo resolveInfo = packageManager.resolveService(intent, 0);

                remoteService = new RemoteService(context.getApplicationContext(),
                        resolveInfo.getComponentInfo().getComponentName(), handler, userId);
                sRemoteServices.put(userId, remoteService);
            }
            mRemoteService = remoteService;
        }
    }

    public RoleControllerManager(@NonNull Context context) {
        this(context, context.getMainThreadHandler());
    }

    /**
     * @see RoleControllerService#onGrantDefaultRoles(RoleManagerCallback)
     */
    public void onGrantDefaultRoles(@NonNull IRoleManagerCallback callback) {
        mRemoteService.scheduleRequest(new OnGrantDefaultRolesRequest(mRemoteService, callback));
    }

    /**
     * @see RoleControllerService#onAddRoleHolder(String, String, int, RoleManagerCallback)
     */
    public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName,
            @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
        mRemoteService.scheduleRequest(new OnAddRoleHolderRequest(mRemoteService, roleName,
                packageName, flags, callback));
    }

    /**
     * @see RoleControllerService#onRemoveRoleHolder(String, String, int, RoleManagerCallback)
     */
    public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName,
            @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
        mRemoteService.scheduleRequest(new OnRemoveRoleHolderRequest(mRemoteService, roleName,
                packageName, flags, callback));
    }

    /**
     * @see RoleControllerService#onClearRoleHolders(String, int, RoleManagerCallback)
     */
    public void onClearRoleHolders(@NonNull String roleName,
            @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
        mRemoteService.scheduleRequest(new OnClearRoleHoldersRequest(mRemoteService, roleName,
                flags, callback));
    }

    /**
     * @see RoleControllerService#onSmsKillSwitchToggled(boolean)
     */
    public void onSmsKillSwitchToggled(boolean enabled) {
        mRemoteService.scheduleAsyncRequest(new OnSmsKillSwitchToggledRequest(enabled));
    }

    /**
     * Connection to the remote service.
     */
    private static final class RemoteService extends AbstractMultiplePendingRequestsRemoteService<
            RemoteService, IRoleController> {

        private static final long UNBIND_DELAY_MILLIS = 15 * 1000;
        private static final long REQUEST_TIMEOUT_MILLIS = 15 * 1000;

        /**
         * Create a connection to the remote service
         *
         * @param context the context to use
         * @param componentName the component of the service to connect to
         * @param handler the handler for binding service and callbacks
         * @param userId the user whom remote service should be connected as
         */
        RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
                @NonNull Handler handler, @UserIdInt int userId) {
            super(context, RoleControllerService.SERVICE_INTERFACE, componentName, userId,
                    service -> Log.e(LOG_TAG, "RemoteService " + service + " died"), handler, false,
                    false, 1);
        }

        /**
         * @return The default handler used by this service.
         */
        @NonNull
        public Handler getHandler() {
            return mHandler;
        }

        @Override
        protected @NonNull IRoleController getServiceInterface(@NonNull IBinder binder) {
            return IRoleController.Stub.asInterface(binder);
        }

        @Override
        protected long getTimeoutIdleBindMillis() {
            return UNBIND_DELAY_MILLIS;
        }

        @Override
        protected long getRemoteRequestMillis() {
            return REQUEST_TIMEOUT_MILLIS;
        }

        @Override
        public void scheduleRequest(
                @NonNull BasePendingRequest<RemoteService, IRoleController> pendingRequest) {
            super.scheduleRequest(pendingRequest);
        }

        @Override
        public void scheduleAsyncRequest(@NonNull AsyncRequest<IRoleController> request) {
            super.scheduleAsyncRequest(request);
        }
    }

    /**
     * Request for {@link #onGrantDefaultRoles(IRoleManagerCallback)}.
     */
    private static final class OnGrantDefaultRolesRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final IRoleManagerCallback mCallback;

        @NonNull
        private final IRoleManagerCallback mRemoteCallback;

        private OnGrantDefaultRolesRequest(@NonNull RemoteService service,
                @NonNull IRoleManagerCallback callback) {
            super(service);

            mCallback = callback;

            mRemoteCallback = new IRoleManagerCallback.Stub() {
                @Override
                public void onSuccess() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
                @Override
                public void onFailure() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
            };
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            try {
                mCallback.onFailure();
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onFailure() on callback", e);
            }
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onGrantDefaultRoles(mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onGrantDefaultRoles()", e);
            }
        }
    }

    /**
     * Request for {@link #onAddRoleHolder(String, String, int, IRoleManagerCallback)}.
     */
    private static final class OnAddRoleHolderRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @NonNull
        private final String mPackageName;
        @RoleManager.ManageHoldersFlags
        private final int mFlags;
        @NonNull
        private final IRoleManagerCallback mCallback;

        @NonNull
        private final IRoleManagerCallback mRemoteCallback;

        private OnAddRoleHolderRequest(@NonNull RemoteService service, @NonNull String roleName,
                @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags,
                @NonNull IRoleManagerCallback callback) {
            super(service);

            mRoleName = roleName;
            mPackageName = packageName;
            mFlags = flags;
            mCallback = callback;

            mRemoteCallback = new IRoleManagerCallback.Stub() {
                @Override
                public void onSuccess() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
                @Override
                public void onFailure() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
            };
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            try {
                mCallback.onFailure();
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onFailure() on callback", e);
            }
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onAddRoleHolder(mRoleName, mPackageName, mFlags,
                        mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onAddRoleHolder()", e);
            }
        }
    }

    /**
     * Request for {@link #onRemoveRoleHolder(String, String, int, IRoleManagerCallback)}.
     */
    private static final class OnRemoveRoleHolderRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @NonNull
        private final String mPackageName;
        @RoleManager.ManageHoldersFlags
        private final int mFlags;
        @NonNull
        private final IRoleManagerCallback mCallback;

        @NonNull
        private final IRoleManagerCallback mRemoteCallback;

        private OnRemoveRoleHolderRequest(@NonNull RemoteService service, @NonNull String roleName,
                @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags,
                @NonNull IRoleManagerCallback callback) {
            super(service);

            mRoleName = roleName;
            mPackageName = packageName;
            mFlags = flags;
            mCallback = callback;

            mRemoteCallback = new IRoleManagerCallback.Stub() {
                @Override
                public void onSuccess() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
                @Override
                public void onFailure() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
            };
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            try {
                mCallback.onFailure();
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onFailure() on callback", e);
            }
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onRemoveRoleHolder(mRoleName, mPackageName,
                        mFlags, mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onRemoveRoleHolder()", e);
            }
        }
    }

    /**
     * Request for {@link #onClearRoleHolders(String, int, IRoleManagerCallback)}.
     */
    private static final class OnClearRoleHoldersRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @RoleManager.ManageHoldersFlags
        private final int mFlags;
        @NonNull
        private final IRoleManagerCallback mCallback;

        @NonNull
        private final IRoleManagerCallback mRemoteCallback;

        private OnClearRoleHoldersRequest(@NonNull RemoteService service, @NonNull String roleName,
                @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
            super(service);

            mRoleName = roleName;
            mFlags = flags;
            mCallback = callback;

            mRemoteCallback = new IRoleManagerCallback.Stub() {
                @Override
                public void onSuccess() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
                @Override
                public void onFailure() throws RemoteException {
                    long token = Binder.clearCallingIdentity();
                    try {
                        mCallback.onSuccess();
                    } finally {
                        Binder.restoreCallingIdentity(token);
                        finish();
                    }
                }
            };
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            try {
                mCallback.onFailure();
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onFailure() on callback", e);
            }
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onClearRoleHolders(mRoleName, mFlags,
                        mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onClearRoleHolders()", e);
            }
        }
    }

    /**
     * Request for {@link #onSmsKillSwitchToggled(boolean)}
     */
    private static final class OnSmsKillSwitchToggledRequest
            implements AbstractRemoteService.AsyncRequest<IRoleController> {

        private final boolean mEnabled;

        private OnSmsKillSwitchToggledRequest(boolean enabled) {
            mEnabled = enabled;
        }

        @Override
        public void run(@NonNull IRoleController service) {
            try {
                service.onSmsKillSwitchToggled(mEnabled);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onSmsKillSwitchToggled()", e);
            }
        }
    }
}
Loading