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

Commit f1489b51 authored by Weng Su's avatar Weng Su
Browse files

[Provider Model] Show connected networks in APM/APM networks

- Separate APM and APM network types from other Internet types because
they can coexist at the same time.

- Show no internet icon in airplane-mode networks.

- Show connected non-carrier(Wi-Fi) network in airplane-mode networks.

- Show connected Ethernet network when airplane mode on.

- Screenshot:
  https://screenshot.googleplex.com/cr3eWNLMEuJ8zvP
  https://screenshot.googleplex.com/6DiMqKBBnBoxxhN

Bug: 180778141
Bug: 180778839
Bug: 179106406
Test: manual test
atest -c ConnectedEthernetNetworkControllerTest \
         InternetConnectivityPanelTest \
         InternetPreferenceControllerTest \
         InternetUpdaterTest

Change-Id: I861d5ce879facbb61dfdc5b7be943662d55bdcca
parent 1ebb7fa0
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
<!--
    Copyright (C) 2021 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:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10c0.34,0 0.68,-0.02 1.01,-0.05V20h-1v-0.04c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96H13v-2H9.66c-0.09,-0.66 -0.16,-1.32 -0.16,-2s0.07,-1.35 0.16,-2H21.8C20.87,5.44 16.83,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56C16.43,5.07 17.96,6.35 18.92,8zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82C10.52,6.57 11.17,5.24 12,4.04zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2s0.06,1.34 0.14,2H4.26zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56C7.57,18.93 6.04,17.66 5.08,16zM8.03,8H5.08c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8z"
        android:fillAlpha="0.3"/>
    <path
        android:fillColor="#FF000000"
        android:pathData="M16,14.75c0,-1.93 1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5c0,1.12 -0.69,1.73 -1.36,2.32c-0.64,0.56 -1.26,1.1 -1.26,2.06h-1.75c0,-1.59 0.82,-2.22 1.54,-2.78c0.57,-0.44 1.08,-0.83 1.08,-1.6c0,-0.96 -0.79,-1.75 -1.75,-1.75s-1.75,0.79 -1.75,1.75H16z"/>
    <path
        android:fillColor="#FF000000"
        android:pathData="M18.63,20.25h1.75V22h-1.75V20.25z"/>
</vector>
 No newline at end of file
+28 −0
Original line number Diff line number Diff line
<!--
    Copyright (C) 2021 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:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M2,12C2,6.48 6.47,2 11.99,2C17.52,2 22,6.48 22,12c0,0.34 -0.02,0.67 -0.05,1h-2.02c0.04,-0.33 0.07,-0.66 0.07,-1c0,-0.69 -0.1,-1.36 -0.26,-2h-3.38c0.08,0.66 0.14,1.32 0.14,2c0,0.34 -0.01,0.67 -0.04,1h-2.01c0.03,-0.33 0.05,-0.66 0.05,-1c0,-0.68 -0.07,-1.35 -0.16,-2H9.66c-0.09,0.65 -0.16,1.32 -0.16,2s0.07,1.34 0.16,2H13v2h-2.91c0.43,1.43 1.08,2.76 1.91,3.96V20h1v1.95C12.67,21.98 12.33,22 11.99,22C6.47,22 2,17.52 2,12zM15.97,8h2.95c-0.96,-1.65 -2.49,-2.93 -4.33,-3.56C15.19,5.55 15.65,6.75 15.97,8zM13.91,8C13.48,6.57 12.83,5.24 12,4.04c-0.83,1.2 -1.48,2.53 -1.91,3.96H13.91zM4,12c0,0.69 0.1,1.36 0.26,2h3.38c-0.08,-0.66 -0.14,-1.32 -0.14,-2s0.06,-1.34 0.14,-2H4.26C4.1,10.64 4,11.31 4,12zM8.03,16H5.08c0.96,1.66 2.49,2.93 4.33,3.56C8.81,18.45 8.35,17.25 8.03,16zM5.08,8h2.95c0.32,-1.25 0.78,-2.45 1.38,-3.56C7.57,5.07 6.04,6.34 5.08,8z"
        android:fillAlpha="0.3"/>
    <path
        android:fillColor="#FF000000"
        android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
