1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.permissionpresenterservice;
18 
19 import static com.android.internal.util.Preconditions.checkNotNull;
20 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
21 
22 import android.annotation.NonNull;
23 import android.annotation.SystemApi;
24 import android.app.Service;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.permission.IRuntimePermissionPresenter;
28 import android.content.pm.permission.RuntimePermissionPresentationInfo;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.IBinder;
32 import android.os.RemoteCallback;
33 import android.permission.PermissionControllerService;
34 
35 import java.util.List;
36 
37 /**
38  * This service presents information regarding runtime permissions that is
39  * used for presenting them in the UI. Runtime permissions are presented as
40  * a single permission in the UI but may be composed of several individual
41  * permissions.
42  *
43  * @see RuntimePermissionPresentationInfo
44  *
45  * @hide
46  *
47  * @deprecated use {@link PermissionControllerService} instead
48  */
49 @Deprecated
50 @SystemApi
51 public abstract class RuntimePermissionPresenterService extends Service {
52 
53     /**
54      * The {@link Intent} action that must be declared as handled by a service
55      * in its manifest for the system to recognize it as a runtime permission
56      * presenter service.
57      */
58     public static final String SERVICE_INTERFACE =
59             "android.permissionpresenterservice.RuntimePermissionPresenterService";
60 
61     private static final String KEY_RESULT =
62             "android.content.pm.permission.RuntimePermissionPresenter.key.result";
63 
64     // No need for locking - always set first and never modified
65     private Handler mHandler;
66 
67     @Override
attachBaseContext(Context base)68     public final void attachBaseContext(Context base) {
69         super.attachBaseContext(base);
70         mHandler = new Handler(base.getMainLooper());
71     }
72 
73     /**
74      * Gets the runtime permissions for an app.
75      *
76      * @param packageName The package for which to query.
77      */
onGetAppPermissions( @onNull String packageName)78     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(
79             @NonNull String packageName);
80 
81     @Override
onBind(Intent intent)82     public final IBinder onBind(Intent intent) {
83         return new IRuntimePermissionPresenter.Stub() {
84             @Override
85             public void getAppPermissions(String packageName, RemoteCallback callback) {
86                 checkNotNull(packageName, "packageName");
87                 checkNotNull(callback, "callback");
88 
89                 mHandler.sendMessage(
90                         obtainMessage(RuntimePermissionPresenterService::getAppPermissions,
91                                 RuntimePermissionPresenterService.this, packageName, callback));
92             }
93         };
94     }
95 
96     private void getAppPermissions(@NonNull String packageName, @NonNull RemoteCallback callback) {
97         List<RuntimePermissionPresentationInfo> permissions = onGetAppPermissions(packageName);
98         if (permissions != null && !permissions.isEmpty()) {
99             Bundle result = new Bundle();
100             result.putParcelableList(KEY_RESULT, permissions);
101             callback.sendResult(result);
102         } else {
103             callback.sendResult(null);
104         }
105     }
106 }
107