Merge cherrypicks of ['googleplex-android-review.googlesource.com/32650559', 'googleplex-android-review.googlesource.com/32797479'] into 25Q2-release.

Change-Id: I675d8e59031d99c15c86135c9ecd8797f66deea9
This commit is contained in:
Android Build Coastguard Worker
2025-03-31 20:55:39 -07:00
9 changed files with 261 additions and 87 deletions

View File

@@ -38,7 +38,6 @@ import com.android.settings.network.telephony.TelephonyBasePreferenceController;
import com.android.settingslib.Utils;
import java.util.List;
import java.util.Set;
/** A controller to show some of apps info which supported on Satellite service. */
public class SatelliteAppListCategoryController extends TelephonyBasePreferenceController {
@@ -121,20 +120,7 @@ public class SatelliteAppListCategoryController extends TelephonyBasePreferenceC
== CARRIER_ROAMING_NTN_CONNECT_MANUAL) {
return mIsSmsAvailable;
}
SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class);
if (satelliteManager == null) {
Log.d(TAG, "SatelliteManager is null.");
return false;
}
try {
Set<Integer> restrictionReason =
satelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
return !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
} catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
Log.d(TAG, "Error to getAttachRestrictionReasonsForCarrier : " + ex);
return false;
}
return SatelliteCarrierSettingUtils.isSatelliteAccountEligible(mContext, mSubId);
}
static ApplicationInfo getApplicationInfo(Context context, String packageName) {

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.network.telephony.satellite;
import static android.telephony.CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
import android.content.Context;
import android.telephony.satellite.SatelliteManager;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import java.util.Collections;
import java.util.Set;
/** A until for carrier satellite setting. */
public class SatelliteCarrierSettingUtils {
private static final String TAG = "SatelliteCarrierSettingUtils";
@VisibleForTesting
static SatelliteManagerWrapper sSatelliteManagerWrapper;
/**
* Checks account is eligible.
*
* @return true if there is no restriction reason returned.
*/
public static boolean isSatelliteAccountEligible(Context context, int subId) {
SatelliteManagerWrapper wrapper =
sSatelliteManagerWrapper == null ? new SatelliteManagerWrapper(context)
: sSatelliteManagerWrapper;
Set<Integer> restrictionReason = wrapper.getAttachRestrictionReasonsForCarrier(subId);
return !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
}
/**
* Use getSatelliteDataSupportMode to check data mode is restricted.
*
* @return true if data mode is restricted.
*/
public static boolean isSatelliteDataRestricted(Context context, int subId) {
SatelliteManagerWrapper wrapper =
sSatelliteManagerWrapper == null ? new SatelliteManagerWrapper(context)
: sSatelliteManagerWrapper;
return wrapper.getSatelliteDataSupportMode(subId) <= SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
}
@VisibleForTesting
static class SatelliteManagerWrapper {
private final SatelliteManager mSatelliteManager;
SatelliteManagerWrapper(Context context) {
mSatelliteManager = context.getSystemService(SatelliteManager.class);
}
public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) {
if (mSatelliteManager == null) {
Log.d(TAG, "SatelliteManager is null.");
return Collections.emptySet();
}
try {
Set<Integer> restrictionReason =
mSatelliteManager.getAttachRestrictionReasonsForCarrier(subId);
Log.d(TAG, "Error to getAttachRestrictionReasonsForCarrier : " + restrictionReason);
return restrictionReason;
} catch (SecurityException | IllegalStateException | IllegalArgumentException e) {
Log.d(TAG, "Error to getAttachRestrictionReasonsForCarrier : " + e);
}
return Collections.emptySet();
}
public int getSatelliteDataSupportMode(int subId) {
if (mSatelliteManager == null) {
Log.d(TAG, "SatelliteManager is null.");
return SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
}
var dataMode = SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
try {
dataMode = mSatelliteManager.getSatelliteDataSupportMode(subId);
Log.d(TAG, "Data mode : " + dataMode);
} catch (IllegalStateException e) {
Log.d(TAG, "Failed to get data mode : " + e);
}
return dataMode;
}
}
}

View File

