Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49cfbcc5 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11521484 from bec4c957 to 24Q2-release

Change-Id: I086a5d8514a9b53b90a94e4e4eb47dac4e074bcf
parents de6d552c bec4c957
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -686,7 +686,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
        controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment));
        controllers.add(new BluetoothLeAudioHwOffloadPreferenceController(context, fragment));
        controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context));
        controllers.add(new NfcStackDebugLogPreferenceController(context));
        controllers.add(new NfcSnoopLogPreferenceController(context, fragment));
        controllers.add(new NfcVerboseVendorLogPreferenceController(context, fragment));
        controllers.add(new ShowTapsPreferenceController(context));
+0 −82
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.development;

import android.content.Context;
import android.os.SystemProperties;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;

public class NfcStackDebugLogPreferenceController extends
        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
        PreferenceControllerMixin {

    private static final String NFC_STACK_DEBUGLOG_ENABLED_KEY =
            "nfc_stack_debuglog_enabled";
    @VisibleForTesting
    static final String NFC_STACK_DEBUGLOG_ENABLED_PROPERTY =
            "persist.nfc.debug_enabled";

    public NfcStackDebugLogPreferenceController(Context context) {
        super(context);
    }

    @Override
    public String getPreferenceKey() {
        return NFC_STACK_DEBUGLOG_ENABLED_KEY;
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final boolean isEnabled = (Boolean) newValue;
        try {
            SystemProperties.set(NFC_STACK_DEBUGLOG_ENABLED_PROPERTY,
                    isEnabled ? "true" : "false");
        } catch (RuntimeException e) {
            Log.e(TAG, "Fail to set nfc system property: " + e.getMessage());
        }
        return true;
    }

    @Override
    public void updateState(Preference preference) {
        try {
            final boolean isEnabled = SystemProperties.getBoolean(
                    NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, false /* default */);
            ((TwoStatePreference) mPreference).setChecked(isEnabled);
        } catch (RuntimeException e) {
            Log.e(TAG, "Fail to get nfc system property: " + e.getMessage());
        }
    }

    @Override
    protected void onDeveloperOptionsSwitchDisabled() {
        super.onDeveloperOptionsSwitchDisabled();
        try {
            SystemProperties.set(NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, "false");
            ((TwoStatePreference) mPreference).setChecked(false);
        } catch (RuntimeException e) {
            Log.e(TAG, "Fail to set nfc system property: " + e.getMessage());
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -25,10 +25,17 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach

private const val TAG = "SubscriptionRepository"

fun Context.isSubscriptionEnabledFlow(subId: Int) = subscriptionsChangedFlow().map {
    val subscriptionManager = getSystemService(SubscriptionManager::class.java)

    subscriptionManager?.isSubscriptionEnabled(subId) ?: false
}.flowOn(Dispatchers.Default)

fun Context.subscriptionsChangedFlow() = callbackFlow {
    val subscriptionManager = getSystemService(SubscriptionManager::class.java)!!

+40 −132
Original line number Diff line number Diff line
@@ -16,37 +16,33 @@

package com.android.settings.spa.network

import android.app.Application
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.UserManager
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.telephony.euicc.EuiccManager
import android.util.Log
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Message
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.DataUsage
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.settings.R
import com.android.settings.network.SubscriptionInfoListViewModel
import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.telephony.MobileNetworkUtils
import com.android.settings.wifi.WifiPickerTrackerHelper
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
@@ -59,17 +55,13 @@ import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.Category
import com.android.settingslib.spa.widget.ui.SettingsIcon
import com.android.settingslib.spaprivileged.framework.common.broadcastReceiverFlow

import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOf
@@ -85,10 +77,8 @@ import kotlinx.coroutines.withContext
object NetworkCellularGroupProvider : SettingsPageProvider {
    override val name = "NetworkCellularGroupProvider"

    private lateinit var subscriptionViewModel: SubscriptionInfoListViewModel
    private val owner = createSettingsPage()

    var selectableSubscriptionInfoList: List<SubscriptionInfo> = listOf()
    var defaultVoiceSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
    var defaultSmsSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
    var defaultDataSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID
@@ -106,9 +96,6 @@ object NetworkCellularGroupProvider : SettingsPageProvider {
    @Composable
    override fun Page(arguments: Bundle?) {
        val context = LocalContext.current
        var selectableSubscriptionInfoListRemember = remember {
            mutableListOf<SubscriptionInfo>().toMutableStateList()
        }
        var callsSelectedId = rememberSaveable {
            mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
        }
@@ -122,24 +109,24 @@ object NetworkCellularGroupProvider : SettingsPageProvider {
            mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
        }

        subscriptionViewModel = SubscriptionInfoListViewModel(
                context.applicationContext as Application)
        val subscriptionViewModel = viewModel<SubscriptionInfoListViewModel>()

        remember {
            allOfFlows(context, subscriptionViewModel.selectableSubscriptionInfoListFlow)
                .collectLatestWithLifecycle(LocalLifecycleOwner.current) {
                    selectableSubscriptionInfoListRemember.clear()
                    selectableSubscriptionInfoListRemember.addAll(selectableSubscriptionInfoList)
        }.collectLatestWithLifecycle(LocalLifecycleOwner.current) {
            callsSelectedId.intValue = defaultVoiceSubId
            textsSelectedId.intValue = defaultSmsSubId
            mobileDataSelectedId.intValue = defaultDataSubId
            nonDdsRemember.intValue = nonDds
        }

        PageImpl(selectableSubscriptionInfoListRemember,
        PageImpl(
            subscriptionViewModel.selectableSubscriptionInfoListFlow,
            callsSelectedId,
            textsSelectedId,
            mobileDataSelectedId,
                nonDdsRemember)
            nonDdsRemember
        )
    }

    private fun allOfFlows(context: Context,
@@ -152,13 +139,12 @@ object NetworkCellularGroupProvider : SettingsPageProvider {
                    NetworkCellularGroupProvider::refreshUiStates,
            ).flowOn(Dispatchers.Default)

    fun refreshUiStates(
            inputSelectableSubscriptionInfoList: List<SubscriptionInfo>,
    private fun refreshUiStates(
        selectableSubscriptionInfoList: List<SubscriptionInfo>,
        inputDefaultVoiceSubId: Int,
        inputDefaultSmsSubId: Int,
        inputDefaultDateSubId: Int
    ): Unit {
        selectableSubscriptionInfoList = inputSelectableSubscriptionInfoList
    ) {
        defaultVoiceSubId = inputDefaultVoiceSubId
        defaultSmsSubId = inputDefaultSmsSubId
        defaultDataSubId = inputDefaultDateSubId
@@ -178,25 +164,23 @@ object NetworkCellularGroupProvider : SettingsPageProvider {
}

@Composable
fun PageImpl(selectableSubscriptionInfoList: List<SubscriptionInfo>,
fun PageImpl(
    selectableSubscriptionInfoListFlow: StateFlow<List<SubscriptionInfo>>,
    defaultVoiceSubId: MutableIntState,
    defaultSmsSubId: MutableIntState,
    defaultDataSubId: MutableIntState,
             nonDds: MutableIntState) {
    val context = LocalContext.current
    var activeSubscriptionInfoList: List<SubscriptionInfo> =
    nonDds: MutableIntState
) {
    val selectableSubscriptionInfoList by selectableSubscriptionInfoListFlow
        .collectAsStateWithLifecycle(initialValue = emptyList())
    val activeSubscriptionInfoList: List<SubscriptionInfo> =
        selectableSubscriptionInfoList.filter { subscriptionInfo ->
            subscriptionInfo.simSlotIndex != -1
        }
    var subscriptionManager = context.getSystemService(SubscriptionManager::class.java)

    val stringSims = stringResource(R.string.provider_network_settings_title)
    RegularScaffold(title = stringSims) {
        SimsSectionImpl(
                context,
                subscriptionManager,
                selectableSubscriptionInfoList
        )
        SimsSection(selectableSubscriptionInfoList)
        PrimarySimSectionImpl(
                activeSubscriptionInfoList,
                defaultVoiceSubId,
@@ -207,56 +191,6 @@ fun PageImpl(selectableSubscriptionInfoList: List<SubscriptionInfo>,
    }
}

@Composable
fun SimsSectionImpl(
        context: Context,
        subscriptionManager: SubscriptionManager?,
        subscriptionInfoList: List<SubscriptionInfo>
) {
    val coroutineScope = rememberCoroutineScope()
    for (subInfo in subscriptionInfoList) {
        val checked = rememberSaveable() {
            mutableStateOf(false)
        }
        //TODO: Add the Restricted TwoTargetSwitchPreference in SPA
        TwoTargetSwitchPreference(
                object : SwitchPreferenceModel {
                    override val title = subInfo.displayName.toString()
                    override val summary = { subInfo.number }
                    override val checked = {
                        coroutineScope.launch {
                            withContext(Dispatchers.Default) {
                                checked.value = subscriptionManager?.isSubscriptionEnabled(
                                    subInfo.subscriptionId)?:false
                            }
                        }
                        checked.value
                    }
                    override val onCheckedChange = { newChecked: Boolean ->
                        startToggleSubscriptionDialog(context, subInfo, newChecked)
                    }
                }
        ) {
            startMobileNetworkSettings(context, subInfo)
        }
    }

    // + add sim
    if (showEuiccSettings(context)) {
        RestrictedPreference(
                model = object : PreferenceModel {
                    override val title = stringResource(id = R.string.mobile_network_list_add_more)
                    override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) }
                    override val onClick = {
                        startAddSimFlow(context)
                    }
                },
                restrictions = Restrictions(keys =
                        listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)),
        )
    }
}

@Composable
fun PrimarySimImpl(
    subscriptionInfoList: List<SubscriptionInfo>,
@@ -440,32 +374,6 @@ private fun Context.defaultDefaultDataSubscriptionFlow(): Flow<Int> =
        ).map { SubscriptionManager.getDefaultDataSubscriptionId() }
                .conflate().flowOn(Dispatchers.Default)

private fun startToggleSubscriptionDialog(
        context: Context,
        subInfo: SubscriptionInfo,
        newStatus: Boolean
) {
    SubscriptionUtil.startToggleSubscriptionDialogActivity(
            context,
            subInfo.subscriptionId,
            newStatus
    )
}

private fun startMobileNetworkSettings(context: Context, subInfo: SubscriptionInfo) {
    MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo)
}

private fun startAddSimFlow(context: Context) {
    val intent = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION)
    intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true)
    context.startActivity(intent)
}

private fun showEuiccSettings(context: Context): Boolean {
    return MobileNetworkUtils.showEuiccSettings(context)
}

suspend fun setDefaultVoice(
    subscriptionManager: SubscriptionManager?,
    subId: Int
+98 −0
Original line number Diff line number Diff line
/*
 * 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.spa.network

import android.content.Context
import android.content.Intent
import android.os.UserManager
import android.telephony.SubscriptionInfo
import android.telephony.euicc.EuiccManager
import androidx.compose.foundation.layout.Column
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R
import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.telephony.MobileNetworkUtils
import com.android.settings.network.telephony.isSubscriptionEnabledFlow
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference
import com.android.settingslib.spa.widget.ui.SettingsIcon
import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference

@Composable
fun SimsSection(subscriptionInfoList: List<SubscriptionInfo>) {
    Column {
        for (subInfo in subscriptionInfoList) {
            SimPreference(subInfo)
        }

        AddSim()
    }
}

@Composable
private fun SimPreference(subInfo: SubscriptionInfo) {
    val context = LocalContext.current
    val checked = remember(subInfo.subscriptionId) {
        context.isSubscriptionEnabledFlow(subInfo.subscriptionId)
    }.collectAsStateWithLifecycle(initialValue = false)
    //TODO: Add the Restricted TwoTargetSwitchPreference in SPA
    TwoTargetSwitchPreference(
        object : SwitchPreferenceModel {
            override val title = subInfo.displayName.toString()
            override val summary = { subInfo.number }
            override val checked = { checked.value }
            override val onCheckedChange = { newChecked: Boolean ->
                SubscriptionUtil.startToggleSubscriptionDialogActivity(
                    context,
                    subInfo.subscriptionId,
                    newChecked,
                )
            }
        }
    ) {
        MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo)
    }
}

@Composable
private fun AddSim() {
    val context = LocalContext.current
    if (remember { MobileNetworkUtils.showEuiccSettings(context) }) {
        RestrictedPreference(
            model = object : PreferenceModel {
                override val title = stringResource(id = R.string.mobile_network_list_add_more)
                override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) }
                override val onClick = { startAddSimFlow(context) }
            },
            restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)),
        )
    }
}

private fun startAddSimFlow(context: Context) {
    val intent = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION)
    intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true)
    context.startActivity(intent)
}
Loading