diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3101e9a6ee7..e220b629d54 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -162,8 +162,7 @@ + android:parentActivityName="Settings"/> diff --git a/src/com/android/settings/wifi/ConfigureAccessPointFragment.java b/src/com/android/settings/wifi/ConfigureAccessPointFragment.java new file mode 100644 index 00000000000..a3090a89361 --- /dev/null +++ b/src/com/android/settings/wifi/ConfigureAccessPointFragment.java @@ -0,0 +1,175 @@ +/* + * 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.app.ActionBar; +import android.app.Activity; +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import com.android.settings.R; +import com.android.settings.core.InstrumentedFragment; +import com.android.settingslib.wifi.AccessPoint; + +import androidx.annotation.VisibleForTesting; + +/** + * Detail page for configuring Wi-Fi network. + * + * The AccessPoint should be saved to the argument when launching this class in order to properly + * render this page. + */ +public class ConfigureAccessPointFragment extends InstrumentedFragment implements WifiConfigUiBase { + + public static final String NETWORK_CONFIG_KEY = "network_config_key"; + + private static final int SUBMIT_BUTTON_ID = android.R.id.button1; + private static final int CANCEL_BUTTON_ID = android.R.id.button2; + + private WifiConfigController mUiController; + private Button mSubmitBtn; + private Button mCancelBtn; + private AccessPoint mAccessPoint; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mAccessPoint = new AccessPoint(context, getArguments()); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.SETTINGS_WIFI_CONFIGURE_NETWORK; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + final View rootView = inflater.inflate(R.layout.wifi_add_network_view, + container, false /* attachToRoot */); + + final Button neutral = rootView.findViewById(android.R.id.button3); + if (neutral != null) { + neutral.setVisibility(View.GONE); + } + + mSubmitBtn = rootView.findViewById(SUBMIT_BUTTON_ID); + mCancelBtn = rootView.findViewById(CANCEL_BUTTON_ID); + mSubmitBtn.setOnClickListener(view -> handleSubmitAction()); + mCancelBtn.setOnClickListener(view -> handleCancelAction()); + + mUiController = new WifiConfigController(this, rootView, mAccessPoint, + getMode(), false /* requestFocus */); + + /** + * For this add AccessPoint UI, need to remove the Home button, so set related feature as + * false. + */ + final ActionBar actionBar = getActivity().getActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(false); + actionBar.setHomeButtonEnabled(false); + actionBar.setDisplayShowHomeEnabled(false); + } + + return rootView; + } + + @Override + public void onViewStateRestored(Bundle savedInstanceState) { + super.onViewStateRestored(savedInstanceState); + mUiController.updatePassword(); + } + + @Override + public int getMode() { + return WifiConfigUiBase.MODE_CONNECT; + } + + @Override + public WifiConfigController getController() { + return mUiController; + } + + @Override + public void dispatchSubmit() { + // Do nothing + } + + @Override + public void setTitle(int id) { + getActivity().setTitle(id); + } + + @Override + public void setTitle(CharSequence title) { + getActivity().setTitle(title); + } + + @Override + public void setSubmitButton(CharSequence text) { + mSubmitBtn.setText(text); + } + + @Override + public void setCancelButton(CharSequence text) { + mCancelBtn.setText(text); + } + + @Override + public void setForgetButton(CharSequence text) { + // AddNetwork doesn't need forget button. + } + + @Override + public Button getSubmitButton() { + return mSubmitBtn; + } + + @Override + public Button getCancelButton() { + return mCancelBtn; + } + + @Override + public Button getForgetButton() { + // AddNetwork doesn't need forget button. + return null; + } + + @VisibleForTesting + void handleSubmitAction() { + final Intent intent = new Intent(); + final Activity activity = getActivity(); + intent.putExtra(NETWORK_CONFIG_KEY, mUiController.getConfig()); + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } + + @VisibleForTesting + void handleCancelAction() { + final Activity activity = getActivity(); + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + } +} diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index df6e470a92f..950b6458119 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -173,6 +173,7 @@ public class WifiConfigController implements TextWatcher, private ProxySettings mProxySettings = ProxySettings.UNASSIGNED; private ProxyInfo mHttpProxy = null; private StaticIpConfiguration mStaticIpConfiguration = null; + private boolean mRequestFocus = true; private String[] mLevels; private int mMode; @@ -187,11 +188,17 @@ public class WifiConfigController implements TextWatcher, public WifiConfigController(WifiConfigUiBase parent, View view, AccessPoint accessPoint, int mode) { + this (parent, view, accessPoint, mode, true /* requestFocus */); + } + + public WifiConfigController(WifiConfigUiBase parent, View view, AccessPoint accessPoint, + int mode, boolean requestFocus) { mConfigUi = parent; mView = view; mAccessPoint = accessPoint; mContext = mConfigUi.getContext(); + mRequestFocus = requestFocus; // Init Wi-Fi manager mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); @@ -420,8 +427,10 @@ public class WifiConfigController implements TextWatcher, enableSubmitIfAppropriate(); } - // After done view show and hide, request focus from parent view - mView.findViewById(R.id.l_wifidialog).requestFocus(); + // After done view show and hide, request focus from parameter. + if (mRequestFocus) { + mView.findViewById(R.id.l_wifidialog).requestFocus(); + } } @VisibleForTesting diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 514e5b22d3c..8ac868f1f37 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -50,10 +50,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; - import com.android.settings.LinkifyUtils; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; @@ -61,8 +57,8 @@ import com.android.settings.SettingsActivity; import com.android.settings.core.FeatureFlags; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.SummaryLoader; -import com.android.settings.datausage.DataUsageUtils; import com.android.settings.datausage.DataUsagePreference; +import com.android.settings.datausage.DataUsageUtils; import com.android.settings.location.ScanningSettings; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; @@ -84,6 +80,10 @@ import com.android.settingslib.wifi.WifiTrackerFactory; import java.util.ArrayList; import java.util.List; +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; + /** * Two types of UI are provided here. * @@ -109,6 +109,8 @@ public class WifiSettings extends RestrictedSettingsFragment @VisibleForTesting static final int ADD_NETWORK_REQUEST = 2; + static final int CONFIG_NETWORK_REQUEST = 3; + // Instance state keys private static final String SAVE_DIALOG_MODE = "dialog_mode"; private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state"; @@ -427,6 +429,11 @@ public class WifiSettings extends RestrictedSettingsFragment mWifiTracker.resumeScanning(); } return; + } else if (requestCode == CONFIG_NETWORK_REQUEST) { + if (resultCode == Activity.RESULT_OK) { + handleConfigNetworkSubmitEvent(data); + } + return; } final boolean formerlyRestricted = mIsRestricted; @@ -559,7 +566,10 @@ public class WifiSettings extends RestrictedSettingsFragment break; default: - showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT); + final Bundle bundle = ((LongPressAccessPointPreference) preference).getExtras(); + mSelectedAccessPoint.saveWifiState(bundle); + launchConfigNewNetworkFragment(mSelectedAccessPoint, + WifiConfigUiBase.MODE_CONNECT, bundle); break; } } else if (preference == mAddWifiNetworkPreference) { @@ -1253,4 +1263,30 @@ public class WifiSettings extends RestrictedSettingsFragment return new SummaryProvider(activity, summaryLoader); } }; + + private void handleConfigNetworkSubmitEvent(Intent data) { + final WifiConfiguration wifiConfiguration = data.getParcelableExtra( + ConfigureAccessPointFragment.NETWORK_CONFIG_KEY); + if (wifiConfiguration != null) { + mWifiManager.save(wifiConfiguration, mSaveListener); + + if (mSelectedAccessPoint != null) { + connect(wifiConfiguration, false /*isSavedNetwork*/); + } + mWifiTracker.resumeScanning(); + } + } + + private void launchConfigNewNetworkFragment(AccessPoint accessPoint, int dialogMode, + Bundle bundleForArguments) { + mDialogMode = dialogMode; + final CharSequence title = accessPoint.getTitle(); + new SubSettingLauncher(getContext()) + .setTitleText(title) + .setDestination(ConfigureAccessPointFragment.class.getName()) + .setArguments(bundleForArguments) + .setSourceMetricsCategory(getMetricsCategory()) + .setResultListener(this, CONFIG_NETWORK_REQUEST) + .launch(); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java new file mode 100644 index 00000000000..5a12a88d23e --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java @@ -0,0 +1,93 @@ +/* + * 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 static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.app.settings.SettingsEnums; +import android.os.Bundle; + +import com.android.settings.testutils.shadow.ShadowConnectivityManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.androidx.fragment.FragmentController; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowConnectivityManager.class) +public class ConfigureAccessPointFragmentTest { + + private static final String KEY_SSID = "key_ssid"; + private static final String KEY_SECURITY = "key_security"; + + private ConfigureAccessPointFragment mConfigureAccessPointFragment; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + Bundle bundle = new Bundle(); + + bundle.putString(KEY_SSID, "Test AP"); + bundle.putInt(KEY_SECURITY, 1 /* WEP */); + mConfigureAccessPointFragment = spy(new ConfigureAccessPointFragment()); + mConfigureAccessPointFragment.setArguments(bundle); + FragmentController.setupFragment(mConfigureAccessPointFragment); + } + + @Test + public void getMetricsCategory_shouldReturnConfigureNetwork() { + assertThat(mConfigureAccessPointFragment.getMetricsCategory()).isEqualTo( + SettingsEnums.SETTINGS_WIFI_CONFIGURE_NETWORK); + } + + @Test + public void getMode_shouldBeModeConnected() { + assertThat(mConfigureAccessPointFragment.getMode()).isEqualTo( + WifiConfigUiBase.MODE_CONNECT); + } + + @Test + public void launchFragment_shouldShowSubmitButton() { + assertThat(mConfigureAccessPointFragment.getSubmitButton()).isNotNull(); + } + + @Test + public void launchFragment_shouldShowCancelButton() { + assertThat(mConfigureAccessPointFragment.getCancelButton()).isNotNull(); + } + + @Test + public void onClickSubmitButton_shouldHandleSubmitAction() { + mConfigureAccessPointFragment.getSubmitButton().performClick(); + + verify(mConfigureAccessPointFragment).handleSubmitAction(); + } + + @Test + public void onClickCancelButton_shouldHandleCancelAction() { + mConfigureAccessPointFragment.getCancelButton().performClick(); + + verify(mConfigureAccessPointFragment).handleCancelAction(); + } +}