@@ -23,7 +23,9 @@ import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUP
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING;
import static android.telephony.CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
import static com.android.settings.network.telephony.satellite.SatelliteCarrierSettingUtils.isSatelliteAccountEligible;
import static com.android.settings.network.telephony.satellite.SatelliteCarrierSettingUtils.isSatelliteDataRestricted;
import android.app.Activity;
import android.app.settings.SettingsEnums;
@@ -45,8 +47,6 @@ import androidx.preference.PreferenceCategory;
import com.android.settings.R;
import com.android.settings.dashboard.RestrictedDashboardFragment;
import java.util.Set;
/** Handle Satellite Setting Preference Layout. */
public class SatelliteSetting extends RestrictedDashboardFragment {
private static final String TAG = "SatelliteSetting";
@@ -108,7 +108,7 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
boolean isSatelliteEligible = isSatelliteEligible();
boolean isSatelliteEligible = isSatelliteAccountEligible(getContext(), mSubId);
updateHowItWorksContent(isSatelliteEligible);
}
@@ -141,22 +141,6 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
supportedService.setSummary(R.string.summary_supported_service_for_manual_type);
}
private boolean isSatelliteEligible() {
if (isCarrierRoamingNtnConnectedTypeManual()) {
return mIsSmsAvailableForManualType;
}
try {
Set<Integer> restrictionReason =
mSatelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
Log.d(TAG, "Restriction reason : " + restrictionReason);
return !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
} catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
loge(ex.toString());
return false;
}
}
private PersistableBundle fetchCarrierConfigData(int subId) {
CarrierConfigManager carrierConfigManager = mActivity.getSystemService(
CarrierConfigManager.class);
@@ -189,21 +173,6 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
private boolean isDataAvailableAndNotRestricted() {
return getIntent().getBooleanExtra(EXTRA_IS_SERVICE_DATA_TYPE, false)
&& !isDataRestricted();
}
private boolean isDataRestricted() {
int dataMode = SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
try {
dataMode = mSatelliteManager.getSatelliteDataSupportMode(mSubId);
Log.d(TAG, "Data mode : " + dataMode);
} catch (IllegalStateException e) {
Log.d(TAG, "Failed to get data mode : " + e);
}
return dataMode <= SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
}
private static void loge(String message) {
Log.e(TAG, message);
&& !isSatelliteDataRestricted(getContext(), mSubId);
}
}

View File

@@ -28,12 +28,10 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.PersistableBundle;
import android.telephony.TelephonyManager;
import android.telephony.satellite.SatelliteManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -45,8 +43,6 @@ import com.android.settings.R;
import com.android.settings.network.telephony.TelephonyBasePreferenceController;
import com.android.settingslib.Utils;
import java.util.Set;
/** A controller to control content of "Your mobile plan". */
public class SatelliteSettingAccountInfoController extends TelephonyBasePreferenceController {
private static final String TAG = "SatelliteSettingAccountInfoController";
@@ -164,19 +160,6 @@ public class SatelliteSettingAccountInfoController extends TelephonyBasePreferen
== CARRIER_ROAMING_NTN_CONNECT_MANUAL) {
return mIsSmsAvailable;
}
SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class);
if (satelliteManager == null) {
Log.d(TAG, "SatelliteManager is null.");
return false;
}
try {
Set<Integer> restrictionReason =
satelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
return !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
} catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
Log.d(TAG, "Error to getAttachRestrictionReasonsForCarrier : " + ex.toString());
return false;
}
return SatelliteCarrierSettingUtils.isSatelliteAccountEligible(mContext, mSubId);
}
}

View File

