Migrate WifiDialog2 to Kotlin

Bug: 297036035
Test: unit test
Test: manual - on wifi dialog
Change-Id: I5bcd636705b8514fe3fd784ef380f55e079c6ce7
This commit is contained in:
Chaohui Wang
2023-08-31 19:30:37 +08:00
parent 2df0b3bf6f
commit b1ecd0e392
10 changed files with 267 additions and 329 deletions

View File

@@ -751,15 +751,11 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
@Override
public Dialog onCreateDialog(int dialogId) {
switch (dialogId) {
case WIFI_DIALOG_ID:
// modify network
mDialog = WifiDialog2
.createModal(getActivity(), this, mDialogWifiEntry, mDialogMode);
return mDialog;
default:
return super.onCreateDialog(dialogId);
if (dialogId == WIFI_DIALOG_ID) { // modify network
mDialog = new WifiDialog2(requireContext(), this, mDialogWifiEntry, mDialogMode);
return mDialog;
}
return super.onCreateDialog(dialogId);
}
@Override

View File

@@ -1,233 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi;
import android.annotation.StyleRes;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.wifitrackerlib.WifiEntry;
/**
* Dialog for users to edit a Wi-Fi network.
*/
public class WifiDialog2 extends AlertDialog implements WifiConfigUiBase2,
DialogInterface.OnClickListener {
/**
* Host UI component of WifiDialog2 can receive callbacks by this interface.
*/
public interface WifiDialog2Listener {
/**
* To forget the Wi-Fi network.
*/
default void onForget(WifiDialog2 dialog) {
}
/**
* To save the Wi-Fi network.
*/
default void onSubmit(WifiDialog2 dialog) {
}
/**
* To trigger Wi-Fi QR code scanner.
*/
default void onScan(WifiDialog2 dialog, String ssid) {
}
}
private static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE;
private static final int BUTTON_FORGET = DialogInterface.BUTTON_NEUTRAL;
private final int mMode;
private final WifiDialog2Listener mListener;
private final WifiEntry mWifiEntry;
private View mView;
private WifiConfigController2 mController;
private boolean mHideSubmitButton;
/**
* Creates a WifiDialog2 with no additional style. It displays as a dialog above the current
* view.
*/
public static WifiDialog2 createModal(Context context, WifiDialog2Listener listener,
WifiEntry wifiEntry, int mode) {
return new WifiDialog2(context, listener, wifiEntry, mode, 0 /* style */,
mode == WifiConfigUiBase2.MODE_VIEW /* hideSubmitButton */);
}
/**
* Creates a WifiDialog2 with customized style. It displays as a dialog above the current
* view.
*/
public static WifiDialog2 createModal(Context context, WifiDialog2Listener listener,
WifiEntry wifiEntry, int mode, @StyleRes int style) {
return new WifiDialog2(context, listener, wifiEntry, mode, style,
mode == WifiConfigUiBase2.MODE_VIEW /* hideSubmitButton */);
}
/* package */ WifiDialog2(Context context, WifiDialog2Listener listener, WifiEntry wifiEntry,
int mode, @StyleRes int style, boolean hideSubmitButton) {
super(context, style);
mMode = mode;
mListener = listener;
mWifiEntry = wifiEntry;
mHideSubmitButton = hideSubmitButton;
}
@Override
public WifiConfigController2 getController() {
return mController;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setWindowsOverlay();
mView = getLayoutInflater().inflate(R.layout.wifi_dialog, /* root */ null);
setView(mView);
mController = new WifiConfigController2(this, mView, mWifiEntry, mMode);
super.onCreate(savedInstanceState);
if (mHideSubmitButton) {
mController.hideSubmitButton();
} else {
/* During creation, the submit button can be unavailable to determine
* visibility. Right after creation, update button visibility */
mController.enableSubmitIfAppropriate();
}
if (mWifiEntry == null) {
mController.hideForgetButton();
}
}
private void setWindowsOverlay() {
final Window window = getWindow();
final WindowManager.LayoutParams lp = window.getAttributes();
window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
window.setAttributes(lp);
}
@SuppressWarnings("MissingSuperCall") // TODO: Fix me
@Override
protected void onStart() {
final ImageButton ssidScannerButton = findViewById(R.id.ssid_scanner_button);
if (mHideSubmitButton) {
ssidScannerButton.setVisibility(View.GONE);
return;
}
View.OnClickListener onClickScannerButtonListener = v -> {
if (mListener == null) {
return;
}
final TextView ssidEditText = findViewById(R.id.ssid);
final String ssid = ssidEditText.getText().toString();
mListener.onScan(/* WifiDialog2 */ this, ssid);
};
ssidScannerButton.setOnClickListener(onClickScannerButtonListener);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mController.updatePassword();
}
@Override
public void dispatchSubmit() {
if (mListener != null) {
mListener.onSubmit(this);
}
dismiss();
}
@Override
public void onClick(DialogInterface dialogInterface, int id) {
if (mListener != null) {
switch (id) {
case BUTTON_SUBMIT:
mListener.onSubmit(this);
break;
case BUTTON_FORGET:
if (WifiUtils.isNetworkLockedDown(getContext(),
mWifiEntry.getWifiConfiguration())) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
RestrictedLockUtilsInternal.getDeviceOwner(getContext()));
return;
}
mListener.onForget(this);
break;
}
}
}
@Override
public int getMode() {
return mMode;
}
@Override
public Button getSubmitButton() {
return getButton(BUTTON_SUBMIT);
}
@Override
public Button getForgetButton() {
return getButton(BUTTON_FORGET);
}
@Override
public Button getCancelButton() {
return getButton(BUTTON_NEGATIVE);
}
@Override
public void setSubmitButton(CharSequence text) {
setButton(BUTTON_SUBMIT, text, this);
}
@Override
public void setForgetButton(CharSequence text) {
setButton(BUTTON_FORGET, text, this);
}
@Override
public void setCancelButton(CharSequence text) {
setButton(BUTTON_NEGATIVE, text, this);
}
public WifiEntry getWifiEntry() {
return mWifiEntry;
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi
import android.annotation.StyleRes
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import com.android.settings.R
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.wifitrackerlib.WifiEntry
/**
* Dialog for users to edit a Wi-Fi network.
*/
class WifiDialog2 @JvmOverloads constructor(
context: Context,
private val listener: WifiDialog2Listener,
val wifiEntry: WifiEntry?,
private val mode: Int,
@StyleRes style: Int = 0,
private val hideSubmitButton: Boolean = mode == WifiConfigUiBase2.MODE_VIEW,
) : AlertDialog(context, style), WifiConfigUiBase2, DialogInterface.OnClickListener {
/**
* Host UI component of WifiDialog2 can receive callbacks by this interface.
*/
interface WifiDialog2Listener {
/**
* To forget the Wi-Fi network.
*/
fun onForget(dialog: WifiDialog2) {}
/**
* To save the Wi-Fi network.
*/
fun onSubmit(dialog: WifiDialog2) {}
/**
* To trigger Wi-Fi QR code scanner.
*/
fun onScan(dialog: WifiDialog2, ssid: String) {}
}
private lateinit var view: View
private lateinit var controller: WifiConfigController2
override fun getController(): WifiConfigController2 = controller
override fun onCreate(savedInstanceState: Bundle?) {
setWindowsOverlay()
view = layoutInflater.inflate(R.layout.wifi_dialog, null)
setView(view)
controller = WifiConfigController2(this, view, wifiEntry, mode)
super.onCreate(savedInstanceState)
if (hideSubmitButton) {
controller.hideSubmitButton()
} else {
// During creation, the submit button can be unavailable to determine visibility.
// Right after creation, update button visibility
controller.enableSubmitIfAppropriate()
}
if (wifiEntry == null) {
controller.hideForgetButton()
}
}
private fun setWindowsOverlay() {
window?.apply {
val lp = attributes
setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
attributes = lp
}
}
override fun onStart() {
super.onStart()
val ssidScannerButton = requireViewById<ImageButton>(R.id.ssid_scanner_button)
if (hideSubmitButton) {
ssidScannerButton.visibility = View.GONE
} else {
ssidScannerButton.setOnClickListener {
val ssidEditText = requireViewById<TextView>(R.id.ssid)
val ssid = ssidEditText.text.toString()
listener.onScan(this, ssid)
}
}
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
controller.updatePassword()
}
override fun dispatchSubmit() {
listener.onSubmit(this)
dismiss()
}
override fun onClick(dialogInterface: DialogInterface, id: Int) {
when (id) {
BUTTON_SUBMIT -> listener.onSubmit(this)
BUTTON_FORGET -> {
if (WifiUtils.isNetworkLockedDown(context, wifiEntry!!.wifiConfiguration)) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
context,
RestrictedLockUtilsInternal.getDeviceOwner(context)
)
return
}
listener.onForget(this)
}
}
}
override fun getMode(): Int = mode
override fun getSubmitButton(): Button? = getButton(BUTTON_SUBMIT)
override fun getForgetButton(): Button? = getButton(BUTTON_FORGET)
override fun getCancelButton(): Button? = getButton(BUTTON_NEGATIVE)
override fun setSubmitButton(text: CharSequence) {
setButton(BUTTON_SUBMIT, text, this)
}
override fun setForgetButton(text: CharSequence) {
setButton(BUTTON_FORGET, text, this)
}
override fun setCancelButton(text: CharSequence) {
setButton(BUTTON_NEGATIVE, text, this)
}
companion object {
private const val BUTTON_SUBMIT = BUTTON_POSITIVE
private const val BUTTON_FORGET = BUTTON_NEUTRAL
}
}

