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)); - } -}