1 /* 2 * Copyright (C) 2014 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.server.telecom; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.UserInfo; 23 import android.net.Uri; 24 import android.os.UserHandle; 25 import android.os.UserManager; 26 import android.telecom.Log; 27 import android.telecom.PhoneAccount; 28 import android.telecom.PhoneAccountHandle; 29 30 import com.android.server.telecom.components.ErrorDialogActivity; 31 import com.android.server.telecom.flags.FeatureFlags; 32 33 public final class UserUtil { 34 UserUtil()35 private UserUtil() { 36 } 37 38 private static final String LOG_TAG = "UserUtil"; 39 getUserInfoFromUserHandle(Context context, UserHandle userHandle)40 private static UserInfo getUserInfoFromUserHandle(Context context, UserHandle userHandle) { 41 UserManager userManager = context.getSystemService(UserManager.class); 42 return userManager.getUserInfo(userHandle.getIdentifier()); 43 } 44 getUserManagerFromUserHandle(Context context, UserHandle userHandle)45 private static UserManager getUserManagerFromUserHandle(Context context, 46 UserHandle userHandle) { 47 UserManager userManager = null; 48 try { 49 userManager = context.createContextAsUser(userHandle, 0) 50 .getSystemService(UserManager.class); 51 } catch (IllegalStateException e) { 52 Log.e(LOG_TAG, e, "Error while creating context as user = " + userHandle); 53 } 54 return userManager; 55 } 56 isManagedProfile(Context context, UserHandle userHandle, FeatureFlags featureFlags)57 public static boolean isManagedProfile(Context context, UserHandle userHandle, 58 FeatureFlags featureFlags) { 59 UserManager userManager = getUserManagerFromUserHandle(context, userHandle); 60 UserInfo userInfo = getUserInfoFromUserHandle(context, userHandle); 61 return featureFlags.telecomResolveHiddenDependencies() 62 ? userManager != null && userManager.isManagedProfile() 63 : userInfo != null && userInfo.isManagedProfile(); 64 } 65 isPrivateProfile(UserHandle userHandle, Context context)66 public static boolean isPrivateProfile(UserHandle userHandle, Context context) { 67 UserManager um = getUserManagerFromUserHandle(context, userHandle); 68 return um != null && um.isPrivateProfile(); 69 } 70 isProfile(Context context, UserHandle userHandle, FeatureFlags featureFlags)71 public static boolean isProfile(Context context, UserHandle userHandle, 72 FeatureFlags featureFlags) { 73 UserManager userManager = getUserManagerFromUserHandle(context, userHandle); 74 UserInfo userInfo = getUserInfoFromUserHandle(context, userHandle); 75 return featureFlags.telecomResolveHiddenDependencies() 76 ? userManager != null && userManager.isProfile() 77 : userInfo != null && userInfo.profileGroupId != userInfo.id 78 && userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID; 79 } 80 showErrorDialogForRestrictedOutgoingCall(Context context, int stringId, String tag, String reason)81 public static void showErrorDialogForRestrictedOutgoingCall(Context context, 82 int stringId, String tag, String reason) { 83 final Intent intent = new Intent(context, ErrorDialogActivity.class); 84 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 85 intent.putExtra(ErrorDialogActivity.ERROR_MESSAGE_ID_EXTRA, stringId); 86 context.startActivityAsUser(intent, UserHandle.CURRENT); 87 Log.w(tag, "Rejecting non-emergency phone call because " 88 + reason); 89 } 90 hasOutgoingCallsUserRestriction(Context context, UserHandle userHandle, Uri handle, boolean isSelfManaged, String tag, FeatureFlags featureFlags)91 public static boolean hasOutgoingCallsUserRestriction(Context context, 92 UserHandle userHandle, Uri handle, boolean isSelfManaged, String tag, 93 FeatureFlags featureFlags) { 94 // Set handle for conference calls. Refer to {@link Connection#ADHOC_CONFERENCE_ADDRESS}. 95 if (handle == null) { 96 handle = Uri.parse("tel:conf-factory"); 97 } 98 99 if(!isSelfManaged) { 100 // Check DISALLOW_OUTGOING_CALLS restriction. Note: We are skipping this 101 // check in a managed profile user because this check can always be bypassed 102 // by copying and pasting the phone number into the personal dialer. 103 if (!UserUtil.isManagedProfile(context, userHandle, featureFlags)) { 104 final UserManager userManager = context.getSystemService(UserManager.class); 105 boolean hasUserRestriction = featureFlags.telecomResolveHiddenDependencies() 106 ? userManager.hasUserRestrictionForUser( 107 UserManager.DISALLOW_OUTGOING_CALLS, userHandle) 108 : userManager.hasUserRestriction( 109 UserManager.DISALLOW_OUTGOING_CALLS, userHandle); 110 // Only emergency calls are allowed for users with the DISALLOW_OUTGOING_CALLS 111 // restriction. 112 if (!TelephonyUtil.shouldProcessAsEmergency(context, handle)) { 113 if (userManager.hasBaseUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, 114 userHandle)) { 115 String reason = "of DISALLOW_OUTGOING_CALLS restriction"; 116 showErrorDialogForRestrictedOutgoingCall(context, 117 R.string.outgoing_call_not_allowed_user_restriction, tag, reason); 118 return true; 119 } else if (hasUserRestriction) { 120 final DevicePolicyManager dpm = 121 context.getSystemService(DevicePolicyManager.class); 122 if (dpm == null) { 123 return true; 124 } 125 final Intent adminSupportIntent = dpm.createAdminSupportIntent( 126 UserManager.DISALLOW_OUTGOING_CALLS); 127 if (adminSupportIntent != null) { 128 context.startActivityAsUser(adminSupportIntent, userHandle); 129 } 130 return true; 131 } 132 } 133 } 134 } 135 return false; 136 } 137 138 /** 139 * Gets the associated user for the given call. Note: this is applicable to all calls except 140 * outgoing calls as the associated user is already based off of the user placing the 141 * call. 142 * 143 * @param phoneAccountRegistrar 144 * @param currentUser Current user profile (this can either be the admin or a secondary/guest 145 * user). Note that work profile users fall under the admin user. 146 * @param targetPhoneAccount The phone account to retrieve the {@link UserHandle} from. 147 * @return current user if it isn't the admin or if the work profile is paused for the target 148 * phone account handle user, otherwise return the target phone account handle user. If the 149 * flag is disabled, return the legacy {@link UserHandle}. 150 */ getAssociatedUserForCall(boolean isAssociatedUserFlagEnabled, PhoneAccountRegistrar phoneAccountRegistrar, UserHandle currentUser, PhoneAccountHandle targetPhoneAccount)151 public static UserHandle getAssociatedUserForCall(boolean isAssociatedUserFlagEnabled, 152 PhoneAccountRegistrar phoneAccountRegistrar, UserHandle currentUser, 153 PhoneAccountHandle targetPhoneAccount) { 154 if (!isAssociatedUserFlagEnabled) { 155 return targetPhoneAccount.getUserHandle(); 156 } 157 // For multi-user phone accounts, associate the call with the profile receiving/placing 158 // the call. For SIM accounts (that are assigned to specific users), the user association 159 // will be placed on the target phone account handle user. 160 PhoneAccount account = phoneAccountRegistrar.getPhoneAccountUnchecked(targetPhoneAccount); 161 if (account != null) { 162 return account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER) 163 ? currentUser 164 : targetPhoneAccount.getUserHandle(); 165 } 166 // If target phone account handle is null or account cannot be found, 167 // return the current user. 168 return currentUser; 169 } 170 } 171