Create the Wifi Network Details Page.
This page should not be searchable, as it corresponds to a specific access point, thus click on a search result would not have an access point in which to open. Fix WifiPicker bugs b/35883232 and b/35951638 that deal with UI jank. Bug: 34713316 Test: Tracked in b/35963536 and to be implemented in an immediate follow up CL. Change-Id: Iad7f26c7f04c3fc7d07a8e9188843eeb4d44cd36
This commit is contained in:
28
res/drawable/ic_frequency_antenna.xml
Normal file
28
res/drawable/ic_frequency_antenna.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="@color/wifi_details_icon_color">
|
||||||
|
<path
|
||||||
|
android:pathData="M12,5c-3.9,0-7,3.1-7,7h2c0-2.8,2.2-5,5-5s5,2.2,5,5h2C19,8.1,15.9,5,12,5z M13,14.3c0.9-0.4,1.5-1.3,1.5-2.3
|
||||||
|
c0-1.4-1.1-2.5-2.5-2.5S9.5,10.6,9.5,12c0,1,0.6,1.9,1.5,2.3v3.3L7.6,21L9,22.4l3-3l3,3l1.4-1.4L13,17.6V14.3z M12,1
|
||||||
|
C5.9,1,1,5.9,1,12h2c0-5,4-9,9-9s9,4,9,9h2C23,5.9,18.1,1,12,1z"
|
||||||
|
android:fillColor="#FFFFFFFF" />
|
||||||
|
</vector>
|
||||||
26
res/drawable/ic_security_lock_24dp.xml
Normal file
26
res/drawable/ic_security_lock_24dp.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="@color/wifi_details_icon_color">
|
||||||
|
<path
|
||||||
|
android:pathData="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"
|
||||||
|
android:fillColor="#FFFFFFFF" />
|
||||||
|
</vector>
|
||||||
24
res/drawable/ic_settings_widget_background.xml
Normal file
24
res/drawable/ic_settings_widget_background.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:viewportWidth="192"
|
||||||
|
android:viewportHeight="192"
|
||||||
|
android:width="72dp"
|
||||||
|
android:height="72dp">
|
||||||
|
<path
|
||||||
|
android:pathData="M184 96A88 88 0 0 1 96 184 88 88 0 0 1 8 96 88 88 0 0 1 96 8 88 88 0 0 1 184 96Z"
|
||||||
|
android:fillColor="@android:color/white" />
|
||||||
|
</vector>
|
||||||
50
res/layout/connection_detail_pref.xml
Normal file
50
res/layout/connection_detail_pref.xml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/connection_detail_layout"
|
||||||
|
android:background="?android:attr/colorAccent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="144dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/ic_settings_widget_background"
|
||||||
|
android:layout_marginLeft="72dp"
|
||||||
|
android:elevation="2dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@android:id/icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="20dp"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
|
android:textColor="@android:color/white"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -108,4 +108,7 @@
|
|||||||
<!-- Color for the background of the shortcut icons.-->
|
<!-- Color for the background of the shortcut icons.-->
|
||||||
<color name="shortcut_background">#fff5f5f5</color>
|
<color name="shortcut_background">#fff5f5f5</color>
|
||||||
|
|
||||||
|
<!-- Color for preference icons on the Wifi Network Details page -->
|
||||||
|
<color name="wifi_details_icon_color">#8A000000</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1836,6 +1836,14 @@
|
|||||||
<!-- Wi-Fi settings screen, advanced, title of the item to show the Wi-Fi device's current IP address. -->
|
<!-- Wi-Fi settings screen, advanced, title of the item to show the Wi-Fi device's current IP address. -->
|
||||||
<string name="wifi_advanced_ip_address_title">IP address</string>
|
<string name="wifi_advanced_ip_address_title">IP address</string>
|
||||||
|
|
||||||
|
<!-- Wifi Network Details -->
|
||||||
|
<!-- Wifi details preference title to display router IP subnet mask -->
|
||||||
|
<string name="wifi_details_subnet_mask">Subnet Mask</string>
|
||||||
|
<!-- Wifi details preference title to display router DNS info -->
|
||||||
|
<string name="wifi_details_dns">DNS</string>
|
||||||
|
<!-- Wifi details preference category title for IPv6 information -->
|
||||||
|
<string name="wifi_details_ipv6_address_header">IPv6 Addresses</string>
|
||||||
|
|
||||||
<!-- Wifi saved access points. Used as a label under the shortcut icon that goes to Wifi saved access points. [CHAR LIMIT=20] -->
|
<!-- Wifi saved access points. Used as a label under the shortcut icon that goes to Wifi saved access points. [CHAR LIMIT=20] -->
|
||||||
<string name="wifi_saved_access_points_label">Saved networks</string>
|
<string name="wifi_saved_access_points_label">Saved networks</string>
|
||||||
<!-- Wifi Advanced settings. Used as a label under the shortcut icon that goes to Wifi advanced settings. [CHAR LIMIT=20] -->
|
<!-- Wifi Advanced settings. Used as a label under the shortcut icon that goes to Wifi advanced settings. [CHAR LIMIT=20] -->
|
||||||
|
|||||||
73
res/xml/wifi_network_details_fragment.xml
Normal file
73
res/xml/wifi_network_details_fragment.xml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2016 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings" >
|
||||||
|
|
||||||
|
<!-- Connected Network Header -->
|
||||||
|
<Preference
|
||||||
|
android:key="connection_detail"
|
||||||
|
android:layout="@layout/connection_detail_pref"/>
|
||||||
|
|
||||||
|
<!-- General Details Category -->
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="general_details_category" >
|
||||||
|
<!-- Buttons -->
|
||||||
|
<com.android.settings.applications.LayoutPreference
|
||||||
|
android:key="forget_button"
|
||||||
|
android:selectable="false"
|
||||||
|
android:layout="@layout/single_button_panel" />
|
||||||
|
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="signal_strength"
|
||||||
|
android:title="@string/wifi_signal" />
|
||||||
|
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="frequency"
|
||||||
|
android:icon="@drawable/ic_frequency_antenna"
|
||||||
|
android:title="@string/wifi_frequency" />
|
||||||
|
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="security"
|
||||||
|
android:icon="@drawable/ic_security_lock_24dp"
|
||||||
|
android:title="@string/wifi_security" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<!-- IP Details -->
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="ip_details_category"
|
||||||
|
android:title="@string/wifi_ip_address">
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="ip_address"
|
||||||
|
android:title="@string/wifi_ip_address" />
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="router"
|
||||||
|
android:title="@string/wifi_gateway" />
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="subnet_mask"
|
||||||
|
android:title="@string/wifi_details_subnet_mask" />
|
||||||
|
<com.android.settings.wifi.WifiDetailPreference
|
||||||
|
android:key="dns"
|
||||||
|
android:title="@string/wifi_details_dns" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<!-- IPv6 Details -->
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="ipv6_details_category"
|
||||||
|
android:title="@string/wifi_details_ipv6_address_header" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
||||||
51
src/com/android/settings/wifi/WifiDetailPreference.java
Normal file
51
src/com/android/settings/wifi/WifiDetailPreference.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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.content.Context;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceViewHolder;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Preference to be used with the Wifi Network Detail Fragment that allows a summary text to be
|
||||||
|
* set inside the widget resource
|
||||||
|
*/
|
||||||
|
public class WifiDetailPreference extends Preference {
|
||||||
|
private String mDetailText;
|
||||||
|
|
||||||
|
public WifiDetailPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
setWidgetLayoutResource(R.layout.preference_widget_summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDetailText(String text) {
|
||||||
|
mDetailText = text;
|
||||||
|
notifyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||||
|
super.onBindViewHolder(view);
|
||||||
|
TextView textView = ((TextView) view.findViewById(R.id.widget_summary));
|
||||||
|
textView.setText(mDetailText);
|
||||||
|
textView.setPadding(0, 0, 10, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,7 +42,6 @@ import android.support.annotation.VisibleForTesting;
|
|||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
import android.support.v7.preference.PreferenceManager;
|
import android.support.v7.preference.PreferenceManager;
|
||||||
import android.support.v7.preference.PreferenceViewHolder;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
@@ -65,6 +64,7 @@ import com.android.settings.search.Indexable;
|
|||||||
import com.android.settings.search.SearchIndexableRaw;
|
import com.android.settings.search.SearchIndexableRaw;
|
||||||
import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
|
import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
|
||||||
import com.android.settings.widget.SwitchBarController;
|
import com.android.settings.widget.SwitchBarController;
|
||||||
|
import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
import com.android.settingslib.wifi.AccessPoint;
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
import com.android.settingslib.wifi.AccessPoint.AccessPointListener;
|
import com.android.settingslib.wifi.AccessPoint.AccessPointListener;
|
||||||
@@ -187,6 +187,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
getPreferenceManager().setPreferenceComparisonCallback(
|
getPreferenceManager().setPreferenceComparisonCallback(
|
||||||
new PreferenceManager.SimplePreferenceComparisonCallback());
|
new PreferenceManager.SimplePreferenceComparisonCallback());
|
||||||
addPreferencesFromResource(R.xml.wifi_settings);
|
addPreferencesFromResource(R.xml.wifi_settings);
|
||||||
@@ -496,6 +497,12 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceTreeClick(Preference preference) {
|
public boolean onPreferenceTreeClick(Preference preference) {
|
||||||
|
// If the preference has a fragment set, open that
|
||||||
|
if (preference.getFragment() != null) {
|
||||||
|
preference.setOnPreferenceClickListener(null);
|
||||||
|
return super.onPreferenceTreeClick(preference);
|
||||||
|
}
|
||||||
|
|
||||||
if (preference instanceof LongPressAccessPointPreference) {
|
if (preference instanceof LongPressAccessPointPreference) {
|
||||||
mSelectedAccessPoint = ((LongPressAccessPointPreference) preference).getAccessPoint();
|
mSelectedAccessPoint = ((LongPressAccessPointPreference) preference).getAccessPoint();
|
||||||
if (mSelectedAccessPoint == null) {
|
if (mSelectedAccessPoint == null) {
|
||||||
@@ -665,14 +672,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
removeCachedPrefs(mAccessPointsPreferenceCategory);
|
removeCachedPrefs(mAccessPointsPreferenceCategory);
|
||||||
if (!hasAvailableAccessPoints) {
|
if (!hasAvailableAccessPoints) {
|
||||||
setProgressBarVisible(true);
|
setProgressBarVisible(true);
|
||||||
Preference pref = new Preference(getContext()) {
|
Preference pref = new Preference(getPrefContext());
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
|
||||||
super.onBindViewHolder(holder);
|
|
||||||
// Show a line on each side of add network.
|
|
||||||
holder.setDividerAllowedBelow(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
pref.setSelectable(false);
|
pref.setSelectable(false);
|
||||||
pref.setSummary(R.string.wifi_empty_list_wifi_on);
|
pref.setSummary(R.string.wifi_empty_list_wifi_on);
|
||||||
pref.setOrder(index++);
|
pref.setOrder(index++);
|
||||||
@@ -752,7 +752,10 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else same AP is connected, nothing to do
|
// Else same AP is connected, simply refresh the connected access point preference
|
||||||
|
// (first and only access point in this category).
|
||||||
|
((LongPressAccessPointPreference) mConnectedAccessPointPreferenceCategory.getPreference(0))
|
||||||
|
.refresh();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,6 +770,12 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
if (pref == null) {
|
if (pref == null) {
|
||||||
pref = createLongPressActionPointPreference(connectedAp);
|
pref = createLongPressActionPointPreference(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());
|
||||||
|
|
||||||
pref.refresh();
|
pref.refresh();
|
||||||
mConnectedAccessPointPreferenceCategory.addPreference(pref);
|
mConnectedAccessPointPreferenceCategory.addPreference(pref);
|
||||||
mConnectedAccessPointPreferenceCategory.setVisible(true);
|
mConnectedAccessPointPreferenceCategory.setVisible(true);
|
||||||
@@ -862,6 +871,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectedChanged() {
|
public void onConnectedChanged() {
|
||||||
|
onAccessPointsChanged();
|
||||||
changeNextButtonState(mWifiTracker.isConnected());
|
changeNextButtonState(mWifiTracker.isConnected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* 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.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.DhcpInfo;
|
||||||
|
import android.net.LinkProperties;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkBadging;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.net.NetworkUtils;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.net.wifi.WifiInfo;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.PreferenceController;
|
||||||
|
import com.android.settings.core.lifecycle.Lifecycle;
|
||||||
|
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settings.core.lifecycle.events.OnResume;
|
||||||
|
import com.android.settings.wifi.WifiDetailPreference;
|
||||||
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
|
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for logic pertaining to displaying Wifi information for the
|
||||||
|
* {@link WifiNetworkDetailsFragment}.
|
||||||
|
*/
|
||||||
|
public class WifiDetailPreferenceController extends PreferenceController implements
|
||||||
|
LifecycleObserver, OnResume {
|
||||||
|
private static final String TAG = "WifiDetailsPrefCtrl";
|
||||||
|
|
||||||
|
private static final String KEY_CONNECTION_DETAIL_PREF = "connection_detail";
|
||||||
|
private static final String KEY_SIGNAL_STRENGTH_PREF = "signal_strength";
|
||||||
|
private static final String KEY_FREQUENCY_PREF = "frequency";
|
||||||
|
private static final String KEY_SECURITY_PREF = "security";
|
||||||
|
private static final String KEY_IP_ADDRESS_PREF = "ip_address";
|
||||||
|
private static final String KEY_ROUTER_PREF = "router";
|
||||||
|
private static final String KEY_SUBNET_MASK_PREF = "subnet_mask";
|
||||||
|
private static final String KEY_DNS_PREF = "dns";
|
||||||
|
private static final String KEY_IPV6_ADDRESS_CATEGORY = "ipv6_details_category";
|
||||||
|
|
||||||
|
private AccessPoint mAccessPoint;
|
||||||
|
private NetworkInfo mNetworkInfo;
|
||||||
|
private Context mPrefContext;
|
||||||
|
private int mRssi;
|
||||||
|
private String[] mSignalStr;
|
||||||
|
private WifiConfiguration mWifiConfig;
|
||||||
|
private WifiInfo mWifiInfo;
|
||||||
|
private final WifiManager mWifiManager;
|
||||||
|
|
||||||
|
// Preferences - in order of appearance
|
||||||
|
private Preference mConnectionDetailPref;
|
||||||
|
private WifiDetailPreference mSignalStrengthPref;
|
||||||
|
private WifiDetailPreference mFrequencyPref;
|
||||||
|
private WifiDetailPreference mSecurityPref;
|
||||||
|
private WifiDetailPreference mIpAddressPref;
|
||||||
|
private WifiDetailPreference mRouterPref;
|
||||||
|
private WifiDetailPreference mSubnetPref;
|
||||||
|
private WifiDetailPreference mDnsPref;
|
||||||
|
private PreferenceCategory mIpv6AddressCategory;
|
||||||
|
|
||||||
|
public WifiDetailPreferenceController(AccessPoint accessPoint, Context context,
|
||||||
|
Lifecycle lifecycle, WifiManager wifiManager) {
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
mAccessPoint = accessPoint;
|
||||||
|
mNetworkInfo = accessPoint.getNetworkInfo();
|
||||||
|
mRssi = accessPoint.getRssi();
|
||||||
|
mSignalStr = context.getResources().getStringArray(R.array.wifi_signal);
|
||||||
|
mWifiConfig = accessPoint.getConfig();
|
||||||
|
mWifiManager = wifiManager;
|
||||||
|
|
||||||
|
lifecycle.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
// Returns null since this controller contains more than one Preference
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
|
||||||
|
mPrefContext = screen.getPreferenceManager().getContext();
|
||||||
|
|
||||||
|
mConnectionDetailPref = screen.findPreference(KEY_CONNECTION_DETAIL_PREF);
|
||||||
|
|
||||||
|
mSignalStrengthPref =
|
||||||
|
(WifiDetailPreference) screen.findPreference(KEY_SIGNAL_STRENGTH_PREF);
|
||||||
|
mFrequencyPref = (WifiDetailPreference) screen.findPreference(KEY_FREQUENCY_PREF);
|
||||||
|
mSecurityPref = (WifiDetailPreference) screen.findPreference(KEY_SECURITY_PREF);
|
||||||
|
|
||||||
|
mIpAddressPref = (WifiDetailPreference) screen.findPreference(KEY_IP_ADDRESS_PREF);
|
||||||
|
mRouterPref = (WifiDetailPreference) screen.findPreference(KEY_ROUTER_PREF);
|
||||||
|
mSubnetPref = (WifiDetailPreference) screen.findPreference(KEY_SUBNET_MASK_PREF);
|
||||||
|
mDnsPref = (WifiDetailPreference) screen.findPreference(KEY_DNS_PREF);
|
||||||
|
|
||||||
|
mIpv6AddressCategory =
|
||||||
|
(PreferenceCategory) screen.findPreference(KEY_IPV6_ADDRESS_CATEGORY);
|
||||||
|
|
||||||
|
mSecurityPref.setDetailText(mAccessPoint.getSecurityString(false /* concise */));
|
||||||
|
}
|
||||||
|
|
||||||
|
public WifiInfo getWifiInfo() {
|
||||||
|
return mWifiInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
mWifiInfo = mWifiManager.getConnectionInfo();
|
||||||
|
mWifiConfig = mWifiManager.getWifiApConfiguration();
|
||||||
|
|
||||||
|
refreshFromWifiInfo();
|
||||||
|
setIpText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshFromWifiInfo() {
|
||||||
|
if (mWifiInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAccessPoint.update(mWifiConfig, mWifiInfo, mNetworkInfo);
|
||||||
|
|
||||||
|
int iconSignalLevel = WifiManager.calculateSignalLevel(
|
||||||
|
mWifiInfo.getRssi(), WifiManager.RSSI_LEVELS);
|
||||||
|
Drawable wifiIcon = NetworkBadging.getWifiIcon(
|
||||||
|
iconSignalLevel, NetworkBadging.BADGING_NONE, mContext.getTheme()).mutate();
|
||||||
|
|
||||||
|
// Connected Header Pref
|
||||||
|
mConnectionDetailPref.setIcon(wifiIcon);
|
||||||
|
mConnectionDetailPref.setTitle(mAccessPoint.getSettingsSummary());
|
||||||
|
|
||||||
|
// Signal Strength Pref
|
||||||
|
Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate();
|
||||||
|
wifiIconDark.setTint(mContext.getResources().getColor(
|
||||||
|
R.color.wifi_details_icon_color, mContext.getTheme()));
|
||||||
|
mSignalStrengthPref.setIcon(wifiIconDark);
|
||||||
|
|
||||||
|
int summarySignalLevel = WifiManager.calculateSignalLevel(mRssi, mSignalStr.length);
|
||||||
|
mSignalStrengthPref.setDetailText(mSignalStr[summarySignalLevel]);
|
||||||
|
|
||||||
|
// Frequency Pref
|
||||||
|
final int frequency = mWifiInfo.getFrequency();
|
||||||
|
String band = null;
|
||||||
|
if (frequency >= AccessPoint.LOWER_FREQ_24GHZ
|
||||||
|
&& frequency < AccessPoint.HIGHER_FREQ_24GHZ) {
|
||||||
|
band = mContext.getResources().getString(R.string.wifi_band_24ghz);
|
||||||
|
} else if (frequency >= AccessPoint.LOWER_FREQ_5GHZ
|
||||||
|
&& frequency < AccessPoint.HIGHER_FREQ_5GHZ) {
|
||||||
|
band = mContext.getResources().getString(R.string.wifi_band_5ghz);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Unexpected frequency " + frequency);
|
||||||
|
}
|
||||||
|
mFrequencyPref.setDetailText(band);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setIpText() {
|
||||||
|
mIpv6AddressCategory.removeAll();
|
||||||
|
mIpv6AddressCategory.setVisible(false);
|
||||||
|
|
||||||
|
Network currentNetwork = mWifiManager.getCurrentNetwork();
|
||||||
|
if (currentNetwork == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
|
||||||
|
LinkProperties prop = cm.getLinkProperties(currentNetwork);
|
||||||
|
List<InetAddress> addresses = prop.getAllAddresses();
|
||||||
|
|
||||||
|
// Set ip addresses
|
||||||
|
for (int i = 0; i < addresses.size(); i++) {
|
||||||
|
InetAddress addr = addresses.get(i);
|
||||||
|
if (addr instanceof Inet4Address) {
|
||||||
|
mIpAddressPref.setDetailText(addr.getHostAddress());
|
||||||
|
} else if (addr instanceof Inet6Address) {
|
||||||
|
String ip = addr.getHostAddress();
|
||||||
|
Preference pref = new Preference(mPrefContext);
|
||||||
|
pref.setKey(ip);
|
||||||
|
pref.setTitle(ip);
|
||||||
|
mIpv6AddressCategory.addPreference(pref);
|
||||||
|
mIpv6AddressCategory.setVisible(true); // TODO(sghuman): Make sure to
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String subnetMask = null;
|
||||||
|
String router;
|
||||||
|
DhcpInfo dhcp = mWifiManager.getDhcpInfo();
|
||||||
|
if (dhcp != null) {
|
||||||
|
if (dhcp.netmask == 0) {
|
||||||
|
Log.e(TAG, "invalid netmask value of 0 for DhcpInfo: " + dhcp);
|
||||||
|
mSubnetPref.setVisible(false);
|
||||||
|
} else {
|
||||||
|
subnetMask = NetworkUtils.intToInetAddress(dhcp.netmask).getHostAddress();
|
||||||
|
mSubnetPref.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
router = NetworkUtils.intToInetAddress(dhcp.gateway).getHostAddress();
|
||||||
|
} else { // Statically configured IP
|
||||||
|
|
||||||
|
// TODO(sghuman): How do we get subnet mask for static ips?
|
||||||
|
mSubnetPref.setVisible(false);
|
||||||
|
|
||||||
|
router = mWifiManager.getWifiApConfiguration().getStaticIpConfiguration().gateway
|
||||||
|
.getHostAddress();
|
||||||
|
}
|
||||||
|
mRouterPref.setDetailText(router);
|
||||||
|
mSubnetPref.setDetailText(subnetMask);
|
||||||
|
|
||||||
|
// Set DNS
|
||||||
|
addresses = prop.getDnsServers();
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
// addresses is backed by an ArrayList, so use a hand-written iterator for performance gains
|
||||||
|
for (int i = 0; i < addresses.size(); i++) {
|
||||||
|
if (i > 0) builder.append(", ");
|
||||||
|
builder.append(addresses.get(i).getHostAddress());
|
||||||
|
}
|
||||||
|
mDnsPref.setDetailText(builder.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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.content.Context;
|
||||||
|
import android.net.wifi.WifiInfo;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
|
import com.android.settings.core.PreferenceController;
|
||||||
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detail page for the currently connected wifi network.
|
||||||
|
*
|
||||||
|
* <p>The AccessPoint should be saved to the intent Extras when launching this class via
|
||||||
|
* {@link AccessPoint#saveWifiState(Bundle)} in order to properly render this page.
|
||||||
|
*/
|
||||||
|
public class WifiNetworkDetailsFragment extends DashboardFragment {
|
||||||
|
private static final String TAG = "WifiNetworkDetailsFrg";
|
||||||
|
|
||||||
|
// XML KEYS
|
||||||
|
private static final String KEY_FORGET_BUTTON = "forget_button";
|
||||||
|
|
||||||
|
private AccessPoint mAccessPoint;
|
||||||
|
private Button mForgetButton;
|
||||||
|
private WifiDetailPreferenceController mWifiDetailPreferenceController;
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
mAccessPoint = new AccessPoint(context, getArguments());
|
||||||
|
mWifiManager = context.getSystemService(WifiManager.class);
|
||||||
|
|
||||||
|
super.onAttach(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Header Title set automatically from launching Preference
|
||||||
|
|
||||||
|
mForgetButton = (Button) ((LayoutPreference) findPreference(KEY_FORGET_BUTTON))
|
||||||
|
.findViewById(R.id.button);
|
||||||
|
mForgetButton.setText(R.string.forget);
|
||||||
|
mForgetButton.setOnClickListener(view -> forgetNetwork());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forgetNetwork() {
|
||||||
|
WifiInfo info = mWifiDetailPreferenceController.getWifiInfo();
|
||||||
|
mMetricsFeatureProvider.action(getActivity(), MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
|
||||||
|
if (!info.isEphemeral()) {
|
||||||
|
// Network is active but has no network ID - must be ephemeral.
|
||||||
|
mWifiManager.disableEphemeralNetwork(
|
||||||
|
AccessPoint.convertToQuotedString(info.getSSID()));
|
||||||
|
} else if (mAccessPoint.getConfig().isPasspoint()) {
|
||||||
|
mWifiManager.removePasspointConfiguration(mAccessPoint.getConfig().FQDN);
|
||||||
|
} else {
|
||||||
|
mWifiManager.forget(info.getNetworkId(), null /* action listener */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsProto.MetricsEvent.WIFI_NETWORK_DETAILS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getLogTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPreferenceScreenResId() {
|
||||||
|
return R.xml.wifi_network_details_fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||||
|
mWifiDetailPreferenceController = new WifiDetailPreferenceController(
|
||||||
|
mAccessPoint,
|
||||||
|
context,
|
||||||
|
getLifecycle(),
|
||||||
|
mWifiManager);
|
||||||
|
|
||||||
|
ArrayList<PreferenceController> controllers = new ArrayList(1);
|
||||||
|
controllers.add(mWifiDetailPreferenceController);
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,3 +5,4 @@ com.android.settings.inputmethod.InputAndGestureSettings
|
|||||||
com.android.settings.accounts.AccountDetailDashboardFragment
|
com.android.settings.accounts.AccountDetailDashboardFragment
|
||||||
com.android.settings.fuelgauge.PowerUsageDetail
|
com.android.settings.fuelgauge.PowerUsageDetail
|
||||||
com.android.settings.deviceinfo.StorageProfileFragment
|
com.android.settings.deviceinfo.StorageProfileFragment
|
||||||
|
com.android.settings.wifi.details.WifiNetworkDetailsFragment
|
||||||
|
|||||||
Reference in New Issue
Block a user