From 5a7e46dd800dac5ce863b5b337592bca21dc0c2b Mon Sep 17 00:00:00 2001 From: Eric Schwarzenbach Date: Mon, 17 Jul 2017 14:13:02 -0700 Subject: [PATCH] Add modify button to WifiNetworkDetailsFragment. Adds pencil icon to Wifi Detail action bar to modify the network. Modifies package/public visibility to allow the detail package to use the WifiDialog. Listens for changes in WifiConfigurations to propagate changes to the UI in WifiNetworkDetailsFragment. Changes WifiNetworkDetail preference launch to conform to pattern of other Settings apps. Removes unused WifiDetailActionBarObserver. Bug: 36483704, 37082355 Test: make -j40 RunSettingsRoboTests Change-Id: Ie9dc1892eaefdfad4a6bd7040bfc5dbf6236cfb4 --- res/xml/wifi_network_details_fragment.xml | 11 ++- .../settings/wifi/WifiConfigController.java | 2 +- src/com/android/settings/wifi/WifiDialog.java | 3 +- .../android/settings/wifi/WifiSettings.java | 26 +++++-- .../details/WifiDetailActionBarObserver.java | 45 ------------ .../WifiDetailPreferenceController.java | 54 +++++++++++++-- .../details/WifiNetworkDetailsFragment.java | 52 ++++++++++++-- .../WifiDetailActionBarObserverTest.java | 69 ------------------- 8 files changed, 122 insertions(+), 140 deletions(-) delete mode 100644 src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java delete mode 100644 tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml index 550ab36ac0a..5407947f8ec 100644 --- a/res/xml/wifi_network_details_fragment.xml +++ b/res/xml/wifi_network_details_fragment.xml @@ -22,14 +22,14 @@ android:selectable="false" android:order="-10000"/> + + + - - - - diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 5a3d426d125..3cf7f930bda 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -492,7 +492,7 @@ public class WifiConfigController implements TextWatcher, } } - /* package */ WifiConfiguration getConfig() { + public WifiConfiguration getConfig() { if (mMode == WifiConfigUiBase.MODE_VIEW) { return null; } diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 81f2a14ee62..cb3f8df1e77 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -27,8 +27,7 @@ import com.android.settings.R; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.wifi.AccessPoint; -// TODO(b/64069122) Have this extend a dialogfragment to handle the fullscreen launch case. -class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { +public class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { public interface WifiDialogListener { void onForget(WifiDialog dialog); diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index ef6a650a8b0..f3b08bf1dac 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -884,17 +884,20 @@ public class WifiSettings extends RestrictedSettingsFragment * {@link #mConnectedAccessPointPreferenceCategory}. */ private void addConnectedAccessPointPreference(AccessPoint connectedAp) { - String key = connectedAp.getBssid(); - LongPressAccessPointPreference pref = (LongPressAccessPointPreference) - getCachedPreference(key); - if (pref == null) { - pref = createLongPressActionPointPreference(connectedAp); - } + final LongPressAccessPointPreference pref = getOrCreatePreference(connectedAp); // Save the state of the current access point in the bundle so that we can restore it // in the Wifi Network Details Fragment pref.getAccessPoint().saveWifiState(pref.getExtras()); - pref.setFragment(WifiNetworkDetailsFragment.class.getName()); + + // Launch details page on click. + pref.setOnPreferenceClickListener(preference -> { + SettingsActivity activity = (SettingsActivity) WifiSettings.this.getActivity(); + activity.startPreferencePanel(this, + WifiNetworkDetailsFragment.class.getName(), pref.getExtras(), + R.string.wifi_details_title, null, null, 0); + return true; + }); pref.refresh(); mConnectedAccessPointPreferenceCategory.addPreference(pref); @@ -905,6 +908,15 @@ public class WifiSettings extends RestrictedSettingsFragment } } + private LongPressAccessPointPreference getOrCreatePreference(AccessPoint ap) { + LongPressAccessPointPreference pref = (LongPressAccessPointPreference) + getCachedPreference(AccessPointPreference.generatePreferenceKey(ap)); + if (pref == null) { + pref = createLongPressActionPointPreference(ap); + } + return pref; + } + /** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */ private void removeConnectedAccessPointPreference() { mConnectedAccessPointPreferenceCategory.removeAll(); diff --git a/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java b/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java deleted file mode 100644 index 81413d29b85..00000000000 --- a/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 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.details; - -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import com.android.settings.R; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnCreate; - -/** - * ActionBar lifecycle observer for {@link WifiNetworkDetailsFragment}. - */ -public class WifiDetailActionBarObserver implements LifecycleObserver, OnCreate { - - private final Fragment mFragment; - private final Context mContext; - - public WifiDetailActionBarObserver(Context context, Fragment fragment) { - mContext = context; - mFragment = fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - if (mFragment.getActivity() != null) { - mFragment.getActivity().getActionBar() - .setTitle(mContext.getString(R.string.wifi_details_title)); - } - } -} diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index aa23419e692..fcdd0d26169 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.settings.wifi.WifiSettings.isEditabilityLockedDown; +import android.app.Activity; import android.app.Fragment; import android.content.BroadcastReceiver; import android.content.Context; @@ -48,7 +49,7 @@ import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; import android.util.Log; import android.widget.ImageView; - +import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; @@ -60,13 +61,14 @@ import com.android.settings.vpn2.ConnectivityManagerWrapper; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wifi.WifiDialog; +import com.android.settings.wifi.WifiDialog.WifiDialogListener; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.wifi.AccessPoint; - import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -79,7 +81,9 @@ import java.util.stream.Collectors; * {@link WifiNetworkDetailsFragment}. */ public class WifiDetailPreferenceController extends AbstractPreferenceController - implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnResume { + implements PreferenceControllerMixin, WifiDialogListener, LifecycleObserver, OnPause, + OnResume { + private static final String TAG = "WifiDetailsPrefCtrl"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -121,7 +125,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController private NetworkCapabilities mNetworkCapabilities; private int mRssiSignalLevel = -1; private String[] mSignalStr; - private final WifiConfiguration mWifiConfig; + private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; private final WifiManager mWifiManager; private final MetricsFeatureProvider mMetricsFeatureProvider; @@ -147,9 +151,21 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { + case WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION: + if (!intent.getBooleanExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, + false /* defaultValue */)) { + // only one network changed + WifiConfiguration wifiConfiguration = intent + .getParcelableExtra(WifiManager.EXTRA_WIFI_CONFIGURATION); + if (mAccessPoint.matches(wifiConfiguration)) { + mWifiConfig = wifiConfiguration; + } + } + // fall through case WifiManager.NETWORK_STATE_CHANGED_ACTION: case WifiManager.RSSI_CHANGED_ACTION: updateInfo(); + break; } } }; @@ -239,6 +255,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mFilter = new IntentFilter(); mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); + lifecycle.addObserver(this); } @@ -334,7 +352,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController return; } - // Update whether the forgot button should be displayed. + // Update whether the forget button should be displayed. mButtonsPref.setButton1Visible(canForgetNetwork()); refreshNetworkState(); @@ -521,6 +539,32 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mConnectivityManagerWrapper.startCaptivePortalApp(mNetwork); } + @Override + public void onForget(WifiDialog dialog) { + // can't forget network from a 'modify' dialog + } + + @Override + public void onSubmit(WifiDialog dialog) { + if (dialog.getController() != null) { + mWifiManager.save(dialog.getController().getConfig(), new WifiManager.ActionListener() { + @Override + public void onSuccess() { + } + + @Override + public void onFailure(int reason) { + Activity activity = mFragment.getActivity(); + if (activity != null) { + Toast.makeText(activity, + R.string.wifi_failed_save_message, + Toast.LENGTH_SHORT).show(); + } + } + }); + } + } + /** * Wrapper for testing compatibility. */ diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index 4918889ff9d..765bebccb2b 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -15,17 +15,25 @@ */ package com.android.settings.wifi.details; +import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; + +import android.app.Dialog; import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; -import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wifi.WifiConfigUiBase; +import com.android.settings.wifi.WifiDialog; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.wifi.AccessPoint; import java.util.ArrayList; @@ -44,13 +52,9 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { private AccessPoint mAccessPoint; private WifiDetailPreferenceController mWifiDetailPreferenceController; - private WifiDetailActionBarObserver mWifiDetailActionBarObserver; @Override public void onAttach(Context context) { - mWifiDetailActionBarObserver = new WifiDetailActionBarObserver(context, this); - getLifecycle().addObserver(mWifiDetailActionBarObserver); - mAccessPoint = new AccessPoint(context, getArguments()); super.onAttach(context); } @@ -70,6 +74,44 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { return R.xml.wifi_network_details_fragment; } + @Override + public int getDialogMetricsCategory(int dialogId) { + if (dialogId == WIFI_DIALOG_ID) { + return MetricsEvent.DIALOG_WIFI_AP_EDIT; + } + return 0; + } + + @Override + public Dialog onCreateDialog(int dialogId) { + if (getActivity() == null || mWifiDetailPreferenceController == null + || mAccessPoint == null) { + return null; + } + return WifiDialog.createModal(getActivity(), mWifiDetailPreferenceController, mAccessPoint, + WifiConfigUiBase.MODE_MODIFY); + } + + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify); + item.setIcon(R.drawable.ic_mode_edit); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case Menu.FIRST: + showDialog(WIFI_DIALOG_ID); + return true; + default: + return super.onOptionsItemSelected(menuItem); + } + } + @Override protected List getPreferenceControllers(Context context) { ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java deleted file mode 100644 index c573d3cb658..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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.details; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.ActionBar; -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import com.android.settings.R; -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.core.lifecycle.Lifecycle; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class WifiDetailActionBarObserverTest { - - @Mock private Bundle mockBundle; - @Mock private Activity mockActivity; - @Mock private ActionBar mockActionBar; - @Mock private WifiNetworkDetailsFragment mockFragment; - - private Context mContext = RuntimeEnvironment.application; - private Lifecycle mLifecycle; - private WifiDetailActionBarObserver mObserver; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mLifecycle = new Lifecycle(); - - when(mockFragment.getActivity()).thenReturn(mockActivity); - when(mockActivity.getActionBar()).thenReturn(mockActionBar); - - mObserver = new WifiDetailActionBarObserver(mContext, mockFragment); - mLifecycle.addObserver(mObserver); - } - - @Test - public void actionBarIsSetToNetworkInfo() { - mLifecycle.onCreate(mockBundle); - - verify(mockActionBar).setTitle(mContext.getString(R.string.wifi_details_title)); - } -}