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

Commit 42c45161 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add signal strength icons to multi-SIM header" into qt-dev

parents e40b0f7b 223c179c
Loading
Loading
Loading
Loading
+60 −7
Original line number Diff line number Diff line
@@ -19,16 +19,22 @@ 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.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.provider.Settings;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.ArraySet;

import androidx.annotation.VisibleForTesting;
import androidx.collection.ArrayMap;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
@@ -40,9 +46,14 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.network.telephony.DataConnectivityListener;
import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.network.telephony.SignalStrengthListener;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.net.SignalStrengthUtil;

import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * This manages a set of Preferences it places into a PreferenceGroup owned by some parent
@@ -51,7 +62,8 @@ import java.util.Map;
 */
public class SubscriptionsPreferenceController extends AbstractPreferenceController implements
        LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient,
        MobileDataEnabledListener.Client, DataConnectivityListener.Client {
        MobileDataEnabledListener.Client, DataConnectivityListener.Client,
        SignalStrengthListener.Callback {
    private static final String TAG = "SubscriptionsPrefCntrlr";

    private UpdateListener mUpdateListener;
@@ -62,6 +74,8 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
    private SubscriptionsChangeListener mSubscriptionsListener;
    private MobileDataEnabledListener mDataEnabledListener;
    private DataConnectivityListener mConnectivityListener;
    private SignalStrengthListener mSignalStrengthListener;


    // Map of subscription id to Preference
    private Map<Integer, Preference> mSubscriptionPreferences;
@@ -102,6 +116,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
        mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
        mDataEnabledListener = new MobileDataEnabledListener(context, this);
        mConnectivityListener = new DataConnectivityListener(context, this);
        mSignalStrengthListener = new SignalStrengthListener(context, this);
        lifecycle.addObserver(this);
    }

@@ -110,6 +125,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
        mSubscriptionsListener.start();
        mDataEnabledListener.start(SubscriptionManager.getDefaultDataSubscriptionId());
        mConnectivityListener.start();
        mSignalStrengthListener.resume();
        update();
    }

@@ -118,6 +134,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
        mSubscriptionsListener.stop();
        mDataEnabledListener.stop();
        mConnectivityListener.stop();
        mSignalStrengthListener.pause();
    }

    @Override
@@ -136,6 +153,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
                mPreferenceGroup.removePreference(pref);
            }
            mSubscriptionPreferences.clear();
            mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet());
            mUpdateListener.onChildrenUpdated();
            return;
        }
