ContextFixture.java revision 97ef92758cd180f431f095e6bda6ea9f2676d933
10a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan/*
20a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * Copyright (C) 2015 The Android Open Source Project
30a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan *
40a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * Licensed under the Apache License, Version 2.0 (the "License");
50a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * you may not use this file except in compliance with the License.
60a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * You may obtain a copy of the License at
70a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan *
80a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan *      http://www.apache.org/licenses/LICENSE-2.0
90a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan *
100a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * Unless required by applicable law or agreed to in writing, software
110a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * distributed under the License is distributed on an "AS IS" BASIS,
120a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * See the License for the specific language governing permissions and
140a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * limitations under the License.
150a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan */
160a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
170a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanpackage com.android.internal.telephony;
180a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
190a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport com.google.common.collect.ArrayListMultimap;
200a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport com.google.common.collect.Multimap;
210a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
220a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport org.mockito.MockitoAnnotations;
230a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport org.mockito.invocation.InvocationOnMock;
240a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport org.mockito.stubbing.Answer;
250a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2659d1e823d9aa8bc80ec6fd552fd85384bdfa75cdJack Yuimport android.app.AlarmManager;
270a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.app.AppOpsManager;
280a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.app.NotificationManager;
290a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.BroadcastReceiver;
300a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.ComponentName;
31ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.content.ContentProvider;
320a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.ContentResolver;
33ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.content.ContentValues;
340a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.Context;
350a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.Intent;
360a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.IntentFilter;
370a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.ServiceConnection;
380a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.SharedPreferences;
390a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.pm.PackageManager;
400a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.pm.ResolveInfo;
410a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.pm.ServiceInfo;
420a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.content.res.Resources;
43ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.database.Cursor;
44ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.net.Uri;
45b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yuimport android.net.wifi.WifiManager;
460a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.os.Bundle;
470a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.os.Handler;
480a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.os.IInterface;
490e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yuimport android.os.PersistableBundle;
500a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.os.UserHandle;
510a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.os.UserManager;
520ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yuimport android.provider.Settings;
53ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.provider.Telephony;
540a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.telephony.CarrierConfigManager;
550a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.telephony.SubscriptionManager;
560a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.telephony.TelephonyManager;
57ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.test.mock.MockContentProvider;
58ec334adf4017ca172f44612d01456e671f922344Amit Mahajanimport android.test.mock.MockContentResolver;
590a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.test.mock.MockContext;
600a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport android.util.Log;
610a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
620a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport java.util.ArrayList;
630a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport java.util.Arrays;
640a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport java.util.HashMap;
650a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport java.util.List;
660a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport java.util.Map;
670a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
680a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Matchers.anyBoolean;
690a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Matchers.anyString;
700a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.any;
710a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.anyInt;
720a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.doAnswer;
73b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yuimport static org.mockito.Mockito.doReturn;
740a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.eq;
750a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.mock;
760a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.spy;
770a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanimport static org.mockito.Mockito.when;
780a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
790a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan/**
800a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * Controls a test {@link Context} as would be provided by the Android framework to an
810a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * {@code Activity}, {@code Service} or other system-instantiated component.
820a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan *
830a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * Contains Fake<Component> classes like FakeContext for components that require complex and
840a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * reusable stubbing. Others can be mocked using Mockito functions in tests or constructor/public
850a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan * methods of this class.
860a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan */
870a567c9ed954f295df83c753239646c6f6a04128Amit Mahajanpublic class ContextFixture implements TestFixture<Context> {
880a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private static final String TAG = "ContextFixture";
890a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
90ec334adf4017ca172f44612d01456e671f922344Amit Mahajan    public class FakeContentProvider extends MockContentProvider {
91ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        @Override
92ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        public int delete(Uri uri, String selection, String[] selectionArgs) {
93ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            return 0;
94ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        }
95ec334adf4017ca172f44612d01456e671f922344Amit Mahajan
96ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        @Override
97ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        public Uri insert(Uri uri, ContentValues values) {
98ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            if (uri.compareTo(Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw")) == 0) {
99ec334adf4017ca172f44612d01456e671f922344Amit Mahajan                return Uri.withAppendedPath(uri, "1");
100ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            }
101ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            return null;
102ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        }
103ec334adf4017ca172f44612d01456e671f922344Amit Mahajan
104ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        @Override
105ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
106ec334adf4017ca172f44612d01456e671f922344Amit Mahajan                            String sortOrder) {
107ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            return null;
108ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        }
1090ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yu
1100ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yu        @Override
1110ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yu        public Bundle call(String method, String request, Bundle args) {
1120ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yu            return null;
1130ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yu        }
114ec334adf4017ca172f44612d01456e671f922344Amit Mahajan    }
115ec334adf4017ca172f44612d01456e671f922344Amit Mahajan
1160a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public class FakeContext extends MockContext {
1170a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1180a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public PackageManager getPackageManager() {
1190a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return mPackageManager;
1200a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1210a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1220a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1230a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public boolean bindService(
1240a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                Intent serviceIntent,
1250a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                ServiceConnection connection,
1260a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                int flags) {
1270a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            if (mServiceByServiceConnection.containsKey(connection)) {
1280a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                throw new RuntimeException("ServiceConnection already bound: " + connection);
1290a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
1300a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            IInterface service = mServiceByComponentName.get(serviceIntent.getComponent());
1310a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            if (service == null) {
1320a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                throw new RuntimeException("ServiceConnection not found: "
1330a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                        + serviceIntent.getComponent());
1340a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
1350a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            mServiceByServiceConnection.put(connection, service);
1360a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
1370a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return true;
1380a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1390a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1400a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1410a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public void unbindService(
1420a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                ServiceConnection connection) {
1430a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            IInterface service = mServiceByServiceConnection.remove(connection);
1440a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            if (service == null) {
1450a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                throw new RuntimeException("ServiceConnection not found: " + connection);
1460a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
1470a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            connection.onServiceDisconnected(mComponentNameByService.get(service));
1480a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1490a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1500a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1510a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public Object getSystemService(String name) {
1520a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            switch (name) {
1530a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.TELEPHONY_SERVICE:
1540a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return mTelephonyManager;
1550a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.APP_OPS_SERVICE:
1560a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return mAppOpsManager;
1570a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.NOTIFICATION_SERVICE:
1580a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return mNotificationManager;
1590a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.USER_SERVICE:
1600a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return mUserManager;
1610a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.CARRIER_CONFIG_SERVICE:
1620a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return mCarrierConfigManager;
1630a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.POWER_SERVICE:
1640a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    // PowerManager is a final class so cannot be mocked, return real service
1650a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return TestApplication.getAppContext().getSystemService(name);
1660a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
1670a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return mSubscriptionManager;
168b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu                case Context.WIFI_SERVICE:
169b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu                    return mWifiManager;
17059d1e823d9aa8bc80ec6fd552fd85384bdfa75cdJack Yu                case Context.ALARM_SERVICE:
17159d1e823d9aa8bc80ec6fd552fd85384bdfa75cdJack Yu                    return mAlarmManager;
1720a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                default:
1730a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                    return null;
1740a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
1750a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1760a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1770a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1780a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public int getUserId() {
1790a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return 0;
1800a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1810a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1820a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1830a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public Resources getResources() {
1840a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return mResources;
1850a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1860a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1870a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1880a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public String getOpPackageName() {
1890a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return "com.android.internal.telephony";
1900a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1910a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1920a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1930a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public ContentResolver getContentResolver() {
194ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            return mContentResolver;
1950a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
1960a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
1970a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
1985755ef622fec6f3c592467c685503826862a7536fionaxu        public void unregisterReceiver(BroadcastReceiver receiver) {
1995755ef622fec6f3c592467c685503826862a7536fionaxu        }
2005755ef622fec6f3c592467c685503826862a7536fionaxu
2015755ef622fec6f3c592467c685503826862a7536fionaxu        @Override
2020a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
20397ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            Intent result = null;
20497ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            synchronized (mBroadcastReceiversByAction) {
20597ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                for (int i = 0 ; i < filter.countActions(); i++) {
20697ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                    mBroadcastReceiversByAction.put(filter.getAction(i), receiver);
20797ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                    if (result == null) {
20897ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                        result = mStickyBroadcastByAction.get(filter.getAction(i));
20997ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                    }
21097ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                }
2110a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
21297ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan
21397ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            return result;
2140a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2150a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2160a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
2170a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
2180a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                String broadcastPermission, Handler scheduler) {
21997ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            return registerReceiver(receiver, filter);
22097ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        }
22197ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan
22297ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        @Override
22397ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
22497ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                IntentFilter filter, String broadcastPermission, Handler scheduler) {
22597ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            return registerReceiver(receiver, filter);
2260a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2270a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2280a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
2290a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public void sendBroadcast(Intent intent) {
230ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            logd("sendBroadcast called for " + intent.getAction());
23197ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            synchronized (mBroadcastReceiversByAction) {
23297ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                for (BroadcastReceiver broadcastReceiver :
23397ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                        mBroadcastReceiversByAction.get(intent.getAction())) {
23497ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                    broadcastReceiver.onReceive(mContext, intent);
23597ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                }
236ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            }
2370a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2380a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2390a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
2400a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public void sendBroadcast(Intent intent, String receiverPermission) {
241ceea0fa1248e326663ac56e5ba37b0633f8adaccAmit Mahajan            logd("sendBroadcast called for " + intent.getAction());
242ceea0fa1248e326663ac56e5ba37b0633f8adaccAmit Mahajan            sendBroadcast(intent);
2430a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2440a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2450a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
2460a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
2470a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
2480a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                int initialCode, String initialData, Bundle initialExtras) {
2493c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
2503c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            sendBroadcast(intent);
2513c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            if (resultReceiver != null) {
2523c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan                resultReceiver.onReceive(this, intent);
2533c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            }
2540a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2550a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2560a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
2570a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
2580a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
2590a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
2603c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
2613c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            sendBroadcast(intent);
2623c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            if (resultReceiver != null) {
2633c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan                resultReceiver.onReceive(this, intent);
2643c7c2c2dfecfe11991f707a09ce79863e0ffdaa7Amit Mahajan            }
2650a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2660a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2670a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
268ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
269ec334adf4017ca172f44612d01456e671f922344Amit Mahajan                String receiverPermission, int appOp, Bundle options,
270ec334adf4017ca172f44612d01456e671f922344Amit Mahajan                BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
271ec334adf4017ca172f44612d01456e671f922344Amit Mahajan                String initialData, Bundle initialExtras) {
272ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            logd("sendOrderedBroadcastAsUser called for " + intent.getAction());
273ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            sendBroadcast(intent);
274ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            if (resultReceiver != null) {
275ec334adf4017ca172f44612d01456e671f922344Amit Mahajan                resultReceiver.onReceive(this, intent);
276ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            }
277ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        }
278ec334adf4017ca172f44612d01456e671f922344Amit Mahajan
279ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        @Override
28097ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        public void sendStickyBroadcast(Intent intent) {
28197ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            synchronized (mBroadcastReceiversByAction) {
28297ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                sendBroadcast(intent);
28397ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan                mStickyBroadcastByAction.put(intent.getAction(), intent);
28497ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            }
28597ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        }
28697ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan
28797ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        @Override
28897ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan        public void sendStickyBroadcastAsUser(Intent intent, UserHandle ignored) {
28997ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            sendStickyBroadcast(intent);
290b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu        }
291b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu
292b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu        @Override
2930a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
2940a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                throws PackageManager.NameNotFoundException {
2950a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return this;
2960a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
2970a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
2980a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
2990a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public void enforceCallingOrSelfPermission(String permission, String message) {
3000a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            // Don't bother enforcing anything in mock.
3010a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
3020a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3030a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
3040a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public SharedPreferences getSharedPreferences(String name, int mode) {
3050a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return mSharedPreferences;
3060a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
3070a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3080a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        @Override
3090a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        public String getPackageName() {
3100a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            return "com.android.internal.telephony";
3110a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
3120a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
313ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        public int testMethod() {
314ec334adf4017ca172f44612d01456e671f922344Amit Mahajan            return 0;
315ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        }
316ec334adf4017ca172f44612d01456e671f922344Amit Mahajan
317ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        public boolean testMethod1() {
318b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu            return true;
3190a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
3200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    }
3210a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3220a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Multimap<String, ComponentName> mComponentNamesByAction =
3230a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            ArrayListMultimap.create();
3240a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Map<ComponentName, IInterface> mServiceByComponentName =
3250a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            new HashMap<ComponentName, IInterface>();
3260a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
3270a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            new HashMap<ComponentName, ServiceInfo>();
3280a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Map<IInterface, ComponentName> mComponentNameByService =
3290a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            new HashMap<IInterface, ComponentName>();
3300a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Map<ServiceConnection, IInterface> mServiceByServiceConnection =
3310a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            new HashMap<ServiceConnection, IInterface>();
3320a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Multimap<String, BroadcastReceiver> mBroadcastReceiversByAction =
3330a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            ArrayListMultimap.create();
33497ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan    private final HashMap<String, Intent> mStickyBroadcastByAction =
33597ef92758cd180f431f095e6bda6ea9f2676d933Amit Mahajan            new HashMap<String, Intent>();
3360a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3370a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    // The application context is the most important object this class provides to the system
3380a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    // under test.
3390a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Context mContext = spy(new FakeContext());
3400a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3410a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    // We then create a spy on the application context allowing standard Mockito-style
3420a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    // when(...) logic to be used to add specific little responses where needed.
3430a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3440a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final Resources mResources = mock(Resources.class);
3450a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final PackageManager mPackageManager = mock(PackageManager.class);
3460a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
3470a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final AppOpsManager mAppOpsManager = mock(AppOpsManager.class);
3480a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final NotificationManager mNotificationManager = mock(NotificationManager.class);
3490a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final UserManager mUserManager = mock(UserManager.class);
3500a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final CarrierConfigManager mCarrierConfigManager = mock(CarrierConfigManager.class);
3510a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
35259d1e823d9aa8bc80ec6fd552fd85384bdfa75cdJack Yu    private final AlarmManager mAlarmManager = mock(AlarmManager.class);
353b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu    private final WifiManager mWifiManager = mock(WifiManager.class);
354ec334adf4017ca172f44612d01456e671f922344Amit Mahajan    private final ContentProvider mContentProvider = spy(new FakeContentProvider());
3550a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private final SharedPreferences mSharedPreferences = mock(SharedPreferences.class);
356ec334adf4017ca172f44612d01456e671f922344Amit Mahajan    private final MockContentResolver mContentResolver = new MockContentResolver();
3570e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    private final PersistableBundle mBundle = new PersistableBundle();
3580a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3590a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public ContextFixture() {
3600a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        MockitoAnnotations.initMocks(this);
3610a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3620a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        doAnswer(new Answer<List<ResolveInfo>>() {
3630a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            @Override
3640a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
3650a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                return doQueryIntentServices(
3660a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                        (Intent) invocation.getArguments()[0],
3670a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                        (Integer) invocation.getArguments()[1]);
3680a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
3690a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }).when(mPackageManager).queryIntentServices((Intent) any(), anyInt());
3700a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3710a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        doAnswer(new Answer<List<ResolveInfo>>() {
3720a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            @Override
3730a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
3740a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                return doQueryIntentServices(
3750a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                        (Intent) invocation.getArguments()[0],
3760a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                        (Integer) invocation.getArguments()[1]);
3770a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
3780a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());
3790a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3800a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        // return default value unless overridden by test
3810a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        doAnswer(new Answer() {
3820a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            @Override
3830a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            public Object answer(InvocationOnMock invocation) throws Throwable {
3840a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                Object[] args = invocation.getArguments();
3850a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                return args[1];
3860a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
3870a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }).when(mSharedPreferences).getBoolean(anyString(), anyBoolean());
388ec334adf4017ca172f44612d01456e671f922344Amit Mahajan
3890e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
3900e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
391ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        mContentResolver.addProvider(Telephony.Sms.CONTENT_URI.getAuthority(), mContentProvider);
3920ffd5632e025ebbe0d3eedfda942f1fb07342a43Jack Yu        mContentResolver.addProvider(Settings.System.CONTENT_URI.getAuthority(), mContentProvider);
3930a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
3940a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
3950a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    @Override
3960a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public Context getTestDouble() {
3970a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        return mContext;
3980a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
3990a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
4000a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public void putResource(int id, final String value) {
4010a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        when(mResources.getText(eq(id))).thenReturn(value);
4020a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        when(mResources.getString(eq(id))).thenReturn(value);
4030a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        when(mResources.getString(eq(id), any())).thenAnswer(new Answer<String>() {
4040a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            @Override
4050a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            public String answer(InvocationOnMock invocation) {
4060a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                Object[] args = invocation.getArguments();
4070a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan                return String.format(value, Arrays.copyOfRange(args, 1, args.length));
4080a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            }
4090a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        });
4100a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
4110a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
4120a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    public void putBooleanResource(int id, boolean value) {
4130a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        when(mResources.getBoolean(eq(id))).thenReturn(value);
4140a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
4150a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
416b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu    public void putStringArrayResource(int id, String[] values) {
417b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu        doReturn(values).when(mResources).getStringArray(eq(id));
418b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu    }
419b6514b21f3d8ed47a088b741a18fe0b1de2308eaJack Yu
4200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public PersistableBundle getCarrierConfigBundle() {
4210e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        return mBundle;
4220e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    }
4230e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
4240a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private void addService(String action, ComponentName name, IInterface service) {
4250a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        mComponentNamesByAction.put(action, name);
4260a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        mServiceByComponentName.put(name, service);
4270a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        mComponentNameByService.put(service, name);
4280a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
4290a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
4300a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) {
4310a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        List<ResolveInfo> result = new ArrayList<ResolveInfo>();
4320a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
4330a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            ResolveInfo resolveInfo = new ResolveInfo();
4340a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            resolveInfo.serviceInfo = mServiceInfoByComponentName.get(componentName);
4350a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan            result.add(resolveInfo);
4360a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        }
4370a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan        return result;
4380a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
4390a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan
440ec334adf4017ca172f44612d01456e671f922344Amit Mahajan    private static void logd(String s) {
441ec334adf4017ca172f44612d01456e671f922344Amit Mahajan        Log.d(TAG, s);
4420a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan    }
4430a567c9ed954f295df83c753239646c6f6a04128Amit Mahajan}
444