Add Satellite Messaging activity

Add satellite messaging activity into Settings for carrier satellite
service

Bug: 319035517
Test: manual
1. Set CarrierConfig Key KEY_SATELLITE_ATTACH_SUPPORTED_BOOL as false then verify satellite messaging menu is not shwon from
   Settings > Network & internet > SIMs > test sim
2. Set CarrierConfig key KEY_SATELLITE_ATTACH_SUPPORTED_BOOL as true
3. Insert test SIM
3. Get into to Settings > Network & internet > SIMs > test sim > verify Satellite messaging is shown
4. Verify whether descriptions are as directed. icons are as directed.
5. Add satellite messaging does not work when click
6. Invoke web browser with test website when click 'More about satellite messaging'
7. Replace SIM of which MCC/MNC is not test sim
8. verify no action happen when click 'More about satellite messaging'

Change-Id: Iee8fad58b41cbca34f373d2a9df1d074c447cfb1
This commit is contained in:
Hakjun Choi
2024-01-09 20:00:15 +00:00
parent 17acb392bf
commit 2f57f53831
15 changed files with 657 additions and 3 deletions

View File

@@ -627,6 +627,27 @@
android:value="true" />
</activity>
<activity android:name="Settings$SatelliteSettingActivity"
android:label="@string/satellite_setting"
android:exported="true"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter android:priority="1">
<action android:name="android.settings.SATELLITE_SETTING" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE_LAUNCH" />
</intent-filter>
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.network.telephony.SatelliteSetting" />
<meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
android:value="@string/menu_key_network"/>
</activity>
<activity android:name="Settings$ApnSettingsActivity"
android:label="@string/apn_settings"
android:exported="true"

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2024 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q534,800 584,782.5Q634,765 676,732L228,284Q195,326 177.5,376Q160,426 160,480Q160,614 253,707Q346,800 480,800ZM732,676Q765,634 782.5,584Q800,534 800,480Q800,346 707,253Q614,160 480,160Q426,160 376,177.5Q326,195 284,228L732,676Z"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2024 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M424,664L706,382L650,326L424,552L310,438L254,494L424,664ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,346 707,253Q614,160 480,160Q346,160 253,253Q160,346 160,480Q160,614 253,707Q346,800 480,800ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2024 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M560,928L560,848Q677,848 758.5,766.5Q840,685 840,568L920,568Q920,643 891.5,708.5Q863,774 814.5,822.5Q766,871 700.5,899.5Q635,928 560,928ZM560,768L560,688Q610,688 645,653Q680,618 680,568L760,568Q760,651 701.5,709.5Q643,768 560,768ZM222,903Q207,903 192,897Q177,891 165,880L23,738Q12,726 6,711Q0,696 0,681Q0,665 6,650.5Q12,636 23,625L150,498Q173,475 207,474.5Q241,474 264,497L314,547L342,519L292,469Q269,446 269,413Q269,380 292,357L349,300Q372,277 405.5,277Q439,277 462,300L512,350L540,322L490,272Q467,249 467,215.5Q467,182 490,159L617,32Q629,20 644,14Q659,8 674,8Q689,8 703.5,14Q718,20 730,32L872,174Q884,185 889.5,199.5Q895,214 895,230Q895,245 889.5,260Q884,275 872,287L745,414Q722,437 688.5,437Q655,437 632,414L582,364L554,392L604,442Q627,465 626.5,498.5Q626,532 603,555L547,611Q524,634 490.5,634Q457,634 434,611L384,561L356,589L406,639Q429,662 428.5,696Q428,730 405,753L278,880Q267,891 252.5,897Q238,903 222,903ZM222,824Q222,824 222,824Q222,824 222,824L264,782L122,640L80,682Q80,682 80,682Q80,682 80,682L222,824ZM307,739L349,697Q349,697 349,697Q349,697 349,697L207,555Q207,555 207,555Q207,555 207,555L165,597L307,739ZM491,555Q491,555 491,555Q491,555 491,555L547,499Q547,499 547,499Q547,499 547,499L405,357Q405,357 405,357Q405,357 405,357L349,413Q349,413 349,413Q349,413 349,413L491,555ZM689,357Q689,357 689,357Q689,357 689,357L731,315L589,173L547,215Q547,215 547,215Q547,215 547,215L689,357ZM774,272L816,230Q816,230 816,230Q816,230 816,230L674,88Q674,88 674,88Q674,88 674,88L632,130L774,272ZM448,456L448,456Q448,456 448,456Q448,456 448,456L448,456Q448,456 448,456Q448,456 448,456L448,456Q448,456 448,456Q448,456 448,456L448,456Q448,456 448,456Q448,456 448,456Z"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2024 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M676,860L620,804L704,720L620,636L676,580L760,664L844,580L900,636L817,720L900,804L844,860L760,777L676,860ZM80,880L880,81L880,508Q862,497 842,490.5Q822,484 800,480L800,274L273,800L530,800Q538,823 550,843Q562,863 577,880L80,880ZM273,800L800,274L800,274Q800,274 800,274Q800,274 800,274Q724,350 662,411.5Q600,473 540.5,532.5Q481,592 417,656Q353,720 273,800Q273,800 273,800Q273,800 273,800L273,800Z"/>
</vector>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2024 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="24dp"/>
<solid android:color="@android:color/transparent"/>
<stroke
android:width="1dp"
android:color="?android:attr/textColorPrimary"/>
</shape>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2024 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/satellite_more_information_background_outline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeight"
android:focusable="false"
android:gravity="center_vertical">
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:focusable="false"
android:hyphenationFrequency="normalFast"
android:lineBreakWordStyle="phrase"
android:maxLines="10" />
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:focusable="false"
android:hyphenationFrequency="normalFast"
android:lineBreakWordStyle="phrase"
android:maxLines="10" />
</LinearLayout>

