Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d32f590f authored by Weng Su's avatar Weng Su Committed by Android (Google) Code Review
Browse files

Merge "Show Hotspot informations in Network details settings" into main

parents 7bdddc9c 25e20caf
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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] -->
+24 −0
Original line number Diff line number Diff line
@@ -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"
+120 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;

@@ -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
@@ -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);
@@ -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);
@@ -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;
    }
}
+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);
    }
}
+41 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -533,6 +537,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
    private void refreshPage() {
        Log.d(TAG, "Update UI!");

        // refresh header icon
        refreshEntryHeaderIcon();
        // refresh header
        refreshEntityHeader();

@@ -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) {
@@ -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);
@@ -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