</vector>
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ import com.android.settingslib.core.AbstractPreferenceController;
 * PreferenceController to show the connected ethernet network.
 */
public class ConnectedEthernetNetworkController extends AbstractPreferenceController
        implements InternetUpdater.OnInternetTypeChangedListener {
        implements InternetUpdater.InternetChangeListener {

    public static final String KEY = "connected_ethernet_network";

+26 −17
Original line number Diff line number Diff line
@@ -19,10 +19,10 @@ package com.android.settings.network;
import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;

import static com.android.settings.network.InternetUpdater.INTERNET_APM;
import static com.android.settings.network.InternetUpdater.INTERNET_APM_NETWORKS;
import static com.android.settings.network.InternetUpdater.INTERNET_CELLULAR;
import static com.android.settings.network.InternetUpdater.INTERNET_ETHERNET;
import static com.android.settings.network.InternetUpdater.INTERNET_NETWORKS_AVAILABLE;
import static com.android.settings.network.InternetUpdater.INTERNET_OFF;
import static com.android.settings.network.InternetUpdater.INTERNET_WIFI;

import android.content.Context;
@@ -53,7 +53,7 @@ import java.util.Map;
 */
public class InternetPreferenceController extends AbstractPreferenceController implements
        LifecycleObserver, SummaryUpdater.OnSummaryChangeListener,
        InternetUpdater.OnInternetTypeChangedListener {
        InternetUpdater.InternetChangeListener {

    public static final String KEY = "internet_settings";

@@ -65,8 +65,8 @@ public class InternetPreferenceController extends AbstractPreferenceController i
    @VisibleForTesting
    static Map<Integer, Integer> sIconMap = new HashMap<>();
    static {
        sIconMap.put(INTERNET_APM, R.drawable.ic_airplanemode_active);
        sIconMap.put(INTERNET_APM_NETWORKS, R.drawable.ic_airplane_safe_networks_24dp);
        sIconMap.put(INTERNET_OFF, R.drawable.ic_no_internet_unavailable);
        sIconMap.put(INTERNET_NETWORKS_AVAILABLE, R.drawable.ic_no_internet_available);
        sIconMap.put(INTERNET_WIFI, R.drawable.ic_wifi_signal_4);
        sIconMap.put(INTERNET_CELLULAR, R.drawable.ic_network_cell);
        sIconMap.put(INTERNET_ETHERNET, R.drawable.ic_settings_ethernet);
@@ -74,8 +74,8 @@ public class InternetPreferenceController extends AbstractPreferenceController i

    private static Map<Integer, Integer> sSummaryMap = new HashMap<>();
    static {
        sSummaryMap.put(INTERNET_APM, R.string.condition_airplane_title);
        sSummaryMap.put(INTERNET_APM_NETWORKS, R.string.airplane_mode_network_available);
        sSummaryMap.put(INTERNET_OFF, R.string.condition_airplane_title);
        sSummaryMap.put(INTERNET_NETWORKS_AVAILABLE, R.string.disconnected);
        sSummaryMap.put(INTERNET_WIFI, 0);
        sSummaryMap.put(INTERNET_CELLULAR, 0);
        sSummaryMap.put(INTERNET_ETHERNET, R.string.to_switch_networks_disconnect_ethernet);
@@ -114,8 +114,8 @@ public class InternetPreferenceController extends AbstractPreferenceController i
            }
        }

        if (mustUseWiFiHelperSummary(mSummaryHelper.isWifiConnected(),
                mSummaryHelper.getSummary())) {
        if (mInternetType == INTERNET_WIFI) {
            mPreference.setSummary(mSummaryHelper.getSummary());
            return;
        }

@@ -124,6 +124,12 @@ public class InternetPreferenceController extends AbstractPreferenceController i
            return;
        }

        if (mInternetType == INTERNET_NETWORKS_AVAILABLE
                && mInternetUpdater.isApmNetworksAvailable()) {
            mPreference.setSummary(R.string.airplane_mode_network_available);
            return;
        }

        final @IdRes int summary = sSummaryMap.get(mInternetType);
        if (summary != 0) {
            mPreference.setSummary(summary);
@@ -157,6 +163,7 @@ public class InternetPreferenceController extends AbstractPreferenceController i
     *
     * @param internetType the internet type
     */
    @Override
    public void onInternetTypeChanged(@InternetUpdater.InternetType int internetType) {
        final boolean needUpdate = (internetType != mInternetType);
        mInternetType = internetType;
@@ -167,19 +174,21 @@ public class InternetPreferenceController extends AbstractPreferenceController i
        }
    }

    /**
     * Called when airplane mode state is changed.
     */
    @Override
    public void onSummaryChanged(String summary) {
        mustUseWiFiHelperSummary(mSummaryHelper.isWifiConnected(), summary);
    public void onAirplaneModeChanged(boolean isAirplaneModeOn) {
        ThreadUtils.postOnMainThread(() -> {
            updateState(mPreference);
        });
    }

    @VisibleForTesting
    boolean mustUseWiFiHelperSummary(boolean isWifiConnected, String summary) {
        final boolean needUpdate = (mInternetType == INTERNET_WIFI)
                || (mInternetType == INTERNET_APM_NETWORKS && isWifiConnected);
        if (needUpdate && mPreference != null) {
    @Override
    public void onSummaryChanged(String summary) {
        if (mInternetType == INTERNET_WIFI && mPreference != null) {
            mPreference.setSummary(summary);
        }
        return needUpdate;
    }

    @VisibleForTesting
+114 −35
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkCapabilities.Transport;
import android.net.wifi.WifiManager;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;
@@ -55,27 +56,45 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange

    private static final String TAG = "InternetUpdater";

    private OnInternetTypeChangedListener mOnInternetTypeChangedListener;
    private InternetChangeListener mListener;

    /** Interface that handles the internet type changed callback */
    public interface OnInternetTypeChangedListener {
    /** Interface that handles the internet updater callback */
    public interface InternetChangeListener {
        /**
         * Called when internet type is changed.
         *
         * @param internetType the internet type
         */
        void onInternetTypeChanged(@InternetType int internetType);
        default void onInternetTypeChanged(@InternetType int internetType) {};

        /**
         * Called when airplane mode state is changed.
         */
        default void onAirplaneModeChanged(boolean isAirplaneModeOn) {};

        /**
         * Called when airplane mode networks state is changed.
         */
        default void onAirplaneModeNetworksChanged(boolean available) {};
    }

    /**
     * Indicates this internet is unavailable type in airplane mode on.
     * Indicates the internet is off when airplane mode is on.
     */
    public static final int INTERNET_APM = 0;
    public static final int INTERNET_OFF = 0;

    /**
     * Indicates this internet uses an airplane mode network type.
     * Indicates this internet is not connected (includes no networks connected) or network(s)
     * available.
     *
     * Examples include:
     * <p>When airplane mode is turned off, and some networks (Wi-Fi, Mobile-data) are turned on,
     * but no network can access the Internet.
     *
     * <p>When the airplane mode is turned on, and the WiFi is also turned on, but the WiFi is not
     * connected or cannot access the Internet.
     */
    public static final int INTERNET_APM_NETWORKS = 1;
    public static final int INTERNET_NETWORKS_AVAILABLE = 1;

    /**
     * Indicates this internet uses a Wi-Fi network type.
@@ -94,8 +113,8 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange

    @Retention(RetentionPolicy.SOURCE)
    @android.annotation.IntDef(prefix = { "INTERNET_" }, value = {
            INTERNET_APM,
            INTERNET_APM_NETWORKS,
            INTERNET_OFF,
            INTERNET_NETWORKS_AVAILABLE,
            INTERNET_WIFI,
            INTERNET_CELLULAR,
            INTERNET_ETHERNET,
@@ -110,6 +129,8 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange
    @VisibleForTesting
    AirplaneModeEnabler mAirplaneModeEnabler;

    @VisibleForTesting
    boolean mInternetAvailable;
    @VisibleForTesting
    @Transport int mTransport;
    private static Map<Integer, Integer> sTransportMap = new HashMap<>();
@@ -120,22 +141,14 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange
    }

    private NetworkCallback mNetworkCallback = new NetworkCallback() {
        @Override
        public void onAvailable(@NonNull Network network) {
            if (network == null) {
                return;
            }
            final NetworkCapabilities networkCapabilities =
                    mConnectivityManager.getNetworkCapabilities(network);
            if (networkCapabilities == null) {
                return;
            }
            for (@Transport int transport : networkCapabilities.getTransportTypes()) {
                if (sTransportMap.containsKey(transport)) {
                    mTransport = transport;
                    break;
                }
        public void onCapabilitiesChanged(@NonNull Network network,
                @NonNull NetworkCapabilities networkCapabilities) {
            checkNetworkCapabilities(networkCapabilities);
        }

        @Override
        public void onLost(@NonNull Network network) {
            mInternetAvailable = false;
            update();
        }
    };
@@ -143,18 +156,22 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange
    private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            update();
            fetchActiveNetwork();
            if (mListener != null && mAirplaneModeEnabler.isAirplaneModeOn()) {
                mListener.onAirplaneModeNetworksChanged(
                        mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED);
            }
        }
    };

    public InternetUpdater(Context context, Lifecycle lifecycle,
            OnInternetTypeChangedListener listener) {
    public InternetUpdater(Context context, Lifecycle lifecycle, InternetChangeListener listener) {
        mContext = context;
        mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, this);
        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
        mWifiManager = mContext.getSystemService(WifiManager.class);
        mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mOnInternetTypeChangedListener = listener;
        mListener = listener;
        fetchActiveNetwork();
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
@@ -178,18 +195,65 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange

    @Override
    public void onAirplaneModeChanged(boolean isAirplaneModeOn) {
        fetchActiveNetwork();
        if (mListener != null) {
            mListener.onAirplaneModeChanged(isAirplaneModeOn);
        }
    }

    private void fetchActiveNetwork() {
        Network activeNetwork = mConnectivityManager.getActiveNetwork();
        if (activeNetwork == null) {
            mInternetAvailable = false;
            update();
            return;
        }

        NetworkCapabilities activeNetworkCapabilities =
                mConnectivityManager.getNetworkCapabilities(activeNetwork);
        if (activeNetworkCapabilities == null) {
            mInternetAvailable = false;
            update();
            return;
        }

        checkNetworkCapabilities(activeNetworkCapabilities);
    }

    private void checkNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
        if (!networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
            mInternetAvailable = false;
            update();
            return;
        }

        boolean internetAvailable = false;
        for (@Transport int transport : networkCapabilities.getTransportTypes()) {
            if (sTransportMap.containsKey(transport)) {
                mTransport = transport;
                internetAvailable = true;
                Log.i(TAG, "Detect an internet capability network with transport type: "
                        + mTransport);
                break;
            }
        }
        mInternetAvailable = internetAvailable;
        update();
    }

    @VisibleForTesting
    void update() {
        if (mAirplaneModeEnabler.isAirplaneModeOn()) {
            mInternetType = mWifiManager.isWifiEnabled() ? INTERNET_APM_NETWORKS : INTERNET_APM;
        } else {
            mInternetType = sTransportMap.get(mTransport);
        @InternetType int internetType = INTERNET_NETWORKS_AVAILABLE;
        if (mInternetAvailable) {
            internetType = sTransportMap.get(mTransport);
        } else if (mAirplaneModeEnabler.isAirplaneModeOn()
                && mWifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
            internetType = INTERNET_OFF;
        }
        if (mOnInternetTypeChangedListener != null) {
            mOnInternetTypeChangedListener.onInternetTypeChanged(mInternetType);
        mInternetType = internetType;

        if (mListener != null) {
            mListener.onInternetTypeChanged(mInternetType);
        }
    }

@@ -199,4 +263,19 @@ public class InternetUpdater implements AirplaneModeEnabler.OnAirplaneModeChange
    public @InternetType int getInternetType() {
        return mInternetType;
    }

    /**
     * Return ture when the airplane mode is on.
     */
    public boolean isAirplaneModeOn() {
        return mAirplaneModeEnabler.isAirplaneModeOn();
    }

    /**
     * Return ture when the APM networks is available.
     */
    public boolean isApmNetworksAvailable() {
        return mAirplaneModeEnabler.isAirplaneModeOn()
                && (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED);
    }
}
Loading