View File

@@ -3256,6 +3256,10 @@
<!-- Summary of the communal settings under Settings > Communal [CHAR LIMIT=50] -->
<string name="communal_settings_summary">Communal settings</string>
<!-- _satellite_setting_preference_layout -->
<!-- _satellite_setting_preference_layout screen title-->
<string name="satellite_setting">Satellite Messaging</string>
<!-- APN Settings -->
<!-- APN settings screen title -->
<string name="apn_settings">APNs</string>
@@ -11405,6 +11409,43 @@
<string name="mobile_data_usage_title">App data usage</string>
<!-- Summary to show the current network mode is invalid. [CHAR LIMIT=NONE]-->
<string name="mobile_network_mode_error">Invalid Network Mode <xliff:g id="networkModeId" example="0">%1$d</xliff:g>. Ignore.</string>
<!-- Title for _satellite_setting_preference_layout in mobile network settings [CHAR LIMIT=60] -->
<string name="satellite_setting_title">Satellite messaging</string>
<!-- Summary for _satellite_setting_preference_layout. [CHAR LIMIT=NONE]-->
<string name="satellite_setting_enabled_summary">Send and receive text messages by satellite. Included with your account.</string>
<!-- Summary for _satellite_setting_preference_layout. [CHAR LIMIT=NONE]-->
<string name="satellite_setting_disabled_summary">Send and receive text messages by satellite. Non included with your account.</string>
<!-- Search keywords for "_satellite_setting_preference_layout" [CHAR_LIMIT=NONE] -->
<string name="keywords_satellite_setting">Satellite messaging</string>
<!-- Category name "About satellite messaging" [CHAR_LIMIT=NONE] -->
<string name="category_name_about_satellite_messaging">About satellite messaging</string>
<!-- Summary for category "About satellite messaging" [CHAR_LIMIT=NONE] -->
<string name="title_about_satellite_setting">You can send and receive text messages by satellite as part of an eligible <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> account</string>
<!-- Category title "Your mobile plan" [CHAR_LIMIT=NONE] -->
<string name="category_title_your_satellite_plan">Your <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> plan</string>
<!-- Title for category "Your mobile plan when satellite is included in plan" [CHAR_LIMIT=NONE] -->
<string name="title_have_satellite_plan">Satellite messaging is included with your account</string>
<!-- Title for category "Your mobile plan when satellite is not included in plan" [CHAR_LIMIT=NONE] -->
<string name="title_no_satellite_plan">Satellite messaging isn\u2019t included with your account</string>
<!-- text view add satellite messaging" [CHAR_LIMIT=NONE] -->
<string name="summary_add_satellite_setting">Add satellite messaging</string>
<!-- Category name "How it works" [CHAR_LIMIT=NONE] -->
<string name="category_name_how_it_works">How it works</string>
<!-- Title for satellite connection guide [CHAR_LIMIT=NONE] -->
<string name="title_satellite_connection_guide">When you don\u2019t have a mobile network</string>
<!-- Summary for satellite connection guide [CHAR_LIMIT=NONE] -->
<string name="summary_satellite_connection_guide">Your phone will auto-connect to a satellite. For the best connection, keep a clear view of the sky.</string>
<!-- Title for satellite supported service [CHAR_LIMIT=NONE] -->
<string name="title_supported_service">After your phone connects to a satellite</string>
<!-- Summary for satellite supported service [CHAR_LIMIT=NONE] -->
<string name="summary_supported_service">You can text anyone, including emergency services. Your phone will reconnect to a mobile network when available.</string>
<!-- learn more text - more about satellite messaging [CHAR_LIMIT=NONE] -->
<string name="satellite_setting_summary_more_information">Satellite messaging may take longer and is available only in some areas, Weather and certain structures may affect your satellite connection. Calling by satellite isn\u2019t available.\n\nIt may take some time for changes to your account to show in Settings. Contact <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> for details.</string>
<!-- more about satellite messaging [CHAR_LIMIT=NONE] -->
<string name="more_about_satellite_messaging">More about satellite messaging</string>
<!-- URL for more info about satellite messaging [CHAR LIMIT=60] -->
<string name="more_info_satellite_messaging_link" translatable="false"></string>
<!-- Title for Apn settings in mobile network settings [CHAR LIMIT=60] -->
<string name="mobile_network_apn_title">Access Point Names</string>
<!-- Search keywords for "Access Point Names" [CHAR_LIMIT=NONE] -->

