Revert some new APIs for restrictions provider
Simplify back to being a broadcast receiver and add an extra to indicate that a new request is desired vs. returning a pending response from before. Change-Id: Iafd16ed98293a2cc09006d2cce097fc3d590bbe2
This commit is contained in:
@@ -118,9 +118,7 @@ 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 \
|
||||
|
||||
@@ -6571,11 +6571,10 @@ package android.bluetooth.le {
|
||||
|
||||
package android.content {
|
||||
|
||||
public abstract class AbstractRestrictionsProvider extends android.app.Service {
|
||||
public abstract class AbstractRestrictionsProvider extends android.content.BroadcastReceiver {
|
||||
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);
|
||||
method public void onReceive(android.content.Context, android.content.Intent);
|
||||
method public abstract void requestPermission(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle);
|
||||
}
|
||||
|
||||
public abstract class AbstractThreadedSyncAdapter {
|
||||
@@ -7957,24 +7956,25 @@ 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 EXTRA_PACKAGE_NAME = "package_name";
|
||||
field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "response";
|
||||
field public static final java.lang.String ACTION_REQUEST_PERMISSION = "android.content.action.REQUEST_PERMISSION";
|
||||
field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
|
||||
field public static final java.lang.String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE";
|
||||
field public static final java.lang.String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE";
|
||||
field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE";
|
||||
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_NEW_REQUEST = "android.request.new_request";
|
||||
field public static final java.lang.String REQUEST_KEY_TITLE = "android.request.title";
|
||||
field public static final java.lang.String REQUEST_TYPE_APPROVAL = "android.request.type.approval";
|
||||
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";
|
||||
@@ -7989,11 +7989,6 @@ package android.content {
|
||||
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 {
|
||||
ctor public SearchRecentSuggestionsProvider();
|
||||
method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
|
||||
|
||||
@@ -16,78 +16,65 @@
|
||||
|
||||
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)}.
|
||||
* Abstract implementation of a Restrictions Provider BroadcastReceiver. To implement a
|
||||
* Restrictions Provider, extend from this class and implement the abstract methods.
|
||||
* Export this receiver 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.
|
||||
*
|
||||
* @see RestrictionsManager
|
||||
*/
|
||||
public abstract class AbstractRestrictionsProvider extends Service {
|
||||
public abstract class AbstractRestrictionsProvider extends BroadcastReceiver {
|
||||
|
||||
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
|
||||
* Provider should 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.
|
||||
* <p>
|
||||
* If the request bundle contains the key {@link RestrictionsManager#REQUEST_KEY_NEW_REQUEST},
|
||||
* then a new request must be sent. Otherwise the provider can look up any previous response
|
||||
* to the same requestId and return the cached response.
|
||||
*
|
||||
* @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_APPROVAL
|
||||
* @see RestrictionsManager#REQUEST_TYPE_LOCAL_APPROVAL
|
||||
* @see RestrictionsManager#REQUEST_KEY_ID
|
||||
*/
|
||||
public abstract void requestPermission(String packageName, String requestType, Bundle request);
|
||||
public abstract void requestPermission(Context context,
|
||||
String packageName, String requestType, Bundle request);
|
||||
|
||||
private class RestrictionsProviderWrapper extends IRestrictionsProvider.Stub {
|
||||
/**
|
||||
* Intercept standard Restrictions Provider broadcasts. Implementations
|
||||
* should not override this method; it is better to implement the
|
||||
* convenience callbacks for each action.
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
|
||||
@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);
|
||||
if (RestrictionsManager.ACTION_REQUEST_PERMISSION.equals(action)) {
|
||||
String packageName = intent.getStringExtra(RestrictionsManager.EXTRA_PACKAGE_NAME);
|
||||
String requestType = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_TYPE);
|
||||
Bundle request = intent.getBundleExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE);
|
||||
requestPermission(context, packageName, requestType, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
** 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);
|
||||
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package android.content;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.content.IPermissionResponseCallback;
|
||||
|
||||
/**
|
||||
* Interface used by the RestrictionsManager
|
||||
@@ -28,6 +27,4 @@ interface IRestrictionsManager {
|
||||
boolean hasRestrictionsProvider();
|
||||
void requestPermission(in String packageName, in String requestTemplate, in Bundle requestData);
|
||||
void notifyPermissionResponse(in String packageName, in Bundle response);
|
||||
void getPermissionResponse(in String packageName, in String requestId,
|
||||
in IPermissionResponseCallback callback);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
** 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;
|
||||
|
||||
/**
|
||||
* Interface to a restrictions provider service component.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface IRestrictionsProvider {
|
||||
|
||||
void requestPermission(in String packageName, in String requestType, in Bundle requestBundle);
|
||||
Bundle getPermissionResponse(in String packageName, in String requestId);
|
||||
|
||||
}
|
||||
@@ -32,21 +32,17 @@ import java.util.List;
|
||||
* <p>
|
||||
* Apps can expose a set of restrictions via an XML file specified in the manifest.
|
||||
* <p>
|
||||
* If the user has an active restrictions provider, dynamic requests can be made in
|
||||
* If the user has an active Restrictions Provider, dynamic requests can be made in
|
||||
* addition to the statically imposed restrictions. Dynamic requests are app-specific
|
||||
* and can be expressed via a predefined set of request types.
|
||||
* <p>
|
||||
* The RestrictionsManager forwards the dynamic requests to the active
|
||||
* restrictions provider. The restrictions provider can respond back to requests by calling
|
||||
* Restrictions Provider. The Restrictions Provider can respond back to requests by calling
|
||||
* {@link #notifyPermissionResponse(String, Bundle)}, when
|
||||
* a response is received from the administrator of the device or user.
|
||||
* The response is relayed back to the application via a protected broadcast,
|
||||
* {@link #ACTION_PERMISSION_RESPONSE_RECEIVED}.
|
||||
* <p>
|
||||
* Prior responses to requests can also be queried through calls to
|
||||
* {@link #getPermissionResponse(String, PermissionResponseCallback)}, if the provider
|
||||
* saves old responses.
|
||||
* <p>
|
||||
* Static restrictions are specified by an XML file referenced by a meta-data attribute
|
||||
* in the manifest. This enables applications as well as any web administration consoles
|
||||
* to be able to read the list of available restrictions from the apk.
|
||||
@@ -72,10 +68,8 @@ public class RestrictionsManager {
|
||||
private static final String TAG = "RestrictionsManager";
|
||||
|
||||
/**
|
||||
* Broadcast intent delivered when a response is received for a permission
|
||||
* request. The response is not available for later query, so the receiver
|
||||
* must persist and/or immediately act upon the response. The application
|
||||
* should not interrupt the user by coming to the foreground if it isn't
|
||||
* Broadcast intent delivered when a response is received for a permission request. The
|
||||
* application should not interrupt the user by coming to the foreground if it isn't
|
||||
* currently in the foreground. It can either post a notification informing
|
||||
* the user of the response or wait until the next time the user launches the app.
|
||||
* <p>
|
||||
@@ -88,10 +82,33 @@ public class RestrictionsManager {
|
||||
public static final String ACTION_PERMISSION_RESPONSE_RECEIVED =
|
||||
"android.intent.action.PERMISSION_RESPONSE_RECEIVED";
|
||||
|
||||
/**
|
||||
* Broadcast intent sent to the Restrictions Provider to handle a permission request from
|
||||
* an app. It will have the following extras: {@link #EXTRA_PACKAGE_NAME},
|
||||
* {@link #EXTRA_REQUEST_TYPE} and {@link #EXTRA_REQUEST_BUNDLE}. The Restrictions Provider
|
||||
* will handle the request and respond back to the RestrictionsManager, when a response is
|
||||
* available, by calling {@link #notifyPermissionResponse}.
|
||||
* <p>
|
||||
* The BroadcastReceiver must require the {@link android.Manifest.permission#BIND_DEVICE_ADMIN}
|
||||
* permission to ensure that only the system can send the broadcast.
|
||||
*/
|
||||
public static final String ACTION_REQUEST_PERMISSION =
|
||||
"android.content.action.REQUEST_PERMISSION";
|
||||
|
||||
/**
|
||||
* The package name of the application making the request.
|
||||
*/
|
||||
public static final String EXTRA_PACKAGE_NAME = "package_name";
|
||||
public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
|
||||
|
||||
/**
|
||||
* The request type passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
|
||||
*/
|
||||
public static final String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE";
|
||||
|
||||
/**
|
||||
* The request bundle passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
|
||||
*/
|
||||
public static final String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE";
|
||||
|
||||
/**
|
||||
* Contains a response from the administrator for specific request.
|
||||
@@ -101,7 +118,7 @@ public class RestrictionsManager {
|
||||
* <li>{@link #RESPONSE_KEY_RESULT}: The response result.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static final String EXTRA_RESPONSE_BUNDLE = "response";
|
||||
public static final String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE";
|
||||
|
||||
/**
|
||||
* Request type for a simple question, with a possible title and icon.
|
||||
@@ -113,7 +130,7 @@ public class RestrictionsManager {
|
||||
* {@link #REQUEST_KEY_DATA}, {@link #REQUEST_KEY_ICON}, {@link #REQUEST_KEY_TITLE},
|
||||
* {@link #REQUEST_KEY_APPROVE_LABEL} and {@link #REQUEST_KEY_DENY_LABEL}.
|
||||
*/
|
||||
public static final String REQUEST_TYPE_QUESTION = "android.request.type.question";
|
||||
public static final String REQUEST_TYPE_APPROVAL = "android.request.type.approval";
|
||||
|
||||
/**
|
||||
* Request type for a local password challenge. This is a way for an app to ask
|
||||
@@ -204,22 +221,14 @@ public class RestrictionsManager {
|
||||
public static final String REQUEST_KEY_DENY_LABEL = "android.request.deny_label";
|
||||
|
||||
/**
|
||||
* Key for requestor's name contained in the request bundle. This value is not specified by
|
||||
* the application. It is automatically inserted into the Bundle by the Restrictions Provider
|
||||
* before it is sent to the administrator.
|
||||
* Key for issuing a new request, contained in the request bundle. If this is set to true,
|
||||
* the Restrictions Provider must make a new request. If it is false or not specified, then
|
||||
* the Restrictions Provider can return a cached response that has the same requestId, if
|
||||
* available. If there's no cached response, it will issue a new one to the administrator.
|
||||
* <p>
|
||||
* Type: String
|
||||
* Type: boolean
|
||||
*/
|
||||
public static final String REQUEST_KEY_REQUESTOR_NAME = "android.request.requestor";
|
||||
|
||||
/**
|
||||
* Key for requestor's device name contained in the request bundle. This value is not specified
|
||||
* by the application. It is automatically inserted into the Bundle by the Restrictions Provider
|
||||
* before it is sent to the administrator.
|
||||
* <p>
|
||||
* Type: String
|
||||
*/
|
||||
public static final String REQUEST_KEY_DEVICE_NAME = "android.request.device";
|
||||
public static final String REQUEST_KEY_NEW_REQUEST = "android.request.new_request";
|
||||
|
||||
/**
|
||||
* Key for the response in the response bundle sent to the application, for a permission
|
||||
@@ -249,8 +258,8 @@ public class RestrictionsManager {
|
||||
public static final int RESULT_NO_RESPONSE = 3;
|
||||
|
||||
/**
|
||||
* Response result value indicating that the request is unknown, when returned through a
|
||||
* call to #getPendingResponse
|
||||
* Response result value indicating that the request is unknown, when it's not a new
|
||||
* request.
|
||||
*/
|
||||
public static final int RESULT_UNKNOWN_REQUEST = 4;
|
||||
|
||||
@@ -311,19 +320,6 @@ public class RestrictionsManager {
|
||||
private final Context mContext;
|
||||
private final IRestrictionsManager mService;
|
||||
|
||||
/**
|
||||
* Callback object for returning a response for a request.
|
||||
*
|
||||
* @see #getPermissionResponse
|
||||
*/
|
||||
public static abstract class PermissionResponseCallback {
|
||||
/**
|
||||
* Contains the response
|
||||
* @param response
|
||||
*/
|
||||
public abstract void onResponse(Bundle response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -350,11 +346,10 @@ public class RestrictionsManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application to check if there is an active restrictions provider. If
|
||||
* there isn't, {@link #getPermissionResponse(String, PermissionResponseCallback)}
|
||||
* and {@link #requestPermission(String, Bundle)} are not available.
|
||||
* Called by an application to check if there is an active Restrictions Provider. If
|
||||
* there isn't, {@link #requestPermission(String, Bundle)} is not available.
|
||||
*
|
||||
* @return whether there is an active restrictions provider.
|
||||
* @return whether there is an active Restrictions Provider.
|
||||
*/
|
||||
public boolean hasRestrictionsProvider() {
|
||||
try {
|
||||
@@ -374,13 +369,24 @@ public class RestrictionsManager {
|
||||
*
|
||||
* @param requestType The type of request. The type could be one of the
|
||||
* predefined types specified here or a custom type that the specific
|
||||
* restrictions provider might understand. For custom types, the type name should be
|
||||
* Restrictions Provider might understand. For custom types, the type name should be
|
||||
* namespaced to avoid collisions with predefined types and types specified by
|
||||
* other restrictions providers.
|
||||
* other Restrictions Providers.
|
||||
* @param request A Bundle containing the data corresponding to the specified request
|
||||
* type. The keys for the data in the bundle depend on the request type.
|
||||
*
|
||||
* @throws IllegalArgumentException if any of the required parameters are missing.
|
||||
*/
|
||||
public void requestPermission(String requestType, Bundle request) {
|
||||
if (requestType == null) {
|
||||
throw new NullPointerException("requestType cannot be null");
|
||||
}
|
||||
if (request == null) {
|
||||
throw new NullPointerException("request cannot be null");
|
||||
}
|
||||
if (!request.containsKey(REQUEST_KEY_ID)) {
|
||||
throw new IllegalArgumentException("REQUEST_KEY_ID must be specified");
|
||||
}
|
||||
try {
|
||||
if (mService != null) {
|
||||
mService.requestPermission(mContext.getPackageName(), requestType, request);
|
||||
@@ -391,41 +397,27 @@ public class RestrictionsManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application to query for any available response from the restrictions provider
|
||||
* for the given requestId. The call returns immediately and the response will be returned
|
||||
* via the provided callback. This does not initiate a new request and does not wait
|
||||
* for a response to be received. It merely returns any previously received response
|
||||
* or indicates if there was no available response. If there are multiple responses
|
||||
* available for the same request ID, the most recent one is returned.
|
||||
* Called by the Restrictions Provider to deliver a response to an application.
|
||||
*
|
||||
* @param requestId The ID of the original request made via
|
||||
* {@link #requestPermission(String, Bundle)}. It's possible to also query for responses
|
||||
* to requests made on a different device with the same requestId, if the Restrictions
|
||||
* Provider happens to sync responses across devices with the same account managed by the
|
||||
* restrictions provider.
|
||||
* @param callback The response is returned via the callback object. Cannot be null.
|
||||
*/
|
||||
public void getPermissionResponse(String requestId, PermissionResponseCallback callback) {
|
||||
if (requestId == null || callback == null) {
|
||||
throw new NullPointerException("requestId or callback cannot be null");
|
||||
}
|
||||
try {
|
||||
if (mService != null) {
|
||||
mService.getPermissionResponse(mContext.getPackageName(), requestId,
|
||||
new PermissionResponseCallbackWrapper(callback));
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Log.w(TAG, "Couldn't reach service");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the restrictions provider to deliver a response to an application.
|
||||
*
|
||||
* @param packageName the application to deliver the response to.
|
||||
* @param packageName the application to deliver the response to. Cannot be null.
|
||||
* @param response the Bundle containing the response status, request ID and other information.
|
||||
* Cannot be null.
|
||||
*
|
||||
* @throws IllegalArgumentException if any of the required parameters are missing.
|
||||
*/
|
||||
public void notifyPermissionResponse(String packageName, Bundle response) {
|
||||
if (packageName == null) {
|
||||
throw new NullPointerException("packageName cannot be null");
|
||||
}
|
||||
if (response == null) {
|
||||
throw new NullPointerException("request cannot be null");
|
||||
}
|
||||
if (!response.containsKey(REQUEST_KEY_ID)) {
|
||||
throw new IllegalArgumentException("REQUEST_KEY_ID must be specified");
|
||||
}
|
||||
if (!response.containsKey(RESPONSE_KEY_RESULT)) {
|
||||
throw new IllegalArgumentException("RESPONSE_KEY_RESULT must be specified");
|
||||
}
|
||||
try {
|
||||
if (mService != null) {
|
||||
mService.notifyPermissionResponse(packageName, response);
|
||||
@@ -447,19 +439,4 @@ public class RestrictionsManager {
|
||||
// TODO:
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class PermissionResponseCallbackWrapper
|
||||
extends IPermissionResponseCallback.Stub {
|
||||
|
||||
private PermissionResponseCallback mCallback;
|
||||
|
||||
PermissionResponseCallbackWrapper(PermissionResponseCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Bundle response) {
|
||||
mCallback.onResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,17 +23,13 @@ import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.admin.IDevicePolicyManager;
|
||||
import android.content.AbstractRestrictionsProvider;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.IPermissionResponseCallback;
|
||||
import android.content.IRestrictionsProvider;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IRestrictionsManager;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
@@ -127,58 +123,12 @@ public final class RestrictionsManagerService extends SystemService {
|
||||
enforceCallerMatchesPackage(callingUid, packageName, "Package name does not" +
|
||||
" match caller ");
|
||||
// Prepare and broadcast the intent to the provider
|
||||
Intent intent = new Intent();
|
||||
Intent intent = new Intent(RestrictionsManager.ACTION_REQUEST_PERMISSION);
|
||||
intent.setComponent(restrictionsProvider);
|
||||
new ProviderServiceConnection(intent, null, userHandle) {
|
||||
@Override
|
||||
public void run() throws RemoteException {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "calling requestPermission for " + packageName
|
||||
+ ", type=" + requestType + ", data=" + requestData);
|
||||
}
|
||||
mRestrictionsProvider.requestPermission(packageName,
|
||||
requestType, requestData);
|
||||
}
|
||||
}.bind();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPermissionResponse(final String packageName, final String requestId,
|
||||
final IPermissionResponseCallback callback) throws RemoteException {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
int userHandle = UserHandle.getUserId(callingUid);
|
||||
if (mDpm != null) {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
ComponentName restrictionsProvider =
|
||||
mDpm.getRestrictionsProvider(userHandle);
|
||||
// Check if there is a restrictions provider
|
||||
if (restrictionsProvider == null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot fetch permission without a restrictions provider registered");
|
||||
}
|
||||
// Check that the packageName matches the caller.
|
||||
enforceCallerMatchesPackage(callingUid, packageName, "Package name does not" +
|
||||
" match caller ");
|
||||
// Prepare and broadcast the intent to the provider
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(restrictionsProvider);
|
||||
new ProviderServiceConnection(intent, callback.asBinder(), userHandle) {
|
||||
@Override
|
||||
public void run() throws RemoteException {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "calling getPermissionResponse for " + packageName
|
||||
+ ", id=" + requestId);
|
||||
}
|
||||
Bundle response = mRestrictionsProvider.getPermissionResponse(
|
||||
packageName, requestId);
|
||||
callback.onResponse(response);
|
||||
}
|
||||
}.bind();
|
||||
intent.putExtra(RestrictionsManager.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RestrictionsManager.EXTRA_REQUEST_TYPE, requestType);
|
||||
intent.putExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, requestData);
|
||||
mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -226,81 +176,5 @@ public final class RestrictionsManagerService extends SystemService {
|
||||
// Shouldn't happen
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ProviderServiceConnection
|
||||
implements IBinder.DeathRecipient, ServiceConnection {
|
||||
|
||||
protected IRestrictionsProvider mRestrictionsProvider;
|
||||
private Intent mIntent;
|
||||
protected int mUserHandle;
|
||||
protected IBinder mResponse;
|
||||
private boolean mAbort;
|
||||
|
||||
public ProviderServiceConnection(Intent intent, IBinder response, int userHandle) {
|
||||
mIntent = intent;
|
||||
mResponse = response;
|
||||
mUserHandle = userHandle;
|
||||
if (mResponse != null) {
|
||||
try {
|
||||
mResponse.linkToDeath(this, 0 /* flags */);
|
||||
} catch (RemoteException re) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Bind to the RestrictionsProvider process */
|
||||
public void bind() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "binding to service: " + mIntent);
|
||||
}
|
||||
mContext.bindServiceAsUser(mIntent, this, Context.BIND_AUTO_CREATE,
|
||||
new UserHandle(mUserHandle));
|
||||
}
|
||||
|
||||
private void close() {
|
||||
mAbort = true;
|
||||
unbind();
|
||||
}
|
||||
|
||||
private void unbind() {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "unbinding from service");
|
||||
}
|
||||
mContext.unbindService(this);
|
||||
}
|
||||
|
||||
/** Implement this to call the appropriate method on the service */
|
||||
public abstract void run() throws RemoteException;
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "connected to " + name);
|
||||
}
|
||||
mRestrictionsProvider = IRestrictionsProvider.Stub.asInterface(service);
|
||||
if (!mAbort) {
|
||||
try {
|
||||
run();
|
||||
} catch (RemoteException re) {
|
||||
Log.w("RestrictionsProvider", "Remote exception: " + re);
|
||||
}
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "disconnected from " + name);
|
||||
}
|
||||
mRestrictionsProvider = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
mAbort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user