blob: 405be1a2520c7807822b23cd0f57d5e1c5c60be9 [file] [log] [blame]
Svet Ganovae0e03a2016-02-25 18:22:10 -08001/*
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
17package android.permissionpresenterservice;
18
19import android.annotation.SystemApi;
20import android.app.Service;
21import android.content.Context;
22import android.content.Intent;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.permission.IRuntimePermissionPresenter;
25import android.content.pm.permission.RuntimePermissionPresentationInfo;
26import android.content.pm.permission.RuntimePermissionPresenter;
27import android.os.Bundle;
28import android.os.Handler;
29import android.os.IBinder;
30import android.os.Looper;
31import android.os.Message;
32import android.os.RemoteCallback;
33import com.android.internal.os.SomeArgs;
34
35import 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
49public 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
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 */
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 */
81 public abstract List<ApplicationInfo> onGetAppsUsingPermissions(boolean system);
82
83 @Override
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}