View File

@@ -170,7 +170,7 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog
createDialogWithSuwTheme();
} else {
if (mIsWifiTrackerLib) {
mDialog2 = WifiDialog2.createModal(this, this,
mDialog2 = new WifiDialog2(this, this,
mNetworkDetailsTracker.getWifiEntry(), WifiConfigUiBase2.MODE_CONNECT);
} else {
mDialog = WifiDialog.createModal(
@@ -201,7 +201,7 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog
? R.style.SuwAlertDialogThemeCompat_DayNight :
R.style.SuwAlertDialogThemeCompat_Light;
if (mIsWifiTrackerLib) {
mDialog2 = WifiDialog2.createModal(this, this,
mDialog2 = new WifiDialog2(this, this,
mNetworkDetailsTracker.getWifiEntry(),
WifiConfigUiBase2.MODE_CONNECT, targetStyle);
} else {

View File

@@ -602,15 +602,11 @@ public class WifiSettings extends RestrictedSettingsFragment
@Override
public Dialog onCreateDialog(int dialogId) {
switch (dialogId) {
case WIFI_DIALOG_ID:
// modify network
mDialog = WifiDialog2
.createModal(getActivity(), this, mDialogWifiEntry, mDialogMode);
return mDialog;
default:
return super.onCreateDialog(dialogId);
if (dialogId == WIFI_DIALOG_ID) { // modify network
mDialog = new WifiDialog2(requireContext(), this, mDialogWifiEntry, mDialogMode);
return mDialog;
}
return super.onCreateDialog(dialogId);
}
@Override

View File

@@ -180,7 +180,7 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl
}
final WifiEntry wifiEntry = mNetworkDetailsTracker.getWifiEntry();
return WifiDialog2.createModal(getActivity(), this, wifiEntry,
return new WifiDialog2(getActivity(), this, wifiEntry,
WifiConfigUiBase2.MODE_MODIFY);
}

View File

@@ -482,8 +482,8 @@ public class NetworkProviderSettingsTest {
when(mWifiEntry.canConnect()).thenReturn(true);
final WifiConfigController2 controller = mock(WifiConfigController2.class);
when(controller.getConfig()).thenReturn(config);
final WifiDialog2 wifiDialog2 = spy(WifiDialog2.createModal(mContext, null /* listener */,
mWifiEntry, mode));
WifiDialog2.WifiDialog2Listener listener = mock(WifiDialog2.WifiDialog2Listener.class);
final WifiDialog2 wifiDialog2 = spy(new WifiDialog2(mContext, listener, mWifiEntry, mode));
when(wifiDialog2.getController()).thenReturn(controller);
return wifiDialog2;
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.wifi.WifiDialog2.WifiDialog2Listener;
import com.android.wifitrackerlib.WifiEntry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowEntityHeaderController.class)
public class WifiDialog2Test {
@Mock private WifiEntry mMockWifiEntry;
private Context mContext = RuntimeEnvironment.application;
private WifiDialog2Listener mListener = new WifiDialog2Listener() {};
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void createModal_usesDefaultTheme() {
WifiDialog2 modal = WifiDialog2
.createModal(mContext, mListener, mMockWifiEntry, WifiConfigUiBase2.MODE_CONNECT);
WifiDialog2 wifiDialog2 = new WifiDialog2(mContext, mListener, mMockWifiEntry,
WifiConfigUiBase2.MODE_CONNECT, 0 /* style */, false /* hideSubmitButton */);
assertThat(modal.getContext().getThemeResId())
.isEqualTo(wifiDialog2.getContext().getThemeResId());
}
@Test
public void createModal_whenSetTheme_shouldBeCustomizedTheme() {
WifiDialog2 modal = WifiDialog2.createModal(mContext, mListener, mMockWifiEntry,
WifiConfigUiBase2.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
WifiDialog2 wifiDialog2 = new WifiDialog2(mContext, mListener, mMockWifiEntry,
WifiConfigUiBase2.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light,
false /* hideSubmitButton */);
assertThat(modal.getContext().getThemeResId())
.isEqualTo(wifiDialog2.getContext().getThemeResId());
}
}

View File

@@ -364,8 +364,8 @@ public class WifiSettingsTest {
when(wifiEntry.canConnect()).thenReturn(true);
final WifiConfigController2 controller = mock(WifiConfigController2.class);
when(controller.getConfig()).thenReturn(config);
final WifiDialog2 wifiDialog2 = spy(WifiDialog2.createModal(mContext, null /* listener */,
wifiEntry, mode));
WifiDialog2.WifiDialog2Listener listener = mock(WifiDialog2.WifiDialog2Listener.class);
final WifiDialog2 wifiDialog2 = spy(new WifiDialog2(mContext, listener, wifiEntry, mode));
when(wifiDialog2.getController()).thenReturn(controller);
return wifiDialog2;
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi
import androidx.activity.ComponentActivity
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
import com.android.settings.wifi.WifiDialog2.WifiDialog2Listener
import com.android.wifitrackerlib.WifiEntry
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
@RunWith(AndroidJUnit4::class)
class WifiDialog2Test {
@get:Rule
val activityScenarioRule = ActivityScenarioRule(ComponentActivity::class.java)
@get:Rule
val mockito: MockitoRule = MockitoJUnit.rule()
@Mock
private lateinit var mockWifiEntry: WifiEntry
private val listener = object : WifiDialog2Listener {}
@Test
fun constructor_usesDefaultTheme() {
activityScenarioRule.scenario.onActivity { activity ->
val wifiDialog2 = WifiDialog2(
context = activity,
listener = listener,
wifiEntry = mockWifiEntry,
mode = WifiConfigUiBase2.MODE_CONNECT,
style = 0,
hideSubmitButton = false
)
val modal = WifiDialog2(
context = activity,
listener = listener,
wifiEntry = mockWifiEntry,
mode = WifiConfigUiBase2.MODE_CONNECT,
)
assertThat(modal.context.themeResId).isEqualTo(wifiDialog2.context.themeResId)
}
}
@Test
fun constructor_whenSetTheme_shouldBeCustomizedTheme() {
activityScenarioRule.scenario.onActivity { activity ->
val wifiDialog2 = WifiDialog2(
context = activity,
listener = listener,
wifiEntry = mockWifiEntry,
mode = WifiConfigUiBase2.MODE_CONNECT,
style = R.style.SuwAlertDialogThemeCompat_Light,
hideSubmitButton = false,
)
val modal = WifiDialog2(
context = activity,
listener = listener,
wifiEntry = mockWifiEntry,
mode = WifiConfigUiBase2.MODE_CONNECT,
style = R.style.SuwAlertDialogThemeCompat_Light,
)
assertThat(modal.context.themeResId).isEqualTo(wifiDialog2.context.themeResId)
}
}
}