Merge changes from topic "TelephonySatelliteNotifications" into main
* changes:
Fix NPE by initializing notification manager
Added flag check in SatelliteAccessController
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 4fb96a2..188baaa 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -439,7 +439,10 @@
mUserManager.getSerialNumbersOfUsers(/* excludeDying= */ true);
List<UserHandle> users = new ArrayList<>(serialNumbersOfUsers.length);
for (long serialNumber : serialNumbersOfUsers) {
- users.add(mUserManager.getUserForSerialNumber(serialNumber));
+ UserHandle userHandle = mUserManager.getUserForSerialNumber(serialNumber);
+ if (userHandle != null) {
+ users.add(userHandle);
+ }
}
return users;
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 440c39d..47c00af 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -13227,14 +13227,17 @@
return;
}
if (isAllowed) {
- if (mFeatureFlags.carrierRoamingNbIotNtn()
- && !mSatelliteAccessController.getSatelliteDisallowedReasons()
- .isEmpty()) {
- result.accept(SATELLITE_RESULT_ACCESS_BARRED);
- } else {
- mSatelliteController.requestSatelliteEnabled(
+ ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ Log.d(LOG_TAG, "updateSystemSelectionChannels resultCode="
+ + resultCode);
+ mSatelliteController.requestSatelliteEnabled(
enableSatellite, enableDemoMode, isEmergency, callback);
- }
+ }
+ };
+ mSatelliteAccessController.updateSystemSelectionChannels(
+ resultReceiver);
} else {
result.accept(SATELLITE_RESULT_ACCESS_BARRED);
}
@@ -13767,6 +13770,25 @@
}
/**
+ * Request to get the currently selected satellite subscription id.
+ *
+ * @param result The result receiver that returns the currently selected satellite subscription
+ * id if the request is successful or an error code if the request failed.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void requestSelectedNbIotSatelliteSubscriptionId(@NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission("requestSelectedNbIotSatelliteSubscriptionId");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.requestSelectedNbIotSatelliteSubscriptionId(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* Inform whether the device is aligned with the satellite in both real and demo mode.
*
* @param isAligned {@code true} Device is aligned with the satellite.
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index ef169de..ef2e80f 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -59,6 +59,7 @@
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
@@ -71,10 +72,12 @@
import android.provider.DeviceConfig;
import android.telecom.TelecomManager;
import android.telephony.AnomalyReporter;
+import android.telephony.CarrierConfigManager;
import android.telephony.DropBoxManagerLoggerBackend;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PersistentLogger;
import android.telephony.Rlog;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
@@ -83,7 +86,9 @@
import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
+import android.telephony.satellite.SystemSelectionSpecifier;
import android.text.TextUtils;
+import android.util.IntArray;
import android.util.Pair;
import com.android.internal.R;
@@ -100,6 +105,7 @@
import com.android.internal.telephony.satellite.metrics.AccessControllerMetricsStats;
import com.android.internal.telephony.satellite.metrics.ConfigUpdaterMetricsStats;
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.phone.PhoneGlobals;
@@ -162,6 +168,8 @@
protected static final int EVENT_CONFIG_DATA_UPDATED = 4;
protected static final int EVENT_COUNTRY_CODE_CHANGED = 5;
protected static final int EVENT_LOCATION_SETTINGS_ENABLED = 6;
+ protected static final int CMD_UPDATE_SYSTEM_SELECTION_CHANNELS = 7;
+ protected static final int EVENT_LOCATION_SETTINGS_DISABLED = 8;
public static final int DEFAULT_REGIONAL_SATELLITE_CONFIG_ID = 0;
public static final int UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID = -1;
@@ -246,11 +254,16 @@
@NonNull
private final ISatelliteProvisionStateCallback mInternalSatelliteProvisionStateCallback;
@NonNull
+ private final ResultReceiver mInternalUpdateSystemSelectionChannelsResultReceiver;
+ @NonNull
protected final Object mLock = new Object();
@GuardedBy("mLock")
@NonNull
private final Set<ResultReceiver> mSatelliteAllowResultReceivers = new HashSet<>();
@NonNull
+ private final Set<ResultReceiver>
+ mUpdateSystemSelectionChannelsResultReceivers = new HashSet<>();
+ @NonNull
private List<String> mSatelliteCountryCodes;
private boolean mIsSatelliteAllowAccessControl;
@Nullable
@@ -292,6 +305,17 @@
@NonNull
private HashMap<Integer, SatelliteAccessConfiguration> mSatelliteAccessConfigMap =
new HashMap<>();
+ @NonNull private final CarrierConfigManager mCarrierConfigManager;
+ @NonNull private final CarrierConfigManager.CarrierConfigChangeListener
+ mCarrierConfigChangeListener;
+ /**
+ * Key: Sub Id, Value: (key: Regional satellite config Id, value: SatelliteRegionalConfig
+ * contains satellite config IDs and set of earfcns in the corresponding regions).
+ */
+ @GuardedBy("mRegionalSatelliteEarfcnsLock")
+ private Map<Integer, Map<Integer, SatelliteRegionalConfig>>
+ mSatelliteRegionalConfigPerSubMap = new HashMap();
+ @NonNull private final Object mRegionalSatelliteEarfcnsLock = new Object();
/** These are used for CTS test */
private Path mCtsSatS2FilePath = null;
@@ -375,6 +399,9 @@
if (mLocationManager.isLocationEnabled()) {
plogd("Location settings is just enabled");
sendRequestAsync(EVENT_LOCATION_SETTINGS_ENABLED, null);
+ } else {
+ plogd("Location settings is just enabled");
+ sendRequestAsync(EVENT_LOCATION_SETTINGS_DISABLED, null);
}
}
}
@@ -453,6 +480,8 @@
mNotifySatelliteAvailabilityEnabled =
context.getResources().getBoolean(
R.bool.config_satellite_should_notify_availability);
+ initializeSatelliteSystemNotification(context);
+ registerDefaultSmsAppChangedBroadcastReceiver(context);
mInternalSatelliteSupportedStateCallback = new ISatelliteSupportedStateCallback.Stub() {
@Override
@@ -532,10 +561,27 @@
mInternalSatelliteProvisionStateCallback);
plogd("registerForSatelliteProvisionStateChanged result: " + result);
+ mInternalUpdateSystemSelectionChannelsResultReceiver = new ResultReceiver(this) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ plogd("UpdateSystemSelectionChannels.onReceiveResult: resultCode=" + resultCode
+ + ", resultData=" + resultData);
+ sendUpdateSystemSelectionChannelsResult(resultCode, resultData);
+ }
+ };
+
// Init the SatelliteOnDeviceAccessController so that the S2 level can be cached
initSatelliteOnDeviceAccessController();
registerLocationModeChangedBroadcastReceiver(context);
- registerDefaultSmsAppChangedBroadcastReceiver(context);
+
+ mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+ mCarrierConfigChangeListener =
+ (slotIndex, subId, carrierId, specificCarrierId) ->
+ handleCarrierConfigChanged(slotIndex, subId, carrierId, specificCarrierId);
+ if (mCarrierConfigManager != null) {
+ mCarrierConfigManager.registerCarrierConfigChangeListener(
+ new HandlerExecutor(new Handler(looper)), mCarrierConfigChangeListener);
+ }
}
private void updateCurrentSatelliteAllowedState(boolean isAllowed) {
@@ -591,10 +637,14 @@
updateSatelliteConfigData((Context) ar.userObj);
break;
case EVENT_LOCATION_SETTINGS_ENABLED:
+ case EVENT_LOCATION_SETTINGS_DISABLED:
// Fall through
case EVENT_COUNTRY_CODE_CHANGED:
handleSatelliteAllowedRegionPossiblyChanged(msg.what);
break;
+ case CMD_UPDATE_SYSTEM_SELECTION_CHANNELS:
+ handleCmdUpdateSystemSelectionChannels((ResultReceiver) msg.obj);
+ break;
default:
plogw("SatelliteAccessControllerHandler: unexpected message code: " + msg.what);
break;
@@ -734,6 +784,28 @@
return true;
}
+ /**
+ * Report updated system selection to modem and report the update result.
+ */
+ public void updateSystemSelectionChannels(@NonNull ResultReceiver result) {
+ plogd("updateSystemSelectionChannels");
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("updateSystemSelectionChannels: "
+ + "carrierRoamingNbIotNtn flag is disabled");
+ result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
+ return;
+ }
+ synchronized (mLock) {
+ if (mRegionalConfigId == null) {
+ plogd("updateSystemSelectionChannels: Invalid Regional config ID."
+ + " System Selection channels can not be passed down to modem");
+ result.send(SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED, null);
+ return;
+ }
+ }
+ sendRequestAsync(CMD_UPDATE_SYSTEM_SELECTION_CHANNELS, result);
+ }
+
protected File getTestSatelliteS2File(String fileName) {
plogd("getTestSatelliteS2File: fileName=" + fileName);
if (TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_S2_FILE_NAME)) {
@@ -758,15 +830,22 @@
Path targetDir = ctsFile.toPath();
Path targetSatS2FilePath = targetDir.resolve(sourceFileName);
try {
- InputStream inputStream = phoneGlobals.getAssets().open(sourceFileName);
+ var assetManager = phoneGlobals.getAssets();
+ if (assetManager == null) {
+ loge("copyTestSatS2FileToPhoneDirectory: no assets");
+ return null;
+ }
+ InputStream inputStream = assetManager.open(sourceFileName);
if (inputStream == null) {
loge("copyTestSatS2FileToPhoneDirectory: Resource=" + sourceFileName
+ " not found");
+ return null;
} else {
Files.copy(inputStream, targetSatS2FilePath, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException ex) {
loge("copyTestSatS2FileToPhoneDirectory: ex=" + ex);
+ return null;
}
return targetSatS2FilePath;
}
@@ -1330,6 +1409,11 @@
}
private void showSatelliteSystemNotification() {
+ if (mNotificationManager == null) {
+ logd("showSatelliteSystemNotification: NotificationManager is null");
+ return;
+ }
+
if (mSatelliteDisallowedReasons.isEmpty()) {
if (!hasAlreadyNotified(KEY_AVAILABLE_NOTIFICATION_SHOWN, 0)) {
mNotificationManager.notifyAsUser(
@@ -2070,6 +2154,78 @@
}
}
+ private void handleCmdUpdateSystemSelectionChannels(
+ @NonNull ResultReceiver resultReceiver) {
+ synchronized (mLock) {
+ mUpdateSystemSelectionChannelsResultReceivers.add(resultReceiver);
+ if (mUpdateSystemSelectionChannelsResultReceivers.size() > 1) {
+ plogd("updateSystemSelectionChannels is already being processed");
+ return;
+ }
+ int subId = mSatelliteController.getSelectedSatelliteSubId();
+ plogd("handleCmdUpdateSystemSelectionChannels: SatellitePhone subId: " + subId);
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ String mccmnc = "";
+ final SubscriptionInfo subInfo = SubscriptionManagerService.getInstance()
+ .getSubscriptionInfo(subId);
+ if (subInfo != null) {
+ mccmnc = subInfo.getMccString() + subInfo.getMncString();
+ }
+
+ synchronized (mRegionalSatelliteEarfcnsLock) {
+ /* Key: Regional satellite config ID, Value: SatelliteRegionalConfig
+ * contains satellite config IDs and set of earfcns in the corresponding regions.
+ */
+ Map<Integer, SatelliteRegionalConfig> satelliteRegionalConfigMap =
+ mSatelliteRegionalConfigPerSubMap.get(subId);
+ if (satelliteRegionalConfigMap == null || satelliteRegionalConfigMap.isEmpty()) {
+ plogd("handleCmdUpdateSystemSelectionChannels: config IDs and Earfcns are not"
+ + " found for subId: "
+ + subId);
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ SatelliteRegionalConfig satelliteRegionalConfig = satelliteRegionalConfigMap.get(
+ mRegionalConfigId);
+ if (satelliteRegionalConfig == null) {
+ plogd("handleCmdUpdateSystemSelectionChannels: "
+ + "Earfcns for satellite config Id: " + mRegionalConfigId
+ + " not found");
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+ IntArray bands = new IntArray();
+ IntArray earfcns = new IntArray();
+ for (Integer value : satelliteRegionalConfig.getEarfcns()) {
+ earfcns.add(value);
+ }
+
+ mSatelliteController.updateSystemSelectionChannels(
+ new SystemSelectionSpecifier(mccmnc, bands, earfcns),
+ mInternalUpdateSystemSelectionChannelsResultReceiver);
+ }
+ }
+ }
+
+ private void sendUpdateSystemSelectionChannelsResult(int resultCode, Bundle resultData) {
+ plogd("sendUpdateSystemSelectionChannelsResult: resultCode=" + resultCode);
+
+ synchronized (mLock) {
+ for (ResultReceiver resultReceiver : mUpdateSystemSelectionChannelsResultReceivers) {
+ resultReceiver.send(resultCode, resultData);
+ }
+ mUpdateSystemSelectionChannelsResultReceivers.clear();
+ }
+ }
+
private static boolean getSatelliteAccessAllowFromOverlayConfig(@NonNull Context context) {
Boolean accessAllowed = null;
try {
@@ -2615,6 +2771,69 @@
resetRequired);
}
+ private static final class SatelliteRegionalConfig {
+ /** Regional satellite config IDs */
+ private final int mConfigId;
+
+ /** Set of earfcns in the corresponding regions */
+ private final Set<Integer> mEarfcns;
+
+ SatelliteRegionalConfig(int configId, Set<Integer> earfcns) {
+ this.mConfigId = configId;
+ this.mEarfcns = earfcns;
+ }
+
+ public Set<Integer> getEarfcns() {
+ return mEarfcns;
+ }
+ }
+
+ private void updateSatelliteRegionalConfig(int subId) {
+ plogd("updateSatelliteRegionalConfig: subId: " + subId);
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return;
+ }
+
+ mSatelliteController.updateRegionalSatelliteEarfcns(subId);
+ //key: regional satellite config Id,
+ //value: set of earfcns in the corresponding regions
+ Map<String, Set<Integer>> earfcnsMap = mSatelliteController
+ .getRegionalSatelliteEarfcns(subId);
+ if (earfcnsMap.isEmpty()) {
+ plogd("updateSatelliteRegionalConfig: Earfcns are not found for subId: "
+ + subId);
+ return;
+ }
+
+ synchronized (mRegionalSatelliteEarfcnsLock) {
+ SatelliteRegionalConfig satelliteRegionalConfig;
+ /* Key: Regional satellite config ID, Value: SatelliteRegionalConfig
+ * contains satellite config IDs and set of earfcns in the corresponding regions.
+ */
+ Map<Integer, SatelliteRegionalConfig> satelliteRegionalConfigMap = new HashMap<>();
+ for (String configId: earfcnsMap.keySet()) {
+ Set<Integer> earfcnsSet = new HashSet<>();
+ for (int earfcn : earfcnsMap.get(configId)) {
+ earfcnsSet.add(earfcn);
+ }
+ satelliteRegionalConfig = new SatelliteRegionalConfig(Integer.valueOf(configId),
+ earfcnsSet);
+ satelliteRegionalConfigMap.put(Integer.valueOf(configId), satelliteRegionalConfig);
+ }
+
+ mSatelliteRegionalConfigPerSubMap.put(subId, satelliteRegionalConfigMap);
+ }
+ }
+
+ private void handleCarrierConfigChanged(int slotIndex, int subId,
+ int carrierId, int specificCarrierId) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("handleCarrierConfigChanged: carrierRoamingNbIotNtn flag is disabled");
+ return;
+ }
+ updateSatelliteRegionalConfig(subId);
+ }
+
private void plogv(@NonNull String log) {
Rlog.v(TAG, log);
if (mPersistentLogger != null) {
diff --git a/tests/src/com/android/TelephonyTestBase.java b/tests/src/com/android/TelephonyTestBase.java
index 3e74eb7..94e91d3 100644
--- a/tests/src/com/android/TelephonyTestBase.java
+++ b/tests/src/com/android/TelephonyTestBase.java
@@ -35,6 +35,8 @@
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.data.DataConfigManager;
import com.android.internal.telephony.data.DataNetworkController;
+import com.android.internal.telephony.metrics.MetricsCollector;
+import com.android.internal.telephony.metrics.PersistAtomsStorage;
import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneInterfaceManager;
@@ -65,6 +67,7 @@
@Mock protected PhoneGlobals mPhoneGlobals;
@Mock protected GsmCdmaPhone mPhone;
@Mock protected DataNetworkController mDataNetworkController;
+ @Mock private MetricsCollector mMetricsCollector;
private final HashMap<InstanceKey, Object> mOldInstances = new HashMap<>();
private final LinkedList<InstanceKey> mInstanceKeys = new LinkedList<>();
@@ -92,6 +95,9 @@
replaceInstance(PhoneFactory.class, "sPhone", null, mPhone);
replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
replaceInstance(PhoneGlobals.class, "sMe", null, mPhoneGlobals);
+ replaceInstance(PhoneFactory.class, "sMetricsCollector", null, mMetricsCollector);
+
+ doReturn(Mockito.mock(PersistAtomsStorage.class)).when(mMetricsCollector).getAtomsStorage();
doReturn(mDataNetworkController).when(mPhone).getDataNetworkController();
doReturn(Collections.emptyList()).when(mDataNetworkController)
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index a684ef5..bf7832a 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -21,13 +21,18 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
@@ -44,7 +49,10 @@
import android.util.Log;
import android.util.SparseArray;
+import androidx.test.InstrumentationRegistry;
+
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
@@ -87,6 +95,11 @@
}
@Override
+ public AssetManager getAssets() {
+ return Mockito.mock(AssetManager.class);
+ }
+
+ @Override
public Executor getMainExecutor() {
// Just run on current thread
return Runnable::run;
@@ -98,6 +111,11 @@
}
@Override
+ public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
+ return this;
+ }
+
+ @Override
public String getPackageName() {
return "com.android.phone.tests";
}
@@ -226,6 +244,11 @@
return new Handler(Looper.getMainLooper());
}
+ @Override
+ public Resources.Theme getTheme() {
+ return InstrumentationRegistry.getTargetContext().getTheme();
+ }
+
/**
* @return CarrierConfig PersistableBundle for the subscription specified.
*/
@@ -274,6 +297,11 @@
}
}
+ @Override
+ public void unbindService(ServiceConnection conn) {
+ // Override the base implementation to ensure we don't crash.
+ }
+
public void grantPermission(String permission) {
synchronized (mPermissionTable) {
if (permission == null) return;
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index 5c18cc5..b388954 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -49,6 +49,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -87,7 +88,6 @@
import android.os.CancellationSignal;
import android.os.DropBoxManager;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -101,12 +101,14 @@
import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteInfo;
import android.telephony.satellite.SatelliteManager;
+import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
import android.util.Pair;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import com.android.TelephonyTestBase;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyCountryDetector;
@@ -115,6 +117,7 @@
import com.android.internal.telephony.satellite.SatelliteConfigParser;
import com.android.internal.telephony.satellite.SatelliteController;
import com.android.internal.telephony.satellite.SatelliteModemInterface;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
import org.junit.After;
import org.junit.Before;
@@ -123,10 +126,8 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import java.io.File;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -141,8 +142,9 @@
import java.util.function.Consumer;
/** Unit test for {@link SatelliteAccessController} */
-@RunWith(AndroidJUnit4.class)
-public class SatelliteAccessControllerTest {
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class SatelliteAccessControllerTest extends TelephonyTestBase {
private static final String TAG = "SatelliteAccessControllerTest";
private static final String[] TEST_SATELLITE_COUNTRY_CODES = {"US", "CA", "UK"};
private static final String[] TEST_SATELLITE_COUNTRY_CODES_EMPTY = {""};
@@ -176,8 +178,7 @@
private SatelliteModemInterface mMockSatelliteModemInterface;
@Mock
private DropBoxManager mMockDropBoxManager;
- @Mock
- private Context mMockContext;
+ private Context mMockContext; // alias of mContext
@Mock
private Phone mMockPhone;
@Mock
@@ -224,7 +225,6 @@
private ConcurrentHashMap<IBinder, ISatelliteCommunicationAllowedStateCallback>
mSatelliteCommunicationAllowedStateCallbackMap;
- private Looper mLooper;
private TestableLooper mTestableLooper;
private Phone[] mPhones;
private TestSatelliteAccessController mSatelliteAccessControllerUT;
@@ -289,17 +289,10 @@
@Before
public void setUp() throws Exception {
- logd("setUp");
- MockitoAnnotations.initMocks(this);
+ super.setUp();
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
-
- HandlerThread handlerThread = new HandlerThread("SatelliteAccessControllerTest");
- handlerThread.start();
- mLooper = handlerThread.getLooper();
- mTestableLooper = new TestableLooper(mLooper);
+ mMockContext = mContext;
+ mTestableLooper = TestableLooper.get(this);
when(mMockContext.getSystemServiceName(LocationManager.class)).thenReturn(
Context.LOCATION_SERVICE);
when(mMockContext.getSystemServiceName(TelecomManager.class)).thenReturn(
@@ -312,6 +305,11 @@
mMockTelecomManager);
when(mMockContext.getSystemService(DropBoxManager.class)).thenReturn(
mMockDropBoxManager);
+ doAnswer(inv -> {
+ var args = inv.getArguments();
+ return InstrumentationRegistry.getTargetContext()
+ .getDir((String) args[0], (Integer) args[1]);
+ }).when(mPhoneGlobals).getDir(anyString(), anyInt());
mPhones = new Phone[]{mMockPhone, mMockPhone2};
replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
replaceInstance(SatelliteController.class, "sInstance", null,
@@ -320,6 +318,8 @@
mMockSatelliteModemInterface);
replaceInstance(TelephonyCountryDetector.class, "sInstance", null,
mMockCountryDetector);
+ replaceInstance(ControllerMetricsStats.class, "sInstance", null,
+ mock(ControllerMetricsStats.class));
when(mMockSatelliteController.getSatellitePhone()).thenReturn(mMockPhone);
when(mMockPhone.getSubId()).thenReturn(SubscriptionManager.getDefaultSubscriptionId());
@@ -361,8 +361,8 @@
any(SatelliteOnDeviceAccessController.LocationToken.class)))
.thenReturn(DEFAULT_REGIONAL_SATELLITE_CONFIG_ID);
- when(mMockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(
- mMockSharedPreferences);
+ doReturn(mMockSharedPreferences).when(mMockContext)
+ .getSharedPreferences(anyString(), anyInt());
when(mMockSharedPreferences.getBoolean(anyString(), anyBoolean())).thenReturn(true);
when(mMockSharedPreferences.getStringSet(anyString(), any()))
.thenReturn(Set.of(TEST_SATELLITE_COUNTRY_CODES));
@@ -392,28 +392,19 @@
NotificationManager.class)).thenReturn(Context.NOTIFICATION_SERVICE);
when(mMockContext.getSystemService(Context.NOTIFICATION_SERVICE))
.thenReturn(mMockNotificationManager);
- when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
+ doReturn(mMockApplicationInfo).when(mMockContext).getApplicationInfo();
mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
when(mMockPackageManager.getApplicationInfo(anyString(), anyInt()))
.thenReturn(mMockApplicationInfo);
mSatelliteAccessControllerUT = new TestSatelliteAccessController(mMockContext,
- mMockFeatureFlags, mLooper, mMockLocationManager, mMockTelecomManager,
- mMockSatelliteOnDeviceAccessController, mMockSatS2File);
+ mMockFeatureFlags, mTestableLooper.getLooper(), mMockLocationManager,
+ mMockTelecomManager, mMockSatelliteOnDeviceAccessController, mMockSatS2File);
mTestableLooper.processAllMessages();
}
@After
public void tearDown() throws Exception {
- logd("tearDown");
- if (mTestableLooper != null) {
- mTestableLooper.destroy();
- mTestableLooper = null;
- }
-
- if (mLooper != null) {
- mLooper.quit();
- mLooper = null;
- }
+ super.tearDown();
}
@Test
@@ -1480,6 +1471,7 @@
doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
File testS2File = mSatelliteAccessControllerUT
.getTestSatelliteS2File(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
+ assumeTrue("Satellite not supported", testS2File != null && testS2File.exists());
doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
.when(mockConfig).getDeviceSatelliteCountryCodes();
doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
@@ -1800,13 +1792,6 @@
Log.d(TAG, message);
}
- private static void replaceInstance(final Class c,
- final String instanceName, final Object obj, final Object newValue) throws Exception {
- Field field = c.getDeclaredField(instanceName);
- field.setAccessible(true);
- field.set(obj, newValue);
- }
-
private static class TestSatelliteAccessController extends SatelliteAccessController {
public long elapsedRealtimeNanos = 0;
diff --git a/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java b/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
index 9f8a733..f41f861 100644
--- a/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
+++ b/tests/src/com/android/phone/satellite/entitlement/SatelliteEntitlementControllerTest.java
@@ -60,9 +60,6 @@
import com.android.TelephonyTestBase;
import com.android.internal.telephony.ExponentialBackoff;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.metrics.MetricsCollector;
-import com.android.internal.telephony.metrics.PersistAtomsStorage;
import com.android.internal.telephony.satellite.SatelliteController;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.libraries.entitlement.ServiceEntitlementException;
@@ -72,7 +69,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -105,7 +101,6 @@
@Mock Network mNetwork;
@Mock TelephonyManager mTelephonyManager;
@Mock SubscriptionManagerService mMockSubscriptionManagerService;
- @Mock private MetricsCollector mMetricsCollector;
@Mock SatelliteEntitlementApi mSatelliteEntitlementApi;
@Mock SatelliteEntitlementResult mSatelliteEntitlementResult;
@Mock SatelliteController mSatelliteController;
@@ -123,8 +118,6 @@
replaceInstance(SubscriptionManagerService.class, "sInstance", null,
mMockSubscriptionManagerService);
replaceInstance(SatelliteController.class, "sInstance", null, mSatelliteController);
- replaceInstance(PhoneFactory.class, "sMetricsCollector", null, mMetricsCollector);
- doReturn(Mockito.mock(PersistAtomsStorage.class)).when(mMetricsCollector).getAtomsStorage();
mTestableLooper = TestableLooper.get(this);
mHandler = new Handler(mTestableLooper.getLooper());