blob: ded42db9e69beafb076349545358897ad05207b3 [file] [log] [blame]
Santos Cordonf987d1a2014-12-02 03:37:03 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.telecom;
18
Yorke Leecb0bd8a2015-05-18 11:57:14 -070019import static android.Manifest.permission.CALL_PHONE;
Tyler Gunnb652dad2018-03-27 18:49:49 +000020import static android.Manifest.permission.CALL_PRIVILEGED;
Hall Liuecd74a52016-01-12 15:26:36 -080021import static android.Manifest.permission.DUMP;
Yorke Leecb0bd8a2015-05-18 11:57:14 -070022import static android.Manifest.permission.MODIFY_PHONE_STATE;
23import static android.Manifest.permission.READ_PHONE_STATE;
Amit Mahajan3c296932015-07-14 10:23:15 -070024import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
Yorke Leecb0bd8a2015-05-18 11:57:14 -070025import static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
Yorke Lee71734c22015-06-02 14:22:56 -070026import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
Yorke Leecb0bd8a2015-05-18 11:57:14 -070027
Tyler Gunna90ba732017-01-26 07:24:08 -080028import android.Manifest;
Yorke Leeb3984302015-06-15 12:06:35 -070029import android.app.ActivityManager;
Santos Cordonf987d1a2014-12-02 03:37:03 -080030import android.app.AppOpsManager;
Santos Cordonf987d1a2014-12-02 03:37:03 -080031import android.content.ComponentName;
32import android.content.Context;
33import android.content.Intent;
34import android.content.pm.ApplicationInfo;
35import android.content.pm.PackageManager;
36import android.content.res.Resources;
37import android.net.Uri;
38import android.os.Binder;
39import android.os.Bundle;
Tony Mak240656f2015-12-04 11:36:22 +000040import android.os.Process;
Santos Cordonf987d1a2014-12-02 03:37:03 -080041import android.os.UserHandle;
Brad Ebingera3eccfe2016-10-05 15:45:22 -070042import android.telecom.Log;
Santos Cordonf987d1a2014-12-02 03:37:03 -080043import android.telecom.PhoneAccount;
44import android.telecom.PhoneAccountHandle;
Hall Liu874c0f82016-04-29 18:13:18 -070045import android.telecom.TelecomAnalytics;
Santos Cordonf987d1a2014-12-02 03:37:03 -080046import android.telecom.TelecomManager;
Tyler Gunn42ef8082015-11-24 15:34:34 -080047import android.telecom.VideoProfile;
Santos Cordonf987d1a2014-12-02 03:37:03 -080048import android.telephony.SubscriptionManager;
49import android.telephony.TelephonyManager;
Tyler Gunn0edfc662017-04-14 13:46:21 -070050import android.text.TextUtils;
Brad Ebinger62da8e12016-01-28 19:16:08 -080051import android.util.EventLog;
Santos Cordonf987d1a2014-12-02 03:37:03 -080052
Santos Cordonf987d1a2014-12-02 03:37:03 -080053import com.android.internal.telecom.ITelecomService;
54import com.android.internal.util.IndentingPrintWriter;
Hall Liuecda5542015-12-04 11:31:31 -080055import com.android.server.telecom.components.UserCallIntentProcessorFactory;
Mohamedc9261852016-02-05 14:10:17 -080056import com.android.server.telecom.settings.BlockedNumbersActivity;
Santos Cordonf987d1a2014-12-02 03:37:03 -080057
58import java.io.FileDescriptor;
59import java.io.PrintWriter;
Svet Ganov09611182015-04-16 12:29:01 -070060import java.util.Collections;
Santos Cordonf987d1a2014-12-02 03:37:03 -080061import java.util.List;
62
Eugene Suslaccba7202017-02-10 10:56:53 -080063// TODO: Needed for move to system service: import com.android.internal.R;
64
Santos Cordonf987d1a2014-12-02 03:37:03 -080065/**
66 * Implementation of the ITelecom interface.
67 */
Ihab Awad78a5e6b2015-02-06 10:13:05 -080068public class TelecomServiceImpl {
Hall Liu0a6dd302015-12-16 15:06:49 -080069
70 public interface SubscriptionManagerAdapter {
71 int getDefaultVoiceSubId();
72 }
73
74 static class SubscriptionManagerAdapterImpl implements SubscriptionManagerAdapter {
75 @Override
76 public int getDefaultVoiceSubId() {
Shishir Agrawalce688742016-01-25 15:02:21 -080077 return SubscriptionManager.getDefaultVoiceSubscriptionId();
Hall Liu0a6dd302015-12-16 15:06:49 -080078 }
79 }
80
Tyler Gunn897e8512017-05-18 15:46:51 -070081 private static final String TIME_LINE_ARG = "timeline";
Tyler Gunn42ef8082015-11-24 15:34:34 -080082 private static final int DEFAULT_VIDEO_STATE = -1;
Santos Cordon73853962015-02-27 15:13:35 -080083
Ihab Awad8d5d9dd2015-03-12 11:11:06 -070084 private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
Santos Cordonf987d1a2014-12-02 03:37:03 -080085 @Override
Svet Ganov09611182015-04-16 12:29:01 -070086 public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme,
87 String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -080088 try {
89 Log.startSession("TSI.gDOPA");
90 synchronized (mLock) {
91 if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
92 return null;
93 }
Svet Ganov09611182015-04-16 12:29:01 -070094
Brad Ebinger11623a32015-11-25 13:52:02 -080095 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
96 long token = Binder.clearCallingIdentity();
97 try {
98 return mPhoneAccountRegistrar
99 .getOutgoingPhoneAccountForScheme(uriScheme, callingUserHandle);
100 } catch (Exception e) {
101 Log.e(this, e, "getDefaultOutgoingPhoneAccount");
102 throw e;
103 } finally {
104 Binder.restoreCallingIdentity(token);
105 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800106 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800107 } finally {
108 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800109 }
110 }
111
112 @Override
113 public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700114 synchronized (mLock) {
115 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800116 Log.startSession("TSI.gUSOPA");
Tony Mak240656f2015-12-04 11:36:22 +0000117 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
118 return mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount(
119 callingUserHandle);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700120 } catch (Exception e) {
121 Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
122 throw e;
Brad Ebinger11623a32015-11-25 13:52:02 -0800123 } finally {
124 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800125 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800126 }
127 }
128
129 @Override
130 public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800131 try {
132 Log.startSession("TSI.sUSOPA");
133 synchronized (mLock) {
134 enforceModifyPermission();
135 UserHandle callingUserHandle = Binder.getCallingUserHandle();
136 long token = Binder.clearCallingIdentity();
137 try {
138 mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(
139 accountHandle, callingUserHandle);
140 } catch (Exception e) {
141 Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
142 throw e;
143 } finally {
144 Binder.restoreCallingIdentity(token);
145 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700146 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800147 } finally {
148 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800149 }
150 }
151
152 @Override
Santos Cordonea5cb932015-05-07 16:28:38 -0700153 public List<PhoneAccountHandle> getCallCapablePhoneAccounts(
154 boolean includeDisabledAccounts, String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800155 try {
156 Log.startSession("TSI.gCCPA");
157 if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
158 return Collections.emptyList();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700159 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800160 synchronized (mLock) {
161 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
162 long token = Binder.clearCallingIdentity();
163 try {
164 return mPhoneAccountRegistrar.getCallCapablePhoneAccounts(null,
165 includeDisabledAccounts, callingUserHandle);
166 } catch (Exception e) {
167 Log.e(this, e, "getCallCapablePhoneAccounts");
168 throw e;
169 } finally {
170 Binder.restoreCallingIdentity(token);
171 }
172 }
173 } finally {
174 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800175 }
176 }
177
178 @Override
Tyler Gunnebfc9162017-04-07 15:00:49 -0700179 public List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage) {
180 try {
181 Log.startSession("TSI.gSMPA");
182 if (!canReadPhoneState(callingPackage, "Requires READ_PHONE_STATE permission.")) {
183 throw new SecurityException("Requires READ_PHONE_STATE permission.");
184 }
185 synchronized (mLock) {
186 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
187 long token = Binder.clearCallingIdentity();
188 try {
189 return mPhoneAccountRegistrar.getSelfManagedPhoneAccounts(
190 callingUserHandle);
191 } catch (Exception e) {
192 Log.e(this, e, "getSelfManagedPhoneAccounts");
193 throw e;
194 } finally {
195 Binder.restoreCallingIdentity(token);
196 }
197 }
198 } finally {
199 Log.endSession();
200 }
201 }
202
203 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700204 public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme,
205 String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800206 try {
207 Log.startSession("TSI.gPASS");
Tyler Gunn322480c2017-07-17 15:34:02 -0700208 try {
209 enforceModifyPermission(
210 "getPhoneAccountsSupportingScheme requires MODIFY_PHONE_STATE");
211 } catch (SecurityException e) {
212 EventLog.writeEvent(0x534e4554, "62347125", Binder.getCallingUid(),
213 "getPhoneAccountsSupportingScheme: " + callingPackage);
214 return Collections.emptyList();
215 }
216
Brad Ebinger11623a32015-11-25 13:52:02 -0800217 synchronized (mLock) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800218 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
219 long token = Binder.clearCallingIdentity();
220 try {
221 return mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme, false,
222 callingUserHandle);
223 } catch (Exception e) {
224 Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
225 throw e;
226 } finally {
227 Binder.restoreCallingIdentity(token);
228 }
Svet Ganov09611182015-04-16 12:29:01 -0700229 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800230 } finally {
231 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800232 }
233 }
234
235 @Override
236 public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700237 synchronized (mLock) {
Tony Mak240656f2015-12-04 11:36:22 +0000238 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
239 long token = Binder.clearCallingIdentity();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700240 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800241 Log.startSession("TSI.gPAFP");
Tony Mak240656f2015-12-04 11:36:22 +0000242 return mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName,
243 callingUserHandle);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700244 } catch (Exception e) {
245 Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
246 throw e;
Tony Mak240656f2015-12-04 11:36:22 +0000247 } finally {
248 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800249 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700250 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800251 }
252 }
253
254 @Override
255 public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700256 synchronized (mLock) {
Tony Mak240656f2015-12-04 11:36:22 +0000257 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
258 long token = Binder.clearCallingIdentity();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700259 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800260 Log.startSession("TSI.gPA");
Tony Mak240656f2015-12-04 11:36:22 +0000261 // In ideal case, we should not resolve the handle across profiles. But given
262 // the fact that profile's call is handled by its parent user's in-call UI,
263 // parent user's in call UI need to be able to get phone account from the
264 // profile's phone account handle.
265 return mPhoneAccountRegistrar
266 .getPhoneAccount(accountHandle, callingUserHandle,
267 /* acrossProfiles */ true);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700268 } catch (Exception e) {
269 Log.e(this, e, "getPhoneAccount %s", accountHandle);
270 throw e;
Tony Mak240656f2015-12-04 11:36:22 +0000271 } finally {
272 Binder.restoreCallingIdentity(token);
Brad Ebinger11623a32015-11-25 13:52:02 -0800273 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800274 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800275 }
276 }
277
278 @Override
279 public int getAllPhoneAccountsCount() {
Tyler Gunn322480c2017-07-17 15:34:02 -0700280 try {
281 Log.startSession("TSI.gAPAC");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700282 try {
Tyler Gunn322480c2017-07-17 15:34:02 -0700283 enforceModifyPermission(
284 "getAllPhoneAccountsCount requires MODIFY_PHONE_STATE permission.");
285 } catch (SecurityException e) {
286 EventLog.writeEvent(0x534e4554, "62347125", Binder.getCallingUid(),
287 "getAllPhoneAccountsCount");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700288 throw e;
289 }
Tyler Gunn322480c2017-07-17 15:34:02 -0700290
291 synchronized (mLock) {
292 try {
293 // This list is pre-filtered for the calling user.
294 return getAllPhoneAccounts().size();
295 } catch (Exception e) {
296 Log.e(this, e, "getAllPhoneAccountsCount");
297 throw e;
298
299 }
300 }
301 } finally {
302 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800303 }
304 }
305
306 @Override
307 public List<PhoneAccount> getAllPhoneAccounts() {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700308 synchronized (mLock) {
309 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800310 Log.startSession("TSI.gAPA");
Tyler Gunn322480c2017-07-17 15:34:02 -0700311 try {
312 enforceModifyPermission(
313 "getAllPhoneAccounts requires MODIFY_PHONE_STATE permission.");
314 } catch (SecurityException e) {
315 EventLog.writeEvent(0x534e4554, "62347125", Binder.getCallingUid(),
316 "getAllPhoneAccounts");
317 throw e;
318 }
319
320 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
321 long token = Binder.clearCallingIdentity();
322 try {
323 return mPhoneAccountRegistrar.getAllPhoneAccounts(callingUserHandle);
324 } catch (Exception e) {
325 Log.e(this, e, "getAllPhoneAccounts");
326 throw e;
327 } finally {
328 Binder.restoreCallingIdentity(token);
329 }
Tony Mak240656f2015-12-04 11:36:22 +0000330 } finally {
Brad Ebinger11623a32015-11-25 13:52:02 -0800331 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800332 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800333 }
334 }
335
336 @Override
337 public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
Tyler Gunn322480c2017-07-17 15:34:02 -0700338 try {
339 Log.startSession("TSI.gAPAH");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700340 try {
Tyler Gunn322480c2017-07-17 15:34:02 -0700341 enforceModifyPermission(
342 "getAllPhoneAccountHandles requires MODIFY_PHONE_STATE permission.");
343 } catch (SecurityException e) {
344 EventLog.writeEvent(0x534e4554, "62347125", Binder.getCallingUid(),
345 "getAllPhoneAccountHandles");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700346 throw e;
347 }
Tyler Gunn322480c2017-07-17 15:34:02 -0700348
349 synchronized (mLock) {
350 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
351 long token = Binder.clearCallingIdentity();
352 try {
353 return mPhoneAccountRegistrar.getAllPhoneAccountHandles(callingUserHandle);
354 } catch (Exception e) {
355 Log.e(this, e, "getAllPhoneAccounts");
356 throw e;
357 } finally {
358 Binder.restoreCallingIdentity(token);
359 }
360 }
361 } finally {
362 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800363 }
364 }
365
366 @Override
367 public PhoneAccountHandle getSimCallManager() {
Sailesh Nepalfc43ea82015-07-28 19:30:28 -0700368 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800369 Log.startSession("TSI.gSCM");
370 long token = Binder.clearCallingIdentity();
371 int user;
372 try {
373 user = ActivityManager.getCurrentUser();
374 return getSimCallManagerForUser(user);
375 } finally {
376 Binder.restoreCallingIdentity(token);
377 }
Sailesh Nepalfc43ea82015-07-28 19:30:28 -0700378 } finally {
Brad Ebinger11623a32015-11-25 13:52:02 -0800379 Log.endSession();
Sailesh Nepalfc43ea82015-07-28 19:30:28 -0700380 }
Sailesh Nepalfc43ea82015-07-28 19:30:28 -0700381 }
382
383 @Override
384 public PhoneAccountHandle getSimCallManagerForUser(int user) {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700385 synchronized (mLock) {
386 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800387 Log.startSession("TSI.gSCMFU");
Tony Mak240656f2015-12-04 11:36:22 +0000388 final int callingUid = Binder.getCallingUid();
Santos Cordon59c21a72015-06-11 10:11:21 -0700389 long token = Binder.clearCallingIdentity();
390 try {
Tony Mak240656f2015-12-04 11:36:22 +0000391 if (user != ActivityManager.getCurrentUser()) {
392 enforceCrossUserPermission(callingUid);
393 }
394 return mPhoneAccountRegistrar.getSimCallManager(UserHandle.of(user));
Santos Cordon59c21a72015-06-11 10:11:21 -0700395 } finally {
Santos Cordon59c21a72015-06-11 10:11:21 -0700396 Binder.restoreCallingIdentity(token);
397 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700398 } catch (Exception e) {
399 Log.e(this, e, "getSimCallManager");
400 throw e;
Brad Ebinger11623a32015-11-25 13:52:02 -0800401 } finally {
402 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800403 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800404 }
405 }
406
407 @Override
Santos Cordonf987d1a2014-12-02 03:37:03 -0800408 public void registerPhoneAccount(PhoneAccount account) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800409 try {
410 Log.startSession("TSI.rPA");
411 synchronized (mLock) {
412 if (!mContext.getApplicationContext().getResources().getBoolean(
413 com.android.internal.R.bool.config_voice_capable)) {
414 Log.w(this,
415 "registerPhoneAccount not allowed on non-voice capable device.");
416 return;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700417 }
Yorke Lee58061752015-05-04 11:06:26 -0700418 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800419 enforcePhoneAccountModificationForPackage(
420 account.getAccountHandle().getComponentName().getPackageName());
Tyler Gunnacb3bc82017-01-09 09:43:56 -0800421 if (account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
422 enforceRegisterSelfManaged();
Tyler Gunn9e806ee2017-02-06 20:49:24 -0800423 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) ||
424 account.hasCapabilities(
425 PhoneAccount.CAPABILITY_CONNECTION_MANAGER) ||
426 account.hasCapabilities(
427 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
428 throw new SecurityException("Self-managed ConnectionServices " +
429 "cannot also be call capable, connection managers, or " +
430 "SIM accounts.");
431 }
Tyler Gunn2b17f232017-03-08 08:51:00 -0800432
433 // For self-managed CS, the phone account registrar will override the
434 // label the user has set for the phone account. This ensures the
435 // self-managed cs implementation can't spoof their app name.
Tyler Gunnacb3bc82017-01-09 09:43:56 -0800436 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800437 if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
438 enforceRegisterSimSubscriptionPermission();
439 }
440 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
441 enforceRegisterMultiUser();
442 }
443 enforceUserHandleMatchesCaller(account.getAccountHandle());
Tyler Gunncbc9be22017-04-19 10:52:36 -0700444 final long token = Binder.clearCallingIdentity();
445 try {
446 mPhoneAccountRegistrar.registerPhoneAccount(account);
447 } finally {
448 Binder.restoreCallingIdentity(token);
449 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800450 } catch (Exception e) {
451 Log.e(this, e, "registerPhoneAccount %s", account);
452 throw e;
Yorke Lee58061752015-05-04 11:06:26 -0700453 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700454 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800455 } finally {
456 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800457 }
458 }
459
460 @Override
461 public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700462 synchronized (mLock) {
463 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800464 Log.startSession("TSI.uPA");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700465 enforcePhoneAccountModificationForPackage(
466 accountHandle.getComponentName().getPackageName());
467 enforceUserHandleMatchesCaller(accountHandle);
Tyler Gunncbc9be22017-04-19 10:52:36 -0700468 final long token = Binder.clearCallingIdentity();
469 try {
470 mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
471 } finally {
472 Binder.restoreCallingIdentity(token);
473 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700474 } catch (Exception e) {
475 Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
476 throw e;
Brad Ebinger11623a32015-11-25 13:52:02 -0800477 } finally {
478 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700479 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800480 }
481 }
482
483 @Override
484 public void clearAccounts(String packageName) {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700485 synchronized (mLock) {
486 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800487 Log.startSession("TSI.cA");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700488 enforcePhoneAccountModificationForPackage(packageName);
489 mPhoneAccountRegistrar
490 .clearAccounts(packageName, Binder.getCallingUserHandle());
491 } catch (Exception e) {
492 Log.e(this, e, "clearAccounts %s", packageName);
493 throw e;
Brad Ebinger11623a32015-11-25 13:52:02 -0800494 } finally {
495 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700496 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800497 }
498 }
499
500 /**
501 * @see android.telecom.TelecomManager#isVoiceMailNumber
502 */
503 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700504 public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number,
505 String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800506 try {
507 Log.startSession("TSI.iVMN");
508 synchronized (mLock) {
509 if (!canReadPhoneState(callingPackage, "isVoiceMailNumber")) {
510 return false;
511 }
512 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
513 if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
514 callingUserHandle)) {
515 Log.d(this, "%s is not visible for the calling user [iVMN]", accountHandle);
516 return false;
517 }
518 long token = Binder.clearCallingIdentity();
519 try {
520 return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
521 } catch (Exception e) {
522 Log.e(this, e, "getSubscriptionIdForPhoneAccount");
523 throw e;
524 } finally {
525 Binder.restoreCallingIdentity(token);
526 }
Svet Ganov09611182015-04-16 12:29:01 -0700527 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800528 } finally {
529 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800530 }
531 }
532
533 /**
Yorke Leefb5ec302015-04-15 16:15:55 -0700534 * @see android.telecom.TelecomManager#getVoiceMailNumber
Santos Cordonf987d1a2014-12-02 03:37:03 -0800535 */
536 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700537 public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800538 try {
539 Log.startSession("TSI.gVMN");
540 synchronized (mLock) {
541 if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
Yorke Leefb5ec302015-04-15 16:15:55 -0700542 return null;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700543 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800544 try {
545 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
546 if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
547 callingUserHandle)) {
548 Log.d(this, "%s is not visible for the calling user [gVMN]",
549 accountHandle);
550 return null;
551 }
Hall Liu0a6dd302015-12-16 15:06:49 -0800552 int subId = mSubscriptionManagerAdapter.getDefaultVoiceSubId();
Brad Ebinger11623a32015-11-25 13:52:02 -0800553 if (accountHandle != null) {
554 subId = mPhoneAccountRegistrar
555 .getSubscriptionIdForPhoneAccount(accountHandle);
556 }
557 return getTelephonyManager().getVoiceMailNumber(subId);
558 } catch (Exception e) {
559 Log.e(this, e, "getSubscriptionIdForPhoneAccount");
560 throw e;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700561 }
Ihab Awad78a5e6b2015-02-06 10:13:05 -0800562 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800563 } finally {
564 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800565 }
566 }
567
568 /**
Nancy Chenba304752015-01-24 23:29:22 -0800569 * @see android.telecom.TelecomManager#getLine1Number
570 */
571 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700572 public String getLine1Number(PhoneAccountHandle accountHandle, String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800573 try {
574 Log.startSession("getL1N");
575 if (!canReadPhoneState(callingPackage, "getLine1Number")) {
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700576 return null;
577 }
578
Brad Ebinger11623a32015-11-25 13:52:02 -0800579 synchronized (mLock) {
580 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
581 if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
582 callingUserHandle)) {
583 Log.d(this, "%s is not visible for the calling user [gL1N]", accountHandle);
584 return null;
585 }
586
587 long token = Binder.clearCallingIdentity();
588 try {
589 int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
590 accountHandle);
Shishir Agrawalce688742016-01-25 15:02:21 -0800591 return getTelephonyManager().getLine1Number(subId);
Brad Ebinger11623a32015-11-25 13:52:02 -0800592 } catch (Exception e) {
593 Log.e(this, e, "getSubscriptionIdForPhoneAccount");
594 throw e;
595 } finally {
596 Binder.restoreCallingIdentity(token);
597 }
Nancy Chenba304752015-01-24 23:29:22 -0800598 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800599 } finally {
600 Log.endSession();
Nancy Chenba304752015-01-24 23:29:22 -0800601 }
602 }
603
604 /**
Santos Cordonf987d1a2014-12-02 03:37:03 -0800605 * @see android.telecom.TelecomManager#silenceRinger
606 */
607 @Override
Yorke Lee53101962015-04-29 16:25:29 -0700608 public void silenceRinger(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800609 try {
610 Log.startSession("TSI.sR");
611 synchronized (mLock) {
612 enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700613
Brad Ebinger11623a32015-11-25 13:52:02 -0800614 long token = Binder.clearCallingIdentity();
615 try {
616 Log.i(this, "Silence Ringer requested by %s", callingPackage);
Hall Liue091ab92015-12-18 17:05:30 -0800617 mCallsManager.getCallAudioManager().silenceRingers();
Sailesh Nepalc07b8e12016-01-23 16:43:10 -0800618 mCallsManager.getInCallController().silenceRinger();
Brad Ebinger11623a32015-11-25 13:52:02 -0800619 } finally {
620 Binder.restoreCallingIdentity(token);
621 }
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700622 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800623 } finally {
624 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700625 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800626 }
627
628 /**
629 * @see android.telecom.TelecomManager#getDefaultPhoneApp
Yorke Lee5b3fc0a2015-04-23 17:42:57 -0700630 * @deprecated - Use {@link android.telecom.TelecomManager#getDefaultDialerPackage()}
631 * instead.
Santos Cordonf987d1a2014-12-02 03:37:03 -0800632 */
633 @Override
634 public ComponentName getDefaultPhoneApp() {
Brad Ebinger11623a32015-11-25 13:52:02 -0800635 try {
636 Log.startSession("TSI.gDPA");
637 // No need to synchronize
638 Resources resources = mContext.getResources();
639 return new ComponentName(
640 resources.getString(R.string.ui_default_package),
641 resources.getString(R.string.dialer_default_class));
642 } finally {
643 Log.endSession();
644 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800645 }
646
647 /**
Yorke Lee5291d4a2015-04-24 16:42:36 -0700648 * @return the package name of the current user-selected default dialer. If no default
649 * has been selected, the package name of the system dialer is returned. If
650 * neither exists, then {@code null} is returned.
Yorke Lee5b3fc0a2015-04-23 17:42:57 -0700651 * @see android.telecom.TelecomManager#getDefaultDialerPackage
652 */
653 @Override
654 public String getDefaultDialerPackage() {
Yorke Lee29c003e2015-05-04 17:09:27 -0700655 try {
Brad Ebinger11623a32015-11-25 13:52:02 -0800656 Log.startSession("TSI.gDDP");
657 final long token = Binder.clearCallingIdentity();
658 try {
Hall Liu7c928322016-12-06 18:15:39 -0800659 return mDefaultDialerCache.getDefaultDialerApplication(
660 ActivityManager.getCurrentUser());
Brad Ebinger11623a32015-11-25 13:52:02 -0800661 } finally {
662 Binder.restoreCallingIdentity(token);
663 }
Yorke Lee29c003e2015-05-04 17:09:27 -0700664 } finally {
Brad Ebinger11623a32015-11-25 13:52:02 -0800665 Log.endSession();
Yorke Lee29c003e2015-05-04 17:09:27 -0700666 }
Yorke Lee5b3fc0a2015-04-23 17:42:57 -0700667 }
668
669 /**
670 * @see android.telecom.TelecomManager#getSystemDialerPackage
671 */
672 @Override
673 public String getSystemDialerPackage() {
Brad Ebinger11623a32015-11-25 13:52:02 -0800674 try {
675 Log.startSession("TSI.gSDP");
676 return mContext.getResources().getString(R.string.ui_default_package);
677 } finally {
678 Log.endSession();
679 }
Yorke Lee5b3fc0a2015-04-23 17:42:57 -0700680 }
681
682 /**
Santos Cordonf987d1a2014-12-02 03:37:03 -0800683 * @see android.telecom.TelecomManager#isInCall
684 */
685 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700686 public boolean isInCall(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800687 try {
688 Log.startSession("TSI.iIC");
689 if (!canReadPhoneState(callingPackage, "isInCall")) {
690 return false;
691 }
Svet Ganov09611182015-04-16 12:29:01 -0700692
Brad Ebinger11623a32015-11-25 13:52:02 -0800693 synchronized (mLock) {
Tyler Gunnbaf105b2017-04-11 15:21:03 -0700694 return mCallsManager.hasOngoingCalls();
Brad Ebinger11623a32015-11-25 13:52:02 -0800695 }
696 } finally {
697 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700698 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800699 }
700
701 /**
Tyler Gunn37e782b2017-02-10 09:42:03 -0800702 * @see android.telecom.TelecomManager#isInManagedCall
703 */
704 @Override
705 public boolean isInManagedCall(String callingPackage) {
706 try {
707 Log.startSession("TSI.iIMC");
708 if (!canReadPhoneState(callingPackage, "isInManagedCall")) {
709 throw new SecurityException("Only the default dialer or caller with " +
710 "READ_PHONE_STATE permission can use this method.");
711 }
712
713 synchronized (mLock) {
714 return mCallsManager.hasOngoingManagedCalls();
715 }
716 } finally {
717 Log.endSession();
718 }
719 }
720
721 /**
Santos Cordonf987d1a2014-12-02 03:37:03 -0800722 * @see android.telecom.TelecomManager#isRinging
723 */
724 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700725 public boolean isRinging(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800726 try {
727 Log.startSession("TSI.iR");
Tyler Gunn322480c2017-07-17 15:34:02 -0700728 if (!isPrivilegedDialerCalling(callingPackage)) {
729 try {
730 enforceModifyPermission(
731 "isRinging requires MODIFY_PHONE_STATE permission.");
732 } catch (SecurityException e) {
733 EventLog.writeEvent(0x534e4554, "62347125", "isRinging: " + callingPackage);
734 throw e;
735 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800736 }
Svet Ganov09611182015-04-16 12:29:01 -0700737
Brad Ebinger11623a32015-11-25 13:52:02 -0800738 synchronized (mLock) {
739 // Note: We are explicitly checking the calls telecom is tracking rather than
740 // relying on mCallsManager#getCallState(). Since getCallState() relies on the
741 // current state as tracked by PhoneStateBroadcaster, any failure to properly
742 // track the current call state there could result in the wrong ringing state
743 // being reported by this API.
744 return mCallsManager.hasRingingCall();
745 }
746 } finally {
747 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700748 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800749 }
750
751 /**
752 * @see TelecomManager#getCallState
753 */
754 @Override
755 public int getCallState() {
Brad Ebinger11623a32015-11-25 13:52:02 -0800756 try {
757 Log.startSession("TSI.getCallState");
758 synchronized (mLock) {
759 return mCallsManager.getCallState();
760 }
761 } finally {
762 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700763 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800764 }
765
766 /**
767 * @see android.telecom.TelecomManager#endCall
768 */
769 @Override
Tyler Gunn587fc272018-02-07 16:07:29 -0800770 public boolean endCall(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800771 try {
772 Log.startSession("TSI.eC");
773 synchronized (mLock) {
Tyler Gunne27a5312018-05-02 13:41:44 -0700774 if (!enforceAnswerCallPermission(callingPackage, Binder.getCallingUid())) {
775 throw new SecurityException("requires ANSWER_PHONE_CALLS permission");
776 }
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700777
Brad Ebinger11623a32015-11-25 13:52:02 -0800778 long token = Binder.clearCallingIdentity();
779 try {
Tyler Gunn587fc272018-02-07 16:07:29 -0800780 return endCallInternal(callingPackage);
Brad Ebinger11623a32015-11-25 13:52:02 -0800781 } finally {
782 Binder.restoreCallingIdentity(token);
783 }
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700784 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800785 } finally {
786 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700787 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800788 }
789
790 /**
791 * @see android.telecom.TelecomManager#acceptRingingCall
792 */
793 @Override
Eugene Suslaccba7202017-02-10 10:56:53 -0800794 public void acceptRingingCall(String packageName) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800795 try {
796 Log.startSession("TSI.aRC");
797 synchronized (mLock) {
Eugene Suslaccba7202017-02-10 10:56:53 -0800798 if (!enforceAnswerCallPermission(packageName, Binder.getCallingUid())) return;
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700799
Brad Ebinger11623a32015-11-25 13:52:02 -0800800 long token = Binder.clearCallingIdentity();
801 try {
802 acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
803 } finally {
804 Binder.restoreCallingIdentity(token);
805 }
Tyler Gunn42ef8082015-11-24 15:34:34 -0800806 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800807 } finally {
808 Log.endSession();
Tyler Gunn42ef8082015-11-24 15:34:34 -0800809 }
810 }
811
812 /**
813 * @see android.telecom.TelecomManager#acceptRingingCall(int)
814 *
815 */
816 @Override
Eugene Suslaccba7202017-02-10 10:56:53 -0800817 public void acceptRingingCallWithVideoState(String packageName, int videoState) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800818 try {
819 Log.startSession("TSI.aRCWVS");
820 synchronized (mLock) {
Eugene Suslaccba7202017-02-10 10:56:53 -0800821 if (!enforceAnswerCallPermission(packageName, Binder.getCallingUid())) return;
Tyler Gunn42ef8082015-11-24 15:34:34 -0800822
Brad Ebinger11623a32015-11-25 13:52:02 -0800823 long token = Binder.clearCallingIdentity();
824 try {
825 acceptRingingCallInternal(videoState);
826 } finally {
827 Binder.restoreCallingIdentity(token);
828 }
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700829 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800830 } finally {
831 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700832 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800833 }
834
835 /**
836 * @see android.telecom.TelecomManager#showInCallScreen
837 */
838 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700839 public void showInCallScreen(boolean showDialpad, String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800840 try {
841 Log.startSession("TSI.sICS");
842 if (!canReadPhoneState(callingPackage, "showInCallScreen")) {
843 return;
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700844 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800845
846 synchronized (mLock) {
847
848 long token = Binder.clearCallingIdentity();
849 try {
850 mCallsManager.getInCallController().bringToForeground(showDialpad);
851 } finally {
852 Binder.restoreCallingIdentity(token);
853 }
854 }
855 } finally {
856 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700857 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800858 }
859
860 /**
861 * @see android.telecom.TelecomManager#cancelMissedCallsNotification
862 */
863 @Override
Yorke Lee53101962015-04-29 16:25:29 -0700864 public void cancelMissedCallsNotification(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800865 try {
866 Log.startSession("TSI.cMCN");
867 synchronized (mLock) {
868 enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
Tony Maka9930942016-01-15 10:57:14 +0000869 UserHandle userHandle = Binder.getCallingUserHandle();
Brad Ebinger11623a32015-11-25 13:52:02 -0800870 long token = Binder.clearCallingIdentity();
871 try {
Tony Maka9930942016-01-15 10:57:14 +0000872 mCallsManager.getMissedCallNotifier().clearMissedCalls(userHandle);
Brad Ebinger11623a32015-11-25 13:52:02 -0800873 } finally {
874 Binder.restoreCallingIdentity(token);
875 }
Santos Cordonebf2d0f2015-05-15 10:28:29 -0700876 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800877 } finally {
878 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700879 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800880 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800881 /**
882 * @see android.telecom.TelecomManager#handleMmi
883 */
884 @Override
Yorke Lee53101962015-04-29 16:25:29 -0700885 public boolean handlePinMmi(String dialString, String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800886 try {
887 Log.startSession("TSI.hPM");
888 synchronized (mLock) {
889 enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
Santos Cordonf987d1a2014-12-02 03:37:03 -0800890
Brad Ebinger11623a32015-11-25 13:52:02 -0800891 // Switch identity so that TelephonyManager checks Telecom's permissions
892 // instead.
893 long token = Binder.clearCallingIdentity();
894 boolean retval = false;
895 try {
896 retval = getTelephonyManager().handlePinMmi(dialString);
897 } finally {
898 Binder.restoreCallingIdentity(token);
899 }
900
901 return retval;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700902 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800903 }finally {
904 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800905 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800906 }
907
908 /**
909 * @see android.telecom.TelecomManager#handleMmi
910 */
911 @Override
Brad Ebinger11623a32015-11-25 13:52:02 -0800912 public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
913 String dialString, String callingPackage) {
914 try {
915 Log.startSession("TSI.hPMFPA");
916 synchronized (mLock) {
917 enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
Santos Cordonf987d1a2014-12-02 03:37:03 -0800918
Brad Ebinger11623a32015-11-25 13:52:02 -0800919 UserHandle callingUserHandle = Binder.getCallingUserHandle();
920 if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
921 callingUserHandle)) {
922 Log.d(this, "%s is not visible for the calling user [hMMI]", accountHandle);
923 return false;
924 }
925
926 // Switch identity so that TelephonyManager checks Telecom's permissions
927 // instead.
928 long token = Binder.clearCallingIdentity();
929 boolean retval = false;
930 try {
931 int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
932 accountHandle);
933 retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
934 } finally {
935 Binder.restoreCallingIdentity(token);
936 }
937 return retval;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700938 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800939 }finally {
940 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800941 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800942 }
943
944 /**
945 * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
946 */
947 @Override
Yorke Lee53101962015-04-29 16:25:29 -0700948 public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle,
949 String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800950 try {
951 Log.startSession("TSI.aAUFPA");
952 synchronized (mLock) {
953 enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
954 if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
955 Binder.getCallingUserHandle())) {
956 Log.d(this, "%s is not visible for the calling user [gA4PA]",
957 accountHandle);
958 return null;
959 }
960 // Switch identity so that TelephonyManager checks Telecom's permissions
961 // instead.
962 long token = Binder.clearCallingIdentity();
963 String retval = "content://icc/adn/";
964 try {
965 long subId = mPhoneAccountRegistrar
966 .getSubscriptionIdForPhoneAccount(accountHandle);
967 retval = retval + "subId/" + subId;
968 } finally {
969 Binder.restoreCallingIdentity(token);
970 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700971
Brad Ebinger11623a32015-11-25 13:52:02 -0800972 return Uri.parse(retval);
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700973 }
Brad Ebinger11623a32015-11-25 13:52:02 -0800974 } finally {
975 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -0800976 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800977 }
978
979 /**
980 * @see android.telecom.TelecomManager#isTtySupported
981 */
982 @Override
Svet Ganov09611182015-04-16 12:29:01 -0700983 public boolean isTtySupported(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -0800984 try {
985 Log.startSession("TSI.iTS");
Sanket Padawe88efa0c2017-09-08 11:46:34 -0700986 if (!canReadPhoneState(callingPackage, "isTtySupported")) {
987 throw new SecurityException("Only default dialer or an app with" +
988 "READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE can call this api");
Brad Ebinger11623a32015-11-25 13:52:02 -0800989 }
Svet Ganov09611182015-04-16 12:29:01 -0700990
Brad Ebinger11623a32015-11-25 13:52:02 -0800991 synchronized (mLock) {
992 return mCallsManager.isTtySupported();
993 }
994 } finally {
995 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -0700996 }
Santos Cordonf987d1a2014-12-02 03:37:03 -0800997 }
998
999 /**
1000 * @see android.telecom.TelecomManager#getCurrentTtyMode
1001 */
1002 @Override
Svet Ganov09611182015-04-16 12:29:01 -07001003 public int getCurrentTtyMode(String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001004 try {
1005 Log.startSession("TSI.gCTM");
1006 if (!canReadPhoneState(callingPackage, "getCurrentTtyMode")) {
1007 return TelecomManager.TTY_MODE_OFF;
1008 }
Svet Ganov09611182015-04-16 12:29:01 -07001009
Brad Ebinger11623a32015-11-25 13:52:02 -08001010 synchronized (mLock) {
1011 return mCallsManager.getCurrentTtyMode();
1012 }
1013 } finally {
1014 Log.endSession();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001015 }
Santos Cordonf987d1a2014-12-02 03:37:03 -08001016 }
1017
1018 /**
1019 * @see android.telecom.TelecomManager#addNewIncomingCall
1020 */
1021 @Override
1022 public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001023 try {
1024 Log.startSession("TSI.aNIC");
1025 synchronized (mLock) {
1026 Log.i(this, "Adding new incoming call with phoneAccountHandle %s",
Sharvil Nanavati6d3efb42015-05-14 11:36:40 -07001027 phoneAccountHandle);
Brad Ebinger11623a32015-11-25 13:52:02 -08001028 if (phoneAccountHandle != null &&
1029 phoneAccountHandle.getComponentName() != null) {
1030 // TODO(sail): Add unit tests for adding incoming calls from a SIM call
1031 // manager.
1032 if (isCallerSimCallManager() && TelephonyUtil.isPstnComponentName(
1033 phoneAccountHandle.getComponentName())) {
1034 Log.v(this, "Allowing call manager to add incoming call with PSTN" +
1035 " handle");
1036 } else {
1037 mAppOpsManager.checkPackage(
1038 Binder.getCallingUid(),
1039 phoneAccountHandle.getComponentName().getPackageName());
1040 // Make sure it doesn't cross the UserHandle boundary
1041 enforceUserHandleMatchesCaller(phoneAccountHandle);
Tony Mak5851fa02016-02-23 19:41:52 +00001042 enforcePhoneAccountIsRegisteredEnabled(phoneAccountHandle,
1043 Binder.getCallingUserHandle());
Tyler Gunna90ba732017-01-26 07:24:08 -08001044 if (isSelfManagedConnectionService(phoneAccountHandle)) {
1045 // Self-managed phone account, ensure it has MANAGE_OWN_CALLS.
1046 mContext.enforceCallingOrSelfPermission(
1047 android.Manifest.permission.MANAGE_OWN_CALLS,
1048 "Self-managed phone accounts must have MANAGE_OWN_CALLS " +
1049 "permission.");
Tyler Gunn0c7cf9a2017-05-17 11:15:57 -07001050
1051 // Self-managed ConnectionServices can ONLY add new incoming calls
1052 // using their own PhoneAccounts. The checkPackage(..) app opps
1053 // check above ensures this.
Tyler Gunna90ba732017-01-26 07:24:08 -08001054 }
Sharvil Nanavati6d3efb42015-05-14 11:36:40 -07001055 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001056 long token = Binder.clearCallingIdentity();
1057 try {
1058 Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
1059 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
1060 phoneAccountHandle);
1061 intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true);
1062 if (extras != null) {
Jeff Sharkeye2e4cdf2016-03-18 12:19:02 -06001063 extras.setDefusable(true);
Brad Ebinger11623a32015-11-25 13:52:02 -08001064 intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
1065 }
Hall Liuecda5542015-12-04 11:31:31 -08001066 mCallIntentProcessorAdapter.processIncomingCallIntent(
1067 mCallsManager, intent);
Brad Ebinger11623a32015-11-25 13:52:02 -08001068 } finally {
1069 Binder.restoreCallingIdentity(token);
1070 }
1071 } else {
1072 Log.w(this, "Null phoneAccountHandle. Ignoring request to add new" +
1073 " incoming call");
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001074 }
Santos Cordonf987d1a2014-12-02 03:37:03 -08001075 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001076 } finally {
1077 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -08001078 }
1079 }
1080
1081 /**
Sanket Padaweccdf3642017-11-10 14:49:05 -08001082 * @see android.telecom.TelecomManager#acceptHandover
1083 */
1084 @Override
1085 public void acceptHandover(Uri srcAddr, int videoState, PhoneAccountHandle destAcct) {
1086 try {
1087 Log.startSession("TSI.aHO");
1088 synchronized (mLock) {
Tyler Gunn37a4dca2018-01-18 15:00:41 -08001089 Log.i(this, "acceptHandover; srcAddr=%s, videoState=%s, dest=%s",
1090 Log.pii(srcAddr), VideoProfile.videoStateToString(videoState),
Sanket Padaweccdf3642017-11-10 14:49:05 -08001091 destAcct);
Tyler Gunn37a4dca2018-01-18 15:00:41 -08001092
Sanket Padaweccdf3642017-11-10 14:49:05 -08001093 if (destAcct != null && destAcct.getComponentName() != null) {
1094 mAppOpsManager.checkPackage(
1095 Binder.getCallingUid(),
1096 destAcct.getComponentName().getPackageName());
1097 enforceUserHandleMatchesCaller(destAcct);
1098 enforcePhoneAccountIsRegisteredEnabled(destAcct,
1099 Binder.getCallingUserHandle());
1100 if (isSelfManagedConnectionService(destAcct)) {
1101 // Self-managed phone account, ensure it has MANAGE_OWN_CALLS.
1102 mContext.enforceCallingOrSelfPermission(
1103 android.Manifest.permission.MANAGE_OWN_CALLS,
1104 "Self-managed phone accounts must have MANAGE_OWN_CALLS " +
1105 "permission.");
1106 }
Tyler Gunn37a4dca2018-01-18 15:00:41 -08001107 if (!enforceAcceptHandoverPermission(
1108 destAcct.getComponentName().getPackageName(),
1109 Binder.getCallingUid())) {
1110 throw new SecurityException("App must be granted runtime "
1111 + "ACCEPT_HANDOVER permission.");
1112 }
Sanket Padaweccdf3642017-11-10 14:49:05 -08001113
Tyler Gunn37a4dca2018-01-18 15:00:41 -08001114 long token = Binder.clearCallingIdentity();
1115 try {
1116 mCallsManager.acceptHandover(srcAddr, videoState, destAcct);
1117 } finally {
1118 Binder.restoreCallingIdentity(token);
1119 }
Sanket Padaweccdf3642017-11-10 14:49:05 -08001120 } else {
1121 Log.w(this, "Null phoneAccountHandle. Ignoring request " +
1122 "to handover the call");
1123 }
1124 }
1125 } finally {
1126 Log.endSession();
1127 }
1128 }
1129
1130 /**
Santos Cordonf987d1a2014-12-02 03:37:03 -08001131 * @see android.telecom.TelecomManager#addNewUnknownCall
1132 */
1133 @Override
1134 public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001135 try {
1136 Log.startSession("TSI.aNUC");
Tyler Gunn322480c2017-07-17 15:34:02 -07001137 try {
1138 enforceModifyPermission(
1139 "addNewUnknownCall requires MODIFY_PHONE_STATE permission.");
1140 } catch (SecurityException e) {
1141 EventLog.writeEvent(0x534e4554, "62347125", Binder.getCallingUid(),
1142 "addNewUnknownCall");
1143 throw e;
1144 }
1145
Brad Ebinger11623a32015-11-25 13:52:02 -08001146 synchronized (mLock) {
1147 if (phoneAccountHandle != null &&
1148 phoneAccountHandle.getComponentName() != null) {
1149 mAppOpsManager.checkPackage(
1150 Binder.getCallingUid(),
1151 phoneAccountHandle.getComponentName().getPackageName());
Santos Cordonf987d1a2014-12-02 03:37:03 -08001152
Brad Ebinger11623a32015-11-25 13:52:02 -08001153 // Make sure it doesn't cross the UserHandle boundary
1154 enforceUserHandleMatchesCaller(phoneAccountHandle);
Tony Mak5851fa02016-02-23 19:41:52 +00001155 enforcePhoneAccountIsRegisteredEnabled(phoneAccountHandle,
1156 Binder.getCallingUserHandle());
Brad Ebinger11623a32015-11-25 13:52:02 -08001157 long token = Binder.clearCallingIdentity();
Santos Cordonf987d1a2014-12-02 03:37:03 -08001158
Brad Ebinger11623a32015-11-25 13:52:02 -08001159 try {
1160 Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
Jeff Sharkeye2e4cdf2016-03-18 12:19:02 -06001161 if (extras != null) {
1162 extras.setDefusable(true);
1163 intent.putExtras(extras);
1164 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001165 intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true);
1166 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
1167 phoneAccountHandle);
Hall Liuecda5542015-12-04 11:31:31 -08001168 mCallIntentProcessorAdapter.processUnknownCallIntent(mCallsManager, intent);
Brad Ebinger11623a32015-11-25 13:52:02 -08001169 } finally {
1170 Binder.restoreCallingIdentity(token);
1171 }
1172 } else {
1173 Log.i(this,
1174 "Null phoneAccountHandle or not initiated by Telephony. " +
1175 "Ignoring request to add new unknown call.");
Sharvil Nanavati6d3efb42015-05-14 11:36:40 -07001176 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001177 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001178 } finally {
1179 Log.endSession();
Santos Cordonf987d1a2014-12-02 03:37:03 -08001180 }
1181 }
Tyler Gunn47689862014-12-17 17:10:28 -08001182
1183 /**
Yorke Leea3a3adc2015-04-23 12:49:01 -07001184 * @see android.telecom.TelecomManager#placeCall
1185 */
1186 @Override
1187 public void placeCall(Uri handle, Bundle extras, String callingPackage) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001188 try {
1189 Log.startSession("TSI.pC");
1190 enforceCallingPackage(callingPackage);
Tyler Gunna90ba732017-01-26 07:24:08 -08001191
1192 PhoneAccountHandle phoneAccountHandle = null;
1193 if (extras != null) {
1194 phoneAccountHandle = extras.getParcelable(
1195 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
Tyler Gunn141ef582017-05-26 13:38:13 -07001196 if (extras.containsKey(TelecomManager.EXTRA_IS_HANDOVER)) {
1197 // This extra is for Telecom use only so should never be passed in.
1198 extras.remove(TelecomManager.EXTRA_IS_HANDOVER);
1199 }
Tyler Gunna90ba732017-01-26 07:24:08 -08001200 }
1201 boolean isSelfManaged = phoneAccountHandle != null &&
1202 isSelfManagedConnectionService(phoneAccountHandle);
1203 if (isSelfManaged) {
1204 mContext.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_OWN_CALLS,
1205 "Self-managed ConnectionServices require MANAGE_OWN_CALLS permission.");
Tyler Gunn0c7cf9a2017-05-17 11:15:57 -07001206
1207 if (!callingPackage.equals(
1208 phoneAccountHandle.getComponentName().getPackageName())
1209 && !canCallPhone(callingPackage,
1210 "CALL_PHONE permission required to place calls.")) {
1211 // The caller is not allowed to place calls, so we want to ensure that it
1212 // can only place calls through itself.
1213 throw new SecurityException("Self-managed ConnectionServices can only "
1214 + "place calls through their own ConnectionService.");
1215 }
Tyler Gunna90ba732017-01-26 07:24:08 -08001216 } else if (!canCallPhone(callingPackage, "placeCall")) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001217 throw new SecurityException("Package " + callingPackage
1218 + " is not allowed to place phone calls");
Yorke Lee58061752015-05-04 11:06:26 -07001219 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001220
1221 // Note: we can still get here for the default/system dialer, even if the Phone
1222 // permission is turned off. This is because the default/system dialer is always
1223 // allowed to attempt to place a call (regardless of permission state), in case
1224 // it turns out to be an emergency call. If the permission is denied and the
1225 // call is being made to a non-emergency number, the call will be denied later on
1226 // by {@link UserCallIntentProcessor}.
1227
1228 final boolean hasCallAppOp = mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1229 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1230
1231 final boolean hasCallPermission = mContext.checkCallingPermission(CALL_PHONE) ==
1232 PackageManager.PERMISSION_GRANTED;
Tyler Gunnb652dad2018-03-27 18:49:49 +00001233 // The Emergency Dialer has call privileged permission and uses this to place
1234 // emergency calls. We ensure permission checks in
1235 // NewOutgoingCallIntentBroadcaster#process pass by sending this to
1236 // Telecom as an ACTION_CALL_PRIVILEGED intent (which makes sense since the
1237 // com.android.phone process has that permission).
1238 final boolean hasCallPrivilegedPermission = mContext.checkCallingPermission(
1239 CALL_PRIVILEGED) == PackageManager.PERMISSION_GRANTED;
Brad Ebinger11623a32015-11-25 13:52:02 -08001240
1241 synchronized (mLock) {
1242 final UserHandle userHandle = Binder.getCallingUserHandle();
1243 long token = Binder.clearCallingIdentity();
1244 try {
Tyler Gunnb652dad2018-03-27 18:49:49 +00001245 final Intent intent = new Intent(hasCallPrivilegedPermission ?
1246 Intent.ACTION_CALL_PRIVILEGED : Intent.ACTION_CALL, handle);
Jeff Sharkeye2e4cdf2016-03-18 12:19:02 -06001247 if (extras != null) {
1248 extras.setDefusable(true);
1249 intent.putExtras(extras);
1250 }
Hall Liuecda5542015-12-04 11:31:31 -08001251 mUserCallIntentProcessorFactory.create(mContext, userHandle)
1252 .processIntent(
Tyler Gunna90ba732017-01-26 07:24:08 -08001253 intent, callingPackage, isSelfManaged ||
Tyler Gunnb652dad2018-03-27 18:49:49 +00001254 (hasCallAppOp && hasCallPermission),
1255 true /* isLocalInvocation */);
Brad Ebinger11623a32015-11-25 13:52:02 -08001256 } finally {
1257 Binder.restoreCallingIdentity(token);
1258 }
1259 }
1260 } finally {
1261 Log.endSession();
Yorke Leea3a3adc2015-04-23 12:49:01 -07001262 }
1263 }
1264
1265 /**
Santos Cordonea5cb932015-05-07 16:28:38 -07001266 * @see android.telecom.TelecomManager#enablePhoneAccount
1267 */
1268 @Override
Yorke Lee71734c22015-06-02 14:22:56 -07001269 public boolean enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001270 try {
1271 Log.startSession("TSI.ePA");
1272 enforceModifyPermission();
1273 synchronized (mLock) {
1274 long token = Binder.clearCallingIdentity();
1275 try {
1276 // enable/disable phone account
1277 return mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled);
1278 } finally {
1279 Binder.restoreCallingIdentity(token);
1280 }
Yorke Lee71734c22015-06-02 14:22:56 -07001281 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001282 } finally {
1283 Log.endSession();
Yorke Lee71734c22015-06-02 14:22:56 -07001284 }
1285 }
1286
1287 @Override
1288 public boolean setDefaultDialer(String packageName) {
Brad Ebinger11623a32015-11-25 13:52:02 -08001289 try {
1290 Log.startSession("TSI.sDD");
1291 enforcePermission(MODIFY_PHONE_STATE);
1292 enforcePermission(WRITE_SECURE_SETTINGS);
1293 synchronized (mLock) {
1294 long token = Binder.clearCallingIdentity();
1295 try {
Hall Liu7c928322016-12-06 18:15:39 -08001296 final boolean result = mDefaultDialerCache.setDefaultDialer(
1297 packageName, ActivityManager.getCurrentUser());
Brad Ebinger11623a32015-11-25 13:52:02 -08001298 if (result) {
1299 final Intent intent =
1300 new Intent(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
1301 intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,
1302 packageName);
1303 mContext.sendBroadcastAsUser(intent,
1304 new UserHandle(ActivityManager.getCurrentUser()));
1305 }
1306 return result;
1307 } finally {
1308 Binder.restoreCallingIdentity(token);
Yorke Leeb3984302015-06-15 12:06:35 -07001309 }
Santos Cordonea5cb932015-05-07 16:28:38 -07001310 }
Brad Ebinger11623a32015-11-25 13:52:02 -08001311 } finally {
1312 Log.endSession();
Santos Cordonea5cb932015-05-07 16:28:38 -07001313 }
1314 }
1315
Hall Liuecd74a52016-01-12 15:26:36 -08001316 @Override
Hall Liu874c0f82016-04-29 18:13:18 -07001317 public TelecomAnalytics dumpCallAnalytics() {
Hall Liuecd74a52016-01-12 15:26:36 -08001318 try {
1319 Log.startSession("TSI.dCA");
1320 enforcePermission(DUMP);
Hall Liu874c0f82016-04-29 18:13:18 -07001321 return Analytics.dumpToParcelableAnalytics();
Hall Liuecd74a52016-01-12 15:26:36 -08001322 } finally {
1323 Log.endSession();
1324 }
1325 }
1326
Santos Cordonea5cb932015-05-07 16:28:38 -07001327 /**
Tyler Gunn47689862014-12-17 17:10:28 -08001328 * Dumps the current state of the TelecomService. Used when generating problem reports.
1329 *
1330 * @param fd The file descriptor.
1331 * @param writer The print writer to dump the state to.
1332 * @param args Optional dump arguments.
1333 */
1334 @Override
1335 protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
1336 if (mContext.checkCallingOrSelfPermission(
1337 android.Manifest.permission.DUMP)
1338 != PackageManager.PERMISSION_GRANTED) {
1339 writer.println("Permission Denial: can't dump TelecomService " +
1340 "from from pid=" + Binder.getCallingPid() + ", uid=" +
1341 Binder.getCallingUid());
1342 return;
1343 }
1344
Hall Liu5bbbcf72016-08-08 17:23:20 -07001345 if (args.length > 0 && Analytics.ANALYTICS_DUMPSYS_ARG.equals(args[0])) {
1346 Analytics.dumpToEncodedProto(writer, args);
1347 return;
1348 }
Tyler Gunn897e8512017-05-18 15:46:51 -07001349 boolean isTimeLineView = (args.length > 0 && TIME_LINE_ARG.equalsIgnoreCase(args[0]));
Hall Liu5bbbcf72016-08-08 17:23:20 -07001350
Tyler Gunn47689862014-12-17 17:10:28 -08001351 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
Ihab Awad8de76912015-02-17 12:25:52 -08001352 if (mCallsManager != null) {
Ihab Awad78a5e6b2015-02-06 10:13:05 -08001353 pw.println("CallsManager: ");
Tyler Gunn47689862014-12-17 17:10:28 -08001354 pw.increaseIndent();
Ihab Awad8de76912015-02-17 12:25:52 -08001355 mCallsManager.dump(pw);
Tyler Gunn47689862014-12-17 17:10:28 -08001356 pw.decreaseIndent();
1357
Ihab Awad78a5e6b2015-02-06 10:13:05 -08001358 pw.println("PhoneAccountRegistrar: ");
Tyler Gunn47689862014-12-17 17:10:28 -08001359 pw.increaseIndent();
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001360 mPhoneAccountRegistrar.dump(pw);
Tyler Gunn47689862014-12-17 17:10:28 -08001361 pw.decreaseIndent();
Hall Liu32587202015-11-18 11:10:08 -08001362
1363 pw.println("Analytics:");
1364 pw.increaseIndent();
1365 Analytics.dump(pw);
1366 pw.decreaseIndent();
Tyler Gunn47689862014-12-17 17:10:28 -08001367 }
Tyler Gunn897e8512017-05-18 15:46:51 -07001368 if (isTimeLineView) {
1369 Log.dumpEventsTimeline(pw);
1370 } else {
1371 Log.dumpEvents(pw);
1372 }
Tyler Gunn47689862014-12-17 17:10:28 -08001373 }
Abhijith Shastry7a846f52016-02-01 16:49:27 -08001374
Mohamedc9261852016-02-05 14:10:17 -08001375 /**
Abhijith Shastryb1308ec2016-02-29 16:26:09 -08001376 * @see android.telecom.TelecomManager#createManageBlockedNumbersIntent
1377 */
Abhijith Shastryebe7bbe2016-02-29 11:16:30 -08001378 @Override
1379 public Intent createManageBlockedNumbersIntent() {
Abhijith Shastryb1308ec2016-02-29 16:26:09 -08001380 return BlockedNumbersActivity.getIntentForStartingActivity();
Abhijith Shastryebe7bbe2016-02-29 11:16:30 -08001381 }
Tyler Gunnacb3bc82017-01-09 09:43:56 -08001382
1383 /**
1384 * @see android.telecom.TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)
1385 */
1386 @Override
1387 public boolean isIncomingCallPermitted(PhoneAccountHandle phoneAccountHandle) {
1388 try {
1389 Log.startSession("TSI.iICP");
1390 enforcePermission(android.Manifest.permission.MANAGE_OWN_CALLS);
1391 synchronized (mLock) {
1392 long token = Binder.clearCallingIdentity();
1393 try {
Tyler Gunna90ba732017-01-26 07:24:08 -08001394 return mCallsManager.isIncomingCallPermitted(phoneAccountHandle);
Tyler Gunnacb3bc82017-01-09 09:43:56 -08001395 } finally {
1396 Binder.restoreCallingIdentity(token);
1397 }
1398 }
1399 } finally {
1400 Log.endSession();
1401 }
Tyler Gunnacb3bc82017-01-09 09:43:56 -08001402 }
1403
1404 /**
1405 * @see android.telecom.TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)
1406 */
1407 @Override
1408 public boolean isOutgoingCallPermitted(PhoneAccountHandle phoneAccountHandle) {
1409 try {
1410 Log.startSession("TSI.iOCP");
1411 enforcePermission(android.Manifest.permission.MANAGE_OWN_CALLS);
1412 synchronized (mLock) {
1413 long token = Binder.clearCallingIdentity();
1414 try {
Tyler Gunna90ba732017-01-26 07:24:08 -08001415 return mCallsManager.isOutgoingCallPermitted(phoneAccountHandle);
Tyler Gunnacb3bc82017-01-09 09:43:56 -08001416 } finally {
1417 Binder.restoreCallingIdentity(token);
1418 }
1419 }
1420 } finally {
1421 Log.endSession();
1422 }
Tyler Gunnacb3bc82017-01-09 09:43:56 -08001423 }
Tyler Gunn9e806ee2017-02-06 20:49:24 -08001424
1425 /**
1426 * Blocks until all Telecom handlers have completed their current work.
1427 *
1428 * See {@link com.android.commands.telecom.Telecom}.
1429 */
1430 @Override
1431 public void waitOnHandlers() {
1432 try {
1433 Log.startSession("TSI.wOH");
1434 enforceModifyPermission();
1435 synchronized (mLock) {
1436 long token = Binder.clearCallingIdentity();
1437 try {
1438 Log.i(this, "waitOnHandlers");
1439 mCallsManager.waitOnHandlers();
1440 } finally {
1441 Binder.restoreCallingIdentity(token);
1442 }
1443 }
1444 } finally {
1445 Log.endSession();
1446 }
1447 }
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001448 };
1449
Eugene Suslaccba7202017-02-10 10:56:53 -08001450 /**
1451 * @return whether to return early without doing the action/throwing
1452 * @throws SecurityException same as {@link Context#enforceCallingOrSelfPermission}
1453 */
1454 private boolean enforceAnswerCallPermission(String packageName, int uid) {
1455 try {
1456 enforceModifyPermission();
1457 } catch (SecurityException e) {
1458 final String permission = Manifest.permission.ANSWER_PHONE_CALLS;
1459 enforcePermission(permission);
1460
1461 final int opCode = AppOpsManager.permissionToOpCode(permission);
1462 if (opCode != AppOpsManager.OP_NONE
1463 && mAppOpsManager.checkOp(opCode, uid, packageName)
1464 != AppOpsManager.MODE_ALLOWED) {
1465 return false;
1466 }
1467 }
1468 return true;
1469 }
1470
Tyler Gunn37a4dca2018-01-18 15:00:41 -08001471 /**
1472 * @return {@code true} if the app has the handover permission and has received runtime
1473 * permission to perform that operation, {@code false}.
1474 * @throws SecurityException same as {@link Context#enforceCallingOrSelfPermission}
1475 */
1476 private boolean enforceAcceptHandoverPermission(String packageName, int uid) {
1477 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCEPT_HANDOVER,
1478 "App requires ACCEPT_HANDOVER permission to accept handovers.");
1479
1480 final int opCode = AppOpsManager.permissionToOpCode(Manifest.permission.ACCEPT_HANDOVER);
1481 if (opCode != AppOpsManager.OP_ACCEPT_HANDOVER || (
1482 mAppOpsManager.checkOp(opCode, uid, packageName)
1483 != AppOpsManager.MODE_ALLOWED)) {
1484 return false;
1485 }
1486 return true;
1487 }
1488
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001489 private Context mContext;
1490 private AppOpsManager mAppOpsManager;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001491 private PackageManager mPackageManager;
1492 private CallsManager mCallsManager;
1493 private final PhoneAccountRegistrar mPhoneAccountRegistrar;
Hall Liuecda5542015-12-04 11:31:31 -08001494 private final CallIntentProcessor.Adapter mCallIntentProcessorAdapter;
1495 private final UserCallIntentProcessorFactory mUserCallIntentProcessorFactory;
Hall Liu7c928322016-12-06 18:15:39 -08001496 private final DefaultDialerCache mDefaultDialerCache;
Hall Liu0a6dd302015-12-16 15:06:49 -08001497 private final SubscriptionManagerAdapter mSubscriptionManagerAdapter;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001498 private final TelecomSystem.SyncRoot mLock;
1499
1500 public TelecomServiceImpl(
1501 Context context,
1502 CallsManager callsManager,
1503 PhoneAccountRegistrar phoneAccountRegistrar,
Hall Liuecda5542015-12-04 11:31:31 -08001504 CallIntentProcessor.Adapter callIntentProcessorAdapter,
1505 UserCallIntentProcessorFactory userCallIntentProcessorFactory,
Hall Liu7c928322016-12-06 18:15:39 -08001506 DefaultDialerCache defaultDialerCache,
Hall Liu0a6dd302015-12-16 15:06:49 -08001507 SubscriptionManagerAdapter subscriptionManagerAdapter,
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001508 TelecomSystem.SyncRoot lock) {
1509 mContext = context;
1510 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
1511
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001512 mPackageManager = mContext.getPackageManager();
1513
1514 mCallsManager = callsManager;
1515 mLock = lock;
1516 mPhoneAccountRegistrar = phoneAccountRegistrar;
Hall Liuecda5542015-12-04 11:31:31 -08001517 mUserCallIntentProcessorFactory = userCallIntentProcessorFactory;
Hall Liu7c928322016-12-06 18:15:39 -08001518 mDefaultDialerCache = defaultDialerCache;
Hall Liuecda5542015-12-04 11:31:31 -08001519 mCallIntentProcessorAdapter = callIntentProcessorAdapter;
Hall Liu0a6dd302015-12-16 15:06:49 -08001520 mSubscriptionManagerAdapter = subscriptionManagerAdapter;
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001521 }
1522
Ihab Awadaa383cc2015-03-22 22:12:28 -07001523 public ITelecomService.Stub getBinder() {
Ihab Awad8d5d9dd2015-03-12 11:11:06 -07001524 return mBinderImpl;
Santos Cordonf987d1a2014-12-02 03:37:03 -08001525 }
1526
1527 //
1528 // Supporting methods for the ITelecomService interface implementation.
1529 //
1530
Tony Mak240656f2015-12-04 11:36:22 +00001531 private boolean isPhoneAccountHandleVisibleToCallingUser(
1532 PhoneAccountHandle phoneAccountUserHandle, UserHandle callingUser) {
1533 return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser) != null;
Santos Cordonf987d1a2014-12-02 03:37:03 -08001534 }
1535
1536 private boolean isCallerSystemApp() {
1537 int uid = Binder.getCallingUid();
1538 String[] packages = mPackageManager.getPackagesForUid(uid);
1539 for (String packageName : packages) {
1540 if (isPackageSystemApp(packageName)) {
1541 return true;
1542 }
1543 }
1544 return false;
1545 }
1546
1547 private boolean isPackageSystemApp(String packageName) {
1548 try {
1549 ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
1550 PackageManager.GET_META_DATA);
1551 if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
1552 return true;
1553 }
1554 } catch (PackageManager.NameNotFoundException e) {
1555 }
1556 return false;
1557 }
1558
Tyler Gunn42ef8082015-11-24 15:34:34 -08001559 private void acceptRingingCallInternal(int videoState) {
Ihab Awad8de76912015-02-17 12:25:52 -08001560 Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001561 if (call != null) {
Tyler Gunn42ef8082015-11-24 15:34:34 -08001562 if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
1563 videoState = call.getVideoState();
1564 }
1565 call.answer(videoState);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001566 }
1567 }
1568
Tyler Gunn587fc272018-02-07 16:07:29 -08001569 private boolean endCallInternal(String callingPackage) {
Santos Cordonf987d1a2014-12-02 03:37:03 -08001570 // Always operate on the foreground call if one exists, otherwise get the first call in
1571 // priority order by call-state.
Ihab Awad8de76912015-02-17 12:25:52 -08001572 Call call = mCallsManager.getForegroundCall();
Santos Cordonf987d1a2014-12-02 03:37:03 -08001573 if (call == null) {
Ihab Awad8de76912015-02-17 12:25:52 -08001574 call = mCallsManager.getFirstCallWithState(
Santos Cordonf987d1a2014-12-02 03:37:03 -08001575 CallState.ACTIVE,
1576 CallState.DIALING,
Tyler Gunn1e37be52016-07-11 08:54:23 -07001577 CallState.PULLING,
Santos Cordonf987d1a2014-12-02 03:37:03 -08001578 CallState.RINGING,
1579 CallState.ON_HOLD);
1580 }
1581
1582 if (call != null) {
Tyler Gunn275e8822019-05-13 13:58:15 -07001583 if (call.isEmergencyCall()) {
1584 android.util.EventLog.writeEvent(0x534e4554, "132438333", -1, "");
1585 return false;
1586 }
1587
Santos Cordonf987d1a2014-12-02 03:37:03 -08001588 if (call.getState() == CallState.RINGING) {
Tyler Gunn587fc272018-02-07 16:07:29 -08001589 call.reject(false /* rejectWithMessage */, null, callingPackage);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001590 } else {
Tyler Gunn587fc272018-02-07 16:07:29 -08001591 call.disconnect(0 /* disconnectionTimeout */, callingPackage);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001592 }
1593 return true;
1594 }
1595
1596 return false;
1597 }
1598
Brad Ebinger62da8e12016-01-28 19:16:08 -08001599 // Enforce that the PhoneAccountHandle being passed in is both registered to the current user
1600 // and enabled.
Tony Mak5851fa02016-02-23 19:41:52 +00001601 private void enforcePhoneAccountIsRegisteredEnabled(PhoneAccountHandle phoneAccountHandle,
1602 UserHandle callingUserHandle) {
1603 PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccount(phoneAccountHandle,
1604 callingUserHandle);
Brad Ebinger62da8e12016-01-28 19:16:08 -08001605 if(phoneAccount == null) {
1606 EventLog.writeEvent(0x534e4554, "26864502", Binder.getCallingUid(), "R");
1607 throw new SecurityException("This PhoneAccountHandle is not registered for this user!");
1608 }
1609 if(!phoneAccount.isEnabled()) {
1610 EventLog.writeEvent(0x534e4554, "26864502", Binder.getCallingUid(), "E");
1611 throw new SecurityException("This PhoneAccountHandle is not enabled for this user!");
1612 }
1613 }
1614
Santos Cordonf987d1a2014-12-02 03:37:03 -08001615 private void enforcePhoneAccountModificationForPackage(String packageName) {
1616 // TODO: Use a new telecomm permission for this instead of reusing modify.
1617
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001618 int result = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001619
1620 // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
1621 // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
1622 // may also modify PhoneAccounts on behalf of any 'packageName'.
1623
1624 if (result != PackageManager.PERMISSION_GRANTED) {
1625 // Other callers are only allowed to modify PhoneAccounts if the relevant system
1626 // feature is enabled ...
1627 enforceConnectionServiceFeature();
1628 // ... and the PhoneAccounts they refer to are for their own package.
1629 enforceCallingPackage(packageName);
1630 }
1631 }
1632
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001633 private void enforcePermissionOrPrivilegedDialer(String permission, String packageName) {
Yorke Lee53101962015-04-29 16:25:29 -07001634 if (!isPrivilegedDialerCalling(packageName)) {
1635 try {
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001636 enforcePermission(permission);
Yorke Lee53101962015-04-29 16:25:29 -07001637 } catch (SecurityException e) {
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001638 Log.e(this, e, "Caller must be the default or system dialer, or have the permission"
1639 + " %s to perform this operation.", permission);
Yorke Lee53101962015-04-29 16:25:29 -07001640 throw e;
1641 }
Santos Cordonf987d1a2014-12-02 03:37:03 -08001642 }
1643 }
1644
1645 private void enforceCallingPackage(String packageName) {
1646 mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
1647 }
1648
1649 private void enforceConnectionServiceFeature() {
1650 enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
1651 }
1652
Santos Cordonf987d1a2014-12-02 03:37:03 -08001653 private void enforceRegisterSimSubscriptionPermission() {
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001654 enforcePermission(REGISTER_SIM_SUBSCRIPTION);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001655 }
1656
Santos Cordonf987d1a2014-12-02 03:37:03 -08001657 private void enforceModifyPermission() {
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001658 enforcePermission(MODIFY_PHONE_STATE);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001659 }
1660
Tyler Gunn322480c2017-07-17 15:34:02 -07001661 private void enforceModifyPermission(String message) {
1662 mContext.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, message);
1663 }
1664
Santos Cordonf987d1a2014-12-02 03:37:03 -08001665 private void enforcePermission(String permission) {
1666 mContext.enforceCallingOrSelfPermission(permission, null);
1667 }
1668
Tyler Gunnacb3bc82017-01-09 09:43:56 -08001669 private void enforceRegisterSelfManaged() {
1670 mContext.enforceCallingPermission(android.Manifest.permission.MANAGE_OWN_CALLS, null);
1671 }
1672
Santos Cordonf987d1a2014-12-02 03:37:03 -08001673 private void enforceRegisterMultiUser() {
1674 if (!isCallerSystemApp()) {
1675 throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
1676 }
1677 }
1678
1679 private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
1680 if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
1681 throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
1682 }
1683 }
1684
Tony Mak240656f2015-12-04 11:36:22 +00001685 private void enforceCrossUserPermission(int callingUid) {
1686 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1687 mContext.enforceCallingOrSelfPermission(
1688 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
1689 + " INTERACT_ACROSS_USERS_FULL permission");
1690 }
1691 }
1692
Santos Cordonf987d1a2014-12-02 03:37:03 -08001693 private void enforceFeature(String feature) {
1694 PackageManager pm = mContext.getPackageManager();
1695 if (!pm.hasSystemFeature(feature)) {
1696 throw new UnsupportedOperationException(
1697 "System does not support feature " + feature);
1698 }
1699 }
1700
Svet Ganov38f1a4d2015-04-17 15:28:03 -07001701 private boolean canReadPhoneState(String callingPackage, String message) {
Yorke Lee57138a62015-05-18 18:18:08 -07001702 // The system/default dialer can always read phone state - so that emergency calls will
1703 // still work.
1704 if (isPrivilegedDialerCalling(callingPackage)) {
1705 return true;
1706 }
1707
Amit Mahajan3c296932015-07-14 10:23:15 -07001708 try {
Amit Mahajan86b8e332015-07-30 16:02:52 -07001709 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
1710 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
1711 // permission
Amit Mahajan3c296932015-07-14 10:23:15 -07001712 return true;
1713 } catch (SecurityException e) {
1714 // Accessing phone state is gated by a special permission.
1715 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message);
Svet Ganov09611182015-04-16 12:29:01 -07001716
Amit Mahajan3c296932015-07-14 10:23:15 -07001717 // Some apps that have the permission can be restricted via app ops.
1718 return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE,
1719 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1720 }
Svet Ganov09611182015-04-16 12:29:01 -07001721 }
1722
Tyler Gunna90ba732017-01-26 07:24:08 -08001723 private boolean isSelfManagedConnectionService(PhoneAccountHandle phoneAccountHandle) {
1724 if (phoneAccountHandle != null) {
1725 PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
1726 phoneAccountHandle);
Tyler Gunn9e806ee2017-02-06 20:49:24 -08001727 return phoneAccount != null && phoneAccount.isSelfManaged();
Tyler Gunna90ba732017-01-26 07:24:08 -08001728 }
1729 return false;
1730 }
1731
Yorke Leea3a3adc2015-04-23 12:49:01 -07001732 private boolean canCallPhone(String callingPackage, String message) {
Yorke Lee57138a62015-05-18 18:18:08 -07001733 // The system/default dialer can always read phone state - so that emergency calls will
1734 // still work.
1735 if (isPrivilegedDialerCalling(callingPackage)) {
1736 return true;
1737 }
1738
Yorke Leea3a3adc2015-04-23 12:49:01 -07001739 // Accessing phone state is gated by a special permission.
Yorke Leecb0bd8a2015-05-18 11:57:14 -07001740 mContext.enforceCallingOrSelfPermission(CALL_PHONE, message);
Yorke Leea3a3adc2015-04-23 12:49:01 -07001741
1742 // Some apps that have the permission can be restricted via app ops.
1743 return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1744 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1745 }
1746
Sailesh Nepal2a98c972015-03-04 15:43:15 -08001747 private boolean isCallerSimCallManager() {
Yorke Lee9427c0f2015-06-27 11:01:58 -07001748 long token = Binder.clearCallingIdentity();
Tony Mak240656f2015-12-04 11:36:22 +00001749 PhoneAccountHandle accountHandle = null;
Yorke Lee9427c0f2015-06-27 11:01:58 -07001750 try {
Tony Mak240656f2015-12-04 11:36:22 +00001751 accountHandle = mPhoneAccountRegistrar.getSimCallManagerOfCurrentUser();
Yorke Lee9427c0f2015-06-27 11:01:58 -07001752 } finally {
1753 Binder.restoreCallingIdentity(token);
1754 }
1755
Sailesh Nepal2a98c972015-03-04 15:43:15 -08001756 if (accountHandle != null) {
1757 try {
1758 mAppOpsManager.checkPackage(
1759 Binder.getCallingUid(), accountHandle.getComponentName().getPackageName());
1760 return true;
1761 } catch (SecurityException e) {
1762 }
1763 }
1764 return false;
1765 }
1766
Yorke Lee53101962015-04-29 16:25:29 -07001767 private boolean isPrivilegedDialerCalling(String callingPackage) {
1768 mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liu7c928322016-12-06 18:15:39 -08001769 return mDefaultDialerCache.isDefaultOrSystemDialer(
1770 callingPackage, Binder.getCallingUserHandle().getIdentifier());
Santos Cordonf987d1a2014-12-02 03:37:03 -08001771 }
1772
1773 private TelephonyManager getTelephonyManager() {
Hall Liuecda5542015-12-04 11:31:31 -08001774 return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Santos Cordonf987d1a2014-12-02 03:37:03 -08001775 }
Tyler Gunn42ef8082015-11-24 15:34:34 -08001776
1777 /**
1778 * Determines if a video state is valid for accepting an incoming call.
1779 * For the purpose of accepting a call, states {@link VideoProfile#STATE_AUDIO_ONLY}, and
1780 * any combination of {@link VideoProfile#STATE_RX_ENABLED} and
1781 * {@link VideoProfile#STATE_TX_ENABLED} are considered valid.
1782 *
1783 * @param videoState The video state.
1784 * @return {@code true} if the video state is valid, {@code false} otherwise.
1785 */
1786 private boolean isValidAcceptVideoState(int videoState) {
1787 // Given a video state input, turn off TX and RX so that we can determine if those were the
1788 // only bits set.
1789 int remainingState = videoState & ~VideoProfile.STATE_TX_ENABLED;
1790 remainingState = remainingState & ~VideoProfile.STATE_RX_ENABLED;
1791
1792 // If only TX or RX were set (or neither), the video state is valid.
1793 return remainingState == 0;
1794 }
Santos Cordonf987d1a2014-12-02 03:37:03 -08001795}