@@ -144,16 +162,20 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
        mSubscriptionPreferences = new ArrayMap<>();

        int order = mStartOrder;
        final Set<Integer> activeSubIds = new ArraySet<>();
        final int dataDefaultSubId = SubscriptionManager.getDefaultDataSubscriptionId();
        for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mManager)) {
            final int subId = info.getSubscriptionId();
            activeSubIds.add(subId);
            Preference pref = existingPrefs.remove(subId);
            if (pref == null) {
                pref = new Preference(mPreferenceGroup.getContext());
                mPreferenceGroup.addPreference(pref);
            }
            pref.setTitle(info.getDisplayName());
            pref.setSummary(getSummary(subId));
            pref.setIcon(R.drawable.ic_network_cell);
            final boolean isDefaultForData = (subId == dataDefaultSubId);
            pref.setSummary(getSummary(subId, isDefaultForData));
            setIcon(pref, subId, isDefaultForData);
            pref.setOrder(order++);

            pref.setOnPreferenceClickListener(clickedPref -> {
@@ -165,6 +187,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl

            mSubscriptionPreferences.put(subId, pref);
        }
        mSignalStrengthListener.updateSubscriptionIds(activeSubIds);

        // Remove any old preferences that no longer map to a subscription.
        for (Preference pref : existingPrefs.values()) {
@@ -173,6 +196,32 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
        mUpdateListener.onChildrenUpdated();
    }

    @VisibleForTesting
    boolean shouldInflateSignalStrength(int subId) {
        return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId);
    }

    @VisibleForTesting
    void setIcon(Preference pref, int subId, boolean isDefaultForData) {
        final TelephonyManager mgr = mContext.getSystemService(
                TelephonyManager.class).createForSubscriptionId(subId);
        final SignalStrength strength = mgr.getSignalStrength();
        int level = (strength == null) ? 0 : strength.getLevel();
        int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
        if (shouldInflateSignalStrength(subId)) {
            level += 1;
            numLevels += 1;
        }
        final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled();
        pref.setIcon(getIcon(level, numLevels, showCutOut));
    }

    @VisibleForTesting
    Drawable getIcon(int level, int numLevels, boolean cutOut) {
        return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels,
                NO_CELL_DATA_TYPE_ICON, cutOut);
    }

    private boolean activeNetworkIsCellular() {
        final Network activeNetwork = mConnectivityManager.getActiveNetwork();
        if (activeNetwork == null) {
@@ -197,10 +246,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
     *
     * If a subscription isn't the default for anything, we just say it is available.
     */
    protected String getSummary(int subId) {
    protected String getSummary(int subId, boolean isDefaultForData) {
        final int callsDefaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
        final int smsDefaultSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
        final int dataDefaultSubId = SubscriptionManager.getDefaultDataSubscriptionId();

        String line1 = null;
        if (subId == callsDefaultSubId && subId == smsDefaultSubId) {
@@ -212,10 +260,10 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
        }

        String line2 = null;
        if (subId == dataDefaultSubId) {
        if (isDefaultForData) {
            final TelephonyManager telMgrForSub = mContext.getSystemService(
                    TelephonyManager.class).createForSubscriptionId(subId);
            boolean dataEnabled = telMgrForSub.isDataEnabled();
            final boolean dataEnabled = telMgrForSub.isDataEnabled();
            if (dataEnabled && activeNetworkIsCellular()) {
                line2 = mContext.getString(R.string.mobile_data_active);
            } else if (!dataEnabled) {
@@ -277,4 +325,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
    public void onDataConnectivityChange() {
        update();
    }

    @Override
    public void onSignalStrengthChanged() {
        update();
    }
}
+40 −0
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.PersistableBundle;
import android.os.SystemProperties;
import android.provider.Settings;
@@ -37,6 +41,7 @@ import android.telephony.euicc.EuiccManager;
import android.telephony.ims.feature.ImsFeature;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;

import androidx.annotation.VisibleForTesting;

@@ -45,7 +50,10 @@ import com.android.ims.ImsManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.ArrayUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.graph.SignalDrawable;

import java.util.Arrays;
import java.util.List;
@@ -65,6 +73,10 @@ public class MobileNetworkUtils {
    private static final String LEGACY_ACTION_CONFIGURE_PHONE_ACCOUNT =
            "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";

    // The following constants are used to draw signal icon.
    public static final int NO_CELL_DATA_TYPE_ICON = 0;
    public static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);

    /**
     * Returns if DPC APNs are enforced.
     */
@@ -495,4 +507,32 @@ public class MobileNetworkUtils {

        return false;
    }

    public static Drawable getSignalStrengthIcon(Context context, int level, int numLevels,
            int iconType, boolean cutOut) {
        SignalDrawable signalDrawable = new SignalDrawable(context);
        signalDrawable.setLevel(
                SignalDrawable.getState(level, numLevels, cutOut));

        // Make the network type drawable
        Drawable networkDrawable =
                iconType == NO_CELL_DATA_TYPE_ICON
                        ? EMPTY_DRAWABLE
                        : context
                                .getResources().getDrawable(iconType, context.getTheme());

        // Overlay the two drawables
        final Drawable[] layers = {networkDrawable, signalDrawable};
        final int iconSize =
                context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);

        LayerDrawable icons = new LayerDrawable(layers);
        // Set the network type icon at the top left
        icons.setLayerGravity(0 /* index of networkDrawable */, Gravity.TOP | Gravity.LEFT);
        // Set the signal strength icon at the bottom right
        icons.setLayerGravity(1 /* index of SignalDrawable */, Gravity.BOTTOM | Gravity.RIGHT);
        icons.setLayerSize(1 /* index of SignalDrawable */, iconSize, iconSize);
        icons.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
        return icons;
    }
}
+6 −40
Original line number Diff line number Diff line
@@ -16,22 +16,17 @@

package com.android.settings.network.telephony;

import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.telephony.CellInfo;
import android.telephony.CellSignalStrength;
import android.telephony.SignalStrength;
import android.util.Log;
import android.view.Gravity;

import androidx.preference.Preference;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.graph.SignalDrawable;

import java.util.List;

@@ -45,18 +40,12 @@ public class NetworkOperatorPreference extends Preference {

    private static final int LEVEL_NONE = -1;

    // number of signal strength level
    public static final int NUMBER_OF_LEVELS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
    private CellInfo mCellInfo;
    private List<String> mForbiddenPlmns;
    private int mLevel = LEVEL_NONE;
    private boolean mShow4GForLTE;
    private boolean mUseNewApi;

    // The following constants are used to draw signal icon.
    private static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
    private static final int NO_CELL_DATA_CONNECTED_ICON = 0;

    public NetworkOperatorPreference(
            CellInfo cellinfo, Context context, List<String> forbiddenPlmns, boolean show4GForLTE) {
        super(context);
@@ -113,39 +102,16 @@ public class NetworkOperatorPreference extends Preference {
            case CellInfo.TYPE_CDMA:
                return R.drawable.signal_strength_1x;
            default:
                return 0;
                return MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
        }
    }

    private void updateIcon(int level) {
        if (!mUseNewApi || level < 0 || level >= NUMBER_OF_LEVELS) {
        if (!mUseNewApi || level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
            return;
        }
        Context context = getContext();
        SignalDrawable signalDrawable = new SignalDrawable(getContext());
        signalDrawable.setLevel(
                SignalDrawable.getState(level, NUMBER_OF_LEVELS, false /* cutOut */));

        // Make the network type drawable
        int iconType = getIconIdForCell(mCellInfo);
        Drawable networkDrawable =
                iconType == NO_CELL_DATA_CONNECTED_ICON
                        ? EMPTY_DRAWABLE
                        : getContext()
                                .getResources().getDrawable(iconType, getContext().getTheme());

        // Overlay the two drawables
        final Drawable[] layers = {networkDrawable, signalDrawable};
        final int iconSize =
                context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);

        LayerDrawable icons = new LayerDrawable(layers);
        // Set the network type icon at the top left
        icons.setLayerGravity(0 /* index of networkDrawable */, Gravity.TOP | Gravity.LEFT);
        // Set the signal strength icon at the bottom right
        icons.setLayerGravity(1 /* index of SignalDrawable */, Gravity.BOTTOM | Gravity.RIGHT);
        icons.setLayerSize(1 /* index of SignalDrawable */, iconSize, iconSize);
        icons.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
        setIcon(icons);
        setIcon(MobileNetworkUtils.getSignalStrengthIcon(context, level, NUM_SIGNAL_STRENGTH_BINS,
                getIconIdForCell(mCellInfo), false));
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -336,7 +337,7 @@ public class NetworkSelectSettings extends DashboardFragment {
                pref.setSummary(R.string.network_connected);
                // Update the signal strength icon, since the default signalStrength value would be
                // zero (it would be quite confusing why the connected network has no signal)
                pref.setIcon(NetworkOperatorPreference.NUMBER_OF_LEVELS - 1);
                pref.setIcon(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
                mConnectedPreferenceCategory.addPreference(pref);
            } else {
                // Remove the connected network operators category
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.network.telephony;

import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.ArraySet;

import com.google.common.collect.Sets;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/** Helper class to manage listening to signal strength changes on a set of mobile network
 *  subscriptions */
public class SignalStrengthListener {

    private TelephonyManager mBaseTelephonyManager;
    private Callback mCallback;
    private Map<Integer, PhoneStateListener> mListeners;

    public interface Callback {
        void onSignalStrengthChanged();
    }

    public SignalStrengthListener(Context context, Callback callback) {
        mBaseTelephonyManager = context.getSystemService(TelephonyManager.class);
        mCallback = callback;
        mListeners = new TreeMap<>();
    }

    /** Resumes listening for signal strength changes for the set of ids from the last call to
     * {@link #updateSubscriptionIds(Set)}  */
    public void resume() {
        for (int subId : mListeners.keySet()) {
            startListening(subId);
        }
    }

    /** Pauses listening for signal strength changes */
    public void pause() {
        for (int subId : mListeners.keySet()) {
            stopListening(subId);
        }
    }

    /** Updates the set of ids we want to be listening for, beginning to listen for any new ids and
     * stopping listening for any ids not contained in the new set */
    public void updateSubscriptionIds(Set<Integer> ids) {
        Set<Integer> currentIds = new ArraySet<>(mListeners.keySet());
        for (int idToRemove : Sets.difference(currentIds, ids)) {
            stopListening(idToRemove);
            mListeners.remove(idToRemove);
        }
        for (int idToAdd : Sets.difference(ids, currentIds)) {
            PhoneStateListener listener = new PhoneStateListener() {
                @Override
                public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                    mCallback.onSignalStrengthChanged();
                }
            };
            mListeners.put(idToAdd, listener);
            startListening(idToAdd);
        }
    }

    private void startListening(int subId) {
        TelephonyManager mgr = mBaseTelephonyManager.createForSubscriptionId(subId);
        mgr.listen(mListeners.get(subId), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    }

    private void stopListening(int subId) {
        TelephonyManager mgr = mBaseTelephonyManager.createForSubscriptionId(subId);
        mgr.listen(mListeners.get(subId), PhoneStateListener.LISTEN_NONE);
    }
}
Loading