• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.annotation.SystemApi;
20 import android.app.Service;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.ApplicationInfo;
24 import android.content.pm.permission.IRuntimePermissionPresenter;
25 import android.content.pm.permission.RuntimePermissionPresentationInfo;
26 import android.content.pm.permission.RuntimePermissionPresenter;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.IBinder;
30 import android.os.Looper;
31 import android.os.Message;
32 import android.os.RemoteCallback;
33 import com.android.internal.os.SomeArgs;
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 RuntimePermissionPresenter
44  * @see RuntimePermissionPresentationInfo
45  *
46  * @hide
47  */
48 @SystemApi
49 public abstract class RuntimePermissionPresenterService extends Service {
50 
51     /**
52      * The {@link Intent} action that must be declared as handled by a service
53      * in its manifest for the system to recognize it as a runtime permission
54      * presenter service.
55      */
56     public static final String SERVICE_INTERFACE =
57             "android.permissionpresenterservice.RuntimePermissionPresenterService";
58 
59     // No need for locking - always set first and never modified
60     private Handler mHandler;
61 
62     @Override
attachBaseContext(Context base)63     public final void attachBaseContext(Context base) {
64         super.attachBaseContext(base);
65         mHandler = new MyHandler(base.getMainLooper());
66     }
67 
68     /**
69      * Gets the runtime permissions for an app.
70      *
71      * @param packageName The package for which to query.
72      */
onGetAppPermissions(String packageName)73     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
74 
75     /**
76      * Gets the apps that use runtime permissions.
77      *
78      * @param system Whether to return only the system apps or only the non-system ones.
79      * @return The app list.
80      */
onGetAppsUsingPermissions(boolean system)81     public abstract List<ApplicationInfo> onGetAppsUsingPermissions(boolean system);
82 
83     @Override
onBind(Intent intent)84     public final IBinder onBind(Intent intent) {
85         return new IRuntimePermissionPresenter.Stub() {
86             @Override
87             public void getAppPermissions(String packageName, RemoteCallback callback) {
88                 SomeArgs args = SomeArgs.obtain();
89                 args.arg1 = packageName;
90                 args.arg2 = callback;
91                 mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
92                         args).sendToTarget();
93             }
94 
95             @Override
96             public void getAppsUsingPermissions(boolean system, RemoteCallback callback) {
97                 mHandler.obtainMessage(MyHandler.MSG_GET_APPS_USING_PERMISSIONS,
98                         system ? 1 : 0, 0, callback).sendToTarget();
99             }
100         };
101     }
102 
103     private final class MyHandler extends Handler {
104         public static final int MSG_GET_APP_PERMISSIONS = 1;
105         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
106 
107         public MyHandler(Looper looper) {
108             super(looper, null, false);
109         }
110 
111         @Override
112         public void handleMessage(Message msg) {
113             switch (msg.what) {
114                 case MSG_GET_APP_PERMISSIONS: {
115                     SomeArgs args = (SomeArgs) msg.obj;
116                     String packageName = (String) args.arg1;
117                     RemoteCallback callback = (RemoteCallback) args.arg2;
118                     args.recycle();
119                     List<RuntimePermissionPresentationInfo> permissions =
120                             onGetAppPermissions(packageName);
121                     if (permissions != null && !permissions.isEmpty()) {
122                         Bundle result = new Bundle();
123                         result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT,
124                                 permissions);
125                         callback.sendResult(result);
126                     } else {
127                         callback.sendResult(null);
128                     }
129                 } break;
130 
131                 case MSG_GET_APPS_USING_PERMISSIONS: {
132                     RemoteCallback callback = (RemoteCallback) msg.obj;
133                     final boolean system = msg.arg1 == 1;
134                     List<ApplicationInfo> apps = onGetAppsUsingPermissions(system);
135                     if (apps != null && !apps.isEmpty()) {
136                         Bundle result = new Bundle();
137                         result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT, apps);
138                         callback.sendResult(result);
139                     } else {
140                         callback.sendResult(null);
141                     }
142                 } break;
143             }
144         }
145     }
146 }
147