From 10f0cd821c0a16242ad9dd5c0aaf4c9c2a75f854 Mon Sep 17 00:00:00 2001 From: Jacky Wang Date: Tue, 3 Dec 2024 16:20:35 +0800 Subject: [PATCH] [Catalyst] Migrate "Use Wi-Fi calling" Bug: 372732219 Flag: com.android.settings.flags.catalyst_wifi_calling Test: devtool Change-Id: I3183b1234b4129aa0cf0e5bc5324596a08f21195 --- .../WifiCallingMainSwitchPreference.kt | 110 ++++++++++++++++++ .../wifi/calling/WifiCallingScreen.kt | 11 +- .../calling/WifiCallingSettingsForSub.java | 12 +- 3 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt diff --git a/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt b/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt new file mode 100644 index 00000000000..f6056f4ce8f --- /dev/null +++ b/src/com/android/settings/wifi/calling/WifiCallingMainSwitchPreference.kt @@ -0,0 +1,110 @@ +/* + * 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.wifi.calling + +import android.content.Context +import android.telephony.SubscriptionManager +import android.telephony.TelephonyManager +import android.telephony.ims.ImsMmTelManager +import android.util.Log +import com.android.settings.R +import com.android.settings.network.ims.WifiCallingQueryImsState +import com.android.settings.network.telephony.wificalling.WifiCallingRepository +import com.android.settings.widget.SettingsMainSwitchPreference +import com.android.settings.wifi.calling.WifiCallingSettingsForSub.getCarrierActivityIntent +import com.android.settingslib.datastore.KeyValueStore +import com.android.settingslib.datastore.NoOpKeyedObservable +import com.android.settingslib.metadata.PreferenceAvailabilityProvider +import com.android.settingslib.metadata.ReadWritePermit +import com.android.settingslib.metadata.SensitivityLevel +import com.android.settingslib.metadata.TwoStatePreference +import com.android.settingslib.preference.TwoStatePreferenceBinding +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking + +/** + * Metadata of the "Use Wi-Fi calling" preference. + * + * TODO(b/372732219): apply metadata to UI + */ +class WifiCallingMainSwitchPreference(private val subId: Int) : + TwoStatePreference, TwoStatePreferenceBinding, PreferenceAvailabilityProvider { + + override val key: String + get() = KEY + + override val title: Int + get() = R.string.wifi_calling_main_switch_title + + override fun isEnabled(context: Context) = + context.isCallStateIdle(subId) && + WifiCallingQueryImsState(context, subId).isAllowUserControl + + override fun isAvailable(context: Context) = + SubscriptionManager.isValidSubscriptionId(subId) && + runBlocking { WifiCallingRepository(context, subId).wifiCallingReadyFlow().first() } + + override fun createWidget(context: Context) = SettingsMainSwitchPreference(context) + + override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) = + ReadWritePermit.ALLOW + + override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) = + when { + value == true && + (DisclaimerItemFactory.create(context, subId).isNotEmpty() || + getCarrierActivityIntent(context, subId) != null) -> + ReadWritePermit.REQUIRE_USER_AGREEMENT + else -> ReadWritePermit.ALLOW + } + + override val sensitivityLevel + get() = SensitivityLevel.NO_SENSITIVITY + + override fun storage(context: Context): KeyValueStore = WifiCallingStore(context, subId) + + @Suppress("UNCHECKED_CAST") + private class WifiCallingStore(context: Context, private val subId: Int) : + NoOpKeyedObservable(), KeyValueStore { + private val queryIms = WifiCallingQueryImsState(context, subId) + + override fun contains(key: String) = key == KEY + + override fun getValue(key: String, valueType: Class) = + (queryIms.isEnabledByUser && queryIms.isAllowUserControl) as T + + override fun setValue(key: String, valueType: Class, value: T?) { + if (value is Boolean) { + try { + ImsMmTelManager.createForSubscriptionId(subId).isVoWiFiSettingEnabled = value + } catch (e: Exception) { + Log.w(TAG, "fail to enable wifi calling", e) + } + } + } + } + + companion object { + // TODO(b/372732219): The key is different from XML to avoid applying metadata to UI. + const val KEY = "wifi_calling_switch" + const val TAG = KEY + + private fun Context.isCallStateIdle(subId: Int) = + getSystemService(TelephonyManager::class.java)?.getCallState(subId) == + TelephonyManager.CALL_STATE_IDLE + } +} diff --git a/src/com/android/settings/wifi/calling/WifiCallingScreen.kt b/src/com/android/settings/wifi/calling/WifiCallingScreen.kt index c0386c5bbf1..6ab5e564f06 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingScreen.kt +++ b/src/com/android/settings/wifi/calling/WifiCallingScreen.kt @@ -16,6 +16,7 @@ package com.android.settings.wifi.calling import android.content.Context +import android.telephony.SubscriptionManager import com.android.settings.R import com.android.settings.flags.Flags import com.android.settingslib.metadata.ProvidePreferenceScreen @@ -39,9 +40,15 @@ class WifiCallingScreen : PreferenceScreenCreator { override fun hasCompleteHierarchy() = false - override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {} + override fun getPreferenceHierarchy(context: Context) = + preferenceHierarchy(this) { + val subId = SubscriptionManager.getDefaultSubscriptionId() + if (SubscriptionManager.isValidSubscriptionId(subId)) { + +WifiCallingMainSwitchPreference(subId) + } + } companion object { const val KEY = "wifi_calling" } -} \ No newline at end of file +} diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java index 1de3f5c1fe1..46be70dfddb 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java @@ -486,17 +486,21 @@ public class WifiCallingSettingsForSub extends DashboardFragment .launch(); } + private @Nullable Intent getCarrierActivityIntent() { + return getCarrierActivityIntent(getActivity(), mSubId); + } + /* * Get the Intent to launch carrier emergency address management activity. * Return null when no activity found. */ - private Intent getCarrierActivityIntent() { + static @Nullable Intent getCarrierActivityIntent(Context context, int subId) { // Retrieve component name from carrier config final CarrierConfigManager configManager = - getActivity().getSystemService(CarrierConfigManager.class); + context.getSystemService(CarrierConfigManager.class); if (configManager == null) return null; - final PersistableBundle bundle = configManager.getConfigForSubId(mSubId); + final PersistableBundle bundle = configManager.getConfigForSubId(subId); if (bundle == null) return null; final String carrierApp = bundle.getString( @@ -509,7 +513,7 @@ public class WifiCallingSettingsForSub extends DashboardFragment // Build and return intent final Intent intent = new Intent(); intent.setComponent(componentName); - intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mSubId); + intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); return intent; }