View File

@@ -208,6 +208,7 @@
<PreferenceCategory
android:key="network_operators_category_key"
android:title="@string/network_operator_category"
settings:allowDividerBelow="true"
settings:controller="com.android.settings.network.telephony.NetworkPreferenceCategoryController">
<com.android.settings.spa.preference.ComposePreference
@@ -221,12 +222,19 @@
settings:controller="com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController"/>
</PreferenceCategory>
<com.android.settingslib.RestrictedPreference
android:key="telephony_satellite_setting_key"
android:persistent="false"
android:title="@string/satellite_setting_title"
settings:keywords="@string/keywords_satellite_setting"
settings:controller=
"com.android.settings.network.telephony.SatelliteSettingPreferenceController"/>
<!--We want separate APN setting from reset of settings because we want user to change it with caution-->
<com.android.settingslib.RestrictedPreference
android:key="telephony_apn_key"
android:persistent="false"
android:title="@string/mobile_network_apn_title"
settings:allowDividerAbove="true"
settings:keywords="@string/keywords_access_point_names"
settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>
@@ -249,7 +257,7 @@
android:title="@string/require_cellular_encryption_title"
android:summary="@string/require_cellular_encryption_summary"
settings:controller=
"com.android.settings.network.telephony.NullAlgorithmsPreferenceController" />
"com.android.settings.network.telephony.NullAlgorithmsPreferenceController"/>
<SwitchPreferenceCompat
android:key="nr_advanced_calling"

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2024 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="satellite_setting"
android:title="@string/satellite_setting"
settings:keywords="@string/keywords_satellite_setting">
<PreferenceCategory
android:title="@string/category_name_about_satellite_messaging">
<com.android.settingslib.widget.TopIntroPreference
android:key="key_about_satellite_messaging"/>
</PreferenceCategory>
<PreferenceCategory
android:key="key_category_your_satellite_plan"
android:title="@string/category_title_your_satellite_plan">
<Preference
android:key="key_your_satellite_plan"
android:icon="?android:attr/textColorPrimary"/>
</PreferenceCategory>
<PreferenceCategory
android:key="key_category_how_it_works"
android:title="@string/category_name_how_it_works"
android:clickable="false"
android:focusable="false">
<Preference
android:key="key_satellite_connection_guide"
android:title="@string/title_satellite_connection_guide"
android:summary="@string/summary_satellite_connection_guide"
android:icon="@drawable/ic_signal_cellular_nodata_24px"/>
<Preference
android:key="key_supported_service"
android:title="@string/title_supported_service"
android:summary="@string/summary_supported_service"
android:icon="@drawable/ic_satellite_alt_24px"/>
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference
android:key="satellite_setting_extra_info_footer_pref"
android:layout="@layout/satellite_setting_more_information_layout"
android:selectable="false"
settings:searchable="false"/>
</PreferenceScreen>

View File

@@ -345,6 +345,7 @@ public class Settings extends SettingsActivity {
/* empty */
}
public static class SatelliteSettingActivity extends SettingsActivity { /* empty */ }
public static class ApnSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiCallingSettingsActivity extends SettingsActivity { /* empty */ }
public static class MemorySettingsActivity extends SettingsActivity { /* empty */ }

