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.wifi.data.repository.demo
18 
19 import android.net.wifi.WifiManager
20 import android.os.Bundle
21 import com.android.systemui.dagger.SysUISingleton
22 import com.android.systemui.dagger.qualifiers.Application
23 import com.android.systemui.demomode.DemoMode.COMMAND_NETWORK
24 import com.android.systemui.demomode.DemoModeController
25 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
26 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
27 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
28 import javax.inject.Inject
29 import kotlinx.coroutines.CoroutineScope
30 import kotlinx.coroutines.flow.SharingStarted
31 import kotlinx.coroutines.flow.map
32 import kotlinx.coroutines.flow.shareIn
33 
34 /** Data source to map between demo mode commands and inputs into [DemoWifiRepository]'s flows */
35 @SysUISingleton
36 class DemoModeWifiDataSource
37 @Inject
38 constructor(
39     demoModeController: DemoModeController,
40     @Application scope: CoroutineScope,
41 ) {
42     private val demoCommandStream = demoModeController.demoFlowForCommand(COMMAND_NETWORK)
43     private val _wifiCommands = demoCommandStream.map { args -> args.toWifiEvent() }
44     val wifiEvents = _wifiCommands.shareIn(scope, SharingStarted.WhileSubscribed())
45 
46     private fun Bundle.toWifiEvent(): FakeWifiEventModel? {
47         val wifi = getString("wifi") ?: return null
48         return when (wifi) {
49             "show" -> activeWifiEvent()
50             "carriermerged" -> carrierMergedWifiEvent()
51             else -> FakeWifiEventModel.WifiDisabled
52         }
53     }
54 
55     private fun Bundle.activeWifiEvent(): FakeWifiEventModel.Wifi {
56         val level = getString("level")?.toInt()
57         val activity = getString("activity").toActivity()
58         val ssid = getString("ssid")
59         val validated = getString("fully").toBoolean()
60         val hotspotDeviceType = getString("hotspot").toHotspotDeviceType()
61 
62         return FakeWifiEventModel.Wifi(
63             level = level,
64             activity = activity,
65             ssid = ssid,
66             validated = validated,
67             hotspotDeviceType,
68         )
69     }
70 
71     private fun Bundle.carrierMergedWifiEvent(): FakeWifiEventModel.CarrierMerged {
72         val subId = getString("slot")?.toInt() ?: DEFAULT_CARRIER_MERGED_SUB_ID
73         val level = getString("level")?.toInt() ?: 0
74         val numberOfLevels = getString("numlevels")?.toInt() ?: DEFAULT_NUM_LEVELS
75         val activity = getString("activity").toActivity()
76 
77         return FakeWifiEventModel.CarrierMerged(subId, level, numberOfLevels, activity)
78     }
79 
80     private fun String?.toActivity(): Int =
81         when (this) {
82             "inout" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT
83             "in" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN
84             "out" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT
85             else -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE
86         }
87 
88     private fun String?.toHotspotDeviceType(): WifiNetworkModel.HotspotDeviceType {
89         return when (this) {
90             null,
91             "none" -> WifiNetworkModel.HotspotDeviceType.NONE
92             "unknown" -> WifiNetworkModel.HotspotDeviceType.UNKNOWN
93             "phone" -> WifiNetworkModel.HotspotDeviceType.PHONE
94             "tablet" -> WifiNetworkModel.HotspotDeviceType.TABLET
95             "laptop" -> WifiNetworkModel.HotspotDeviceType.LAPTOP
96             "watch" -> WifiNetworkModel.HotspotDeviceType.WATCH
97             "auto" -> WifiNetworkModel.HotspotDeviceType.AUTO
98             else -> WifiNetworkModel.HotspotDeviceType.INVALID
99         }
100     }
101 
102     companion object {
103         const val DEFAULT_CARRIER_MERGED_SUB_ID = 10
104     }
105 }
106