Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2016 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.internal.telephony;
     18 
     19 import static org.mockito.Mockito.any;
     20 import static org.mockito.Mockito.anyInt;
     21 import static org.mockito.Mockito.doAnswer;
     22 import static org.mockito.Mockito.doReturn;
     23 import static org.mockito.Mockito.eq;
     24 import static org.mockito.Mockito.mock;
     25 import static org.mockito.Mockito.spy;
     26 import static org.mockito.Mockito.when;
     27 
     28 import android.app.AlarmManager;
     29 import android.app.AppOpsManager;
     30 import android.app.DownloadManager;
     31 import android.app.NotificationManager;
     32 import android.app.usage.UsageStatsManager;
     33 import android.content.BroadcastReceiver;
     34 import android.content.ComponentName;
     35 import android.content.ContentProvider;
     36 import android.content.ContentResolver;
     37 import android.content.ContentValues;
     38 import android.content.Context;
     39 import android.content.Intent;
     40 import android.content.IntentFilter;
     41 import android.content.ServiceConnection;
     42 import android.content.SharedPreferences;
     43 import android.content.pm.PackageManager;
     44 import android.content.pm.ResolveInfo;
     45 import android.content.pm.ServiceInfo;
     46 import android.content.res.AssetManager;
     47 import android.content.res.Configuration;
     48 import android.content.res.Resources;
     49 import android.database.Cursor;
     50 import android.database.MatrixCursor;
     51 import android.net.ConnectivityManager;
     52 import android.net.Uri;
     53 import android.net.wifi.WifiManager;
     54 import android.os.BatteryManager;
     55 import android.os.Bundle;
     56 import android.os.Handler;
     57 import android.os.IInterface;
     58 import android.os.PersistableBundle;
     59 import android.os.UserHandle;
     60 import android.os.UserManager;
     61 import android.preference.PreferenceManager;
     62 import android.provider.Settings;
     63 import android.provider.Telephony.ServiceStateTable;
     64 import android.telecom.TelecomManager;
     65 import android.telephony.CarrierConfigManager;
     66 import android.telephony.SubscriptionManager;
     67 import android.telephony.TelephonyManager;
     68 import android.telephony.euicc.EuiccManager;
     69 import android.test.mock.MockContentProvider;
     70 import android.test.mock.MockContentResolver;
     71 import android.test.mock.MockContext;
     72 import android.util.Log;
     73 
     74 import com.google.common.collect.ArrayListMultimap;
     75 import com.google.common.collect.Multimap;
     76 
     77 import org.mockito.MockitoAnnotations;
     78 import org.mockito.invocation.InvocationOnMock;
     79 import org.mockito.stubbing.Answer;
     80 
     81 import java.util.ArrayList;
     82 import java.util.Arrays;
     83 import java.util.Collection;
     84 import java.util.HashMap;
     85 import java.util.HashSet;
     86 import java.util.List;
     87 import java.util.Locale;
     88 import java.util.Map;
     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  * Contains Fake<Component> classes like FakeContext for components that require complex and
     95  * reusable stubbing. Others can be mocked using Mockito functions in tests or constructor/public
     96  * methods of this class.
     97  */
     98 public class ContextFixture implements TestFixture<Context> {
     99     private static final String TAG = "ContextFixture";
    100     public static final String PERMISSION_ENABLE_ALL = "android.permission.STUB_PERMISSION";
    101 
    102     public class FakeContentProvider extends MockContentProvider {
    103         private String[] mColumns = {"name", "value"};
    104         private HashMap<String, String> mKeyValuePairs = new HashMap<String, String>();
    105         private int mNumKeyValuePairs = 0;
    106 
    107         @Override
    108         public int delete(Uri uri, String selection, String[] selectionArgs) {
    109             return 0;
    110         }
    111 
    112         @Override
    113         public Uri insert(Uri uri, ContentValues values) {
    114             Uri newUri = null;
    115             if (values != null) {
    116                 mKeyValuePairs.put(values.getAsString("name"), values.getAsString("value"));
    117                 mNumKeyValuePairs++;
    118                 newUri = Uri.withAppendedPath(uri, "" + mNumKeyValuePairs);
    119             }
    120             logd("insert called, new mNumKeyValuePairs: " + mNumKeyValuePairs + " uri: " + uri +
    121                     " newUri: " + newUri);
    122             return newUri;
    123         }
    124 
    125         @Override
    126         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
    127                             String sortOrder) {
    128             //assuming query will always be of the form 'name = ?'
    129             logd("query called, mNumKeyValuePairs: " + mNumKeyValuePairs + " uri: " + uri);
    130             if (mKeyValuePairs.containsKey(selectionArgs[0])) {
    131                 MatrixCursor cursor = new MatrixCursor(projection);
    132                 cursor.addRow(new String[]{mKeyValuePairs.get(selectionArgs[0])});
    133                 return cursor;
    134             }
    135             return null;
    136         }
    137 
    138         @Override
    139         public Bundle call(String method, String request, Bundle args) {
    140             logd("call called, mNumKeyValuePairs: " + mNumKeyValuePairs + " method: " + method +
    141                     " request: " + request);
    142             switch(method) {
    143                 case Settings.CALL_METHOD_GET_GLOBAL:
    144                 case Settings.CALL_METHOD_GET_SECURE:
    145                 case Settings.CALL_METHOD_GET_SYSTEM:
    146                     if (mKeyValuePairs.containsKey(request)) {
    147                         Bundle b = new Bundle(1);
    148                         b.putCharSequence("value", mKeyValuePairs.get(request));
    149                         logd("returning value pair: " + mKeyValuePairs.get(request) + " for " +
    150                                 request);
    151                         return b;
    152                     }
    153                     break;
    154                 case Settings.CALL_METHOD_PUT_GLOBAL:
    155                 case Settings.CALL_METHOD_PUT_SECURE:
    156                 case Settings.CALL_METHOD_PUT_SYSTEM:
    157                     logd("adding key-value pair: " + request + "-" + (String)args.get("value"));
    158                     mKeyValuePairs.put(request, (String)args.get("value"));
    159                     mNumKeyValuePairs++;
    160                     break;
    161             }
    162             return null;
    163         }
    164     }
    165 
    166     private final HashMap<String, Object> mSystemServices = new HashMap<String, Object>();
    167 
    168     public void setSystemService(String name, Object service) {
    169         synchronized (mSystemServices) {
    170             mSystemServices.put(name, service);
    171         }
    172     }
    173 
    174     public class FakeContext extends MockContext {
    175         @Override
    176         public PackageManager getPackageManager() {
    177             return mPackageManager;
    178         }
    179 
    180         @Override
    181         public boolean bindService(
    182                 Intent serviceIntent,
    183                 ServiceConnection connection,
    184                 int flags) {
    185             if (mServiceByServiceConnection.containsKey(connection)) {
    186                 throw new RuntimeException("ServiceConnection already bound: " + connection);
    187             }
    188             IInterface service = mServiceByComponentName.get(serviceIntent.getComponent());
    189             if (service == null) {
    190                 service = mServiceByPackageName.get(serviceIntent.getPackage());
    191             }
    192             if (service == null) {
    193                 throw new RuntimeException(
    194                         String.format("ServiceConnection not found for component: %s, package: %s",
    195                                 serviceIntent.getComponent(), serviceIntent.getPackage()));
    196             }
    197             mServiceByServiceConnection.put(connection, service);
    198             connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
    199             return true;
    200         }
    201 
    202         @Override
    203         public void unbindService(
    204                 ServiceConnection connection) {
    205             IInterface service = mServiceByServiceConnection.remove(connection);
    206             if (service == null) {
    207                 throw new RuntimeException("ServiceConnection not found: " + connection);
    208             }
    209             connection.onServiceDisconnected(mComponentNameByService.get(service));
    210         }
    211 
    212         @Override
    213         public Object getSystemService(String name) {
    214             synchronized (mSystemServices) {
    215                 Object service = mSystemServices.get(name);
    216                 if (service != null) return service;
    217             }
    218             switch (name) {
    219                 case Context.TELEPHONY_SERVICE:
    220                     return mTelephonyManager;
    221                 case Context.APP_OPS_SERVICE:
    222                     return mAppOpsManager;
    223                 case Context.NOTIFICATION_SERVICE:
    224                     return mNotificationManager;
    225                 case Context.USER_SERVICE:
    226                     return mUserManager;
    227                 case Context.CARRIER_CONFIG_SERVICE:
    228                     return mCarrierConfigManager;
    229                 case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
    230                     return mSubscriptionManager;
    231                 case Context.WIFI_SERVICE:
    232                     return mWifiManager;
    233                 case Context.ALARM_SERVICE:
    234                     return mAlarmManager;
    235                 case Context.CONNECTIVITY_SERVICE:
    236                     return mConnectivityManager;
    237                 case Context.USAGE_STATS_SERVICE:
    238                     return mUsageStatManager;
    239                 case Context.BATTERY_SERVICE:
    240                     return mBatteryManager;
    241                 case Context.EUICC_SERVICE:
    242                     return mEuiccManager;
    243                 case Context.TELECOM_SERVICE:
    244                     return mTelecomManager;
    245                 case Context.DOWNLOAD_SERVICE:
    246                     return mDownloadManager;
    247                 case Context.DISPLAY_SERVICE:
    248                 case Context.POWER_SERVICE:
    249                     // PowerManager and DisplayManager are final classes so cannot be mocked,
    250                     // return real services.
    251                     return TestApplication.getAppContext().getSystemService(name);
    252                 default:
    253                     return null;
    254             }
    255         }
    256 
    257         @Override
    258         public String getSystemServiceName(Class<?> serviceClass) {
    259             if (serviceClass == SubscriptionManager.class) {
    260                 return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
    261             }
    262             return super.getSystemServiceName(serviceClass);
    263         }
    264 
    265         @Override
    266         public int getUserId() {
    267             return 0;
    268         }
    269 
    270         @Override
    271         public AssetManager getAssets() {
    272             return mAssetManager;
    273         }
    274 
    275         @Override
    276         public Resources getResources() {
    277             return mResources;
    278         }
    279 
    280         @Override
    281         public String getOpPackageName() {
    282             return "com.android.internal.telephony";
    283         }
    284 
    285         @Override
    286         public ContentResolver getContentResolver() {
    287             return mContentResolver;
    288         }
    289 
    290         @Override
    291         public Resources.Theme getTheme() {
    292             return null;
    293         }
    294 
    295         @Override
    296         public void unregisterReceiver(BroadcastReceiver receiver) {
    297         }
    298 
    299         @Override
    300         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    301             return registerReceiver(receiver, filter, null, null);
    302         }
    303 
    304         @Override
    305         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
    306                 String broadcastPermission, Handler scheduler) {
    307             return registerReceiverAsUser(receiver, null, filter, broadcastPermission, scheduler);
    308         }
    309 
    310         @Override
    311         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
    312                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
    313             Intent result = null;
    314             synchronized (mBroadcastReceiversByAction) {
    315                 for (int i = 0 ; i < filter.countActions() ; i++) {
    316                     mBroadcastReceiversByAction.put(filter.getAction(i), receiver);
    317                     if (result == null) {
    318                         result = mStickyBroadcastByAction.get(filter.getAction(i));
    319                     }
    320                 }
    321             }
    322 
    323             return result;
    324         }
    325 
    326         @Override
    327         public void sendBroadcast(Intent intent) {
    328             logd("sendBroadcast called for " + intent.getAction());
    329             synchronized (mBroadcastReceiversByAction) {
    330                 for (BroadcastReceiver broadcastReceiver :
    331                         mBroadcastReceiversByAction.get(intent.getAction())) {
    332                     broadcastReceiver.onReceive(mContext, intent);
    333                 }
    334             }
    335         }
    336 
    337         @Override
    338         public void sendBroadcast(Intent intent, String receiverPermission) {
    339             logd("sendBroadcast called for " + intent.getAction());
    340             sendBroadcast(intent);
    341         }
    342 
    343         @Override
    344         public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
    345             logd("sendOrderedBroadcast called for " + intent.getAction());
    346             sendBroadcast(intent);
    347         }
    348 
    349         @Override
    350         public void sendOrderedBroadcast(Intent intent, String receiverPermission,
    351                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    352                 String initialData, Bundle initialExtras) {
    353             sendOrderedBroadcast(intent, receiverPermission);
    354             if (resultReceiver != null) {
    355                 synchronized (mOrderedBroadcastReceivers) {
    356                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
    357                 }
    358             }
    359         }
    360 
    361         @Override
    362         public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
    363                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    364                 String initialData, Bundle initialExtras) {
    365             sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
    366                     initialCode, initialData, initialExtras);
    367         }
    368 
    369         @Override
    370         public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
    371                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    372                 String initialData, Bundle initialExtras) {
    373             sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
    374                     initialCode, initialData, initialExtras);
    375         }
    376 
    377         @Override
    378         public void sendBroadcastAsUser(Intent intent, UserHandle user) {
    379             sendBroadcast(intent);
    380         }
    381 
    382         @Override
    383         public void sendBroadcastAsUser(Intent intent, UserHandle user,
    384                                         String receiverPermission) {
    385             sendBroadcast(intent);
    386         }
    387 
    388         @Override
    389         public void sendBroadcastAsUser(Intent intent, UserHandle user,
    390                                         String receiverPermission, int appOp) {
    391             sendBroadcast(intent);
    392         }
    393 
    394         @Override
    395         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    396                 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
    397                 int initialCode, String initialData, Bundle initialExtras) {
    398             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
    399             sendBroadcast(intent);
    400             if (resultReceiver != null) {
    401                 synchronized (mOrderedBroadcastReceivers) {
    402                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
    403                 }
    404             }
    405         }
    406 
    407         @Override
    408         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    409                 String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
    410                 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    411             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
    412             sendBroadcast(intent);
    413             if (resultReceiver != null) {
    414                 synchronized (mOrderedBroadcastReceivers) {
    415                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
    416                 }
    417             }
    418         }
    419 
    420         @Override
    421         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    422                 String receiverPermission, int appOp, Bundle options,
    423                 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    424                 String initialData, Bundle initialExtras) {
    425             logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
    426             sendBroadcast(intent);
    427             if (resultReceiver != null) {
    428                 synchronized (mOrderedBroadcastReceivers) {
    429                     mOrderedBroadcastReceivers.put(intent, resultReceiver);
    430                 }
    431             }
    432         }
    433 
    434         @Override
    435         public void sendStickyBroadcast(Intent intent) {
    436             logd("sendStickyBroadcast called for " + intent.getAction());
    437             synchronized (mBroadcastReceiversByAction) {
    438                 sendBroadcast(intent);
    439                 mStickyBroadcastByAction.put(intent.getAction(), intent);
    440             }
    441         }
    442 
    443         @Override
    444         public void sendStickyBroadcastAsUser(Intent intent, UserHandle ignored) {
    445             logd("sendStickyBroadcastAsUser called for " + intent.getAction());
    446             sendStickyBroadcast(intent);
    447         }
    448 
    449         @Override
    450         public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
    451                 throws PackageManager.NameNotFoundException {
    452             return this;
    453         }
    454 
    455         @Override
    456         public void enforceCallingOrSelfPermission(String permission, String message) {
    457             if (mPermissionTable.contains(permission)
    458                     || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
    459                 return;
    460             }
    461             logd("requested permission: " + permission + " got denied");
    462             throw new SecurityException(permission + " denied: " + message);
    463         }
    464 
    465         @Override
    466         public void enforcePermission(String permission, int pid, int uid, String message) {
    467             enforceCallingOrSelfPermission(permission, message);
    468         }
    469 
    470         @Override
    471         public int checkCallingOrSelfPermission(String permission) {
    472             if (mPermissionTable.contains(permission)
    473                     || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
    474                 logd("checkCallingOrSelfPermission: " + permission + " return GRANTED");
    475                 return PackageManager.PERMISSION_GRANTED;
    476             } else {
    477                 logd("checkCallingOrSelfPermission: " + permission + " return DENIED");
    478                 return PackageManager.PERMISSION_DENIED;
    479             }
    480         }
    481 
    482         @Override
    483         public int checkPermission(String permission, int pid, int uid) {
    484             return checkCallingOrSelfPermission(permission);
    485         }
    486 
    487         @Override
    488         public SharedPreferences getSharedPreferences(String name, int mode) {
    489             return mSharedPreferences;
    490         }
    491 
    492         @Override
    493         public String getPackageName() {
    494             return "com.android.internal.telephony";
    495         }
    496     }
    497 
    498     private final Multimap<String, ComponentName> mComponentNamesByAction =
    499             ArrayListMultimap.create();
    500     private final Map<ComponentName, IInterface> mServiceByComponentName =
    501             new HashMap<ComponentName, IInterface>();
    502     private final Map<String, IInterface> mServiceByPackageName =
    503             new HashMap<String, IInterface>();
    504     private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
    505             new HashMap<ComponentName, ServiceInfo>();
    506     private final Map<ComponentName, IntentFilter> mIntentFilterByComponentName = new HashMap<>();
    507     private final Map<IInterface, ComponentName> mComponentNameByService =
    508             new HashMap<IInterface, ComponentName>();
    509     private final Map<ServiceConnection, IInterface> mServiceByServiceConnection =
    510             new HashMap<ServiceConnection, IInterface>();
    511     private final Multimap<String, BroadcastReceiver> mBroadcastReceiversByAction =
    512             ArrayListMultimap.create();
    513     private final HashMap<String, Intent> mStickyBroadcastByAction =
    514             new HashMap<String, Intent>();
    515     private final Multimap<Intent, BroadcastReceiver> mOrderedBroadcastReceivers =
    516             ArrayListMultimap.create();
    517     private final HashSet<String> mPermissionTable = new HashSet<>();
    518 
    519 
    520 
    521     // The application context is the most important object this class provides to the system
    522     // under test.
    523     private final Context mContext = spy(new FakeContext());
    524 
    525     // We then create a spy on the application context allowing standard Mockito-style
    526     // when(...) logic to be used to add specific little responses where needed.
    527 
    528     private final Resources mResources = mock(Resources.class);
    529     private final PackageManager mPackageManager = mock(PackageManager.class);
    530     private final TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
    531     private final DownloadManager mDownloadManager = mock(DownloadManager.class);
    532     private final AppOpsManager mAppOpsManager = mock(AppOpsManager.class);
    533     private final NotificationManager mNotificationManager = mock(NotificationManager.class);
    534     private final UserManager mUserManager = mock(UserManager.class);
    535     private final CarrierConfigManager mCarrierConfigManager = mock(CarrierConfigManager.class);
    536     private final SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
    537     private final AlarmManager mAlarmManager = mock(AlarmManager.class);
    538     private final AssetManager mAssetManager = new AssetManager();
    539     private final ConnectivityManager mConnectivityManager = mock(ConnectivityManager.class);
    540     private final UsageStatsManager mUsageStatManager = null;
    541     private final WifiManager mWifiManager = mock(WifiManager.class);
    542     private final BatteryManager mBatteryManager = mock(BatteryManager.class);
    543     private final EuiccManager mEuiccManager = mock(EuiccManager.class);
    544     private final TelecomManager mTelecomManager = mock(TelecomManager.class);
    545 
    546     private final ContentProvider mContentProvider = spy(new FakeContentProvider());
    547 
    548     private final Configuration mConfiguration = new Configuration();
    549     private final SharedPreferences mSharedPreferences = PreferenceManager
    550             .getDefaultSharedPreferences(TestApplication.getAppContext());
    551     private final MockContentResolver mContentResolver = new MockContentResolver();
    552     private final PersistableBundle mBundle = new PersistableBundle();
    553 
    554     public ContextFixture() {
    555         MockitoAnnotations.initMocks(this);
    556 
    557         doAnswer(new Answer<List<ResolveInfo>>() {
    558             @Override
    559             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
    560                 return doQueryIntentServices(
    561                         (Intent) invocation.getArguments()[0],
    562                         (Integer) invocation.getArguments()[1]);
    563             }
    564         }).when(mPackageManager).queryIntentServices((Intent) any(), anyInt());
    565 
    566         doAnswer(new Answer<List<ResolveInfo>>() {
    567             @Override
    568             public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
    569                 return doQueryIntentServices(
    570                         (Intent) invocation.getArguments()[0],
    571                         (Integer) invocation.getArguments()[1]);
    572             }
    573         }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());
    574 
    575         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
    576         //doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt());
    577         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
    578 
    579         mConfiguration.locale = Locale.US;
    580         doReturn(mConfiguration).when(mResources).getConfiguration();
    581 
    582         mContentResolver.addProvider(Settings.AUTHORITY, mContentProvider);
    583         // Settings caches the provider after first get/set call, this is needed to make sure
    584         // Settings is using mContentProvider as the cached provider across all tests.
    585         Settings.Global.getInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
    586         mContentResolver.addProvider(ServiceStateTable.AUTHORITY, mContentProvider);
    587         mPermissionTable.add(PERMISSION_ENABLE_ALL);
    588     }
    589 
    590     @Override
    591     public Context getTestDouble() {
    592         return mContext;
    593     }
    594 
    595     public void putResource(int id, final String value) {
    596         when(mResources.getText(eq(id))).thenReturn(value);
    597         when(mResources.getString(eq(id))).thenReturn(value);
    598         when(mResources.getString(eq(id), any())).thenAnswer(new Answer<String>() {
    599             @Override
    600             public String answer(InvocationOnMock invocation) {
    601                 Object[] args = invocation.getArguments();
    602                 return String.format(value, Arrays.copyOfRange(args, 1, args.length));
    603             }
    604         });
    605     }
    606 
    607     public void putBooleanResource(int id, boolean value) {
    608         when(mResources.getBoolean(eq(id))).thenReturn(value);
    609     }
    610 
    611     public void putStringArrayResource(int id, String[] values) {
    612         doReturn(values).when(mResources).getStringArray(eq(id));
    613     }
    614 
    615     public void putIntArrayResource(int id, int[] values) {
    616         doReturn(values).when(mResources).getIntArray(eq(id));
    617     }
    618 
    619     public void putIntResource(int id, int value) {
    620         doReturn(value).when(mResources).getInteger(eq(id));
    621     }
    622 
    623     public PersistableBundle getCarrierConfigBundle() {
    624         return mBundle;
    625     }
    626 
    627     public void addService(String action, ComponentName name, String packageName,
    628                            IInterface service, ServiceInfo serviceInfo) {
    629         addService(action, name, packageName, service, serviceInfo, null /* filter */);
    630     }
    631 
    632     public void addService(String action, ComponentName name, String packageName,
    633             IInterface service, ServiceInfo serviceInfo, IntentFilter filter) {
    634         mComponentNamesByAction.put(action, name);
    635         mServiceInfoByComponentName.put(name, serviceInfo);
    636         mIntentFilterByComponentName.put(name, filter);
    637         mServiceByComponentName.put(name, service);
    638         mServiceByPackageName.put(packageName, service);
    639         mComponentNameByService.put(service, name);
    640     }
    641 
    642     private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) {
    643         List<ResolveInfo> result = new ArrayList<ResolveInfo>();
    644         for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
    645             ResolveInfo resolveInfo = new ResolveInfo();
    646             resolveInfo.serviceInfo = mServiceInfoByComponentName.get(componentName);
    647             resolveInfo.filter = mIntentFilterByComponentName.get(componentName);
    648             result.add(resolveInfo);
    649         }
    650         return result;
    651     }
    652 
    653     public void sendBroadcastToOrderedBroadcastReceivers() {
    654         synchronized (mOrderedBroadcastReceivers) {
    655             // having a map separate from mOrderedBroadcastReceivers is helpful here as onReceive()
    656             // call within the loop may lead to sendOrderedBroadcast() which can add to
    657             // mOrderedBroadcastReceivers
    658             Collection<Map.Entry<Intent, BroadcastReceiver>> map =
    659                     mOrderedBroadcastReceivers.entries();
    660             for (Map.Entry<Intent, BroadcastReceiver> entry : map) {
    661                 entry.getValue().onReceive(mContext, entry.getKey());
    662                 mOrderedBroadcastReceivers.remove(entry.getKey(), entry.getValue());
    663             }
    664         }
    665     }
    666 
    667     public void addCallingOrSelfPermission(String permission) {
    668         synchronized (mPermissionTable) {
    669             if (mPermissionTable != null && permission != null) {
    670                 mPermissionTable.remove(PERMISSION_ENABLE_ALL);
    671                 mPermissionTable.add(permission);
    672             }
    673         }
    674     }
    675 
    676     public void removeCallingOrSelfPermission(String permission) {
    677         synchronized (mPermissionTable) {
    678             if (mPermissionTable != null && permission != null) {
    679                 mPermissionTable.remove(permission);
    680             }
    681         }
    682     }
    683 
    684     private static void logd(String s) {
    685         Log.d(TAG, s);
    686     }
    687 }
    688