1f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon/*
2f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * Copyright (C) 2014 The Android Open Source Project
3f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon *
4f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * you may not use this file except in compliance with the License.
6f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * You may obtain a copy of the License at
7f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon *
8f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon *
10f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * Unless required by applicable law or agreed to in writing, software
11f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * See the License for the specific language governing permissions and
14f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * limitations under the License.
15f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon */
16f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
17f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonpackage com.android.server.telecom;
18f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
19f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.Manifest;
20f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.annotation.SdkConstant;
21f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.app.AppOpsManager;
22f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.app.Service;
23f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.content.ComponentName;
24f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.content.Context;
25f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.content.Intent;
26f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.content.pm.ApplicationInfo;
27f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.content.pm.PackageManager;
28f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.content.res.Resources;
29f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.net.Uri;
30f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.Binder;
31f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.Bundle;
32f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.Handler;
33f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.IBinder;
34f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.Looper;
35f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.Message;
36f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.UserHandle;
37f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.os.UserManager;
38f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.telecom.CallState;
39f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.telecom.PhoneAccount;
40f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.telecom.PhoneAccountHandle;
41f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.telecom.TelecomManager;
42f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.telephony.SubscriptionManager;
43f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.telephony.TelephonyManager;
44f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport android.text.TextUtils;
45f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
46f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon// TODO: Needed for move to system service: import com.android.internal.R;
47f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport com.android.internal.telecom.ITelecomService;
48f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport com.android.internal.util.IndentingPrintWriter;
49f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
50f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport java.io.FileDescriptor;
51f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport java.io.PrintWriter;
52f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport java.util.ArrayList;
53f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonimport java.util.List;
54f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
55f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon/**
56f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon * Implementation of the ITelecom interface.
57f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon */
58f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordonpublic class TelecomService extends Service {
59f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /**
60f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * The {@link Intent} that must be declared as handled by the service.
61f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     */
62f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
63f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    public static final String SERVICE_INTERFACE = "android.telecom.ITelecomService";
64f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
65f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /** The context. */
66f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private Context mContext;
67f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
68f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /**
69f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
70f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * request after sending. The main thread will notify the request when it is complete.
71f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     */
72f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final class MainThreadRequest {
73f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /** The result of the request that is run on the main thread */
74f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public Object result;
75f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /** Object that can be used to store non-integer arguments */
76f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public Object arg;
77f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
78f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
79f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /**
80f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * A handler that processes messages on the main thread. Since many of the method calls are not
81f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * thread safe this is needed to shuttle the requests from the inbound binder threads to the
82f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * main thread.
83f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     */
84f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private final class MainThreadHandler extends Handler {
85f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
86f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void handleMessage(Message msg) {
87f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (msg.obj instanceof MainThreadRequest) {
88f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                MainThreadRequest request = (MainThreadRequest) msg.obj;
89f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Object result = null;
90f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                switch (msg.what) {
91f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_SILENCE_RINGER:
92f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mCallsManager.getRinger().silence();
93f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
94f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_SHOW_CALL_SCREEN:
95f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mCallsManager.getInCallController().bringToForeground(msg.arg1 == 1);
96f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
97f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_END_CALL:
98f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        result = endCallInternal();
99f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
100f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_ACCEPT_RINGING_CALL:
101f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        acceptRingingCallInternal();
102f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
103f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_CANCEL_MISSED_CALLS_NOTIFICATION:
104f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mMissedCallNotifier.clearMissedCalls();
105f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
106f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_IS_TTY_SUPPORTED:
107f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        result = mCallsManager.isTtySupported();
108f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
109f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_GET_CURRENT_TTY_MODE:
110f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        result = mCallsManager.getCurrentTtyMode();
111f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
112f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    case MSG_NEW_INCOMING_CALL:
113f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        if (request.arg == null || !(request.arg instanceof Intent)) {
114f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                            Log.w(this, "Invalid new incoming call request");
115f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                            break;
116f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        }
117f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        CallReceiver.processIncomingCallIntent((Intent) request.arg);
118f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        break;
119f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
120f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
121f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (result != null) {
122f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    request.result = result;
123f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    synchronized(request) {
124f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        request.notifyAll();
125f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    }
126f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
127f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
128f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
129f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
130f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
131f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final String TAG = TelecomService.class.getSimpleName();
132f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
133f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final String SERVICE_NAME = "telecom";
134f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
135f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_SILENCE_RINGER = 1;
136f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_SHOW_CALL_SCREEN = 2;
137f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_END_CALL = 3;
138f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_ACCEPT_RINGING_CALL = 4;
139f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5;
140f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_IS_TTY_SUPPORTED = 6;
141f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_GET_CURRENT_TTY_MODE = 7;
142f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private static final int MSG_NEW_INCOMING_CALL = 8;
143f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
144f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
145f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
146f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private CallsManager mCallsManager;
147f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private MissedCallNotifier mMissedCallNotifier;
148f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private PhoneAccountRegistrar mPhoneAccountRegistrar;
149f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private AppOpsManager mAppOpsManager;
150f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private UserManager mUserManager;
151f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private PackageManager mPackageManager;
152f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private TelecomServiceImpl mServiceImpl;
153f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
154f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    @Override
155f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    public void onCreate() {
156f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        super.onCreate();
157f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
158f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        Log.d(this, "onCreate");
159f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mContext = this;
160f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
161f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mServiceImpl = new TelecomServiceImpl();
162f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
163f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        TelecomGlobals globals = TelecomGlobals.getInstance();
164f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        globals.initialize(this);
165f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
166f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mMissedCallNotifier = globals.getMissedCallNotifier();
167f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mPhoneAccountRegistrar = globals.getPhoneAccountRegistrar();
168f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mCallsManager = globals.getCallsManager();
169f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
170f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mPackageManager = mContext.getPackageManager();
171f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
172f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
173f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    @Override
174f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    public IBinder onBind(Intent intent) {
175f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        Log.d(this, "onBind");
176f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return mServiceImpl;
177f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
178f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
179f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /**
180f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * Implementation of the ITelecomService interface.
181f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * TODO: Reorganize this inner class to top of file.
182f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     */
183f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    class TelecomServiceImpl extends ITelecomService.Stub {
184f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
185f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
186e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            enforceReadPermission();
187e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            long token = Binder.clearCallingIdentity();
188f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
189f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                PhoneAccountHandle defaultOutgoingPhoneAccount =
190f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getDefaultOutgoingPhoneAccount(uriScheme);
191f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                // Make sure that the calling user can see this phone account.
192f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (defaultOutgoingPhoneAccount != null
193f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        && !isVisibleToCaller(defaultOutgoingPhoneAccount)) {
194f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    Log.w(this, "No account found for the calling user");
195f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    return null;
196f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
197f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return defaultOutgoingPhoneAccount;
198f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
199f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getDefaultOutgoingPhoneAccount");
200f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
201e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            } finally {
202e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon                Binder.restoreCallingIdentity(token);
203f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
204f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
205f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
206f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
207f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
208f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
209f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                PhoneAccountHandle userSelectedOutgoingPhoneAccount =
210f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount();
211f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                // Make sure that the calling user can see this phone account.
212f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) {
213f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    Log.w(this, "No account found for the calling user");
214f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    return null;
215f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
216f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return userSelectedOutgoingPhoneAccount;
217f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
218f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
219f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
220f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
221f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
222f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
223f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
224f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
225f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermission();
226f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
227f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
228f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle);
229f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
230f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
231f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
232f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
233f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
234f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
235f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
236f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
237e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            enforceReadPermission();
238e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            long token = Binder.clearCallingIdentity();
239f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
240f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return filterForAccountsVisibleToCaller(
241f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getCallCapablePhoneAccounts());
242f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
243f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getCallCapablePhoneAccounts");
244f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
245e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            } finally {
246e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon                Binder.restoreCallingIdentity(token);
247f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
248f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
249f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
250f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
251f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
252e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            enforceReadPermission();
253e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            long token = Binder.clearCallingIdentity();
254f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
255f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return filterForAccountsVisibleToCaller(
256f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme));
257f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
258f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
259f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
260e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            } finally {
261e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon                Binder.restoreCallingIdentity(token);
262f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
263f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
264f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
265f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
266f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
267f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
268f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return filterForAccountsVisibleToCaller(
269f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName));
270f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
271f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
272f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
273f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
274f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
275f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
276f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
277f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
278f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
279f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (!isVisibleToCaller(accountHandle)) {
280f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    Log.w(this, "%s is not visible for the calling user", accountHandle);
281f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    return null;
282f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
283f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle);
284f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
285f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getPhoneAccount %s", accountHandle);
286f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
287f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
288f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
289f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
290f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
291f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public int getAllPhoneAccountsCount() {
292f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
293f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                // This list is pre-filtered for the calling user.
294f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return getAllPhoneAccounts().size();
295f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
296f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getAllPhoneAccountsCount");
297f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
298f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
299f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
300f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
301f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
302f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public List<PhoneAccount> getAllPhoneAccounts() {
303f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
304f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                List<PhoneAccount> allPhoneAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
305f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(allPhoneAccounts.size());
306f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                for (PhoneAccount phoneAccount : profilePhoneAccounts) {
307f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    if (isVisibleToCaller(phoneAccount)) {
308f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        profilePhoneAccounts.add(phoneAccount);
309f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    }
310f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
311f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return profilePhoneAccounts;
312f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
313f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getAllPhoneAccounts");
314f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
315f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
316f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
317f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
318f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
319f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
320f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
321f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return filterForAccountsVisibleToCaller(
322f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getAllPhoneAccountHandles());
323f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
324f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getAllPhoneAccounts");
325f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
326f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
327f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
328f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
329f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
330f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public PhoneAccountHandle getSimCallManager() {
331f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
332f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager();
333f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (!isVisibleToCaller(accountHandle)) {
334f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    Log.w(this, "%s is not visible for the calling user", accountHandle);
335f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    return null;
336f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
337f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return accountHandle;
338f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
339f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getSimCallManager");
340f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
341f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
342f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
343f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
344f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
345f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void setSimCallManager(PhoneAccountHandle accountHandle) {
346f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermission();
347f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
348f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
349f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mPhoneAccountRegistrar.setSimCallManager(accountHandle);
350f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
351f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "setSimCallManager");
352f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
353f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
354f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
355f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
356f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
357f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public List<PhoneAccountHandle> getSimCallManagers() {
358e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            enforceReadPermission();
359e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            long token = Binder.clearCallingIdentity();
360f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
361f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return filterForAccountsVisibleToCaller(
362f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts());
363f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
364f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getSimCallManagers");
365f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
366e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon            } finally {
367e6a33f2e9ec77f900260a50242d657668706c0aeSantos Cordon                Binder.restoreCallingIdentity(token);
368f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
369f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
370f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
371f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
372f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void registerPhoneAccount(PhoneAccount account) {
373f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
374f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforcePhoneAccountModificationForPackage(
375f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        account.getAccountHandle().getComponentName().getPackageName());
376f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
377f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    enforceRegisterCallProviderPermission();
378f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
379f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
380f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    enforceRegisterSimSubscriptionPermission();
381f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
382f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) {
383f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    enforceRegisterConnectionManagerPermission();
384f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
385f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
386f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    enforceRegisterMultiUser();
387f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
388f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforceUserHandleMatchesCaller(account.getAccountHandle());
389f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
390f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mPhoneAccountRegistrar.registerPhoneAccount(account);
391f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
392f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "registerPhoneAccount %s", account);
393f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
394f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
395f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
396f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
397f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
398f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
399f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
400f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforcePhoneAccountModificationForPackage(
401f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        accountHandle.getComponentName().getPackageName());
402f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforceUserHandleMatchesCaller(accountHandle);
403f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
404f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
405f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
406f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
407f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
408f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
409f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
410f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
411f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void clearAccounts(String packageName) {
412f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
413f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforcePhoneAccountModificationForPackage(packageName);
414f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mPhoneAccountRegistrar.clearAccounts(packageName, Binder.getCallingUserHandle());
415f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
416f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "clearAccounts %s", packageName);
417f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
418f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
419f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
420f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
421f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
422f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#isVoiceMailNumber
423f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
424f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
425f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
426f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermissionOrDefaultDialer();
427f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
428f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (!isVisibleToCaller(accountHandle)) {
429f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    Log.w(this, "%s is not visible for the calling user", accountHandle);
430f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    return false;
431f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
432f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
433f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
434f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getSubscriptionIdForPhoneAccount");
435f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
436f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
437f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
438f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
439f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
440f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#hasVoiceMailNumber
441f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
442f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
443f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
444f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermissionOrDefaultDialer();
445f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
446f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (!isVisibleToCaller(accountHandle)) {
447f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    Log.w(this, "%s is not visible for the calling user", accountHandle);
448f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    return false;
449f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
450f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
451ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
452f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return !TextUtils.isEmpty(getTelephonyManager().getVoiceMailNumber(subId));
453f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (Exception e) {
454f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(this, e, "getSubscriptionIdForPhoneAccount");
455f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                throw e;
456f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
457f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
458f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
459f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
460ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen         * @see android.telecom.TelecomManager#getLine1Number
461ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen         */
462ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen        @Override
463ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen        public String getLine1Number(PhoneAccountHandle accountHandle) {
464ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen            enforceReadPermissionOrDefaultDialer();
465ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen            try {
466ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                if (!isVisibleToCaller(accountHandle)) {
467ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                    Log.w(this, "%s is not visible for the calling user", accountHandle);
468ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                    return null;
469ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                }
470ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
471ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                return getTelephonyManager().getLine1NumberForSubscriber(subId);
472ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen            } catch (Exception e) {
473ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                Log.e(this, e, "getSubscriptionIdForPhoneAccount");
474ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen                throw e;
475ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen            }
476ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen        }
477ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen
478ba304759d08cfe4995168b8eb359992ba97ccc89Nancy Chen        /**
479f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#silenceRinger
480f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
481f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
482f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void silenceRinger() {
483f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            Log.d(this, "silenceRinger");
484f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermission();
485f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            sendRequestAsync(MSG_SILENCE_RINGER, 0);
486f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
487f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
488f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
489f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#getDefaultPhoneApp
490f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
491f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
492f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public ComponentName getDefaultPhoneApp() {
493f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            Resources resources = mContext.getResources();
494f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return new ComponentName(
495f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    resources.getString(R.string.ui_default_package),
496f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    resources.getString(R.string.dialer_default_class));
497f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
498f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
499f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
500f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#isInCall
501f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
502f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
503f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean isInCall() {
504f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermission();
505f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Do not use sendRequest() with this method since it could cause a deadlock with
506f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // audio service, which we call into from the main thread: AudioManager.setMode().
507f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            final int callState = mCallsManager.getCallState();
508f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return callState == TelephonyManager.CALL_STATE_OFFHOOK
509f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    || callState == TelephonyManager.CALL_STATE_RINGING;
510f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
511f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
512f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
513f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#isRinging
514f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
515f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
516f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean isRinging() {
517f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermission();
518f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING;
519f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
520f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
521f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
522f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see TelecomManager#getCallState
523f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
524f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
525f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public int getCallState() {
526f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return mCallsManager.getCallState();
527f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
528f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
529f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
530f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#endCall
531f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
532f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
533f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean endCall() {
534f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermission();
535f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return (boolean) sendRequest(MSG_END_CALL);
536f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
537f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
538f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
539f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#acceptRingingCall
540f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
541f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
542f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void acceptRingingCall() {
543f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermission();
544f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0);
545f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
546f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
547f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
548f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#showInCallScreen
549f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
550f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
551f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void showInCallScreen(boolean showDialpad) {
552f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermissionOrDefaultDialer();
553f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
554f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
555f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
556f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
557f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#cancelMissedCallsNotification
558f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
559f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
560f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void cancelMissedCallsNotification() {
561f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermissionOrDefaultDialer();
562f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0);
563f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
564f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
565f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
566f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#handleMmi
567f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
568f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
569f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean handlePinMmi(String dialString) {
570f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermissionOrDefaultDialer();
571f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
572f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Switch identity so that TelephonyManager checks Telecom's permissions instead.
573f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            long token = Binder.clearCallingIdentity();
574f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            boolean retval = false;
575f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
576f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                retval = getTelephonyManager().handlePinMmi(dialString);
577f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } finally {
578f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Binder.restoreCallingIdentity(token);
579f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
580f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
581f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return retval;
582f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
583f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
584f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
585f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#handleMmi
586f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
587f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
588f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
589f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                String dialString) {
590f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermissionOrDefaultDialer();
591f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
592f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (!isVisibleToCaller(accountHandle)) {
593f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.w(this, "%s is not visible for the calling user", accountHandle);
594f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return false;
595f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
596f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
597f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Switch identity so that TelephonyManager checks Telecom's permissions instead.
598f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            long token = Binder.clearCallingIdentity();
599f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            boolean retval = false;
600f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
601f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
602f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
603f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } finally {
604f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Binder.restoreCallingIdentity(token);
605f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
606f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
607f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return retval;
608f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
609f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
610f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
611f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
612f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
613f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
614f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
615f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermissionOrDefaultDialer();
616f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
617f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (!isVisibleToCaller(accountHandle)) {
618f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.w(this, "%s is not visible for the calling user", accountHandle);
619f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return null;
620f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
621f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
622f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Switch identity so that TelephonyManager checks Telecom's permissions instead.
623f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            long token = Binder.clearCallingIdentity();
624f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            String retval = "content://icc/adn/";
625f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
626f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                long subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
627f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                retval = retval + "subId/" + subId;
628f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } finally {
629f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Binder.restoreCallingIdentity(token);
630f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
631f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
632f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return Uri.parse(retval);
633f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
634f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
635f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
636f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#isTtySupported
637f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
638f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
639f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public boolean isTtySupported() {
640f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermission();
641f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED);
642f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
643f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
644f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
645f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#getCurrentTtyMode
646f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
647f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
648f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public int getCurrentTtyMode() {
649f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermission();
650f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE);
651f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
652f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
653f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
654f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#addNewIncomingCall
655f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
656f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
657f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
658f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            Log.i(this, "Adding new incoming call with phoneAccountHandle %s", phoneAccountHandle);
659f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
660f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mAppOpsManager.checkPackage(
661f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
662f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
663f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                // Make sure it doesn't cross the UserHandle boundary
664f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforceUserHandleMatchesCaller(phoneAccountHandle);
665f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
666f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
667f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
668f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, true);
669f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                if (extras != null) {
670f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
671f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
672f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                sendRequestAsync(MSG_NEW_INCOMING_CALL, 0, intent);
673f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } else {
674f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.w(this, "Null phoneAccountHandle. Ignoring request to add new incoming call");
675f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
676f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
677f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
678f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        /**
679f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         * @see android.telecom.TelecomManager#addNewUnknownCall
680f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon         */
681f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        @Override
682f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
683f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null &&
684f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    TelephonyUtil.isPstnComponentName(phoneAccountHandle.getComponentName())) {
685f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mAppOpsManager.checkPackage(
686f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
687f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
688f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                // Make sure it doesn't cross the UserHandle boundary
689f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                enforceUserHandleMatchesCaller(phoneAccountHandle);
690f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
691f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
692f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.setClass(mContext, CallReceiver.class);
693f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
694f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.putExtras(extras);
695f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.putExtra(CallReceiver.KEY_IS_UNKNOWN_CALL, true);
696f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
697f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mContext.sendBroadcastAsUser(intent, phoneAccountHandle.getUserHandle());
698f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } else {
699f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.i(this, "Null phoneAccountHandle or not initiated by Telephony. Ignoring request"
700f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        + " to add new unknown call.");
701f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
702f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
703476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn
704476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn        /**
705476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn         * Dumps the current state of the TelecomService.  Used when generating problem reports.
706476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn         *
707476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn         * @param fd The file descriptor.
708476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn         * @param writer The print writer to dump the state to.
709476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn         * @param args Optional dump arguments.
710476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn         */
711476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn        @Override
712476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn        protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
713476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn            if (mContext.checkCallingOrSelfPermission(
714476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                    android.Manifest.permission.DUMP)
715476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                    != PackageManager.PERMISSION_GRANTED) {
716476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                writer.println("Permission Denial: can't dump TelecomService " +
717476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                        "from from pid=" + Binder.getCallingPid() + ", uid=" +
718476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                        Binder.getCallingUid());
719476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                return;
720476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn            }
721476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn
722476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn            final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
723476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn            if (mCallsManager != null) {
724476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                pw.println("mCallsManager: ");
725476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                pw.increaseIndent();
726476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                mCallsManager.dump(pw);
727476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                pw.decreaseIndent();
728476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn
729476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                pw.println("mPhoneAccountRegistrar: ");
730476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                pw.increaseIndent();
731476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                mPhoneAccountRegistrar.dump(pw);
732476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn                pw.decreaseIndent();
733476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn            }
734476898696befd384e92532aabb45be5c81efa9f6Tyler Gunn        }
735f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
736f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
737f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    //
738f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    // Supporting methods for the ITelecomService interface implementation.
739f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    //
740f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
741f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) {
742f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (accountHandle == null) {
743f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return false;
744f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
745f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
746f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle));
747f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
748f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
749f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private boolean isVisibleToCaller(PhoneAccount account) {
750f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (account == null) {
751f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return false;
752f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
753f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
754f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and
755f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // all profiles. Only Telephony and SIP accounts should have this capability.
756f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
757f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return true;
758f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
759f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
760f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle();
761f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (phoneAccountUserHandle == null) {
762f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return false;
763f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
764f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
765f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        List<UserHandle> profileUserHandles;
766f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (isCallerSystemApp()) {
767f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // If the caller lives in /system/priv-app, it can see PhoneAccounts for all of the
768f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // *profiles* that the calling user owns, but not for any other *users*.
769f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            profileUserHandles = mUserManager.getUserProfiles();
770f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        } else {
771f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Otherwise, it has to be owned by the current caller's profile.
772f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            profileUserHandles = new ArrayList<>(1);
773f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            profileUserHandles.add(Binder.getCallingUserHandle());
774f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
775f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
776f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return profileUserHandles.contains(phoneAccountUserHandle);
777f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
778f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
779f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /**
780f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling
781f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * user can see.
782f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     *
783f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * @param phoneAccountHandles Unfiltered list of account handles.
784f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     *
785f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles.
786f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     */
787f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private List<PhoneAccountHandle> filterForAccountsVisibleToCaller(
788f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            List<PhoneAccountHandle> phoneAccountHandles) {
789f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        List<PhoneAccountHandle> profilePhoneAccountHandles =
790f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                new ArrayList<>(phoneAccountHandles.size());
791f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) {
792f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (isVisibleToCaller(phoneAccountHandle)) {
793f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                profilePhoneAccountHandles.add(phoneAccountHandle);
794f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
795f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
796f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return profilePhoneAccountHandles;
797f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
798f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
799f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private boolean isCallerSystemApp() {
800f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        int uid = Binder.getCallingUid();
801f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        String[] packages = mPackageManager.getPackagesForUid(uid);
802f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        for (String packageName : packages) {
803f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (isPackageSystemApp(packageName)) {
804f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return true;
805f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
806f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
807f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return false;
808f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
809f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
810f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private boolean isPackageSystemApp(String packageName) {
811f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        try {
812f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
813f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    PackageManager.GET_META_DATA);
814f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
815f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return true;
816f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
817f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        } catch (PackageManager.NameNotFoundException e) {
818f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
819f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return false;
820f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
821f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
822f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void acceptRingingCallInternal() {
823f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
824f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (call != null) {
825f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            call.answer(call.getVideoState());
826f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
827f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
828f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
829f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private boolean endCallInternal() {
830f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // Always operate on the foreground call if one exists, otherwise get the first call in
831f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // priority order by call-state.
832f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        Call call = mCallsManager.getForegroundCall();
833f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (call == null) {
834f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            call = mCallsManager.getFirstCallWithState(
835f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    CallState.ACTIVE,
836f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    CallState.DIALING,
837f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    CallState.RINGING,
838f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    CallState.ON_HOLD);
839f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
840f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
841f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (call != null) {
842f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            if (call.getState() == CallState.RINGING) {
843f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                call.reject(false /* rejectWithMessage */, null);
844f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } else {
845f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                call.disconnect();
846f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
847f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return true;
848f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
849f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
850f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return false;
851f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
852f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
853f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforcePhoneAccountModificationForPackage(String packageName) {
854f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // TODO: Use a new telecomm permission for this instead of reusing modify.
855f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
856f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
857f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
858f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
859f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
860f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        // may also modify PhoneAccounts on behalf of any 'packageName'.
861f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
862f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (result != PackageManager.PERMISSION_GRANTED) {
863f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Other callers are only allowed to modify PhoneAccounts if the relevant system
864f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // feature is enabled ...
865f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceConnectionServiceFeature();
866f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // ... and the PhoneAccounts they refer to are for their own package.
867f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceCallingPackage(packageName);
868f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
869f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
870f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
871f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceReadPermissionOrDefaultDialer() {
872f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (!isDefaultDialerCalling()) {
873f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceReadPermission();
874f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
875f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
876f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
877f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceModifyPermissionOrDefaultDialer() {
878f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (!isDefaultDialerCalling()) {
879f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            enforceModifyPermission();
880f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
881f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
882f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
883f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceCallingPackage(String packageName) {
884f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
885f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
886f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
887f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceConnectionServiceFeature() {
888f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
889f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
890f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
891f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceRegisterCallProviderPermission() {
892f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER);
893f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
894f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
895f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceRegisterSimSubscriptionPermission() {
896f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION);
897f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
898f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
899f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceRegisterConnectionManagerPermission() {
900f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER);
901f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
902f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
903f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceReadPermission() {
904f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        enforcePermission(Manifest.permission.READ_PHONE_STATE);
905f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
906f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
907f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceModifyPermission() {
908f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        enforcePermission(Manifest.permission.MODIFY_PHONE_STATE);
909f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
910f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
911f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforcePermission(String permission) {
912f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mContext.enforceCallingOrSelfPermission(permission, null);
913f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
914f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
915f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceRegisterMultiUser() {
916f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (!isCallerSystemApp()) {
917f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
918f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
919f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
920f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
921f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
922f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
923f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
924f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
925f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
926f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
927f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private void enforceFeature(String feature) {
928f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        PackageManager pm = mContext.getPackageManager();
929f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (!pm.hasSystemFeature(feature)) {
930f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            throw new UnsupportedOperationException(
931f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    "System does not support feature " + feature);
932f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
933f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
934f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
935f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private boolean isDefaultDialerCalling() {
936f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        ComponentName defaultDialerComponent = getDefaultPhoneAppInternal();
937f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (defaultDialerComponent != null) {
938f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            try {
939f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                mAppOpsManager.checkPackage(
940f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        Binder.getCallingUid(), defaultDialerComponent.getPackageName());
941f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                return true;
942f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            } catch (SecurityException e) {
943f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                Log.e(TAG, e, "Could not get default dialer.");
944f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
945f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
946f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return false;
947f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
948f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
949f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private ComponentName getDefaultPhoneAppInternal() {
950f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        Resources resources = mContext.getResources();
951f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return new ComponentName(
952f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                resources.getString(R.string.ui_default_package),
953f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                resources.getString(R.string.dialer_default_class));
954f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
955f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
956f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private TelephonyManager getTelephonyManager() {
957f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
958f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
959f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
960f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private MainThreadRequest sendRequestAsync(int command, int arg1) {
961f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return sendRequestAsync(command, arg1, null);
962f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
963f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
964f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private MainThreadRequest sendRequestAsync(int command, int arg1, Object arg) {
965f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        MainThreadRequest request = new MainThreadRequest();
966f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        request.arg = arg;
967f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        mMainThreadHandler.obtainMessage(command, arg1, 0, request).sendToTarget();
968f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        return request;
969f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
970f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
971f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    /**
972f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * Posts the specified command to be executed on the main thread, waits for the request to
973f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     * complete, and returns the result.
974f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon     */
975f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    private Object sendRequest(int command) {
976f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
977f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            MainThreadRequest request = new MainThreadRequest();
978f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            mMainThreadHandler.handleMessage(mMainThreadHandler.obtainMessage(command, request));
979f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return request.result;
980f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        } else {
981f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            MainThreadRequest request = sendRequestAsync(command, 0);
982f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon
983f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            // Wait for the request to complete
984f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            synchronized (request) {
985f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                while (request.result == null) {
986f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    try {
987f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        request.wait();
988f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    } catch (InterruptedException e) {
989f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                        // Do nothing, go back and wait until the request is complete
990f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                    }
991f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon                }
992f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            }
993f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon            return request.result;
994f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon        }
995f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon    }
996f987d1a6f1d02164210a70b417db2bc14576236cSantos Cordon}
997