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

Commit f6e2fcc2 authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Improvements to Restrictions API

Convert restrictions provider to a service instead of a receiver.
Add a way to get pending responses from restrictions provider.
Add AbstractRestrictionsProvider.
Add a callback API for responses.

Removed some constants in RestrictionsManager.
Added new constants for errors and error codes.
Much improved javadocs.

Bug: 16176009

Change-Id: I838a50fabc80b94b632294b3a55cd5d8092acf55
parent 7ab9d759
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -118,7 +118,9 @@ LOCAL_SRC_FILES += \
	core/java/android/content/IIntentReceiver.aidl \
	core/java/android/content/IIntentSender.aidl \
	core/java/android/content/IOnPrimaryClipChangedListener.aidl \
        core/java/android/content/IPermissionResponseCallback.aidl \
	core/java/android/content/IRestrictionsManager.aidl \
        core/java/android/content/IRestrictionsProvider.aidl \
	core/java/android/content/ISyncAdapter.aidl \
	core/java/android/content/ISyncContext.aidl \
	core/java/android/content/ISyncServiceAdapter.aidl \
+37 −15
Original line number Diff line number Diff line
@@ -6570,6 +6570,13 @@ package android.bluetooth.le {
package android.content {
  public abstract class AbstractRestrictionsProvider extends android.app.Service {
    ctor public AbstractRestrictionsProvider();
    method public abstract android.os.Bundle getPermissionResponse(java.lang.String, java.lang.String);
    method public final android.os.IBinder onBind(android.content.Intent);
    method public abstract void requestPermission(java.lang.String, java.lang.String, android.os.Bundle);
  }
  public abstract class AbstractThreadedSyncAdapter {
    ctor public AbstractThreadedSyncAdapter(android.content.Context, boolean);
    ctor public AbstractThreadedSyncAdapter(android.content.Context, boolean, boolean);
@@ -7949,26 +7956,41 @@ package android.content {
  public class RestrictionsManager {
    method public android.os.Bundle getApplicationRestrictions();
    method public java.util.List<android.content.RestrictionEntry> getManifestRestrictions(java.lang.String);
    method public void getPermissionResponse(java.lang.String, android.content.RestrictionsManager.PermissionResponseCallback);
    method public boolean hasRestrictionsProvider();
    method public void notifyPermissionResponse(java.lang.String, android.os.Bundle);
    method public void requestPermission(java.lang.String, android.os.Bundle);
    field public static final java.lang.String ACTION_PERMISSION_RESPONSE_RECEIVED = "android.intent.action.PERMISSION_RESPONSE_RECEIVED";
    field public static final java.lang.String ACTION_REQUEST_PERMISSION = "android.intent.action.REQUEST_PERMISSION";
    field public static final java.lang.String EXTRA_PACKAGE_NAME = "package_name";
    field public static final java.lang.String EXTRA_REQUEST_BUNDLE = "request_bundle";
    field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "response_bundle";
    field public static final java.lang.String EXTRA_TEMPLATE_ID = "template_id";
    field public static final java.lang.String REQUEST_KEY_APPROVE_LABEL = "android.req_template.accept";
    field public static final java.lang.String REQUEST_KEY_DATA = "android.req_template.data";
    field public static final java.lang.String REQUEST_KEY_DENY_LABEL = "android.req_template.reject";
    field public static final java.lang.String REQUEST_KEY_DEVICE_NAME = "android.req_template.device";
    field public static final java.lang.String REQUEST_KEY_ICON = "android.req_template.icon";
    field public static final java.lang.String REQUEST_KEY_ID = "android.req_template.req_id";
    field public static final java.lang.String REQUEST_KEY_MESSAGE = "android.req_template.mesg";
    field public static final java.lang.String REQUEST_KEY_REQUESTOR_NAME = "android.req_template.requestor";
    field public static final java.lang.String REQUEST_KEY_TITLE = "android.req_template.title";
    field public static final java.lang.String REQUEST_TEMPLATE_QUESTION = "android.req_template.type.simple";
    field public static final java.lang.String RESPONSE_KEY_BOOLEAN = "android.req_template.response";
    field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "response";
    field public static final java.lang.String REQUEST_KEY_APPROVE_LABEL = "android.request.approve_label";
    field public static final java.lang.String REQUEST_KEY_DATA = "android.request.data";
    field public static final java.lang.String REQUEST_KEY_DENY_LABEL = "android.request.deny_label";
    field public static final java.lang.String REQUEST_KEY_DEVICE_NAME = "android.request.device";
    field public static final java.lang.String REQUEST_KEY_ICON = "android.request.icon";
    field public static final java.lang.String REQUEST_KEY_ID = "android.request.id";
    field public static final java.lang.String REQUEST_KEY_MESSAGE = "android.request.mesg";
    field public static final java.lang.String REQUEST_KEY_REQUESTOR_NAME = "android.request.requestor";
    field public static final java.lang.String REQUEST_KEY_TITLE = "android.request.title";
    field public static final java.lang.String REQUEST_TYPE_LOCAL_APPROVAL = "android.request.type.local_approval";
    field public static final java.lang.String REQUEST_TYPE_QUESTION = "android.request.type.question";
    field public static final java.lang.String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode";
    field public static final java.lang.String RESPONSE_KEY_ERROR_MESSAGE = "android.response.errormsg";
    field public static final java.lang.String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp";
    field public static final java.lang.String RESPONSE_KEY_RESULT = "android.response.result";
    field public static final int RESULT_APPROVED = 1; // 0x1
    field public static final int RESULT_DENIED = 2; // 0x2
    field public static final int RESULT_ERROR = 5; // 0x5
    field public static final int RESULT_ERROR_BAD_REQUEST = 1; // 0x1
    field public static final int RESULT_ERROR_INTERNAL = 3; // 0x3
    field public static final int RESULT_ERROR_NETWORK = 2; // 0x2
    field public static final int RESULT_NO_RESPONSE = 3; // 0x3
    field public static final int RESULT_UNKNOWN_REQUEST = 4; // 0x4
  }
  public static abstract class RestrictionsManager.PermissionResponseCallback {
    ctor public RestrictionsManager.PermissionResponseCallback();
    method public abstract void onResponse(android.os.Bundle);
  }
  public class SearchRecentSuggestionsProvider extends android.content.ContentProvider {
+6 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.app.admin;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Activity;
import android.content.AbstractRestrictionsProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -2661,19 +2662,19 @@ public class DevicePolicyManager {
    }

    /**
     * Designates a specific broadcast receiver component as the provider for
     * Designates a specific service component as the provider for
     * making permission requests of a local or remote administrator of the user.
     * <p/>
     * Only a profile owner can designate the restrictions provider.
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param receiver The component name of a BroadcastReceiver that handles the
     * {@link RestrictionsManager#ACTION_REQUEST_PERMISSION} intent. If this param is null,
     * @param provider The component name of the service that implements
     * {@link AbstractRestrictionsProvider}. If this param is null,
     * it removes the restrictions provider previously assigned.
     */
    public void setRestrictionsProvider(ComponentName admin, ComponentName receiver) {
    public void setRestrictionsProvider(ComponentName admin, ComponentName provider) {
        if (mService != null) {
            try {
                mService.setRestrictionsProvider(admin, receiver);
                mService.setRestrictionsProvider(admin, provider);
            } catch (RemoteException re) {
                Log.w(TAG, "Failed to set permission provider on device policy service");
            }
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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.content;

import android.app.Service;
import android.app.admin.DevicePolicyManager;
import android.os.Bundle;
import android.os.IBinder;

/**
 * Abstract implementation of a Restrictions Provider Service. To implement a Restrictions Provider,
 * extend from this class and implement the abstract methods. Export this service in the
 * manifest. A profile owner device admin can then register this component as a Restrictions
 * Provider using {@link DevicePolicyManager#setRestrictionsProvider(ComponentName, ComponentName)}.
 * <p>
 * The function of a Restrictions Provider is to transport permission requests from apps on this
 * device to an administrator (most likely on a remote device or computer) and deliver back
 * responses. The response should be sent back to the app via
 * {@link RestrictionsManager#notifyPermissionResponse(String, Bundle)}.
 * <p>
 * Apps can also query previously received responses using
 * {@link #getPermissionResponse(String, String)}. The period for which previously received
 * responses are available is left to the implementation of the Restrictions Provider.
 */
public abstract class AbstractRestrictionsProvider extends Service {

    private static final String TAG = "AbstractRestrictionsProvider";

    @Override
    public final IBinder onBind(Intent intent) {
        return new RestrictionsProviderWrapper().asBinder();
    }

    /**
     * Checks to see if there is a response for a prior request and returns the response bundle if
     * it exists. If there is no response yet or if the request is not known, the returned bundle
     * should contain the response code in {@link RestrictionsManager#RESPONSE_KEY_RESULT}.
     *
     * @param packageName the application that is requesting a permission response.
     * @param requestId the id of the request for which the response is needed.
     * @return a bundle containing at a minimum the result of the request. It could contain other
     * optional information such as error codes and cookies.
     *
     * @see RestrictionsManager#RESPONSE_KEY_RESULT
     */
    public abstract Bundle getPermissionResponse(String packageName, String requestId);

    /**
     * An asynchronous permission request made by an application for an operation that requires
     * authorization by a local or remote administrator other than the user. The Restrictions
     * Provider must transfer the request to the administrator and deliver back a response, when
     * available. The calling application is aware that the response could take an indefinite
     * amount of time.
     *
     * @param packageName the application requesting permission.
     * @param requestType the type of request, which determines the content and presentation of
     * the request data.
     * @param request the request data bundle containing at a minimum a request id.
     *
     * @see RestrictionsManager#REQUEST_TYPE_QUESTION
     * @see RestrictionsManager#REQUEST_TYPE_LOCAL_APPROVAL
     * @see RestrictionsManager#REQUEST_KEY_ID
     */
    public abstract void requestPermission(String packageName, String requestType, Bundle request);

    private class RestrictionsProviderWrapper extends IRestrictionsProvider.Stub {

        @Override
        public Bundle getPermissionResponse(String packageName, String requestId) {
            return AbstractRestrictionsProvider.this
                    .getPermissionResponse(packageName, requestId);
        }

        @Override
        public void requestPermission(String packageName, String templateId, Bundle request) {
            AbstractRestrictionsProvider.this.requestPermission(packageName, templateId, request);
        }
    }
}
+30 −0
Original line number Diff line number Diff line
/*
** Copyright 2014, 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.content;

import android.os.Bundle;

/**
 * Callback for permission response queries.
 *
 * @hide
 */
 interface IPermissionResponseCallback {

    void onResponse(in Bundle response);

}
Loading