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