@@ -48,7 +48,6 @@ import com.android.settings.network.telephony.TelephonyBasePreferenceController;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* Preference controller for "Satellite Setting"
@@ -191,10 +190,9 @@ public class SatelliteSettingPreferenceController extends
}
try {
Set<Integer> restrictionReason =
mSatelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
boolean isSatelliteEligible = !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
boolean isSatelliteEligible =
SatelliteCarrierSettingUtils.isSatelliteAccountEligible(
mContext, mSubId);
if (mIsSatelliteEligible == null || mIsSatelliteEligible != isSatelliteEligible) {
mIsSatelliteEligible = isSatelliteEligible;
String summary = mContext.getString(

View File

@@ -47,8 +47,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
/** Preference controller for Satellite functions in mobile network settings. */
public class SatelliteSettingsPreferenceCategoryController
extends TelephonyBasePreferenceController implements DefaultLifecycleObserver {
public class SatelliteSettingsPreferenceCategoryController extends
TelephonyBasePreferenceController implements DefaultLifecycleObserver {
private static final String TAG = "SatelliteSettingsPrefCategoryCon";
@VisibleForTesting
@@ -99,16 +99,22 @@ public class SatelliteSettingsPreferenceCategoryController
if (!com.android.internal.telephony.flags.Flags.carrierEnabledSatelliteFlag()) {
return UNSUPPORTED_ON_DEVICE;
}
final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
if (!mIsSatelliteSupported.get()) {
boolean isSatelliteConnectedTypeIsAuto =
CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC == carrierConfig.getInt(
KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC);
// SatelliteManager#requestIsSupported is only supported for manual connection type, so
// if type is auto, this check shall be skipped.
if (!isSatelliteConnectedTypeIsAuto && !mIsSatelliteSupported.get()) {
return UNSUPPORTED_ON_DEVICE;
}
final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
boolean isSatelliteSosSupported = false;
if (Flags.satelliteOemSettingsUxMigration()) {
isSatelliteSosSupported = carrierConfig.getBoolean(
KEY_SATELLITE_ESOS_SUPPORTED_BOOL);
isSatelliteSosSupported = carrierConfig.getBoolean(KEY_SATELLITE_ESOS_SUPPORTED_BOOL);
}
if (!carrierConfig.getBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL)) {
@@ -119,9 +125,7 @@ public class SatelliteSettingsPreferenceCategoryController
return AVAILABLE_UNSEARCHABLE;
}
if (CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC == carrierConfig.getInt(
KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC)) {
if (isSatelliteConnectedTypeIsAuto) {
return AVAILABLE_UNSEARCHABLE;
} else {
return mCarrierRoamingNtnModeCallback.isSatelliteSmsAvailable()
@@ -171,8 +175,7 @@ public class SatelliteSettingsPreferenceCategoryController
SatelliteSettingsPreferenceCategoryController mController;
private boolean mIsSatelliteSmsAvailable = false;
CarrierRoamingNtnModeCallback(
SatelliteSettingsPreferenceCategoryController controller) {
CarrierRoamingNtnModeCallback(SatelliteSettingsPreferenceCategoryController controller) {
mController = controller;
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.network.telephony.satellite;
import static android.telephony.CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL;
import static android.telephony.CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.os.Looper;
import android.telephony.satellite.SatelliteManager;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class SatelliteCarrierSettingUtilsTest {
private static final int TEST_SUB_ID = 0;
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private Context mContext;
@Before
public void setUp() {
if (Looper.myLooper() == null) {
Looper.prepare();
}
mContext = spy(ApplicationProvider.getApplicationContext());
}
@Test
public void isSatelliteAccountEligible_noRestrictedReason_returnTrue() {
SatelliteCarrierSettingUtils.SatelliteManagerWrapper wrapper =
new SatelliteCarrierSettingUtils.SatelliteManagerWrapper(mContext) {
@Override
public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) {
return Collections.emptySet();
}
};
SatelliteCarrierSettingUtils.sSatelliteManagerWrapper = wrapper;
boolean result = SatelliteCarrierSettingUtils.isSatelliteAccountEligible(mContext,
TEST_SUB_ID);
assertThat(result).isTrue();
}
@Test
public void isSatelliteAccountEligible_hasRestrictedReason_returnFalse() throws Exception {
SatelliteCarrierSettingUtils.sSatelliteManagerWrapper =
new SatelliteCarrierSettingUtils.SatelliteManagerWrapper(mContext) {
@Override
public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) {
Set<Integer> set = new HashSet<>();
set.add(SatelliteManager
.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
return set;
}
};
boolean result = SatelliteCarrierSettingUtils.isSatelliteAccountEligible(mContext,
TEST_SUB_ID);
assertThat(result).isFalse();
}
@Test
public void isSatelliteDataRestricted_unlimitedDataMode_returnFalse() throws Exception {
SatelliteCarrierSettingUtils.sSatelliteManagerWrapper =
new SatelliteCarrierSettingUtils.SatelliteManagerWrapper(mContext) {
@Override
public int getSatelliteDataSupportMode(int subId) {
return SATELLITE_DATA_SUPPORT_ALL;
}
};
boolean result = SatelliteCarrierSettingUtils.isSatelliteDataRestricted(mContext,
TEST_SUB_ID);
assertThat(result).isFalse();
}
@Test
public void isSatelliteDataRestricted_restrictedDataMode_returnTrue() throws Exception {
SatelliteCarrierSettingUtils.sSatelliteManagerWrapper =
new SatelliteCarrierSettingUtils.SatelliteManagerWrapper(mContext) {
@Override
public int getSatelliteDataSupportMode(int subId) {
return SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED;
}
};
boolean result = SatelliteCarrierSettingUtils.isSatelliteDataRestricted(mContext,
TEST_SUB_ID);
assertThat(result).isTrue();
}
}

View File

@@ -59,7 +59,7 @@ import org.mockito.junit.MockitoRule;
@RunWith(AndroidJUnit4.class)
@UiThreadTest
public class SatelliteSettingsPreferenceControllerTest {
public class SatelliteSettingPreferenceControllerTest {
private static final String KEY = "SatelliteSettingsPreferenceControllerTest";
private static final int TEST_SUB_ID = 5;

View File

@@ -77,6 +77,8 @@ public class SatelliteSettingsPreferenceCategoryControllerTest {
CarrierConfigCache.setTestInstance(mContext, mCarrierConfigCache);
mController = new SatelliteSettingsPreferenceCategoryController(mContext, KEY);
when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mPersistableBundle);
mPersistableBundle.putInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC);
when(mContext.getSystemService(SatelliteManager.class)).thenReturn(satelliteManager);
mController.mIsSatelliteSupported.set(true);
}
@@ -95,7 +97,10 @@ public class SatelliteSettingsPreferenceCategoryControllerTest {
@Test
@EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void getAvailabilityStatus_deviceUnsupported_returnUnsupported() {
mPersistableBundle.putInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
CARRIER_ROAMING_NTN_CONNECT_MANUAL);
mController.mIsSatelliteSupported.set(false);
mController.init(TEST_SUB_ID);
int result = mController.getAvailabilityStatus(TEST_SUB_ID);