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