1 /* 2 * Copyright (C) 2023 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.wifi; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.Context; 21 import android.graphics.Bitmap; 22 import android.net.wifi.SoftApConfiguration; 23 import android.util.Log; 24 25 import com.android.car.settings.R; 26 import com.android.car.settings.common.FragmentController; 27 import com.android.car.settings.wifi.preferences.WifiTetherQrCodePreference; 28 import com.android.settingslib.qrcode.QrCodeGenerator; 29 30 /** 31 * Controls WiFi Hotspot QR code. 32 */ 33 public class WifiTetherQrCodePreferenceController extends 34 WifiTetherBasePreferenceController<WifiTetherQrCodePreference> implements 35 WifiTetheringHandler.WifiTetheringAvailabilityListener { 36 private static final String TAG = WifiTetherPasswordPreferenceController.class.getSimpleName(); 37 private static final String QR_CODE_FORMAT = "WIFI:T:WPA;S:%s;P:%s;;"; 38 private static final String QR_CODE_FORMAT_NOPASS = "WIFI:T:nopass;S:%s;;"; 39 40 private WifiTetheringHandler mWifiTetheringHandler; 41 WifiTetherQrCodePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)42 public WifiTetherQrCodePreferenceController(Context context, 43 String preferenceKey, 44 FragmentController fragmentController, 45 CarUxRestrictions uxRestrictions) { 46 super(context, preferenceKey, fragmentController, uxRestrictions); 47 mWifiTetheringHandler = new WifiTetheringHandler(context, 48 fragmentController.getSettingsLifecycle(), this, /* monitorRestarts= */ false); 49 } 50 51 @Override getPreferenceType()52 protected Class<WifiTetherQrCodePreference> getPreferenceType() { 53 return WifiTetherQrCodePreference.class; 54 } 55 56 @Override getSummary()57 protected String getSummary() { 58 return null; 59 } 60 61 @Override getDefaultSummary()62 protected String getDefaultSummary() { 63 return null; 64 } 65 66 @Override onStartInternal()67 protected void onStartInternal() { 68 super.onStartInternal(); 69 mWifiTetheringHandler.onStartInternal(); 70 } 71 72 @Override onStopInternal()73 protected void onStopInternal() { 74 mWifiTetheringHandler.onStopInternal(); 75 } 76 77 @Override onWifiTetheringAvailable()78 public void onWifiTetheringAvailable() { 79 refreshUi(); 80 } 81 82 @Override onWifiTetheringUnavailable()83 public void onWifiTetheringUnavailable() { 84 refreshUi(); 85 } 86 87 @Override enablePreference()88 public void enablePreference() { 89 // No op. 90 } 91 92 @Override disablePreference()93 public void disablePreference() { 94 // No op. 95 } 96 97 @Override getDefaultAvailabilityStatus()98 protected int getDefaultAvailabilityStatus() { 99 if (mWifiTetheringHandler.isWifiTetheringEnabled()) { 100 return AVAILABLE_FOR_VIEWING; 101 } 102 return CONDITIONALLY_UNAVAILABLE; 103 } 104 105 @Override updateState(WifiTetherQrCodePreference preference)106 protected void updateState(WifiTetherQrCodePreference preference) { 107 super.updateState(preference); 108 updateQrCode(preference); 109 } 110 updateQrCode(WifiTetherQrCodePreference preference)111 private void updateQrCode(WifiTetherQrCodePreference preference) { 112 if (mWifiTetheringHandler.isWifiTetheringEnabled()) { 113 Bitmap bmp = null; 114 String name = getCarSoftApConfig().getSsid(); 115 String password = getCarSoftApConfig().getPassphrase(); 116 int securityType = getCarSoftApConfig().getSecurityType(); 117 String content; 118 if (securityType == SoftApConfiguration.SECURITY_TYPE_OPEN) { 119 content = String.format(QR_CODE_FORMAT_NOPASS, name); 120 } else { 121 content = String.format(QR_CODE_FORMAT, name, password); 122 } 123 try { 124 int size = getContext().getResources().getDimensionPixelSize( 125 R.dimen.hotspot_qr_code_size); 126 int margin = getContext().getResources().getDimensionPixelSize( 127 R.dimen.qr_code_margin); 128 bmp = QrCodeGenerator.encodeQrCode(content, size, margin); 129 } catch (Exception e) { 130 Log.w(TAG, "Exception found: " + e); 131 } 132 preference.setPreferenceInfo(bmp, name, password); 133 } 134 } 135 } 136