diff options
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | api/current.txt | 25 | ||||
-rw-r--r-- | core/java/android/content/AbstractRestrictionsProvider.java | 71 | ||||
-rw-r--r-- | core/java/android/content/IPermissionResponseCallback.aidl | 30 | ||||
-rw-r--r-- | core/java/android/content/IRestrictionsManager.aidl | 3 | ||||
-rw-r--r-- | core/java/android/content/IRestrictionsProvider.aidl | 31 | ||||
-rw-r--r-- | core/java/android/content/RestrictionsManager.java | 163 | ||||
-rw-r--r-- | services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java | 136 |
8 files changed, 114 insertions, 347 deletions
diff --git a/Android.mk b/Android.mk index 96b2b17c2247..27795ffde03c 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/api/current.txt b/api/current.txt index 623c2815bf63..d0c91b056282 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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[]); diff --git a/core/java/android/content/AbstractRestrictionsProvider.java b/core/java/android/content/AbstractRestrictionsProvider.java index 1119478b9932..3272970c9ded 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 { - - @Override - public Bundle getPermissionResponse(String packageName, String requestId) { - return AbstractRestrictionsProvider.this - .getPermissionResponse(packageName, requestId); - } + /** + * 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 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 8309768957ba..000000000000 --- 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 49eb65bd74d0..b1c0a3afd9b4 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 @@ 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); } diff --git a/core/java/android/content/IRestrictionsProvider.aidl b/core/java/android/content/IRestrictionsProvider.aidl deleted file mode 100644 index 4506b72aa200..000000000000 --- 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 5ef2dbc39bdb..fa069a27d42e 100644 --- a/core/java/android/content/RestrictionsManager.java +++ b/core/java/android/content/RestrictionsManager.java @@ -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> @@ -89,9 +83,32 @@ public class RestrictionsManager { "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. - * <p> - * Type: String - */ - 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. + * 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_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; @@ -312,19 +321,6 @@ public class RestrictionsManager { 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 @@ 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,45 +369,27 @@ 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) { - try { - if (mService != null) { - mService.requestPermission(mContext.getPackageName(), requestType, request); - } - } catch (RemoteException re) { - Log.w(TAG, "Couldn't reach service"); + if (requestType == null) { + throw new NullPointerException("requestType cannot be null"); } - } - - /** - * 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. - * - * @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"); + 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.getPermissionResponse(mContext.getPackageName(), requestId, - new PermissionResponseCallbackWrapper(callback)); + mService.requestPermission(mContext.getPackageName(), requestType, request); } } catch (RemoteException re) { Log.w(TAG, "Couldn't reach service"); @@ -420,12 +397,27 @@ public class RestrictionsManager { } /** - * Called by the restrictions provider to deliver a response to an application. + * 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); - } - } } diff --git a/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java b/services/restrictions/java/com/android/server/restrictions/RestrictionsManagerService.java index 1db3c5ed6a81..4fe30e675cd4 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.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; - } - } } } |