summaryrefslogtreecommitdiff
path: root/src/com/android/server/telecom/UserUtil.java
blob: 670ad34389c544b011a71e44c95b33113a434afe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.telecom;

import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;

import com.android.server.telecom.components.ErrorDialogActivity;
import com.android.server.telecom.flags.FeatureFlags;

public final class UserUtil {

    private UserUtil() {
    }

    private static UserInfo getUserInfoFromUserHandle(Context context, UserHandle userHandle) {
        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
        return userManager.getUserInfo(userHandle.getIdentifier());
    }

    public static boolean isManagedProfile(Context context, UserHandle userHandle) {
        UserInfo userInfo = getUserInfoFromUserHandle(context, userHandle);
        return userInfo != null && userInfo.isManagedProfile();
    }

    public static boolean isProfile(Context context, UserHandle userHandle) {
        UserInfo userInfo = getUserInfoFromUserHandle(context, userHandle);
        return userInfo != null && userInfo.profileGroupId != userInfo.id;
    }

    public static void showErrorDialogForRestrictedOutgoingCall(Context context,
            int stringId, String tag, String reason) {
        final Intent intent = new Intent(context, ErrorDialogActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(ErrorDialogActivity.ERROR_MESSAGE_ID_EXTRA, stringId);
        context.startActivityAsUser(intent, UserHandle.CURRENT);
        Log.w(tag, "Rejecting non-emergency phone call because "
                + reason);
    }

    public static boolean hasOutgoingCallsUserRestriction(Context context,
            UserHandle userHandle, Uri handle, boolean isSelfManaged, String tag) {
        // Set handle for conference calls. Refer to {@link Connection#ADHOC_CONFERENCE_ADDRESS}.
        if (handle == null) {
            handle = Uri.parse("tel:conf-factory");
        }

        if(!isSelfManaged) {
            // Check DISALLOW_OUTGOING_CALLS restriction. Note: We are skipping this
            // check in a managed profile user because this check can always be bypassed
            // by copying and pasting the phone number into the personal dialer.
            if (!UserUtil.isManagedProfile(context, userHandle)) {
                // Only emergency calls are allowed for users with the DISALLOW_OUTGOING_CALLS
                // restriction.
                if (!TelephonyUtil.shouldProcessAsEmergency(context, handle)) {
                    final UserManager userManager =
                            (UserManager) context.getSystemService(Context.USER_SERVICE);
                    if (userManager.hasBaseUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
                            userHandle)) {
                        String reason = "of DISALLOW_OUTGOING_CALLS restriction";
                        showErrorDialogForRestrictedOutgoingCall(context,
                                R.string.outgoing_call_not_allowed_user_restriction, tag, reason);
                        return true;
                    } else if (userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
                            userHandle)) {
                        final DevicePolicyManager dpm =
                                context.getSystemService(DevicePolicyManager.class);
                        if (dpm == null) {
                            return true;
                        }
                        final Intent adminSupportIntent = dpm.createAdminSupportIntent(
                                UserManager.DISALLOW_OUTGOING_CALLS);
                        if (adminSupportIntent != null) {
                            context.startActivityAsUser(adminSupportIntent, userHandle);
                        }
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Gets the associated user for the given call. Note: this is applicable to all calls except
     * outgoing calls as the associated user is already based off of the user placing the
     * call.
     *
     * @param phoneAccountRegistrar
     * @param currentUser Current user profile (this can either be the admin or a secondary/guest
     *                    user). Note that work profile users fall under the admin user.
     * @param targetPhoneAccount The phone account to retrieve the {@link UserHandle} from.
     * @return current user if it isn't the admin or if the work profile is paused for the target
     * phone account handle user, otherwise return the target phone account handle user. If the
     * flag is disabled, return the legacy {@link UserHandle}.
     */
    public static UserHandle getAssociatedUserForCall(boolean isAssociatedUserFlagEnabled,
            PhoneAccountRegistrar phoneAccountRegistrar, UserHandle currentUser,
            PhoneAccountHandle targetPhoneAccount) {
        if (!isAssociatedUserFlagEnabled) {
            return targetPhoneAccount.getUserHandle();
        }
        // For multi-user phone accounts, associate the call with the profile receiving/placing
        // the call. For SIM accounts (that are assigned to specific users), the user association
        // will be placed on the target phone account handle user.
        PhoneAccount account = phoneAccountRegistrar.getPhoneAccountUnchecked(targetPhoneAccount);
        if (account != null) {
            return account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)
                    ? currentUser
                    : targetPhoneAccount.getUserHandle();
        }
        // If target phone account handle is null or account cannot be found,
        // return the current user.
        return currentUser;
    }
}