1 /* 2 * Copyright (C) 2021 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.car.settings.qc; 18 19 import static com.android.car.qc.QCItem.QC_ACTION_TOGGLE_STATE; 20 import static com.android.car.qc.QCItem.QC_TYPE_ACTION_SWITCH; 21 import static com.android.car.settings.qc.SettingsQCRegistry.HOTSPOT_ROW_URI; 22 23 import android.content.Context; 24 import android.content.Intent; 25 import android.graphics.drawable.Icon; 26 import android.net.TetheringManager; 27 import android.net.Uri; 28 import android.net.wifi.SoftApConfiguration; 29 import android.net.wifi.WifiManager; 30 import android.text.TextUtils; 31 32 import com.android.car.qc.QCActionItem; 33 import com.android.car.qc.QCItem; 34 import com.android.car.qc.QCList; 35 import com.android.car.qc.QCRow; 36 import com.android.car.settings.R; 37 38 /** 39 * QCItem for showing a hotspot row element. 40 * The row contains an icon, the status, and a switch to enable/disable hotspot. 41 */ 42 public class HotspotRow extends SettingsQCItem { 43 private final TetheringManager mTetheringManager; 44 private final WifiManager mWifiManager; 45 // Assume hotspot is available until notified otherwise. 46 private boolean mIsSupported = true; 47 private int mConnectedDevicesCount; 48 HotspotRow(Context context)49 public HotspotRow(Context context) { 50 super(context); 51 mTetheringManager = context.getSystemService(TetheringManager.class); 52 mWifiManager = context.getSystemService(WifiManager.class); 53 } 54 55 @Override getQCItem()56 QCItem getQCItem() { 57 Icon icon = Icon.createWithResource(getContext(), R.drawable.ic_qc_hotspot); 58 59 QCActionItem hotpotToggle = new QCActionItem.Builder(QC_TYPE_ACTION_SWITCH) 60 .setChecked(HotspotQCUtils.isHotspotEnabled(mWifiManager)) 61 .setEnabled(!HotspotQCUtils.isHotspotBusy(mWifiManager)) 62 .setAvailable(mIsSupported) 63 .setAction(getBroadcastIntent()) 64 .build(); 65 66 QCRow hotspotRow = new QCRow.Builder() 67 .setIcon(icon) 68 .setTitle(getContext().getString(R.string.hotspot_settings_title)) 69 .setSubtitle(getSubtitle()) 70 .addEndItem(hotpotToggle) 71 .build(); 72 73 return new QCList.Builder() 74 .addRow(hotspotRow) 75 .build(); 76 } 77 78 @Override getUri()79 Uri getUri() { 80 return HOTSPOT_ROW_URI; 81 } 82 getHotspotSupported()83 boolean getHotspotSupported() { 84 return mIsSupported; 85 } 86 setHotspotSupported(boolean supported)87 void setHotspotSupported(boolean supported) { 88 mIsSupported = supported; 89 } 90 setConnectedDevicesCount(int devicesCount)91 void setConnectedDevicesCount(int devicesCount) { 92 mConnectedDevicesCount = devicesCount; 93 } 94 95 @Override onNotifyChange(Intent intent)96 void onNotifyChange(Intent intent) { 97 boolean newState = intent.getBooleanExtra(QC_ACTION_TOGGLE_STATE, 98 !mWifiManager.isWifiApEnabled()); 99 if (newState) { 100 HotspotQCUtils.enableHotspot(mTetheringManager, 101 HotspotQCUtils.getDefaultStartTetheringCallback(getContext(), getUri())); 102 } else { 103 HotspotQCUtils.disableHotspot(mTetheringManager); 104 } 105 } 106 107 @Override getBackgroundWorkerClass()108 Class getBackgroundWorkerClass() { 109 return HotspotRowWorker.class; 110 } 111 112 /** Returns the subtitle to be shown for the hotspot quick controls item. 113 * There are three different states that can be shown: 114 * - If tethering is disabled, return the off string. 115 * - If tethering is enabled but no devices are connected, return the ssid + password string. 116 * - If tethering is enabled and devices are connected, return the devices connected string. 117 */ getSubtitle()118 private String getSubtitle() { 119 if (!HotspotQCUtils.isHotspotEnabled(mWifiManager)) { 120 return getContext().getString(R.string.wifi_hotspot_state_off); 121 } 122 if (mConnectedDevicesCount > 0) { 123 return getContext().getResources().getQuantityString( 124 R.plurals.wifi_tether_connected_summary, mConnectedDevicesCount, 125 mConnectedDevicesCount); 126 } 127 String subtitle = getHotspotSSID(); 128 if (TextUtils.isEmpty(subtitle)) { 129 // If there currently is no SSID to show, use a default "On" string 130 return getContext().getString(R.string.car_ui_preference_switch_on); 131 } 132 String password = getHotspotPassword(); 133 if (!TextUtils.isEmpty(password)) { 134 subtitle += " / " + password; 135 } 136 return subtitle; 137 } 138 getHotspotSSID()139 private String getHotspotSSID() { 140 return mWifiManager.getSoftApConfiguration().getSsid(); 141 } 142 getHotspotPassword()143 private String getHotspotPassword() { 144 int securityType = mWifiManager.getSoftApConfiguration().getSecurityType(); 145 if (securityType == SoftApConfiguration.SECURITY_TYPE_OPEN) { 146 return null; 147 } 148 return mWifiManager.getSoftApConfiguration().getPassphrase(); 149 } 150 } 151