View File

@@ -143,6 +143,7 @@ import com.android.settings.network.apn.ApnEditor;
import com.android.settings.network.apn.ApnSettings;
import com.android.settings.network.telephony.MobileNetworkSettings;
import com.android.settings.network.telephony.NetworkSelectSettings;
import com.android.settings.network.telephony.SatelliteSetting;
import com.android.settings.network.tether.TetherSettings;
import com.android.settings.nfc.PaymentSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
@@ -300,6 +301,7 @@ public class SettingsGateway {
AppNotificationSettings.class.getName(),
NotificationAssistantPicker.class.getName(),
ChannelNotificationSettings.class.getName(),
SatelliteSetting.class.getName(),
ApnSettings.class.getName(),
ApnEditor.class.getName(),
WifiCallingSettings.class.getName(),

View File

@@ -255,6 +255,11 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
roamingPreferenceController.init(getFragmentManager(), mSubId,
mMobileNetworkInfoEntity);
}
final SatelliteSettingPreferenceController satelliteSettingPreferenceController = use(
SatelliteSettingPreferenceController.class);
if (satelliteSettingPreferenceController != null) {
satelliteSettingPreferenceController.init(mSubId);
}
use(ApnPreferenceController.class).init(mSubId);
use(CarrierPreferenceController.class).init(mSubId);
use(DataUsagePreferenceController.class).init(mSubId);

View File

