Loading res/values/strings.xml +15 −0 Original line number Diff line number Diff line Loading @@ -2063,6 +2063,21 @@ <!-- Wifi details preference category title for IPv6 information --> <string name="wifi_details_ipv6_address_header">IPv6 addresses</string> <!-- Hotspot device details preference category title in Network details [CHAR LIMIT=NONE]--> <string name="hotspot_device_details_category">Hotspot device details</string> <!-- Internet source preference in Hotspot device details preference category [CHAR LIMIT=NONE]--> <string name="hotspot_device_details_internet_source">Internet source</string> <!-- Wi-Fi summary in Internet source preference [CHAR LIMIT=NONE]--> <string name="internet_source_wifi">Wi\u2011Fi</string> <!-- Mobile data summary in Internet source preference [CHAR LIMIT=NONE]--> <string name="internet_source_mobile_data">Mobile data</string> <!-- Ethernet summary in Internet source preference [CHAR LIMIT=NONE]--> <string name="internet_source_ethernet">Ethernet</string> <!-- Hotspot device details preference category title in Network details [CHAR LIMIT=NONE]--> <string name="hotspot_connection_category">Hotspot connection</string> <!-- Connection strength preference in Hotspot connection preference category [CHAR LIMIT=NONE]--> <string name="hotspot_connection_strength">Connection strength</string> <!-- 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> <!-- Tab title for showing subscribed WiFi access points. [CHAR LIMIT=20] --> Loading res/xml/wifi_network_details_fragment2.xml +24 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,30 @@ android:key="buttons" android:selectable="false"/> <!-- Hotspot device details category --> <PreferenceCategory android:key="hotspot_device_details_category" android:title="@string/hotspot_device_details_category" settings:isPreferenceVisible="false"> <Preference android:key="hotspot_device_details_internet_source" android:title="@string/hotspot_device_details_internet_source" android:selectable="false" settings:enableCopying="true"/> <Preference android:key="hotspot_device_details_battery" android:title="@string/power_usage_summary_title" android:selectable="false" settings:enableCopying="true"/> </PreferenceCategory> <!-- Hotspot connection category --> <PreferenceCategory android:key="hotspot_connection_category" android:title="@string/hotspot_connection_category" settings:isPreferenceVisible="false"> </PreferenceCategory> <!-- General Details Preferences --> <Preference android:key="signal_strength" Loading src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +120 −1 Original line number Diff line number Diff line Loading @@ -15,14 +15,19 @@ */ package com.android.settings.wifi.details; import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON; import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; import static com.android.settingslib.Utils.formatPercentage; import android.app.Dialog; import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.graphics.ColorFilter; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.net.wifi.sharedconnectivity.app.HotspotNetwork; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; Loading @@ -32,19 +37,23 @@ import android.os.SimpleClock; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.telephony.SignalStrength; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.network.telephony.MobileNetworkUtils; import com.android.settings.overlay.FeatureFactory; import com.android.settings.wifi.WifiConfigUiBase2; import com.android.settings.wifi.WifiDialog2; import com.android.settings.wifi.WifiUtils; import com.android.settings.wifi.details2.AddDevicePreferenceController2; import com.android.settings.wifi.details2.WifiAutoConnectPreferenceController2; import com.android.settings.wifi.details2.WifiDetailPreferenceController2; Loading @@ -52,10 +61,12 @@ import com.android.settings.wifi.details2.WifiMeteredPreferenceController2; import com.android.settings.wifi.details2.WifiPrivacyPreferenceController2; import com.android.settings.wifi.details2.WifiSecondSummaryController2; import com.android.settings.wifi.details2.WifiSubscriptionDetailPreferenceController2; import com.android.settings.wifi.repository.SharedConnectivityRepository; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.graph.ThemedBatteryDrawable; import com.android.wifitrackerlib.NetworkDetailsTracker; import com.android.wifitrackerlib.WifiEntry; Loading @@ -78,6 +89,12 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl // Key of a Bundle to save/restore the selected WifiEntry public static final String KEY_CHOSEN_WIFIENTRY_KEY = "key_chosen_wifientry_key"; public static final String KEY_HOTSPOT_DEVICE_CATEGORY = "hotspot_device_details_category"; public static final String KEY_HOTSPOT_DEVICE_INTERNET_SOURCE = "hotspot_device_details_internet_source"; public static final String KEY_HOTSPOT_DEVICE_BATTERY = "hotspot_device_details_battery"; public static final String KEY_HOTSPOT_CONNECTION_CATEGORY = "hotspot_connection_category"; // Max age of tracked WifiEntries private static final long MAX_SCAN_AGE_MILLIS = 15_000; // Interval between initiating SavedNetworkTracker scans Loading @@ -88,10 +105,15 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl @VisibleForTesting NetworkDetailsTracker mNetworkDetailsTracker; private HandlerThread mWorkerThread; private WifiDetailPreferenceController2 mWifiDetailPreferenceController2; @VisibleForTesting WifiDetailPreferenceController2 mWifiDetailPreferenceController2; private List<WifiDialog2.WifiDialog2Listener> mWifiDialogListeners = new ArrayList<>(); @VisibleForTesting List<AbstractPreferenceController> mControllers; private boolean mIsInstantHotspotFeatureEnabled = SharedConnectivityRepository.isDeviceConfigEnabled(); @VisibleForTesting WifiNetworkDetailsViewModel mWifiNetworkDetailsViewModel; public WifiNetworkDetailsFragment() { super(UserManager.DISALLOW_CONFIG_WIFI); Loading Loading @@ -207,6 +229,10 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl setupNetworksDetailTracker(); final WifiEntry wifiEntry = mNetworkDetailsTracker.getWifiEntry(); if (mIsInstantHotspotFeatureEnabled) { getWifiNetworkDetailsViewModel().setWifiEntry(wifiEntry); } final WifiSecondSummaryController2 wifiSecondSummaryController2 = new WifiSecondSummaryController2(context); wifiSecondSummaryController2.setWifiEntry(wifiEntry); Loading Loading @@ -335,5 +361,98 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl } controller.displayPreference(screen); } if (mIsInstantHotspotFeatureEnabled) { getWifiNetworkDetailsViewModel().setWifiEntry(mNetworkDetailsTracker.getWifiEntry()); } } private WifiNetworkDetailsViewModel getWifiNetworkDetailsViewModel() { if (mWifiNetworkDetailsViewModel == null) { mWifiNetworkDetailsViewModel = FeatureFactory.getFeatureFactory() .getWifiFeatureProvider().getWifiNetworkDetailsViewModel(this); mWifiNetworkDetailsViewModel.getHotspotNetworkData() .observe(this, this::onHotspotNetworkChanged); } return mWifiNetworkDetailsViewModel; } @VisibleForTesting void onHotspotNetworkChanged(WifiNetworkDetailsViewModel.HotspotNetworkData data) { PreferenceScreen screen = getPreferenceScreen(); if (screen == null) { return; } if (data == null) { screen.findPreference(KEY_HOTSPOT_DEVICE_CATEGORY).setVisible(false); screen.findPreference(KEY_HOTSPOT_CONNECTION_CATEGORY).setVisible(false); if (mWifiDetailPreferenceController2 != null) { mWifiDetailPreferenceController2.setSignalStrengthTitle(R.string.wifi_signal); } return; } screen.findPreference(KEY_HOTSPOT_DEVICE_CATEGORY).setVisible(true); updateInternetSource(data.getNetworkType(), data.getUpstreamConnectionStrength()); updateBattery(data.isBatteryCharging(), data.getBatteryPercentage()); screen.findPreference(KEY_HOTSPOT_CONNECTION_CATEGORY).setVisible(true); if (mWifiDetailPreferenceController2 != null) { mWifiDetailPreferenceController2 .setSignalStrengthTitle(R.string.hotspot_connection_strength); } } @VisibleForTesting void updateInternetSource(int networkType, int upstreamConnectionStrength) { Preference internetSource = getPreferenceScreen() .findPreference(KEY_HOTSPOT_DEVICE_INTERNET_SOURCE); Drawable drawable; if (networkType == HotspotNetwork.NETWORK_TYPE_WIFI) { internetSource.setSummary(R.string.internet_source_wifi); drawable = getContext().getDrawable( WifiUtils.getInternetIconResource(upstreamConnectionStrength, false)); } else if (networkType == HotspotNetwork.NETWORK_TYPE_CELLULAR) { internetSource.setSummary(R.string.internet_source_mobile_data); drawable = getMobileDataIcon(upstreamConnectionStrength); } else if (networkType == HotspotNetwork.NETWORK_TYPE_ETHERNET) { internetSource.setSummary(R.string.internet_source_ethernet); drawable = getContext().getDrawable(R.drawable.ic_settings_ethernet); } else { internetSource.setSummary(R.string.summary_placeholder); drawable = null; } if (drawable != null) { drawable.setTintList( Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal)); } internetSource.setIcon(drawable); } @VisibleForTesting Drawable getMobileDataIcon(int level) { return MobileNetworkUtils.getSignalStrengthIcon(getContext(), level, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, NO_CELL_DATA_TYPE_ICON, false, false); } @VisibleForTesting void updateBattery(boolean isChanging, int percentage) { Preference battery = getPreferenceScreen().findPreference(KEY_HOTSPOT_DEVICE_BATTERY); battery.setSummary(formatPercentage(percentage)); ThemedBatteryDrawable drawable = getBatteryDrawable(); if (drawable != null) { drawable.setCharging(isChanging); drawable.setBatteryLevel(percentage); } battery.setIcon(drawable); } @VisibleForTesting ThemedBatteryDrawable getBatteryDrawable() { int frameColor = getContext() .getColor(com.android.settingslib.R.color.meter_background_color); ThemedBatteryDrawable drawable = new ThemedBatteryDrawable(getContext(), frameColor); ColorFilter colorFilter = Utils.getAlphaInvariantColorFilterForColor( Utils.getColorAttrDefaultColor(getContext(), android.R.attr.colorControlNormal)); drawable.setColorFilter(colorFilter); return drawable; } } src/com/android/settings/wifi/details/WifiNetworkDetailsViewModel.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * 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.details; import android.app.Application; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import com.android.settings.overlay.FeatureFactory; import com.android.wifitrackerlib.HotspotNetworkEntry; import com.android.wifitrackerlib.WifiEntry; import org.jetbrains.annotations.NotNull; /** * Wi-Fi Network Details ViewModel */ public class WifiNetworkDetailsViewModel extends AndroidViewModel { private static final String TAG = "WifiNetworkDetailsViewModel"; @VisibleForTesting MutableLiveData<HotspotNetworkData> mHotspotNetworkData = new MutableLiveData<>(); public WifiNetworkDetailsViewModel(@NotNull Application application) { super(application); } /** Sets the {@link WifiEntry} class */ public void setWifiEntry(WifiEntry wifiEntry) { if (!(wifiEntry instanceof HotspotNetworkEntry)) { log("post HotspotNetworkData:null"); mHotspotNetworkData.postValue(null); return; } HotspotNetworkEntry entry = (HotspotNetworkEntry) wifiEntry; HotspotNetworkData data = new HotspotNetworkData( entry.getNetworkType(), entry.getUpstreamConnectionStrength(), entry.getBatteryPercentage(), entry.isBatteryCharging()); log("post HotspotNetworkData:" + data); mHotspotNetworkData.postValue(data); } /** Gets the {@link HotspotNetworkData} LiveData */ public LiveData<HotspotNetworkData> getHotspotNetworkData() { return mHotspotNetworkData; } /** The {@link HotspotNetworkData} class */ static class HotspotNetworkData { private int mNetworkType; private int mUpstreamConnectionStrength; private int mBatteryPercentage; private boolean mIsBatteryCharging; HotspotNetworkData(int networkType, int upstreamConnectionStrength, int batteryPercentage, boolean isBatteryCharging) { mNetworkType = networkType; mUpstreamConnectionStrength = upstreamConnectionStrength; mBatteryPercentage = batteryPercentage; mIsBatteryCharging = isBatteryCharging; } /** Gets the network type */ public int getNetworkType() { return mNetworkType; } /** Gets the upstream connection strength */ public int getUpstreamConnectionStrength() { return mUpstreamConnectionStrength; } /** Gets the battery percentage */ public int getBatteryPercentage() { return mBatteryPercentage; } /** Returns true if the battery is charging */ public boolean isBatteryCharging() { return mIsBatteryCharging; } @Override public String toString() { return getClass().getSimpleName() + ":{networkType:" + mNetworkType + ", upstreamConnectionStrength:" + mUpstreamConnectionStrength + ", batteryPercentage:" + mBatteryPercentage + ", isBatteryCharging:" + mIsBatteryCharging + " }"; } } private void log(String msg) { FeatureFactory.getFeatureFactory().getWifiFeatureProvider().verboseLog(TAG, msg); } } src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java +41 −9 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; import static com.android.settingslib.wifi.WifiUtils.getHotspotIconResource; import android.app.Activity; import android.app.AlertDialog; import android.app.settings.SettingsEnums; Loading Loading @@ -86,6 +88,7 @@ import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.utils.StringUtil; import com.android.settingslib.widget.ActionButtonsPreference; import com.android.settingslib.widget.LayoutPreference; import com.android.wifitrackerlib.HotspotNetworkEntry; import com.android.wifitrackerlib.WifiEntry; import com.android.wifitrackerlib.WifiEntry.ConnectCallback; import com.android.wifitrackerlib.WifiEntry.DisconnectCallback; Loading Loading @@ -172,7 +175,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle // UI elements - in order of appearance private ActionButtonsPreference mButtonsPref; private EntityHeaderController mEntityHeaderController; @VisibleForTesting EntityHeaderController mEntityHeaderController; private Preference mSignalStrengthPref; private Preference mTxLinkSpeedPref; private Preference mRxLinkSpeedPref; Loading Loading @@ -533,6 +537,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle private void refreshPage() { Log.d(TAG, "Update UI!"); // refresh header icon refreshEntryHeaderIcon(); // refresh header refreshEntityHeader(); Loading Loading @@ -561,8 +567,33 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle refreshWifiType(); } @VisibleForTesting void refreshEntryHeaderIcon() { if (mEntityHeaderController == null) { return; } Drawable drawable = getWifiDrawable(mWifiEntry); mEntityHeaderController .setIcon(redrawIconForHeader(drawable)) .done(true /* rebind */); } /** * Returns a Wi-Fi icon {@link Drawable}. * * @param wifiEntry {@link WifiEntry} */ @VisibleForTesting Drawable getWifiDrawable(WifiEntry wifiEntry) { if (wifiEntry instanceof HotspotNetworkEntry) { int deviceType = ((HotspotNetworkEntry) wifiEntry).getDeviceType(); return mContext.getDrawable(getHotspotIconResource(deviceType)); } return mIconInjector.getIcon(wifiEntry.shouldShowXLevelIcon(), wifiEntry.getLevel()); } private void refreshRssiViews() { final int signalLevel = mWifiEntry.getLevel(); int signalLevel = mWifiEntry.getLevel(); // Disappears signal view if not in range. e.g. for saved networks. if (signalLevel == WifiEntry.WIFI_LEVEL_UNREACHABLE) { Loading @@ -571,19 +602,13 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle return; } final boolean showX = mWifiEntry.shouldShowXLevelIcon(); boolean showX = mWifiEntry.shouldShowXLevelIcon(); if (mRssiSignalLevel == signalLevel && mShowX == showX) { return; } mRssiSignalLevel = signalLevel; mShowX = showX; Drawable wifiIcon = mIconInjector.getIcon(mShowX, mRssiSignalLevel); if (mEntityHeaderController != null) { mEntityHeaderController.setIcon(redrawIconForHeader(wifiIcon)).done(true /* rebind */); } Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate(); wifiIconDark.setTintList(Utils.getColorAttr(mContext, android.R.attr.colorControlNormal)); mSignalStrengthPref.setIcon(wifiIconDark); Loading Loading @@ -1120,4 +1145,11 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle public void onSignInResult(@SignInStatus int status) { refreshPage(); } /** Sets signal strength title */ public void setSignalStrengthTitle(int titleResId) { if (mSignalStrengthPref != null) { mSignalStrengthPref.setTitle(titleResId); } } } Loading
res/values/strings.xml +15 −0 Original line number Diff line number Diff line Loading @@ -2063,6 +2063,21 @@ <!-- Wifi details preference category title for IPv6 information --> <string name="wifi_details_ipv6_address_header">IPv6 addresses</string> <!-- Hotspot device details preference category title in Network details [CHAR LIMIT=NONE]--> <string name="hotspot_device_details_category">Hotspot device details</string> <!-- Internet source preference in Hotspot device details preference category [CHAR LIMIT=NONE]--> <string name="hotspot_device_details_internet_source">Internet source</string> <!-- Wi-Fi summary in Internet source preference [CHAR LIMIT=NONE]--> <string name="internet_source_wifi">Wi\u2011Fi</string> <!-- Mobile data summary in Internet source preference [CHAR LIMIT=NONE]--> <string name="internet_source_mobile_data">Mobile data</string> <!-- Ethernet summary in Internet source preference [CHAR LIMIT=NONE]--> <string name="internet_source_ethernet">Ethernet</string> <!-- Hotspot device details preference category title in Network details [CHAR LIMIT=NONE]--> <string name="hotspot_connection_category">Hotspot connection</string> <!-- Connection strength preference in Hotspot connection preference category [CHAR LIMIT=NONE]--> <string name="hotspot_connection_strength">Connection strength</string> <!-- 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> <!-- Tab title for showing subscribed WiFi access points. [CHAR LIMIT=20] --> Loading
res/xml/wifi_network_details_fragment2.xml +24 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,30 @@ android:key="buttons" android:selectable="false"/> <!-- Hotspot device details category --> <PreferenceCategory android:key="hotspot_device_details_category" android:title="@string/hotspot_device_details_category" settings:isPreferenceVisible="false"> <Preference android:key="hotspot_device_details_internet_source" android:title="@string/hotspot_device_details_internet_source" android:selectable="false" settings:enableCopying="true"/> <Preference android:key="hotspot_device_details_battery" android:title="@string/power_usage_summary_title" android:selectable="false" settings:enableCopying="true"/> </PreferenceCategory> <!-- Hotspot connection category --> <PreferenceCategory android:key="hotspot_connection_category" android:title="@string/hotspot_connection_category" settings:isPreferenceVisible="false"> </PreferenceCategory> <!-- General Details Preferences --> <Preference android:key="signal_strength" Loading
src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +120 −1 Original line number Diff line number Diff line Loading @@ -15,14 +15,19 @@ */ package com.android.settings.wifi.details; import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON; import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; import static com.android.settingslib.Utils.formatPercentage; import android.app.Dialog; import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.graphics.ColorFilter; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.net.wifi.sharedconnectivity.app.HotspotNetwork; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; Loading @@ -32,19 +37,23 @@ import android.os.SimpleClock; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.telephony.SignalStrength; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.network.telephony.MobileNetworkUtils; import com.android.settings.overlay.FeatureFactory; import com.android.settings.wifi.WifiConfigUiBase2; import com.android.settings.wifi.WifiDialog2; import com.android.settings.wifi.WifiUtils; import com.android.settings.wifi.details2.AddDevicePreferenceController2; import com.android.settings.wifi.details2.WifiAutoConnectPreferenceController2; import com.android.settings.wifi.details2.WifiDetailPreferenceController2; Loading @@ -52,10 +61,12 @@ import com.android.settings.wifi.details2.WifiMeteredPreferenceController2; import com.android.settings.wifi.details2.WifiPrivacyPreferenceController2; import com.android.settings.wifi.details2.WifiSecondSummaryController2; import com.android.settings.wifi.details2.WifiSubscriptionDetailPreferenceController2; import com.android.settings.wifi.repository.SharedConnectivityRepository; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.graph.ThemedBatteryDrawable; import com.android.wifitrackerlib.NetworkDetailsTracker; import com.android.wifitrackerlib.WifiEntry; Loading @@ -78,6 +89,12 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl // Key of a Bundle to save/restore the selected WifiEntry public static final String KEY_CHOSEN_WIFIENTRY_KEY = "key_chosen_wifientry_key"; public static final String KEY_HOTSPOT_DEVICE_CATEGORY = "hotspot_device_details_category"; public static final String KEY_HOTSPOT_DEVICE_INTERNET_SOURCE = "hotspot_device_details_internet_source"; public static final String KEY_HOTSPOT_DEVICE_BATTERY = "hotspot_device_details_battery"; public static final String KEY_HOTSPOT_CONNECTION_CATEGORY = "hotspot_connection_category"; // Max age of tracked WifiEntries private static final long MAX_SCAN_AGE_MILLIS = 15_000; // Interval between initiating SavedNetworkTracker scans Loading @@ -88,10 +105,15 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl @VisibleForTesting NetworkDetailsTracker mNetworkDetailsTracker; private HandlerThread mWorkerThread; private WifiDetailPreferenceController2 mWifiDetailPreferenceController2; @VisibleForTesting WifiDetailPreferenceController2 mWifiDetailPreferenceController2; private List<WifiDialog2.WifiDialog2Listener> mWifiDialogListeners = new ArrayList<>(); @VisibleForTesting List<AbstractPreferenceController> mControllers; private boolean mIsInstantHotspotFeatureEnabled = SharedConnectivityRepository.isDeviceConfigEnabled(); @VisibleForTesting WifiNetworkDetailsViewModel mWifiNetworkDetailsViewModel; public WifiNetworkDetailsFragment() { super(UserManager.DISALLOW_CONFIG_WIFI); Loading Loading @@ -207,6 +229,10 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl setupNetworksDetailTracker(); final WifiEntry wifiEntry = mNetworkDetailsTracker.getWifiEntry(); if (mIsInstantHotspotFeatureEnabled) { getWifiNetworkDetailsViewModel().setWifiEntry(wifiEntry); } final WifiSecondSummaryController2 wifiSecondSummaryController2 = new WifiSecondSummaryController2(context); wifiSecondSummaryController2.setWifiEntry(wifiEntry); Loading Loading @@ -335,5 +361,98 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl } controller.displayPreference(screen); } if (mIsInstantHotspotFeatureEnabled) { getWifiNetworkDetailsViewModel().setWifiEntry(mNetworkDetailsTracker.getWifiEntry()); } } private WifiNetworkDetailsViewModel getWifiNetworkDetailsViewModel() { if (mWifiNetworkDetailsViewModel == null) { mWifiNetworkDetailsViewModel = FeatureFactory.getFeatureFactory() .getWifiFeatureProvider().getWifiNetworkDetailsViewModel(this); mWifiNetworkDetailsViewModel.getHotspotNetworkData() .observe(this, this::onHotspotNetworkChanged); } return mWifiNetworkDetailsViewModel; } @VisibleForTesting void onHotspotNetworkChanged(WifiNetworkDetailsViewModel.HotspotNetworkData data) { PreferenceScreen screen = getPreferenceScreen(); if (screen == null) { return; } if (data == null) { screen.findPreference(KEY_HOTSPOT_DEVICE_CATEGORY).setVisible(false); screen.findPreference(KEY_HOTSPOT_CONNECTION_CATEGORY).setVisible(false); if (mWifiDetailPreferenceController2 != null) { mWifiDetailPreferenceController2.setSignalStrengthTitle(R.string.wifi_signal); } return; } screen.findPreference(KEY_HOTSPOT_DEVICE_CATEGORY).setVisible(true); updateInternetSource(data.getNetworkType(), data.getUpstreamConnectionStrength()); updateBattery(data.isBatteryCharging(), data.getBatteryPercentage()); screen.findPreference(KEY_HOTSPOT_CONNECTION_CATEGORY).setVisible(true); if (mWifiDetailPreferenceController2 != null) { mWifiDetailPreferenceController2 .setSignalStrengthTitle(R.string.hotspot_connection_strength); } } @VisibleForTesting void updateInternetSource(int networkType, int upstreamConnectionStrength) { Preference internetSource = getPreferenceScreen() .findPreference(KEY_HOTSPOT_DEVICE_INTERNET_SOURCE); Drawable drawable; if (networkType == HotspotNetwork.NETWORK_TYPE_WIFI) { internetSource.setSummary(R.string.internet_source_wifi); drawable = getContext().getDrawable( WifiUtils.getInternetIconResource(upstreamConnectionStrength, false)); } else if (networkType == HotspotNetwork.NETWORK_TYPE_CELLULAR) { internetSource.setSummary(R.string.internet_source_mobile_data); drawable = getMobileDataIcon(upstreamConnectionStrength); } else if (networkType == HotspotNetwork.NETWORK_TYPE_ETHERNET) { internetSource.setSummary(R.string.internet_source_ethernet); drawable = getContext().getDrawable(R.drawable.ic_settings_ethernet); } else { internetSource.setSummary(R.string.summary_placeholder); drawable = null; } if (drawable != null) { drawable.setTintList( Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal)); } internetSource.setIcon(drawable); } @VisibleForTesting Drawable getMobileDataIcon(int level) { return MobileNetworkUtils.getSignalStrengthIcon(getContext(), level, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, NO_CELL_DATA_TYPE_ICON, false, false); } @VisibleForTesting void updateBattery(boolean isChanging, int percentage) { Preference battery = getPreferenceScreen().findPreference(KEY_HOTSPOT_DEVICE_BATTERY); battery.setSummary(formatPercentage(percentage)); ThemedBatteryDrawable drawable = getBatteryDrawable(); if (drawable != null) { drawable.setCharging(isChanging); drawable.setBatteryLevel(percentage); } battery.setIcon(drawable); } @VisibleForTesting ThemedBatteryDrawable getBatteryDrawable() { int frameColor = getContext() .getColor(com.android.settingslib.R.color.meter_background_color); ThemedBatteryDrawable drawable = new ThemedBatteryDrawable(getContext(), frameColor); ColorFilter colorFilter = Utils.getAlphaInvariantColorFilterForColor( Utils.getColorAttrDefaultColor(getContext(), android.R.attr.colorControlNormal)); drawable.setColorFilter(colorFilter); return drawable; } }
src/com/android/settings/wifi/details/WifiNetworkDetailsViewModel.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * 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.details; import android.app.Application; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import com.android.settings.overlay.FeatureFactory; import com.android.wifitrackerlib.HotspotNetworkEntry; import com.android.wifitrackerlib.WifiEntry; import org.jetbrains.annotations.NotNull; /** * Wi-Fi Network Details ViewModel */ public class WifiNetworkDetailsViewModel extends AndroidViewModel { private static final String TAG = "WifiNetworkDetailsViewModel"; @VisibleForTesting MutableLiveData<HotspotNetworkData> mHotspotNetworkData = new MutableLiveData<>(); public WifiNetworkDetailsViewModel(@NotNull Application application) { super(application); } /** Sets the {@link WifiEntry} class */ public void setWifiEntry(WifiEntry wifiEntry) { if (!(wifiEntry instanceof HotspotNetworkEntry)) { log("post HotspotNetworkData:null"); mHotspotNetworkData.postValue(null); return; } HotspotNetworkEntry entry = (HotspotNetworkEntry) wifiEntry; HotspotNetworkData data = new HotspotNetworkData( entry.getNetworkType(), entry.getUpstreamConnectionStrength(), entry.getBatteryPercentage(), entry.isBatteryCharging()); log("post HotspotNetworkData:" + data); mHotspotNetworkData.postValue(data); } /** Gets the {@link HotspotNetworkData} LiveData */ public LiveData<HotspotNetworkData> getHotspotNetworkData() { return mHotspotNetworkData; } /** The {@link HotspotNetworkData} class */ static class HotspotNetworkData { private int mNetworkType; private int mUpstreamConnectionStrength; private int mBatteryPercentage; private boolean mIsBatteryCharging; HotspotNetworkData(int networkType, int upstreamConnectionStrength, int batteryPercentage, boolean isBatteryCharging) { mNetworkType = networkType; mUpstreamConnectionStrength = upstreamConnectionStrength; mBatteryPercentage = batteryPercentage; mIsBatteryCharging = isBatteryCharging; } /** Gets the network type */ public int getNetworkType() { return mNetworkType; } /** Gets the upstream connection strength */ public int getUpstreamConnectionStrength() { return mUpstreamConnectionStrength; } /** Gets the battery percentage */ public int getBatteryPercentage() { return mBatteryPercentage; } /** Returns true if the battery is charging */ public boolean isBatteryCharging() { return mIsBatteryCharging; } @Override public String toString() { return getClass().getSimpleName() + ":{networkType:" + mNetworkType + ", upstreamConnectionStrength:" + mUpstreamConnectionStrength + ", batteryPercentage:" + mBatteryPercentage + ", isBatteryCharging:" + mIsBatteryCharging + " }"; } } private void log(String msg) { FeatureFactory.getFeatureFactory().getWifiFeatureProvider().verboseLog(TAG, msg); } }
src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java +41 −9 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; import static com.android.settingslib.wifi.WifiUtils.getHotspotIconResource; import android.app.Activity; import android.app.AlertDialog; import android.app.settings.SettingsEnums; Loading Loading @@ -86,6 +88,7 @@ import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.utils.StringUtil; import com.android.settingslib.widget.ActionButtonsPreference; import com.android.settingslib.widget.LayoutPreference; import com.android.wifitrackerlib.HotspotNetworkEntry; import com.android.wifitrackerlib.WifiEntry; import com.android.wifitrackerlib.WifiEntry.ConnectCallback; import com.android.wifitrackerlib.WifiEntry.DisconnectCallback; Loading Loading @@ -172,7 +175,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle // UI elements - in order of appearance private ActionButtonsPreference mButtonsPref; private EntityHeaderController mEntityHeaderController; @VisibleForTesting EntityHeaderController mEntityHeaderController; private Preference mSignalStrengthPref; private Preference mTxLinkSpeedPref; private Preference mRxLinkSpeedPref; Loading Loading @@ -533,6 +537,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle private void refreshPage() { Log.d(TAG, "Update UI!"); // refresh header icon refreshEntryHeaderIcon(); // refresh header refreshEntityHeader(); Loading Loading @@ -561,8 +567,33 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle refreshWifiType(); } @VisibleForTesting void refreshEntryHeaderIcon() { if (mEntityHeaderController == null) { return; } Drawable drawable = getWifiDrawable(mWifiEntry); mEntityHeaderController .setIcon(redrawIconForHeader(drawable)) .done(true /* rebind */); } /** * Returns a Wi-Fi icon {@link Drawable}. * * @param wifiEntry {@link WifiEntry} */ @VisibleForTesting Drawable getWifiDrawable(WifiEntry wifiEntry) { if (wifiEntry instanceof HotspotNetworkEntry) { int deviceType = ((HotspotNetworkEntry) wifiEntry).getDeviceType(); return mContext.getDrawable(getHotspotIconResource(deviceType)); } return mIconInjector.getIcon(wifiEntry.shouldShowXLevelIcon(), wifiEntry.getLevel()); } private void refreshRssiViews() { final int signalLevel = mWifiEntry.getLevel(); int signalLevel = mWifiEntry.getLevel(); // Disappears signal view if not in range. e.g. for saved networks. if (signalLevel == WifiEntry.WIFI_LEVEL_UNREACHABLE) { Loading @@ -571,19 +602,13 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle return; } final boolean showX = mWifiEntry.shouldShowXLevelIcon(); boolean showX = mWifiEntry.shouldShowXLevelIcon(); if (mRssiSignalLevel == signalLevel && mShowX == showX) { return; } mRssiSignalLevel = signalLevel; mShowX = showX; Drawable wifiIcon = mIconInjector.getIcon(mShowX, mRssiSignalLevel); if (mEntityHeaderController != null) { mEntityHeaderController.setIcon(redrawIconForHeader(wifiIcon)).done(true /* rebind */); } Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate(); wifiIconDark.setTintList(Utils.getColorAttr(mContext, android.R.attr.colorControlNormal)); mSignalStrengthPref.setIcon(wifiIconDark); Loading Loading @@ -1120,4 +1145,11 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle public void onSignInResult(@SignInStatus int status) { refreshPage(); } /** Sets signal strength title */ public void setSignalStrengthTitle(int titleResId) { if (mSignalStrengthPref != null) { mSignalStrengthPref.setTitle(titleResId); } } }