1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.telecom.tests;
18 
19 import com.google.common.collect.ArrayListMultimap;
20 import com.google.common.collect.Multimap;
21 
22 import com.android.internal.telecom.IConnectionService;
23 import com.android.internal.telecom.IInCallService;
24 
25 import org.mockito.MockitoAnnotations;
26 import org.mockito.invocation.InvocationOnMock;
27 import org.mockito.stubbing.Answer;
28 
29 import android.Manifest;
30 import android.app.AppOpsManager;
31 import android.app.NotificationManager;
32 import android.app.StatusBarManager;
33 import android.app.role.RoleManager;
34 import android.content.BroadcastReceiver;
35 import android.content.ComponentName;
36 import android.content.ContentResolver;
37 import android.content.Context;
38 import android.content.IContentProvider;
39 import android.content.Intent;
40 import android.content.IntentFilter;
41 import android.content.ServiceConnection;
42 import android.content.pm.ApplicationInfo;
43 import android.content.pm.PackageManager;
44 import android.content.pm.ResolveInfo;
45 import android.content.pm.ServiceInfo;
46 import android.content.res.Configuration;
47 import android.content.res.Resources;
48 import android.location.Country;
49 import android.location.CountryDetector;
50 import android.media.AudioManager;
51 import android.os.Bundle;
52 import android.os.Handler;
53 import android.os.IInterface;
54 import android.os.PersistableBundle;
55 import android.os.UserHandle;
56 import android.os.UserManager;
57 import android.telecom.CallAudioState;
58 import android.telecom.ConnectionService;
59 import android.telecom.Log;
60 import android.telecom.InCallService;
61 import android.telecom.PhoneAccount;
62 import android.telecom.TelecomManager;
63 import android.telephony.CarrierConfigManager;
64 import android.telephony.SubscriptionManager;
65 import android.telephony.TelephonyManager;
66 import android.telephony.TelephonyRegistryManager;
67 import android.test.mock.MockContext;
68 
69 import java.io.File;
70 import java.io.IOException;
71 import java.util.ArrayList;
72 import java.util.Arrays;
73 import java.util.HashMap;
74 import java.util.List;
75 import java.util.Locale;
76 import java.util.Map;
77 import java.util.concurrent.Executor;
78 
79 import static org.mockito.ArgumentMatchers.matches;
80 import static org.mockito.Matchers.anyString;
81 import static org.mockito.Mockito.any;
82 import static org.mockito.Mockito.anyInt;
83 import static org.mockito.Mockito.doAnswer;
84 import static org.mockito.Mockito.doReturn;
85 import static org.mockito.Mockito.eq;
86 import static org.mockito.Mockito.mock;
87 import static org.mockito.Mockito.spy;
88 import static org.mockito.Mockito.when;
89 
90 /**
91  * Controls a test {@link Context} as would be provided by the Android framework to an
92  * {@code Activity}, {@code Service} or other system-instantiated component.
93  *
94  * The {@link Context} created by this object is "hollow" but its {@code applicationContext}
95  * property points to an application context implementing all the nontrivial functionality.
96  */
97 public class ComponentContextFixture implements TestFixture<Context> {
98 
99     public class FakeApplicationContext extends MockContext {
100         @Override
getPackageManager()101         public PackageManager getPackageManager() {
102             return mPackageManager;
103         }
104 
105         @Override
getMainExecutor()106         public Executor getMainExecutor() {
107             // TODO: This doesn't actually execute anything as we don't need to do so for now, but
108             //  future users might need it.
109             return mMainExecutor;
110         }
111 
112         @Override
getPackageName()113         public String getPackageName() {
114             return "com.android.server.telecom.tests";
115         }
116 
117         @Override
getPackageResourcePath()118         public String getPackageResourcePath() {
119             return "/tmp/i/dont/know";
120         }
121 
122         @Override
getApplicationContext()123         public Context getApplicationContext() {
124             return mApplicationContextSpy;
125         }
126 
127         @Override
getTheme()128         public Resources.Theme getTheme() {
129             return mResourcesTheme;
130         }
131 
132         @Override
getFilesDir()133         public File getFilesDir() {
134             try {
135                 return File.createTempFile("temp", "temp").getParentFile();
136             } catch (IOException e) {
137                 throw new RuntimeException(e);
138             }
139         }
140 
141         @Override
bindServiceAsUser( Intent serviceIntent, ServiceConnection connection, int flags, UserHandle userHandle)142         public boolean bindServiceAsUser(
143                 Intent serviceIntent,
144                 ServiceConnection connection,
145                 int flags,
146                 UserHandle userHandle) {
147             // TODO: Implement "as user" functionality
148             return bindService(serviceIntent, connection, flags);
149         }
150 
151         @Override
bindService( Intent serviceIntent, ServiceConnection connection, int flags)152         public boolean bindService(
153                 Intent serviceIntent,
154                 ServiceConnection connection,
155                 int flags) {
156             if (mServiceByServiceConnection.containsKey(connection)) {
157                 throw new RuntimeException("ServiceConnection already bound: " + connection);
158             }
159             IInterface service = mServiceByComponentName.get(serviceIntent.getComponent());
160             if (service == null) {
161                 throw new RuntimeException("ServiceConnection not found: "
162                         + serviceIntent.getComponent());
163             }
164             mServiceByServiceConnection.put(connection, service);
165             connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
166             return true;
167         }
168 
169         @Override
unbindService( ServiceConnection connection)170         public void unbindService(
171                 ServiceConnection connection) {
172             IInterface service = mServiceByServiceConnection.remove(connection);
173             if (service == null) {
174                 throw new RuntimeException("ServiceConnection not found: " + connection);
175             }
176             connection.onServiceDisconnected(mComponentNameByService.get(service));
177         }
178 
179         @Override
getSystemService(String name)180         public Object getSystemService(String name) {
181             switch (name) {
182                 case Context.AUDIO_SERVICE:
183                     return mAudioManager;
184                 case Context.TELEPHONY_SERVICE:
185                     return mTelephonyManager;
186                 case Context.APP_OPS_SERVICE:
187                     return mAppOpsManager;
188                 case Context.NOTIFICATION_SERVICE:
189                     return mNotificationManager;
190                 case Context.STATUS_BAR_SERVICE:
191                     return mStatusBarManager;
192                 case Context.USER_SERVICE:
193                     return mUserManager;
194                 case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
195                     return mSubscriptionManager;
196                 case Context.TELECOM_SERVICE:
197                     return mTelecomManager;
198                 case Context.CARRIER_CONFIG_SERVICE:
199                     return mCarrierConfigManager;
200                 case Context.COUNTRY_DETECTOR:
201                     return mCountryDetector;
202                 case Context.ROLE_SERVICE:
203                     return mRoleManager;
204                 case Context.TELEPHONY_REGISTRY_SERVICE:
205                     return mTelephonyRegistryManager;
206                 default:
207                     return null;
208             }
209         }
210 
211         @Override
getSystemServiceName(Class<?> svcClass)212         public String getSystemServiceName(Class<?> svcClass) {
213             if (svcClass == UserManager.class) {
214                 return Context.USER_SERVICE;
215             } else if (svcClass == RoleManager.class) {
216                 return Context.ROLE_SERVICE;
217             } else if (svcClass == AudioManager.class) {
218                 return Context.AUDIO_SERVICE;
219             } else if (svcClass == TelephonyManager.class) {
220                 return Context.TELEPHONY_SERVICE;
221             } else if (svcClass == CarrierConfigManager.class) {
222                 return Context.CARRIER_CONFIG_SERVICE;
223             } else if (svcClass == SubscriptionManager.class) {
224                 return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
225             } else if (svcClass == TelephonyRegistryManager.class) {
226                 return Context.TELEPHONY_REGISTRY_SERVICE;
227             }
228             throw new UnsupportedOperationException();
229         }
230 
231         @Override
getUserId()232         public int getUserId() {
233             return 0;
234         }
235 
236         @Override
getResources()237         public Resources getResources() {
238             return mResources;
239         }
240 
241         @Override
getOpPackageName()242         public String getOpPackageName() {
243             return "com.android.server.telecom.tests";
244         }
245 
246         @Override
getApplicationInfo()247         public ApplicationInfo getApplicationInfo() {
248             return mTestApplicationInfo;
249         }
250 
251         @Override
getContentResolver()252         public ContentResolver getContentResolver() {
253             return new ContentResolver(mApplicationContextSpy) {
254                 @Override
255                 protected IContentProvider acquireProvider(Context c, String name) {
256                     Log.i(this, "acquireProvider %s", name);
257                     return getOrCreateProvider(name);
258                 }
259 
260                 @Override
261                 public boolean releaseProvider(IContentProvider icp) {
262                     return true;
263                 }
264 
265                 @Override
266                 protected IContentProvider acquireUnstableProvider(Context c, String name) {
267                     Log.i(this, "acquireUnstableProvider %s", name);
268                     return getOrCreateProvider(name);
269                 }
270 
271                 private IContentProvider getOrCreateProvider(String name) {
272                     if (!mIContentProviderByUri.containsKey(name)) {
273                         mIContentProviderByUri.put(name, mock(IContentProvider.class));
274                     }
275                     return mIContentProviderByUri.get(name);
276                 }
277 
278                 @Override
279                 public boolean releaseUnstableProvider(IContentProvider icp) {
280                     return false;
281                 }
282 
283                 @Override
284                 public void unstableProviderDied(IContentProvider icp) {
285                 }
286             };
287         }
288 
289         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)290         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
291             // TODO -- this is called by WiredHeadsetManager!!!
292             return null;
293         }
294 
295         @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)296         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
297                 String broadcastPermission, Handler scheduler) {
298             return null;
299         }
300 
301         @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle handle, IntentFilter filter, String broadcastPermission, Handler scheduler)302         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle handle,
303                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
304             return null;
305         }
306 
307         @Override
sendBroadcast(Intent intent)308         public void sendBroadcast(Intent intent) {
309             // TODO -- need to ensure this is captured
310         }
311 
312         @Override
sendBroadcast(Intent intent, String receiverPermission)313         public void sendBroadcast(Intent intent, String receiverPermission) {
314             // TODO -- need to ensure this is captured
315         }
316 
317         @Override
sendBroadcastAsUser(Intent intent, UserHandle userHandle)318         public void sendBroadcastAsUser(Intent intent, UserHandle userHandle) {
319             // TODO -- need to ensure this is captured
320         }
321 
322         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)323         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
324                 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
325                 int initialCode, String initialData, Bundle initialExtras) {
326             // TODO -- need to ensure this is captured
327         }
328 
329         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)330         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
331                 String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
332                 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
333         }
334 
335         @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)336         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
337                 String receiverPermission, int appOp, Bundle options,
338                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
339                 String initialData, Bundle initialExtras) {
340         }
341 
342         @Override
createPackageContextAsUser(String packageName, int flags, UserHandle user)343         public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
344                 throws PackageManager.NameNotFoundException {
345             return this;
346         }
347 
348         @Override
checkCallingOrSelfPermission(String permission)349         public int checkCallingOrSelfPermission(String permission) {
350             return PackageManager.PERMISSION_GRANTED;
351         }
352 
353         @Override
enforceCallingOrSelfPermission(String permission, String message)354         public void enforceCallingOrSelfPermission(String permission, String message) {
355             // Don't bother enforcing anything in mock.
356         }
357 
358         @Override
enforcePermission( String permission, int pid, int uid, String message)359         public void enforcePermission(
360                 String permission, int pid, int uid, String message) {
361             // By default, don't enforce anything in mock.
362         }
363 
364         @Override
startActivityAsUser(Intent intent, UserHandle userHandle)365         public void startActivityAsUser(Intent intent, UserHandle userHandle) {
366             // For capturing
367         }
368     }
369 
370     public class FakeAudioManager extends AudioManager {
371 
372         private boolean mMute = false;
373         private boolean mSpeakerphoneOn = false;
374         private int mAudioStreamValue = 1;
375         private int mMode = AudioManager.MODE_NORMAL;
376         private int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
377 
378         public FakeAudioManager(Context context) {
379             super(context);
380         }
381 
382         @Override
383         public void setMicrophoneMute(boolean value) {
384             mMute = value;
385         }
386 
387         @Override
388         public boolean isMicrophoneMute() {
389             return mMute;
390         }
391 
392         @Override
393         public void setSpeakerphoneOn(boolean value) {
394             mSpeakerphoneOn = value;
395         }
396 
397         @Override
398         public boolean isSpeakerphoneOn() {
399             return mSpeakerphoneOn;
400         }
401 
402         @Override
403         public void setMode(int mode) {
404             mMode = mode;
405         }
406 
407         @Override
408         public int getMode() {
409             return mMode;
410         }
411 
412         @Override
413         public void setRingerModeInternal(int ringerMode) {
414             mRingerMode = ringerMode;
415         }
416 
417         @Override
418         public int getRingerModeInternal() {
419             return mRingerMode;
420         }
421 
422         @Override
423         public void setStreamVolume(int streamTypeUnused, int index, int flagsUnused){
424             mAudioStreamValue = index;
425         }
426 
427         @Override
428         public int getStreamVolume(int streamValueUnused) {
429             return mAudioStreamValue;
430         }
431     }
432 
433     private final Multimap<String, ComponentName> mComponentNamesByAction =
434             ArrayListMultimap.create();
435     private final Map<ComponentName, IInterface> mServiceByComponentName = new HashMap<>();
436     private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName = new HashMap<>();
437     private final Map<IInterface, ComponentName> mComponentNameByService = new HashMap<>();
438     private final Map<ServiceConnection, IInterface> mServiceByServiceConnection = new HashMap<>();
439 
440     private final Context mContext = new MockContext() {
441         @Override
442         public Context getApplicationContext() {
443             return mApplicationContextSpy;
444         }
445 
446         @Override
447         public Resources getResources() {
448             return mResources;
449         }
450     };
451 
452     // The application context is the most important object this class provides to the system
453     // under test.
454     private final Context mApplicationContext = new FakeApplicationContext();
455 
456     // We then create a spy on the application context allowing standard Mockito-style
457     // when(...) logic to be used to add specific little responses where needed.
458 
459     private final Resources.Theme mResourcesTheme = mock(Resources.Theme.class);
460     private final Resources mResources = mock(Resources.class);
461     private final Context mApplicationContextSpy = spy(mApplicationContext);
462     private final PackageManager mPackageManager = mock(PackageManager.class);
463     private final Executor mMainExecutor = mock(Executor.class);
464     private final AudioManager mAudioManager = spy(new FakeAudioManager(mContext));
465     private final TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
466     private final AppOpsManager mAppOpsManager = mock(AppOpsManager.class);
467     private final NotificationManager mNotificationManager = mock(NotificationManager.class);
468     private final UserManager mUserManager = mock(UserManager.class);
469     private final StatusBarManager mStatusBarManager = mock(StatusBarManager.class);
470     private final SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
471     private final CarrierConfigManager mCarrierConfigManager = mock(CarrierConfigManager.class);
472     private final CountryDetector mCountryDetector = mock(CountryDetector.class);
473     private final Map<String, IContentProvider> mIContentProviderByUri = new HashMap<>();
474     private final Configuration mResourceConfiguration = new Configuration();
475     private final ApplicationInfo mTestApplicationInfo = new ApplicationInfo();
476     private final RoleManager mRoleManager = mock(RoleManager.class);
477     private final TelephonyRegistryManager mTelephonyRegistryManager =
478             mock(TelephonyRegistryManager.class);
479 
480     private TelecomManager mTelecomManager = mock(TelecomManager.class);
481 
482     public ComponentContextFixture() {
483         MockitoAnnotations.initMocks(this);
484         when(mResources.getConfiguration()).thenReturn(mResourceConfiguration);
485         when(mResources.getString(anyInt())).thenReturn("");
486         when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
487         mResourceConfiguration.setLocale(Locale.TAIWAN);
488 
489         // TODO: Move into actual tests
490         doReturn(false).when(mAudioManager).isWiredHeadsetOn();
491 
492         doAnswer(new Answer<List<ResolveInfo>>() {
493             @Override
494             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
495                 return doQueryIntentServices(
496                         (Intent) invocation.getArguments()[0],
497                         (Integer) invocation.getArguments()[1]);
498             }
499         }).when(mPackageManager).queryIntentServices((Intent) any(), anyInt());
500 
501         doAnswer(new Answer<List<ResolveInfo>>() {
502             @Override
503             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
504                 return doQueryIntentServices(
505                         (Intent) invocation.getArguments()[0],
506                         (Integer) invocation.getArguments()[1]);
507             }
508         }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());
509 
510         // By default, tests use non-ui apps instead of 3rd party companion apps.
511         when(mPackageManager.checkPermission(
512                 matches(Manifest.permission.CALL_COMPANION_APP), anyString()))
513                 .thenReturn(PackageManager.PERMISSION_DENIED);
514 
515         // Used in CreateConnectionProcessor to rank emergency numbers by viability.
516         // For the test, make them all equal to INVALID so that the preferred PhoneAccount will be
517         // chosen.
518         when(mTelephonyManager.getSubscriptionId(any())).thenReturn(
519                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
520 
521         when(mTelephonyManager.getNetworkOperatorName()).thenReturn("label1");
522         when(mTelephonyManager.getMaxNumberOfSimultaneouslyActiveSims()).thenReturn(1);
523         when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
524         when(mResources.getBoolean(eq(R.bool.grant_location_permission_enabled))).thenReturn(false);
525         doAnswer(new Answer<Void>(){
526             @Override
527             public Void answer(InvocationOnMock invocation) throws Throwable {
528                 return null;
529             }
530         }).when(mAppOpsManager).checkPackage(anyInt(), anyString());
531 
532         when(mNotificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(true);
533 
534         when(mCarrierConfigManager.getConfig()).thenReturn(new PersistableBundle());
535         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(new PersistableBundle());
536 
537         when(mUserManager.getSerialNumberForUser(any(UserHandle.class))).thenReturn(-1L);
538 
539         doReturn(null).when(mApplicationContextSpy).registerReceiver(any(BroadcastReceiver.class),
540                 any(IntentFilter.class));
541 
542         // Make sure we do not hide PII during testing.
543         Log.setTag("TelecomTEST");
544         Log.setIsExtendedLoggingEnabled(true);
545         Log.VERBOSE = true;
546     }
547 
548     @Override
549     public Context getTestDouble() {
550         return mContext;
551     }
552 
553     public void addConnectionService(
554             ComponentName componentName,
555             IConnectionService service)
556             throws Exception {
557         addService(ConnectionService.SERVICE_INTERFACE, componentName, service);
558         ServiceInfo serviceInfo = new ServiceInfo();
559         serviceInfo.permission = android.Manifest.permission.BIND_CONNECTION_SERVICE;
560         serviceInfo.packageName = componentName.getPackageName();
561         serviceInfo.name = componentName.getClassName();
562         mServiceInfoByComponentName.put(componentName, serviceInfo);
563     }
564 
565     public void addInCallService(
566             ComponentName componentName,
567             IInCallService service,
568             int uid)
569             throws Exception {
570         addService(InCallService.SERVICE_INTERFACE, componentName, service);
571         ServiceInfo serviceInfo = new ServiceInfo();
572         serviceInfo.permission = android.Manifest.permission.BIND_INCALL_SERVICE;
573         serviceInfo.packageName = componentName.getPackageName();
574         serviceInfo.applicationInfo = new ApplicationInfo();
575         serviceInfo.applicationInfo.uid = uid;
576         serviceInfo.metaData = new Bundle();
577         serviceInfo.metaData.putBoolean(TelecomManager.METADATA_IN_CALL_SERVICE_UI, false);
578         serviceInfo.name = componentName.getClassName();
579         mServiceInfoByComponentName.put(componentName, serviceInfo);
580 
581         // Used in InCallController to check permissions for CONTROL_INCALL_EXPERIENCE
582         when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[] {
583                 componentName.getPackageName() });
584         when(mPackageManager.checkPermission(eq(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
585                 eq(componentName.getPackageName()))).thenReturn(PackageManager.PERMISSION_GRANTED);
586     }
587 
588     public void putResource(int id, final String value) {
589         when(mResources.getText(eq(id))).thenReturn(value);
590         when(mResources.getString(eq(id))).thenReturn(value);
591         when(mResources.getString(eq(id), any())).thenAnswer(new Answer<String>() {
592             @Override
593             public String answer(InvocationOnMock invocation) {
594                 Object[] args = invocation.getArguments();
595                 return String.format(value, Arrays.copyOfRange(args, 1, args.length));
596             }
597         });
598     }
599 
600     public void putFloatResource(int id, final float value) {
601         when(mResources.getFloat(eq(id))).thenReturn(value);
602     }
603 
604     public void putBooleanResource(int id, boolean value) {
605         when(mResources.getBoolean(eq(id))).thenReturn(value);
606     }
607 
608     public void putStringArrayResource(int id, String[] value) {
609         when(mResources.getStringArray(eq(id))).thenReturn(value);
610     }
611 
612     public void setTelecomManager(TelecomManager telecomManager) {
613         mTelecomManager = telecomManager;
614     }
615 
616     public TelephonyManager getTelephonyManager() {
617         return mTelephonyManager;
618     }
619 
620     private void addService(String action, ComponentName name, IInterface service) {
621         mComponentNamesByAction.put(action, name);
622         mServiceByComponentName.put(name, service);
623         mComponentNameByService.put(service, name);
624     }
625 
626     private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) {
627         List<ResolveInfo> result = new ArrayList<>();
628         for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
629             ResolveInfo resolveInfo = new ResolveInfo();
630             resolveInfo.serviceInfo = mServiceInfoByComponentName.get(componentName);
631             resolveInfo.serviceInfo.metaData = new Bundle();
632             resolveInfo.serviceInfo.metaData.putBoolean(
633                     TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, true);
634             result.add(resolveInfo);
635         }
636         return result;
637     }
638 }
639