@@ -0,0 +1,198 @@
/*
* Copyright (C) 2024 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;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserManager;
import android.telephony.SubscriptionManager;
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 android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import com.android.settings.R;
import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.widget.FooterPreference;
import java.util.Set;
/** Handle Satellite Setting Preference Layout. */
public class SatelliteSetting extends RestrictedDashboardFragment {
private static final String TAG = "SatelliteSetting";
public static final String PREF_KEY_ABOUT_SATELLITE_MESSAGING = "key_about_satellite_messaging";
public static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN =
"key_category_your_satellite_plan";
public static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan";
public static final String PREF_KEY_CATEGORY_HOW_IT_WORKS = "key_category_how_it_works";
private static final String KEY_FOOTER_PREFERENCE = "satellite_setting_extra_info_footer_pref";
public static final String SUB_ID = "sub_id";
private Activity mActivity;
private TelephonyManager mTelephonymanager;
private SatelliteManager mSatelliteManager;
private int mSubId;
public SatelliteSetting() {
super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
}
@Override
public int getMetricsCategory() {
return SettingsEnums.SATELLITE_SETTING;
}
@Override
public void onCreate(@NonNull Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = getActivity();
mTelephonymanager = mActivity.getSystemService(TelephonyManager.class);
mSatelliteManager = mActivity.getSystemService(SatelliteManager.class);
mSubId = mActivity.getIntent().getIntExtra(SUB_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
updateDynamicPreferenceViews();
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.satellite_setting;
}
private void updateDynamicPreferenceViews() {
String operatorName = mTelephonymanager.getSimOperatorName(mSubId);
boolean isSatelliteEligible = isSatelliteEligible();
// About satellite messaging
Preference preference = findPreference(PREF_KEY_ABOUT_SATELLITE_MESSAGING);
preference.setTitle(
getResources().getString(R.string.title_about_satellite_setting, operatorName));
// Your mobile plan
PreferenceCategory prefCategory = findPreference(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
prefCategory.setTitle(getResources().getString(R.string.category_title_your_satellite_plan,
operatorName));
preference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
Drawable icon;
if (isSatelliteEligible) {
/* In case satellite is allowed by carrier's entitlement server, the page will show
the check icon with guidance that satellite is included in user's mobile plan */
preference.setTitle(R.string.title_have_satellite_plan);
icon = getResources().getDrawable(R.drawable.ic_check_circle_24px);
} else {
/* Or, it will show the blocked icon with the guidance that satellite is not included
in user's mobile plan */
preference.setTitle(R.string.title_no_satellite_plan);
/* And, the link url provides more information via web page will be shown */
SpannableString spannable = new SpannableString(
getResources().getString(R.string.summary_add_satellite_setting));
spannable.setSpan(new UnderlineSpan(), 0, spannable.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
preference.setSummary(spannable);
/* The link will lead users to a guide page */
preference.setOnPreferenceClickListener(pref -> {
String url = getResources().getString(R.string.more_info_satellite_messaging_link);
if (!url.isEmpty()) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
return true;
});
icon = getResources().getDrawable(R.drawable.ic_block_24px);
}
icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary));
preference.setIcon(icon);
/* Composes "How it works" section, which guides how users can use satellite messaging, when
satellite messaging is included in user's mobile plan, or it'll will be grey out. */
if (!isSatelliteEligible) {
PreferenceCategory category = findPreference(PREF_KEY_CATEGORY_HOW_IT_WORKS);
category.setEnabled(false);
category.setShouldDisableView(true);
}
// More about satellite messaging
FooterPreference footerPreference = findPreference(KEY_FOOTER_PREFERENCE);
if (footerPreference != null) {
footerPreference.setSummary(
getResources().getString(R.string.satellite_setting_summary_more_information,
operatorName));
final String[] link = new String[1];
link[0] = getResources().getString(R.string.more_info_satellite_messaging_link);
footerPreference.setLearnMoreAction(view -> {
if (!link[0].isEmpty()) {
Intent helpIntent = HelpUtils.getHelpIntent(mActivity, link[0],
this.getClass().getName());
if (helpIntent != null) {
mActivity.startActivityForResult(helpIntent, /*requestCode=*/ 0);
}
}
});
footerPreference.setLearnMoreText(
getResources().getString(R.string.more_about_satellite_messaging));
// TODO : b/320467418 add rounded rectangle border line to footer preference.
}
}
private boolean isSatelliteEligible() {
try {
Set<Integer> restrictionReason =
mSatelliteManager.getSatelliteAttachRestrictionReasonsForCarrier(mSubId);
return !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
} catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
loge(ex.toString());
return false;
}
}
private static void loge(String message) {
Log.e(TAG, message);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2024 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;
import android.content.Context;
import android.content.Intent;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.satellite.SatelliteManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.network.CarrierConfigCache;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import java.util.Set;
/**
* Preference controller for "Satellite Setting"
*/
public class SatelliteSettingPreferenceController extends
TelephonyBasePreferenceController implements LifecycleObserver, OnStart, OnStop {
private static final String TAG = "SatelliteSettingPreferenceController";
CarrierConfigCache mCarrierConfigCache;
SatelliteManager mSatelliteManager;
@Nullable private Boolean mIsSatelliteEligible = null;
public SatelliteSettingPreferenceController(@NonNull Context context, @NonNull String key) {
super(context, key);
mCarrierConfigCache = CarrierConfigCache.getInstance(context);
mSatelliteManager = context.getSystemService(SatelliteManager.class);
}
@Override
public int getAvailabilityStatus(int subId) {
final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
final boolean isSatelliteAttachSupported = carrierConfig.getBoolean(
CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL);
return isSatelliteAttachSupported ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public void onStart() {
}
@Override
public void onStop() {
}
@Override
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
}
@Override
public void updateState(@Nullable Preference preference) {
super.updateState(preference);
if (preference != null) {
updateSummary(preference);
}
}
@Override
public boolean handlePreferenceTreeClick(@NonNull Preference preference) {
if (getPreferenceKey().equals(preference.getKey())) {
// This activity runs in phone process, we must use intent to start
final Intent intent = new Intent(Settings.ACTION_SATELLITE_SETTING);
// This will setup the Home and Search affordance
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true);
intent.putExtra(SatelliteSetting.SUB_ID, mSubId);
mContext.startActivity(intent);
return true;
}
return false;
}
/**
* Set subId for Satellite Settings page.
* @param subId subscription ID.
*/
public void init(int subId) {
logd("init(), subId=" + subId);
mSubId = subId;
}
private void updateSummary(Preference preference) {
try {
Set<Integer> restrictionReason =
mSatelliteManager.getSatelliteAttachRestrictionReasonsForCarrier(mSubId);
boolean isSatelliteEligible = !restrictionReason.contains(
SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
if (mIsSatelliteEligible == null || mIsSatelliteEligible != isSatelliteEligible) {
mIsSatelliteEligible = isSatelliteEligible;
String summary = mContext.getString(
mIsSatelliteEligible ? R.string.satellite_setting_enabled_summary
: R.string.satellite_setting_disabled_summary);
preference.setSummary(summary);
}
} catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
loge(ex.toString());
preference.setSummary(R.string.satellite_setting_disabled_summary);
}
}
private static void logd(String message) {
Log.d(TAG, message);
}
private static void loge(String message) {
Log.e(TAG, message);
}
}