Merge "Import translations. DO NOT MERGE ANYWHERE" into 24D1-dev
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index 8489015..8353861 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -21,10 +21,13 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
+import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_SHARED_PREF;
+
import android.annotation.ArrayRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.Resources;
import android.location.Location;
import android.location.LocationManager;
@@ -56,9 +59,11 @@
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.satellite.SatelliteConfig;
import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.internal.telephony.util.TelephonyUtils;
import com.android.phone.PhoneGlobals;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
@@ -115,56 +120,82 @@
private static SatelliteAccessController sInstance;
/** Feature flags to control behavior and errors. */
- @NonNull private final FeatureFlags mFeatureFlags;
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
@GuardedBy("mLock")
- @Nullable protected SatelliteOnDeviceAccessController mSatelliteOnDeviceAccessController;
- @NonNull private final LocationManager mLocationManager;
- @NonNull private final TelecomManager mTelecomManager;
- @NonNull private final TelephonyCountryDetector mCountryDetector;
- @NonNull private final SatelliteController mSatelliteController;
- @NonNull private final ResultReceiver mInternalSatelliteSupportedResultReceiver;
- @NonNull protected final Object mLock = new Object();
+ @Nullable
+ protected SatelliteOnDeviceAccessController mSatelliteOnDeviceAccessController;
+ @NonNull
+ private final LocationManager mLocationManager;
+ @NonNull
+ private final TelecomManager mTelecomManager;
+ @NonNull
+ private final TelephonyCountryDetector mCountryDetector;
+ @NonNull
+ private final SatelliteController mSatelliteController;
+ @NonNull
+ private final ResultReceiver mInternalSatelliteSupportedResultReceiver;
+ @NonNull
+ protected final Object mLock = new Object();
@GuardedBy("mLock")
@NonNull
private final Set<ResultReceiver> mSatelliteAllowResultReceivers = new HashSet<>();
- @NonNull private List<String> mSatelliteCountryCodes;
+ @NonNull
+ private List<String> mSatelliteCountryCodes;
private boolean mIsSatelliteAllowAccessControl;
- @Nullable private File mSatelliteS2CellFile;
+ @Nullable
+ private File mSatelliteS2CellFile;
private long mLocationFreshDurationNanos;
@GuardedBy("mLock")
private boolean mIsOverlayConfigOverridden = false;
- @NonNull private List<String> mOverriddenSatelliteCountryCodes;
+ @NonNull
+ private List<String> mOverriddenSatelliteCountryCodes;
private boolean mOverriddenIsSatelliteAllowAccessControl;
- @Nullable private File mOverriddenSatelliteS2CellFile;
+ @Nullable
+ private File mOverriddenSatelliteS2CellFile;
private long mOverriddenLocationFreshDurationNanos;
@GuardedBy("mLock")
@NonNull
private final Map<SatelliteOnDeviceAccessController.LocationToken, Boolean>
mCachedAccessRestrictionMap = new LinkedHashMap<>() {
- @Override
- protected boolean removeEldestEntry(
- Entry<SatelliteOnDeviceAccessController.LocationToken, Boolean> eldest) {
- return size() > MAX_CACHE_SIZE;
- }
- };
+ @Override
+ protected boolean removeEldestEntry(
+ Entry<SatelliteOnDeviceAccessController.LocationToken, Boolean> eldest) {
+ return size() > MAX_CACHE_SIZE;
+ }
+ };
@GuardedBy("mLock")
@Nullable
CancellationSignal mLocationRequestCancellationSignal = null;
private int mS2Level = DEFAULT_S2_LEVEL;
@GuardedBy("mLock")
- @Nullable private Location mFreshLastKnownLocation = null;
+ @Nullable
+ private Location mFreshLastKnownLocation = null;
/** These are used for CTS test */
private Path mCtsSatS2FilePath = null;
- private static final String GOOGLE_US_SAN_SAT_S2_FILE_NAME = "google_us_san_sat_s2.dat";
+ protected static final String GOOGLE_US_SAN_SAT_S2_FILE_NAME = "google_us_san_sat_s2.dat";
+
+ /** These are for config updater config data */
+ private static final String SATELLITE_ACCESS_CONTROL_DATA_DIR = "satellite_access_control";
+ private static final String CONFIG_UPDATER_S2_CELL_FILE_NAME = "config_updater_sat_s2.dat";
+ private static final int MIN_S2_LEVEL = 0;
+ private static final int MAX_S2_LEVEL = 30;
+ private static final String CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY =
+ "config_updater_satellite_country_codes";
+ private static final String CONFIG_UPDATER_SATELLITE_IS_ALLOW_ACCESS_CONTROL_KEY =
+ "config_updater_satellite_is_allow_access_control";
+ private SharedPreferences mSharedPreferences;
/**
* Create a SatelliteAccessController instance.
*
- * @param context The context associated with the {@link SatelliteAccessController} instance.
- * @param featureFlags The FeatureFlags that are supported.
- * @param locationManager The LocationManager for querying current location of the device.
- * @param looper The Looper to run the SatelliteAccessController on.
+ * @param context The context associated with the
+ * {@link SatelliteAccessController} instance.
+ * @param featureFlags The FeatureFlags that are supported.
+ * @param locationManager The LocationManager for querying current location of
+ * the device.
+ * @param looper The Looper to run the SatelliteAccessController on.
* @param satelliteOnDeviceAccessController The on-device satellite access controller instance.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -180,7 +211,11 @@
mSatelliteOnDeviceAccessController = satelliteOnDeviceAccessController;
mCountryDetector = TelephonyCountryDetector.getInstance(context);
mSatelliteController = SatelliteController.getInstance();
+ initSharedPreferences(context);
loadOverlayConfigs(context);
+ // loadConfigUpdaterConfigs has to be called after loadOverlayConfigs
+ // since config updater config has higher priority and thus can override overlay config
+ loadConfigUpdaterConfigs();
mSatelliteController.registerForConfigUpdateChanged(this, EVENT_CONFIG_DATA_UPDATED,
context);
if (s2CellFile != null) {
@@ -235,8 +270,8 @@
/**
* Request to get whether satellite communication is allowed for the current location.
*
- * @param subId The subId of the subscription to check whether satellite communication is
- * allowed for the current location for.
+ * @param subId The subId of the subscription to check whether satellite communication is
+ * allowed for the current location for.
* @param result The result receiver that returns whether satellite communication is allowed
* for the current location if the request is successful or an error code
* if the request failed.
@@ -298,7 +333,7 @@
return true;
}
- private File getTestSatelliteS2File(String fileName) {
+ protected File getTestSatelliteS2File(String fileName) {
logd("getTestSatelliteS2File: fileName=" + fileName);
if (TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_S2_FILE_NAME)) {
mCtsSatS2FilePath = copyTestSatS2FileToPhoneDirectory(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
@@ -311,7 +346,8 @@
return new File(fileName);
}
- @Nullable private static Path copyTestSatS2FileToPhoneDirectory(String sourceFileName) {
+ @Nullable
+ private static Path copyTestSatS2FileToPhoneDirectory(String sourceFileName) {
PhoneGlobals phoneGlobals = PhoneGlobals.getInstance();
File ctsFile = phoneGlobals.getDir("cts", Context.MODE_PRIVATE);
if (!ctsFile.exists()) {
@@ -334,6 +370,66 @@
return targetSatS2FilePath;
}
+ @Nullable
+ private static File copySatS2FileToLocalDirectory(@NonNull File sourceFile) {
+ PhoneGlobals phoneGlobals = PhoneGlobals.getInstance();
+ File satelliteAccessControlFile = phoneGlobals.getDir(
+ SATELLITE_ACCESS_CONTROL_DATA_DIR, Context.MODE_PRIVATE);
+ if (!satelliteAccessControlFile.exists()) {
+ satelliteAccessControlFile.mkdirs();
+ }
+
+ Path targetDir = satelliteAccessControlFile.toPath();
+ Path targetSatS2FilePath = targetDir.resolve(CONFIG_UPDATER_S2_CELL_FILE_NAME);
+ try {
+ InputStream inputStream = new FileInputStream(sourceFile);
+ if (inputStream == null) {
+ loge("copySatS2FileToPhoneDirectory: Resource=" + sourceFile.getAbsolutePath()
+ + " not found");
+ return null;
+ } else {
+ Files.copy(inputStream, targetSatS2FilePath, StandardCopyOption.REPLACE_EXISTING);
+ }
+ } catch (IOException ex) {
+ loge("copySatS2FileToPhoneDirectory: ex=" + ex);
+ return null;
+ }
+ return targetSatS2FilePath.toFile();
+ }
+
+ @Nullable
+ private File getConfigUpdaterSatS2CellFileFromLocalDirectory() {
+ PhoneGlobals phoneGlobals = PhoneGlobals.getInstance();
+ File satelliteAccessControlFile = phoneGlobals.getDir(
+ SATELLITE_ACCESS_CONTROL_DATA_DIR, Context.MODE_PRIVATE);
+ if (!satelliteAccessControlFile.exists()) {
+ return null;
+ }
+
+ Path satelliteAccessControlFileDir = satelliteAccessControlFile.toPath();
+ Path configUpdaterSatS2FilePath = satelliteAccessControlFileDir.resolve(
+ CONFIG_UPDATER_S2_CELL_FILE_NAME);
+ return configUpdaterSatS2FilePath.toFile();
+ }
+
+ private boolean isS2CellFileValid(@NonNull File s2CellFile) {
+ try {
+ SatelliteOnDeviceAccessController satelliteOnDeviceAccessController =
+ SatelliteOnDeviceAccessController.create(s2CellFile);
+ int s2Level = satelliteOnDeviceAccessController.getS2Level();
+ if (s2Level < MIN_S2_LEVEL || s2Level > MAX_S2_LEVEL) {
+ loge("isS2CellFileValid: invalid s2 level = " + s2Level);
+ satelliteOnDeviceAccessController.close();
+ return false;
+ }
+ satelliteOnDeviceAccessController.close();
+ } catch (Exception ex) {
+ loge("isS2CellFileValid: Got exception in reading the file, ex=" + ex);
+ return false;
+ }
+ return true;
+ }
+
private void cleanUpCtsResources() {
if (mCtsSatS2FilePath != null) {
try {
@@ -350,61 +446,126 @@
}
/**
- * Update country codes, S2CellFile and satellite region allowed by ConfigUpdater
- * or CarrierConfig
+ * @param countryCodes list of country code (two letters based on the ISO 3166-1).
+ * @return {@code true} if the countryCode is valid {@code false} otherwise.
+ */
+ private boolean isValidCountryCodes(@Nullable List<String> countryCodes) {
+ if (countryCodes == null || countryCodes.isEmpty()) {
+ return false;
+ }
+ for (String countryCode : countryCodes) {
+ if (!TelephonyUtils.isValidCountryCode(countryCode)) {
+ loge("invalid country code : " + countryCode);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean updateSharedPreferencesCountryCodes(
+ @NonNull Context context, @NonNull List<String> value) {
+ if (mSharedPreferences == null) {
+ logd("updateSharedPreferencesCountryCodes: mSharedPreferences is null");
+ initSharedPreferences(context);
+ }
+ if (mSharedPreferences == null) {
+ loge("updateSharedPreferencesCountryCodes: mSharedPreferences is null");
+ return false;
+ }
+ try {
+ mSharedPreferences.edit().putStringSet(
+ CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY, new HashSet<>(value)).apply();
+ return true;
+ } catch (Exception ex) {
+ loge("updateSharedPreferencesCountryCodes error : " + ex);
+ return false;
+ }
+ }
+
+ private boolean updateSharedPreferencesIsAllowAccessControl(
+ @NonNull Context context, boolean value) {
+ if (mSharedPreferences == null) {
+ logd("updateSharedPreferencesIsAllowAccessControl: mSharedPreferences is null");
+ initSharedPreferences(context);
+ }
+ if (mSharedPreferences == null) {
+ loge("updateSharedPreferencesIsAllowAccessControl: mSharedPreferences is null");
+ return false;
+ }
+ try {
+ mSharedPreferences.edit().putBoolean(
+ CONFIG_UPDATER_SATELLITE_IS_ALLOW_ACCESS_CONTROL_KEY,
+ value).apply();
+ return true;
+ } catch (Exception ex) {
+ loge("updateSharedPreferencesAllowRegion : " + ex);
+ return false;
+ }
+ }
+
+ /**
+ * Update country codes and S2CellFile with the new data from ConfigUpdater
*/
private void updateSatelliteConfigData(Context context) {
logd("updateSatelliteConfigData");
SatelliteConfig satelliteConfig = mSatelliteController.getSatelliteConfig();
- if (satelliteConfig != null && satelliteConfig.getSatelliteS2CellFile(context) != null) {
- logd("Check mSatelliteS2CellFile from ConfigUpdater");
- Path pathSatelliteS2CellFile = satelliteConfig.getSatelliteS2CellFile(context);
- mSatelliteS2CellFile = pathSatelliteS2CellFile.toFile();
- if (mSatelliteS2CellFile != null && !mSatelliteS2CellFile.exists()) {
- loge("The satellite S2 cell file " + mSatelliteS2CellFile.getAbsolutePath()
- + " does not exist");
- mSatelliteS2CellFile = null;
- } else {
- logd("S2 cell file from ConfigUpdater:" + mSatelliteS2CellFile.getAbsolutePath());
- }
- }
-
- if (mSatelliteS2CellFile == null) {
- logd("Check mSatelliteS2CellFile from device overlay config");
- String satelliteS2CellFileName = getSatelliteS2CellFileFromOverlayConfig(context);
- mSatelliteS2CellFile = TextUtils.isEmpty(satelliteS2CellFileName)
- ? null : new File(satelliteS2CellFileName);
- if (mSatelliteS2CellFile != null && !mSatelliteS2CellFile.exists()) {
- loge("The satellite S2 cell file " + mSatelliteS2CellFile.getAbsolutePath()
- + " does not exist");
- mSatelliteS2CellFile = null;
- }
- }
-
- if (mSatelliteS2CellFile == null) {
- logd("Since mSatelliteS2CellFile is null, don't need to refer other configurations");
+ if (satelliteConfig == null) {
+ loge("satelliteConfig is null");
return;
}
- if (satelliteConfig != null
- && !satelliteConfig.getDeviceSatelliteCountryCodes().isEmpty()) {
- mSatelliteCountryCodes = satelliteConfig.getDeviceSatelliteCountryCodes();
- logd("update mSatelliteCountryCodes by ConfigUpdater: "
- + String.join(",", mSatelliteCountryCodes));
- } else {
- mSatelliteCountryCodes = getSatelliteCountryCodesFromOverlayConfig(context);
+ List<String> satelliteCountryCodes = satelliteConfig.getDeviceSatelliteCountryCodes();
+ if (!isValidCountryCodes(satelliteCountryCodes)) {
+ logd("country codes is invalid");
+ return;
}
- if (satelliteConfig != null && satelliteConfig.isSatelliteDataForAllowedRegion() != null) {
- mIsSatelliteAllowAccessControl = satelliteConfig.isSatelliteDataForAllowedRegion();
- logd("update mIsSatelliteAllowAccessControl by ConfigUpdater: "
- + mIsSatelliteAllowAccessControl);
- } else {
- mIsSatelliteAllowAccessControl = getSatelliteAccessAllowFromOverlayConfig(context);
+ Boolean isSatelliteDataForAllowedRegion = satelliteConfig.isSatelliteDataForAllowedRegion();
+ if (isSatelliteDataForAllowedRegion == null) {
+ loge("Satellite allowed is not configured with country codes");
+ return;
}
- // Clean up resources so that the new config data will be used when receiving new requests
+ File configUpdaterS2CellFile = satelliteConfig.getSatelliteS2CellFile(context);
+ if (configUpdaterS2CellFile == null || !configUpdaterS2CellFile.exists()) {
+ logd("No S2 cell file configured or the file does not exist");
+ return;
+ }
+
+ if (!isS2CellFileValid(configUpdaterS2CellFile)) {
+ loge("The configured S2 cell file is not valid");
+ return;
+ }
+
+ File localS2CellFile = copySatS2FileToLocalDirectory(configUpdaterS2CellFile);
+ if (localS2CellFile == null || !localS2CellFile.exists()) {
+ loge("Fail to copy S2 cell file to local directory");
+ return;
+ }
+
+ if (!updateSharedPreferencesCountryCodes(context, satelliteCountryCodes)) {
+ loge("Fail to copy country coeds into shared preferences");
+ localS2CellFile.delete();
+ return;
+ }
+
+ if (!updateSharedPreferencesIsAllowAccessControl(
+ context, isSatelliteDataForAllowedRegion.booleanValue())) {
+ loge("Fail to copy allow access control into shared preferences");
+ localS2CellFile.delete();
+ return;
+ }
+
+ mSatelliteS2CellFile = localS2CellFile;
+ mSatelliteCountryCodes = satelliteCountryCodes;
+ mIsSatelliteAllowAccessControl = satelliteConfig.isSatelliteDataForAllowedRegion();
+ logd("Use s2 cell file=" + mSatelliteS2CellFile.getAbsolutePath() + ", country codes="
+ + String.join(",", mSatelliteCountryCodes)
+ + ", mIsSatelliteAllowAccessControl=" + mIsSatelliteAllowAccessControl
+ + " from ConfigUpdater");
+
+ // Clean up resources so that the new config data will be used when serving new requests
cleanupOnDeviceAccessControllerResources();
}
@@ -421,6 +582,36 @@
mLocationFreshDurationNanos = getSatelliteLocationFreshDurationFromOverlayConfig(context);
}
+ private void loadConfigUpdaterConfigs() {
+ if (mSharedPreferences == null) {
+ loge("loadConfigUpdaterConfigs : mSharedPreferences is null");
+ return;
+ }
+
+ Set<String> countryCodes =
+ mSharedPreferences.getStringSet(CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY, null);
+
+ if (countryCodes == null || countryCodes.isEmpty()) {
+ loge("config updater country codes are either null or empty");
+ return;
+ }
+
+ boolean isSatelliteAllowAccessControl =
+ mSharedPreferences.getBoolean(
+ CONFIG_UPDATER_SATELLITE_IS_ALLOW_ACCESS_CONTROL_KEY, true);
+
+ File s2CellFile = getConfigUpdaterSatS2CellFileFromLocalDirectory();
+ if (s2CellFile == null) {
+ loge("s2CellFile is null");
+ return;
+ }
+
+ logd("use config updater config data");
+ mSatelliteS2CellFile = s2CellFile;
+ mSatelliteCountryCodes = countryCodes.stream().collect(Collectors.toList());
+ mIsSatelliteAllowAccessControl = isSatelliteAllowAccessControl;
+ }
+
private long getLocationFreshDurationNanos() {
synchronized (mLock) {
if (mIsOverlayConfigOverridden) {
@@ -430,7 +621,8 @@
}
}
- @NonNull private List<String> getSatelliteCountryCodes() {
+ @NonNull
+ private List<String> getSatelliteCountryCodes() {
synchronized (mLock) {
if (mIsOverlayConfigOverridden) {
return mOverriddenSatelliteCountryCodes;
@@ -439,7 +631,8 @@
}
}
- @Nullable private File getSatelliteS2CellFile() {
+ @Nullable
+ private File getSatelliteS2CellFile() {
synchronized (mLock) {
if (mIsOverlayConfigOverridden) {
return mOverriddenSatelliteS2CellFile;
@@ -660,8 +853,8 @@
}
}
- private void updateCachedAccessRestrictionMap(@NonNull
- SatelliteOnDeviceAccessController.LocationToken locationToken,
+ private void updateCachedAccessRestrictionMap(
+ @NonNull SatelliteOnDeviceAccessController.LocationToken locationToken,
boolean satelliteAllowed) {
synchronized (mLock) {
mCachedAccessRestrictionMap.put(locationToken, satelliteAllowed);
@@ -732,7 +925,8 @@
return false;
}
- @Nullable private Location getFreshLastKnownLocation() {
+ @Nullable
+ private Location getFreshLastKnownLocation() {
Location lastKnownLocation = getLastKnownLocation();
if (lastKnownLocation != null) {
long lastKnownLocationAge =
@@ -771,11 +965,21 @@
return result;
}
+ private void initSharedPreferences(@NonNull Context context) {
+ try {
+ mSharedPreferences =
+ context.getSharedPreferences(SATELLITE_SHARED_PREF, Context.MODE_PRIVATE);
+ } catch (Exception e) {
+ loge("Cannot get default shared preferences: " + e);
+ }
+ }
+
/**
* @return {@code true} if successfully initialize the {@link SatelliteOnDeviceAccessController}
* instance, {@code false} otherwise.
* @throws IllegalStateException in case of getting any exception in creating the
- * {@link SatelliteOnDeviceAccessController} instance and the device is using a user build.
+ * {@link SatelliteOnDeviceAccessController} instance and the
+ * device is using a user build.
*/
private boolean initSatelliteOnDeviceAccessController() throws IllegalStateException {
synchronized (mLock) {
@@ -969,7 +1173,7 @@
/**
* Posts the specified command to be executed on the main thread and returns immediately.
*
- * @param command command to be executed on the main thread
+ * @param command command to be executed on the main thread
* @param argument additional parameters required to perform of the operation
*/
private void sendRequestAsync(int command, @NonNull Object argument) {
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index 8df0603..aabc0fb 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -22,6 +22,7 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.EVENT_CONFIG_DATA_UPDATED;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.GOOGLE_US_SAN_SAT_S2_FILE_NAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -30,6 +31,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -45,6 +47,7 @@
import android.annotation.Nullable;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.Resources;
import android.location.Location;
import android.location.LocationManager;
@@ -85,12 +88,12 @@
import java.io.File;
import java.lang.reflect.Field;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -124,14 +127,26 @@
private SatelliteModemInterface mMockSatelliteModemInterface;
@Mock
private Context mMockContext;
- @Mock private Phone mMockPhone;
- @Mock private Phone mMockPhone2;
- @Mock private FeatureFlags mMockFeatureFlags;
- @Mock private Resources mMockResources;
- @Mock private SatelliteOnDeviceAccessController mMockSatelliteOnDeviceAccessController;
- @Mock Location mMockLocation0;
- @Mock Location mMockLocation1;
- @Mock File mMockSatS2File;
+ @Mock
+ private Phone mMockPhone;
+ @Mock
+ private Phone mMockPhone2;
+ @Mock
+ private FeatureFlags mMockFeatureFlags;
+ @Mock
+ private Resources mMockResources;
+ @Mock
+ private SatelliteOnDeviceAccessController mMockSatelliteOnDeviceAccessController;
+ @Mock
+ Location mMockLocation0;
+ @Mock
+ Location mMockLocation1;
+ @Mock
+ File mMockSatS2File;
+ @Mock
+ SharedPreferences mMockSharedPreferences;
+ @Mock
+ private SharedPreferences.Editor mMockSharedPreferencesEditor;
private Looper mLooper;
private TestableLooper mTestableLooper;
@@ -148,7 +163,6 @@
private ArgumentCaptor<Integer> mConfigUpdateIntCaptor;
@Captor
private ArgumentCaptor<Object> mConfigUpdateObjectCaptor;
-
private boolean mQueriedSatelliteAllowed = false;
private int mQueriedSatelliteAllowedResultCode = SATELLITE_RESULT_SUCCESS;
private Semaphore mSatelliteAllowedSemaphore = new Semaphore(0);
@@ -197,7 +211,7 @@
mMockLocationManager);
when(mMockContext.getSystemService(TelecomManager.class)).thenReturn(
mMockTelecomManager);
- mPhones = new Phone[] {mMockPhone, mMockPhone2};
+ mPhones = new Phone[]{mMockPhone, mMockPhone2};
replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
replaceInstance(SatelliteController.class, "sInstance", null,
mMockSatelliteController);
@@ -231,6 +245,17 @@
when(mMockSatelliteOnDeviceAccessController.isSatCommunicationAllowedAtLocation(
any(SatelliteOnDeviceAccessController.LocationToken.class))).thenReturn(true);
+ when(mMockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(
+ mMockSharedPreferences);
+ when(mMockSharedPreferences.getBoolean(anyString(), anyBoolean())).thenReturn(true);
+ when(mMockSharedPreferences.getStringSet(anyString(), any()))
+ .thenReturn(Set.of(TEST_SATELLITE_COUNTRY_CODES));
+ doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferences).edit();
+ doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
+ .putBoolean(anyString(), anyBoolean());
+ doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
+ .putStringSet(anyString(), any());
+
mSatelliteAccessControllerUT = new TestSatelliteAccessController(mMockContext,
mMockFeatureFlags, mLooper, mMockLocationManager, mMockTelecomManager,
mMockSatelliteOnDeviceAccessController, mMockSatS2File);
@@ -463,7 +488,7 @@
}
@Test
- public void testUpdateSatelliteConfigData() {
+ public void testUpdateSatelliteConfigData() throws Exception {
verify(mMockSatelliteController).registerForConfigUpdateChanged(
mConfigUpdateHandlerCaptor.capture(), mConfigUpdateIntCaptor.capture(),
mConfigUpdateObjectCaptor.capture());
@@ -472,46 +497,58 @@
assertSame(mConfigUpdateIntCaptor.getValue(), EVENT_CONFIG_DATA_UPDATED);
assertSame(mConfigUpdateObjectCaptor.getValue(), mMockContext);
- // Verify the case when the configParser is not exist.
- SatelliteConfigParser spyConfigParserNull =
- spy(new SatelliteConfigParser((byte[]) null));
- doReturn(spyConfigParserNull).when(mMockSatelliteController).getSatelliteConfigParser();
+ // These APIs are executed during loadRemoteConfigs
+ verify(mMockSharedPreferences, times(1)).getStringSet(anyString(), any());
+ verify(mMockSharedPreferences, times(1)).getBoolean(anyString(), anyBoolean());
- sendConfigUpdateChangedEvent(mMockContext);
-
- assertNull(spyConfigParserNull.getConfig());
-
- // Verify the case when the configParser exist but empty.
- SatelliteConfigParser spyConfigParserEmpty =
+ // satelliteConfig is null
+ SatelliteConfigParser spyConfigParser =
spy(new SatelliteConfigParser("test".getBytes()));
- doReturn(spyConfigParserEmpty).when(mMockSatelliteController).getSatelliteConfigParser();
+ doReturn(spyConfigParser).when(mMockSatelliteController).getSatelliteConfigParser();
+ assertNull(spyConfigParser.getConfig());
sendConfigUpdateChangedEvent(mMockContext);
+ verify(mMockSharedPreferences, never()).edit();
- assertNull(spyConfigParserEmpty.getConfig());
+ // satelliteConfig has invalid country codes
+ SatelliteConfig mockConfig = mock(SatelliteConfig.class);
+ doReturn(List.of("USA", "JAP")).when(mockConfig).getDeviceSatelliteCountryCodes();
+ doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
+ doReturn(false).when(mockConfig).isSatelliteDataForAllowedRegion();
- // Verify the case when the configParser exists and has valid data
- SatelliteConfig mockSatelliteConfig = mock(SatelliteConfig.class);
- Path mockTargetSatS2FilePath = mock(Path.class);
- File mockS2CellFile = mock(File.class);
- doReturn(mockS2CellFile).when(mockTargetSatS2FilePath).toFile();
- doReturn(true).when(mockS2CellFile).exists();
- doReturn(false).when(mockSatelliteConfig).isFileExist(any());
- doReturn(mockTargetSatS2FilePath).when(mockSatelliteConfig)
- .copySatS2FileToPhoneDirectory(any(), any());
- doReturn(Arrays.asList("US")).when(mockSatelliteConfig).getDeviceSatelliteCountryCodes();
- doReturn(false).when(mockSatelliteConfig).isSatelliteDataForAllowedRegion();
- doReturn(mockTargetSatS2FilePath).when(mockSatelliteConfig).getSatelliteS2CellFile(any());
- doReturn(mockSatelliteConfig).when(mMockSatelliteController).getSatelliteConfig();
-
- mSatelliteAccessControllerUT.setSatelliteOnDeviceAccessController(
- mMockSatelliteOnDeviceAccessController);
sendConfigUpdateChangedEvent(mMockContext);
+ verify(mMockSharedPreferences, never()).edit();
- verify(mockSatelliteConfig, times(2)).getDeviceSatelliteCountryCodes();
- verify(mockSatelliteConfig, times(2)).isSatelliteDataForAllowedRegion();
- verify(mockSatelliteConfig, times(2)).getSatelliteS2CellFile(any());
- assertTrue(mSatelliteAccessControllerUT.isSatelliteOnDeviceAccessControllerReset());
+ // satelliteConfig does not have is_allow_access_control data
+ doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
+ .when(mockConfig).getDeviceSatelliteCountryCodes();
+ doReturn(null).when(mockConfig).isSatelliteDataForAllowedRegion();
+
+ sendConfigUpdateChangedEvent(mMockContext);
+ verify(mMockSharedPreferences, never()).edit();
+
+ // satelliteConfig doesn't have S2CellFile
+ File mockFile = mock(File.class);
+ doReturn(false).when(mockFile).exists();
+ doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
+ .when(mockConfig).getDeviceSatelliteCountryCodes();
+ doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
+ doReturn(mockFile).when(mockConfig).getSatelliteS2CellFile(mMockContext);
+
+ sendConfigUpdateChangedEvent(mMockContext);
+ verify(mMockSharedPreferences, never()).edit();
+
+ // satelliteConfig has valid data
+ doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
+ File testS2File = mSatelliteAccessControllerUT
+ .getTestSatelliteS2File(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
+ doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
+ .when(mockConfig).getDeviceSatelliteCountryCodes();
+ doReturn(true).when(mockConfig).isSatelliteDataForAllowedRegion();
+ doReturn(testS2File).when(mockConfig).getSatelliteS2CellFile(mMockContext);
+
+ sendConfigUpdateChangedEvent(mMockContext);
+ verify(mMockSharedPreferences, times(2)).edit();
}
private void sendConfigUpdateChangedEvent(Context context) {