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.settings.wifi
18 
19 import android.annotation.StyleRes
20 import android.content.Context
21 import android.content.DialogInterface
22 import android.os.Bundle
23 import android.view.View
24 import android.view.WindowManager
25 import android.widget.Button
26 import android.widget.ImageButton
27 import android.widget.TextView
28 import androidx.annotation.OpenForTesting
29 import androidx.appcompat.app.AlertDialog
30 import com.android.settings.R
31 import com.android.settingslib.RestrictedLockUtils
32 import com.android.settingslib.RestrictedLockUtilsInternal
33 import com.android.wifitrackerlib.WifiEntry
34 
35 /**
36  * Dialog for users to edit a Wi-Fi network.
37  */
38 @OpenForTesting
39 open class WifiDialog2 @JvmOverloads constructor(
40     context: Context,
41     private val listener: WifiDialog2Listener,
42     val wifiEntry: WifiEntry?,
43     private val mode: Int,
44     @StyleRes style: Int = 0,
45     private val hideSubmitButton: Boolean = mode == WifiConfigUiBase2.MODE_VIEW,
46     private val hideMeteredAndPrivacy: Boolean = false,
47     private val isSysUiCaller: Boolean = false,
48 ) : AlertDialog(context, style), WifiConfigUiBase2, DialogInterface.OnClickListener {
49     /**
50      * Host UI component of WifiDialog2 can receive callbacks by this interface.
51      */
52     interface WifiDialog2Listener {
53         /**
54          * To forget the Wi-Fi network.
55          */
onForgetnull56         fun onForget(dialog: WifiDialog2) {}
57 
58         /**
59          * To save the Wi-Fi network.
60          */
onSubmitnull61         fun onSubmit(dialog: WifiDialog2) {}
62 
63         /**
64          * To trigger Wi-Fi QR code scanner.
65          */
onScannull66         fun onScan(dialog: WifiDialog2, ssid: String) {}
67     }
68 
69     private lateinit var view: View
70     private lateinit var controller: WifiConfigController2
71 
getControllernull72     override fun getController(): WifiConfigController2 = controller
73 
74     override fun onCreate(savedInstanceState: Bundle?) {
75         if (isSysUiCaller) {
76             setWindowsOverlay()
77         }
78         view = layoutInflater.inflate(R.layout.wifi_dialog, null)
79         setView(view)
80         controller = WifiConfigController2(this, view, wifiEntry, mode, hideMeteredAndPrivacy)
81         super.onCreate(savedInstanceState)
82         if (hideSubmitButton) {
83             controller.hideSubmitButton()
84         } else {
85             // During creation, the submit button can be unavailable to determine visibility.
86             // Right after creation, update button visibility
87             controller.enableSubmitIfAppropriate()
88         }
89         if (wifiEntry == null) {
90             controller.hideForgetButton()
91         }
92     }
93 
setWindowsOverlaynull94     private fun setWindowsOverlay() {
95         window?.apply {
96             val lp = attributes
97             setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
98             attributes = lp
99         }
100     }
101 
onStartnull102     override fun onStart() {
103         super.onStart()
104         val ssidScannerButton = requireViewById<ImageButton>(R.id.ssid_scanner_button)
105         if (hideSubmitButton) {
106             ssidScannerButton.visibility = View.GONE
107         } else {
108             ssidScannerButton.setOnClickListener {
109                 val ssidEditText = requireViewById<TextView>(R.id.ssid)
110                 val ssid = ssidEditText.text.toString()
111                 listener.onScan(this, ssid)
112             }
113         }
114     }
115 
onRestoreInstanceStatenull116     override fun onRestoreInstanceState(savedInstanceState: Bundle) {
117         super.onRestoreInstanceState(savedInstanceState)
118         controller.updatePassword()
119     }
120 
dispatchSubmitnull121     override fun dispatchSubmit() {
122         listener.onSubmit(this)
123         dismiss()
124     }
125 
onClicknull126     override fun onClick(dialogInterface: DialogInterface, id: Int) {
127         when (id) {
128             BUTTON_SUBMIT -> listener.onSubmit(this)
129             BUTTON_FORGET -> {
130                 if (WifiUtils.isNetworkLockedDown(context, wifiEntry!!.wifiConfiguration)) {
131                     RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
132                         context,
133                         RestrictedLockUtilsInternal.getDeviceOwner(context)
134                     )
135                     return
136                 }
137                 listener.onForget(this)
138             }
139         }
140     }
141 
getModenull142     override fun getMode(): Int = mode
143 
144     override fun getSubmitButton(): Button? = getButton(BUTTON_SUBMIT)
145 
146     override fun getForgetButton(): Button? = getButton(BUTTON_FORGET)
147 
148     override fun getCancelButton(): Button? = getButton(BUTTON_NEGATIVE)
149 
150     override fun setSubmitButton(text: CharSequence) {
151         setButton(BUTTON_SUBMIT, text, this)
152     }
153 
setForgetButtonnull154     override fun setForgetButton(text: CharSequence) {
155         setButton(BUTTON_FORGET, text, this)
156     }
157 
setCancelButtonnull158     override fun setCancelButton(text: CharSequence) {
159         setButton(BUTTON_NEGATIVE, text, this)
160     }
161 
162     companion object {
163         private const val BUTTON_SUBMIT = BUTTON_POSITIVE
164         private const val BUTTON_FORGET = BUTTON_NEUTRAL
165     }
166 }
167