• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.app.supervision;
18 
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.MANAGE_USERS;
21 import static android.Manifest.permission.QUERY_USERS;
22 import static android.permission.flags.Flags.FLAG_ENABLE_SYSTEM_SUPERVISION_ROLE_BEHAVIOR;
23 
24 import android.annotation.FlaggedApi;
25 import android.annotation.Nullable;
26 import android.annotation.RequiresPermission;
27 import android.annotation.SystemApi;
28 import android.annotation.SystemService;
29 import android.annotation.TestApi;
30 import android.annotation.UserHandleAware;
31 import android.annotation.UserIdInt;
32 import android.app.supervision.flags.Flags;
33 import android.compat.annotation.UnsupportedAppUsage;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.os.RemoteException;
37 
38 /**
39  * Service for handling parental supervision.
40  *
41  * @hide
42  */
43 @SystemService(Context.SUPERVISION_SERVICE)
44 @SystemApi
45 @FlaggedApi(Flags.FLAG_SUPERVISION_MANAGER_APIS)
46 public class SupervisionManager {
47     private final Context mContext;
48     @Nullable private final ISupervisionManager mService;
49 
50     /**
51      * Activity action: ask the human user to enable supervision for this user. Only the app that
52      * holds the {@code SYSTEM_SUPERVISION} role can launch this intent.
53      *
54      * <p>The intent must be invoked via {@link Activity#startActivityForResult} to receive the
55      * result of whether or not the user approved the action. If approved, the result will be {@link
56      * Activity#RESULT_OK}.
57      *
58      * <p>If supervision is already enabled, the operation will return a failure result.
59      *
60      * @hide
61      */
62     public static final String ACTION_ENABLE_SUPERVISION =
63             "android.app.supervision.action.ENABLE_SUPERVISION";
64 
65     /**
66      * Activity action: ask the human user to disable supervision for this user. Only the app that
67      * holds the {@code SYSTEM_SUPERVISION} role can launch this intent.
68      *
69      * <p>The intent must be invoked via {@link Activity#startActivityForResult} to receive the
70      * result of whether or not the user approved the action. If approved, the result will be {@link
71      * Activity#RESULT_OK}.
72      *
73      * <p>If supervision is not enabled, the operation will return a failure result.
74      *
75      * @hide
76      */
77     public static final String ACTION_DISABLE_SUPERVISION =
78             "android.app.supervision.action.DISABLE_SUPERVISION";
79 
80     /** @hide */
81     @UnsupportedAppUsage
SupervisionManager(Context context, @Nullable ISupervisionManager service)82     public SupervisionManager(Context context, @Nullable ISupervisionManager service) {
83         mContext = context;
84         mService = service;
85     }
86 
87     /**
88      * Creates an {@link Intent} that can be used with {@link Context#startActivity(Intent)} to
89      * launch the activity to verify supervision credentials.
90      *
91      * <p>A valid {@link Intent} is always returned if supervision is enabled at the time this API
92      * is called, the launched activity still need to perform validity checks as the supervision
93      * state can change when the activity is launched. A null intent is returned if supervision is
94      * disabled at the time of this API call.
95      *
96      * <p>A result code of {@link android.app.Activity#RESULT_OK} indicates successful verification
97      * of the supervision credentials.
98      *
99      * @hide
100      */
101     @SystemApi
102     @FlaggedApi(Flags.FLAG_SUPERVISION_MANAGER_APIS)
103     @RequiresPermission(anyOf = {MANAGE_USERS, QUERY_USERS})
104     @Nullable
createConfirmSupervisionCredentialsIntent()105     public Intent createConfirmSupervisionCredentialsIntent() {
106         if (mService != null) {
107             try {
108                 Intent result = mService.createConfirmSupervisionCredentialsIntent();
109                 if (result != null) {
110                     result.prepareToEnterProcess(
111                             Intent.LOCAL_FLAG_FROM_SYSTEM, mContext.getAttributionSource());
112                 }
113                 return result;
114             } catch (RemoteException e) {
115                 throw e.rethrowFromSystemServer();
116             }
117         }
118         return null;
119     }
120 
121     /**
122      * Returns whether the device is supervised.
123      *
124      * @hide
125      */
126     @SystemApi
127     @FlaggedApi(Flags.FLAG_SUPERVISION_MANAGER_APIS)
128     @RequiresPermission(anyOf = {MANAGE_USERS, QUERY_USERS})
129     @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
isSupervisionEnabled()130     public boolean isSupervisionEnabled() {
131         return isSupervisionEnabledForUser(mContext.getUserId());
132     }
133 
134     /**
135      * Returns whether the device is supervised.
136      *
137      * @hide
138      */
139     @RequiresPermission(anyOf = {MANAGE_USERS, QUERY_USERS})
140     @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
isSupervisionEnabledForUser(@serIdInt int userId)141     public boolean isSupervisionEnabledForUser(@UserIdInt int userId) {
142         if (mService != null) {
143             try {
144                 return mService.isSupervisionEnabledForUser(userId);
145             } catch (RemoteException e) {
146                 throw e.rethrowFromSystemServer();
147             }
148         }
149         return false;
150     }
151 
152     /**
153      * Sets whether the device is supervised for the current user.
154      *
155      * @hide
156      */
157     @TestApi
158     @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
setSupervisionEnabled(boolean enabled)159     public void setSupervisionEnabled(boolean enabled) {
160         setSupervisionEnabledForUser(mContext.getUserId(), enabled);
161     }
162 
163     /**
164      * Sets whether the device is supervised for a given user.
165      *
166      * @hide
167      */
168     @UserHandleAware(requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS)
setSupervisionEnabledForUser(@serIdInt int userId, boolean enabled)169     public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) {
170         if (mService != null) {
171             try {
172                 mService.setSupervisionEnabledForUser(userId, enabled);
173             } catch (RemoteException e) {
174                 throw e.rethrowFromSystemServer();
175             }
176         }
177     }
178 
179     /**
180      * Returns the package name of the app that is acting as the active supervision app or null if
181      * supervision is disabled.
182      *
183      * @hide
184      */
185     @UserHandleAware
186     @Nullable
getActiveSupervisionAppPackage()187     public String getActiveSupervisionAppPackage() {
188         if (mService != null) {
189             try {
190                 return mService.getActiveSupervisionAppPackage(mContext.getUserId());
191             } catch (RemoteException e) {
192                 throw e.rethrowFromSystemServer();
193             }
194         }
195         return null;
196     }
197 
198 
199     /**
200      * @return {@code true} if bypassing the qualification is allowed for the specified role based
201      * on the current state of the device.
202      *
203      * @hide
204      */
205     @SystemApi
206     @FlaggedApi(FLAG_ENABLE_SYSTEM_SUPERVISION_ROLE_BEHAVIOR)
207     @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS)
shouldAllowBypassingSupervisionRoleQualification()208     public boolean shouldAllowBypassingSupervisionRoleQualification() {
209         if (mService != null) {
210             try {
211                 return mService.shouldAllowBypassingSupervisionRoleQualification();
212             } catch (RemoteException e) {
213                 throw e.rethrowFromSystemServer();
214             }
215         }
216         return false;
217     }
218 }
219