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
diff --git a/Android.mk b/Android.mk
index 96b2b17..27795ff 100644
--- a/Android.mk
+++ b/Android.mk
@@ -118,9 +118,7 @@
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 \
diff --git a/api/current.txt b/api/current.txt
index 623c281..d0c91b0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6571,11 +6571,10 @@
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 @@
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 @@
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[]);
diff --git a/core/java/android/content/AbstractRestrictionsProvider.java b/core/java/android/content/AbstractRestrictionsProvider.java
index 1119478..3272970 100644
--- a/core/java/android/content/AbstractRestrictionsProvider.java
+++ b/core/java/android/content/AbstractRestrictionsProvider.java
@@ -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);
}
}
}
diff --git a/core/java/android/content/IPermissionResponseCallback.aidl b/core/java/android/content/IPermissionResponseCallback.aidl
deleted file mode 100644
index 8309768..0000000
--- a/core/java/android/content/IPermissionResponseCallback.aidl
+++ /dev/null
@@ -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);
-
-}
diff --git a/core/java/android/content/IRestrictionsManager.aidl b/core/java/android/content/IRestrictionsManager.aidl
index 49eb65b..b1c0a3a 100644
--- a/core/java/android/content/IRestrictionsManager.aidl
+++ b/core/java/android/content/IRestrictionsManager.aidl
@@ -17,7 +17,6 @@
package android.content;
import android.os.Bundle;
-import android.content.IPermissionResponseCallback;
/**
* Interface used by the RestrictionsManager
@@ -28,6 +27,4 @@
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);
}
diff --git a/core/java/android/content/IRestrictionsProvider.aidl b/core/java/android/content/IRestrictionsProvider.aidl
deleted file mode 100644
index 4506b72..0000000
--- a/core/java/android/content/IRestrictionsProvider.aidl
+++ /dev/null
@@ -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);
-
-}
diff --git a/core/java/android/content/RestrictionsManager.java b/core/java/android/content/RestrictionsManager.java
index 5ef2dbc..fa069a2 100644
--- a/core/java/android/content/RestrictionsManager.java
+++ b/core/java/android/content/RestrictionsManager.java
@@ -32,21 +32,17 @@
* <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 @@
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>
@@ -89,9 +83,32 @@
"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 @@
* <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 @@
* {@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 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 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;
@@ -312,19 +321,6 @@
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
*/
public RestrictionsManager(Context context, IRestrictionsManager service) {
@@ -350,11 +346,10 @@
}
/**
- * 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 @@
*
* @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 @@
}
/**
- * 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 @@
// 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);
- }
- }
}
diff --git a/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java b/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java
index 1db3c5e..4fe30e6 100644
--- a/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java
+++ b/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java
@@ -23,17 +23,13 @@
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 @@
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 @@
// 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;
- }
- }
}
}