1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo 18 19 import android.os.Bundle 20 import android.telephony.Annotation.DataActivityType 21 import android.telephony.TelephonyManager.DATA_ACTIVITY_IN 22 import android.telephony.TelephonyManager.DATA_ACTIVITY_INOUT 23 import android.telephony.TelephonyManager.DATA_ACTIVITY_NONE 24 import android.telephony.TelephonyManager.DATA_ACTIVITY_OUT 25 import com.android.settingslib.SignalIcon.MobileIconGroup 26 import com.android.settingslib.mobile.TelephonyIcons 27 import com.android.systemui.dagger.SysUISingleton 28 import com.android.systemui.dagger.qualifiers.Application 29 import com.android.systemui.demomode.DemoMode.COMMAND_NETWORK 30 import com.android.systemui.demomode.DemoModeController 31 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel 32 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile 33 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.MobileDisabled 34 import javax.inject.Inject 35 import kotlinx.coroutines.CoroutineScope 36 import kotlinx.coroutines.flow.SharingStarted 37 import kotlinx.coroutines.flow.map 38 import kotlinx.coroutines.flow.shareIn 39 40 /** 41 * Data source that can map from demo mode commands to inputs into the 42 * [DemoMobileConnectionsRepository]'s flows 43 */ 44 @SysUISingleton 45 class DemoModeMobileConnectionDataSource 46 @Inject 47 constructor( 48 demoModeController: DemoModeController, 49 @Application scope: CoroutineScope, 50 ) { 51 private val demoCommandStream = demoModeController.demoFlowForCommand(COMMAND_NETWORK) 52 53 // If the args contains "mobile", then all of the args are relevant. It's just the way demo mode 54 // commands work and it's a little silly 55 private val _mobileCommands = demoCommandStream.map { args -> args.toMobileEvent() } 56 val mobileEvents = _mobileCommands.shareIn(scope, SharingStarted.WhileSubscribed()) 57 58 private fun Bundle.toMobileEvent(): FakeNetworkEventModel? { 59 val mobile = getString("mobile") ?: return null 60 return if (mobile == "show") { 61 activeMobileEvent() 62 } else { 63 MobileDisabled(subId = getString("slot")?.toInt()) 64 } 65 } 66 67 /** Parse a valid mobile command string into a network event */ 68 private fun Bundle.activeMobileEvent(): Mobile { 69 // There are many key/value pairs supported by mobile demo mode. Bear with me here 70 val level = getString("level")?.toInt() 71 val dataType = getString("datatype")?.toDataType() 72 val slot = getString("slot")?.toInt() 73 val carrierId = getString("carrierid")?.toInt() 74 val inflateStrength = getString("inflate").toBoolean() 75 val activity = getString("activity")?.toActivity() 76 val carrierNetworkChange = getString("carriernetworkchange") == "show" 77 val roaming = getString("roam") == "show" 78 val name = getString("networkname") ?: "demo mode" 79 80 return Mobile( 81 level = level, 82 dataType = dataType, 83 subId = slot, 84 carrierId = carrierId, 85 inflateStrength = inflateStrength, 86 activity = activity, 87 carrierNetworkChange = carrierNetworkChange, 88 roaming = roaming, 89 name = name, 90 ) 91 } 92 } 93 94 private fun String.toDataType(): MobileIconGroup = 95 when (this) { 96 "1x" -> TelephonyIcons.ONE_X 97 "3g" -> TelephonyIcons.THREE_G 98 "4g" -> TelephonyIcons.FOUR_G 99 "4g+" -> TelephonyIcons.FOUR_G_PLUS 100 "5g" -> TelephonyIcons.NR_5G 101 "5ge" -> TelephonyIcons.LTE_CA_5G_E 102 "5g+" -> TelephonyIcons.NR_5G_PLUS 103 "e" -> TelephonyIcons.E 104 "g" -> TelephonyIcons.G 105 "h" -> TelephonyIcons.H 106 "h+" -> TelephonyIcons.H_PLUS 107 "lte" -> TelephonyIcons.LTE 108 "lte+" -> TelephonyIcons.LTE_PLUS 109 "dis" -> TelephonyIcons.DATA_DISABLED 110 "not" -> TelephonyIcons.NOT_DEFAULT_DATA 111 else -> TelephonyIcons.UNKNOWN 112 } 113 114 @DataActivityType 115 private fun String.toActivity(): Int = 116 when (this) { 117 "inout" -> DATA_ACTIVITY_INOUT 118 "in" -> DATA_ACTIVITY_IN 119 "out" -> DATA_ACTIVITY_OUT 120 else -> DATA_ACTIVITY_NONE 121 } 122