1 /*
2  * Copyright (C) 2018 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 com.android.settingslib;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.os.UserHandle;
25 import android.os.UserManager;
26 import android.provider.Settings;
27 
28 import androidx.annotation.Nullable;
29 
30 import java.util.Objects;
31 
32 /**
33  * Utility class to host methods usable in adding a restricted padlock icon and showing admin
34  * support message dialog.
35  */
36 public class RestrictedLockUtils {
getProfileOrDeviceOwner(Context context, UserHandle user)37     public static EnforcedAdmin getProfileOrDeviceOwner(Context context, UserHandle user) {
38         return getProfileOrDeviceOwner(context, null, user);
39     }
40 
getProfileOrDeviceOwner( Context context, String enforcedRestriction, UserHandle user)41     public static EnforcedAdmin getProfileOrDeviceOwner(
42             Context context, String enforcedRestriction, UserHandle user) {
43         if (user == null) {
44             return null;
45         }
46         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
47                 Context.DEVICE_POLICY_SERVICE);
48         if (dpm == null) {
49             return null;
50         }
51 
52         Context userContext;
53         try {
54             userContext = context.createPackageContextAsUser(context.getPackageName(), 0, user);
55         } catch (PackageManager.NameNotFoundException e) {
56             throw new IllegalStateException(e);
57         }
58 
59         ComponentName adminComponent = userContext.getSystemService(
60                 DevicePolicyManager.class).getProfileOwner();
61         if (adminComponent != null) {
62             return new EnforcedAdmin(adminComponent, enforcedRestriction, user);
63         }
64         if (Objects.equals(dpm.getDeviceOwnerUser(), user)) {
65             adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
66             if (adminComponent != null) {
67                 return new EnforcedAdmin(adminComponent, enforcedRestriction, user);
68             }
69         }
70         return null;
71     }
72 
73     /**
74      * Send the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}.
75      */
sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin)76     public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
77         final Intent intent = getShowAdminSupportDetailsIntent(context, admin);
78         int targetUserId = UserHandle.myUserId();
79         if (admin != null) {
80             if (admin.user != null
81                     && isCurrentUserOrProfile(context, admin.user.getIdentifier())) {
82                 targetUserId = admin.user.getIdentifier();
83             }
84             intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, admin.enforcedRestriction);
85         }
86         context.startActivityAsUser(intent, UserHandle.of(targetUserId));
87     }
88 
getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin)89     public static Intent getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
90         final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
91         if (admin != null) {
92             if (admin.component != null) {
93                 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component);
94             }
95             intent.putExtra(Intent.EXTRA_USER, admin.user);
96         }
97         return intent;
98     }
99 
isCurrentUserOrProfile(Context context, int userId)100     public static boolean isCurrentUserOrProfile(Context context, int userId) {
101         UserManager um = context.getSystemService(UserManager.class);
102         return um.getUserProfiles().contains(UserHandle.of(userId));
103     }
104 
105     public static class EnforcedAdmin {
106         @Nullable
107         public ComponentName component = null;
108         /**
109          * The restriction enforced by admin. It could be any user restriction or policy like
110          * {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}.
111          */
112         @Nullable
113         public String enforcedRestriction = null;
114         @Nullable
115         public UserHandle user = null;
116 
117         // We use this to represent the case where a policy is enforced by multiple admins.
118         public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin();
119 
createDefaultEnforcedAdminWithRestriction( String enforcedRestriction)120         public static EnforcedAdmin createDefaultEnforcedAdminWithRestriction(
121                 String enforcedRestriction) {
122             EnforcedAdmin enforcedAdmin = new EnforcedAdmin();
123             enforcedAdmin.enforcedRestriction = enforcedRestriction;
124             return enforcedAdmin;
125         }
126 
EnforcedAdmin(ComponentName component, UserHandle user)127         public EnforcedAdmin(ComponentName component, UserHandle user) {
128             this.component = component;
129             this.user = user;
130         }
131 
EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user)132         public EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user) {
133             this.component = component;
134             this.enforcedRestriction = enforcedRestriction;
135             this.user = user;
136         }
137 
EnforcedAdmin(EnforcedAdmin other)138         public EnforcedAdmin(EnforcedAdmin other) {
139             if (other == null) {
140                 throw new IllegalArgumentException();
141             }
142             this.component = other.component;
143             this.enforcedRestriction = other.enforcedRestriction;
144             this.user = other.user;
145         }
146 
EnforcedAdmin()147         public EnforcedAdmin() {
148         }
149 
150         @Override
equals(Object o)151         public boolean equals(Object o) {
152             if (this == o) return true;
153             if (o == null || getClass() != o.getClass()) return false;
154             EnforcedAdmin that = (EnforcedAdmin) o;
155             return Objects.equals(user, that.user) &&
156                     Objects.equals(component, that.component) &&
157                     Objects.equals(enforcedRestriction, that.enforcedRestriction);
158         }
159 
160         @Override
hashCode()161         public int hashCode() {
162             return Objects.hash(component, enforcedRestriction, user);
163         }
164 
165         @Override
toString()166         public String toString() {
167             return "EnforcedAdmin{" +
168                     "component=" + component +
169                     ", enforcedRestriction='" + enforcedRestriction +
170                     ", user=" + user +
171                     '}';
172         }
173     }
174 }
175