1 /*
2  * Copyright (C) 2022 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.utils;
18 
19 
20 import android.app.admin.DevicePolicyManager;
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ResolveInfo;
26 import android.os.UserHandle;
27 import android.os.UserManager;
28 import android.provider.Settings;
29 
30 import androidx.annotation.Nullable;
31 
32 import java.util.List;
33 
34 
35 /**
36  * Utility class for find out when to show WorkPolicyInfo
37  */
38 public class WorkPolicyUtils {
39 
40     private final Context mContext;
41     private final PackageManager mPackageManager;
42     private final UserManager mUserManager;
43     private final DevicePolicyManager mDevicePolicyManager;
44 
45     private static final int USER_NULL = -10000;
46 
WorkPolicyUtils( Context context )47     public WorkPolicyUtils(
48             Context context
49     ) {
50         mContext = context;
51         mPackageManager = context.getPackageManager();
52         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
53         mDevicePolicyManager =
54                 (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
55     }
56 
57     /**
58      * Returns {@code true} if it is possilbe to resolve an Intent to launch the "Your work policy
59      * info" page provided by the active Device Owner or Profile Owner app if it exists, {@code
60      * false} otherwise.
61      */
hasWorkPolicy()62     public boolean hasWorkPolicy() {
63         return getWorkPolicyInfoIntentDO() != null || getWorkPolicyInfoIntentPO() != null;
64     }
65 
66     /**
67      * Launches the Device Owner or Profile Owner's activity that displays the "Your work policy
68      * info" page. Returns {@code true} if the activity has indeed been launched.
69      */
showWorkPolicyInfo(Context activityContext)70     public boolean showWorkPolicyInfo(Context activityContext) {
71         Intent intent = getWorkPolicyInfoIntentDO();
72         if (intent != null) {
73             activityContext.startActivity(intent);
74             return true;
75         }
76 
77         intent = getWorkPolicyInfoIntentPO();
78         final int userId = getManagedProfileUserId();
79         if (intent != null && userId != USER_NULL) {
80             activityContext.startActivityAsUser(intent, UserHandle.of(userId));
81             return true;
82         }
83 
84         return false;
85     }
86 
87     /**
88      * Returns the work policy info intent if the device owner component exists,
89      * and returns {@code null} otherwise
90      */
91     @Nullable
getWorkPolicyInfoIntentDO()92     public Intent getWorkPolicyInfoIntentDO() {
93         final ComponentName ownerComponent = getDeviceOwnerComponent();
94         if (ownerComponent == null) {
95             return null;
96         }
97 
98         // Only search for the required action in the Device Owner's package
99         final Intent intent =
100                 new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO)
101                         .setPackage(ownerComponent.getPackageName());
102         final List<ResolveInfo> activities = mPackageManager.queryIntentActivities(intent, 0);
103         if (activities.size() != 0) {
104             return intent;
105         }
106 
107         return null;
108     }
109 
110     @Nullable
getManagedProfileOwnerComponent(int managedUserId)111     private ComponentName getManagedProfileOwnerComponent(int managedUserId) {
112         if (managedUserId == USER_NULL) {
113             return null;
114         }
115         Context managedProfileContext;
116         try {
117             managedProfileContext =
118                     mContext.createPackageContextAsUser(
119                             mContext.getPackageName(), 0, UserHandle.of(managedUserId)
120                     );
121         } catch (PackageManager.NameNotFoundException e) {
122             return null;
123         }
124 
125         DevicePolicyManager managedProfileDevicePolicyManager =
126                 (DevicePolicyManager)
127                         managedProfileContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
128         ComponentName ownerComponent = managedProfileDevicePolicyManager.getProfileOwner();
129         return ownerComponent;
130     }
131 
132     /**
133      * Returns the work policy info intent if the profile owner component exists,
134      * and returns {@code null} otherwise
135      */
136     @Nullable
getWorkPolicyInfoIntentPO()137     public Intent getWorkPolicyInfoIntentPO() {
138         final int managedUserId = getManagedProfileUserId();
139         ComponentName ownerComponent = getManagedProfileOwnerComponent(managedUserId);
140         if (ownerComponent == null) {
141             return null;
142         }
143 
144         // Only search for the required action in the Profile Owner's package
145         final Intent intent =
146                 new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO)
147                         .setPackage(ownerComponent.getPackageName());
148         final List<ResolveInfo> activities =
149                 mPackageManager.queryIntentActivitiesAsUser(
150                         intent, 0, UserHandle.of(managedUserId));
151         if (activities.size() != 0) {
152             return intent;
153         }
154 
155         return null;
156     }
157 
158     @Nullable
getDeviceOwnerComponent()159     private ComponentName getDeviceOwnerComponent() {
160         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
161             return null;
162         }
163         return mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser();
164     }
165 
166     /**
167      * Returns the user id of the managed profile, and returns {@code USER_NULL} otherwise
168      */
getManagedProfileUserId()169     public int getManagedProfileUserId() {
170         List<UserHandle> allProfiles = mUserManager.getAllProfiles();
171         for (UserHandle uh : allProfiles) {
172             int id = uh.getIdentifier();
173             if (mUserManager.isManagedProfile(id)) {
174                 return id;
175             }
176         }
177         return USER_NULL;
178     }
179 
180 }
181