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

Commit deca9ea8 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Create central TelephonyListenerManager.

The TelephonyManager doesn't like have "too many" listeners
registered on int at any given time. It will actually throw
exceptions when this happens. To lighten the load from the SystemUI
side, TelephonyListenerManager now ensures that only one listener is
ever subscribed at any point.

SystemUI can now use this class instead, piggy-backing on the
possibly already subscribed listener to retrieve the events it cares
about.

Also, use Executors in CarrierTextController instead of Handlers.

Bug: 179775696
Test: atest SystemUITests
Change-Id: I626e80a91396161022e1fc6387598521f77bf4fc
parent 9ac5677b
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.keyguard;

import android.content.Context;
import android.content.res.TypedArray;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.method.SingleLineTransformationMethod;
import android.util.AttributeSet;
@@ -26,6 +27,7 @@ import android.widget.TextView;

import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.telephony.TelephonyListenerManager;

import java.util.Locale;

@@ -85,7 +87,10 @@ public class CarrierText extends TextView {
        mSeparator = getResources().getString(
                com.android.internal.R.string.kg_text_message_separator);
        mCarrierTextController = new CarrierTextController(mContext, mSeparator, mShowAirplaneMode,
                mShowMissingSim);
                mShowMissingSim, mContext.getSystemService(TelephonyManager.class),
                Dependency.get(TelephonyListenerManager.class),
                Dependency.get(Dependency.MAIN_EXECUTOR),
                Dependency.get(Dependency.BACKGROUND_EXECUTOR));
        mShouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
        setSelected(mShouldMarquee); // Allow marquee to work.
    }
+45 −32
Original line number Diff line number Diff line
@@ -16,20 +16,15 @@

package com.android.keyguard;

import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -40,11 +35,14 @@ import androidx.annotation.VisibleForTesting;
import com.android.settingslib.WirelessUtils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.telephony.TelephonyListenerManager;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.inject.Inject;
@@ -59,8 +57,6 @@ public class CarrierTextController {
    private static final String TAG = "CarrierTextController";

    private final boolean mIsEmergencyCallCapable;
    private final Handler mMainHandler;
    private final Handler mBgHandler;
    private boolean mTelephonyCapable;
    private boolean mShowMissingSim;
    private boolean mShowAirplaneMode;
@@ -73,6 +69,10 @@ public class CarrierTextController {
    @Nullable // Check for nullability before dispatching
    private CarrierTextCallback mCarrierTextCallback;
    private Context mContext;
    private final TelephonyManager mTelephonyManager;
    private final TelephonyListenerManager mTelephonyListenerManager;
    private final Executor mMainExecutor;
    private final Executor mBgExecutor;
    private CharSequence mSeparator;
    private WakefulnessLifecycle mWakefulnessLifecycle;
    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
@@ -129,11 +129,10 @@ public class CarrierTextController {
        }
    };

    private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    private final ActiveDataSubscriptionIdListener mPhoneStateListener =
            new ActiveDataSubscriptionIdListener() {
        @Override
        public void onActiveDataSubscriptionIdChanged(int subId) {
            mActiveMobileDataSubscription = subId;
                if (mNetworkSupported.get() && mCarrierTextCallback != null) {
                    updateCarrierText();
                }
@@ -163,9 +162,15 @@ public class CarrierTextController {
     * @param separator Separator between different parts of the text
     */
    public CarrierTextController(Context context, CharSequence separator, boolean showAirplaneMode,
            boolean showMissingSim) {
            boolean showMissingSim, TelephonyManager telephonyManager,
            TelephonyListenerManager telephonyListenerManager,
            @Main Executor mainExecutor, @Background Executor bgExecutor) {
        mContext = context;
        mIsEmergencyCallCapable = getTelephonyManager().isVoiceCapable();
        mTelephonyManager = telephonyManager;
        mTelephonyListenerManager = telephonyListenerManager;
        mMainExecutor = mainExecutor;
        mBgExecutor = bgExecutor;
        mIsEmergencyCallCapable = mTelephonyManager.isVoiceCapable();

        mShowAirplaneMode = showAirplaneMode;
        mShowMissingSim = showMissingSim;
@@ -173,12 +178,10 @@ public class CarrierTextController {
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        mSeparator = separator;
        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
        mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
        mSimSlotsNumber = mTelephonyManager.getSupportedModemCount();
        mSimErrorState = new boolean[mSimSlotsNumber];
        mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
        mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
        mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
        mBgHandler.post(() -> {
        mBgExecutor.execute(() -> {
            boolean supported =
                    mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
            if (supported && mNetworkSupported.compareAndSet(false, supported)) {
@@ -208,7 +211,7 @@ public class CarrierTextController {
        CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
                TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
        // mSimErrorState has the state of each sim indexed by slotID.
        for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
        for (int index = 0; index < mTelephonyManager.getActiveModemCount(); index++) {
            if (!mSimErrorState[index]) {
                continue;
            }
@@ -247,26 +250,24 @@ public class CarrierTextController {
     * This call will always be processed in a background thread.
     */
    private void handleSetListening(CarrierTextCallback callback) {
        TelephonyManager telephonyManager = getTelephonyManager();
        if (callback != null) {
            mCarrierTextCallback = callback;
            if (mNetworkSupported.get()) {
                // Keyguard update monitor expects callbacks from main thread
                mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
                mMainExecutor.execute(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
                mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
                telephonyManager.listen(mPhoneStateListener,
                        LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
                mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
            } else {
                // Don't listen and clear out the text when the device isn't a phone.
                mMainHandler.post(() -> callback.updateCarrierInfo(
                mMainExecutor.execute(() -> callback.updateCarrierInfo(
                        new CarrierTextCallbackInfo("", null, false, null)
                ));
            }
        } else {
            mCarrierTextCallback = null;
            mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
            mMainExecutor.execute(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
            mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
            telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
            mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
        }
    }

@@ -277,7 +278,7 @@ public class CarrierTextController {
     * @param callback Callback to provide text updates
     */
    public void setListening(CarrierTextCallback callback) {
        mBgHandler.post(() -> handleSetListening(callback));
        mBgExecutor.execute(() -> handleSetListening(callback));
    }

    protected List<SubscriptionInfo> getSubscriptionInfo() {
@@ -400,7 +401,7 @@ public class CarrierTextController {
    protected void postToCallback(CarrierTextCallbackInfo info) {
        final CarrierTextCallback callback = mCarrierTextCallback;
        if (callback != null) {
            mMainHandler.post(() -> callback.updateCarrierInfo(info));
            mMainExecutor.execute(() -> callback.updateCarrierInfo(info));
        }
    }

@@ -620,14 +621,25 @@ public class CarrierTextController {
    public static class Builder {
        private final Context mContext;
        private final String mSeparator;
        private final TelephonyManager mTelephonyManager;
        private final TelephonyListenerManager mTelephonyListenerManager;
        private final Executor mMainExecutor;
        private final Executor mBgExecutor;
        private boolean mShowAirplaneMode;
        private boolean mShowMissingSim;

        @Inject
        public Builder(Context context, @Main Resources resources) {
        public Builder(Context context, @Main Resources resources,
                TelephonyManager telephonyManager,
                TelephonyListenerManager telephonyListenerManager, @Main Executor mainExecutor,
                @Background Executor bgExecutor) {
            mContext = context;
            mSeparator = resources.getString(
                    com.android.internal.R.string.kg_text_message_separator);
            mTelephonyManager = telephonyManager;
            mTelephonyListenerManager = telephonyListenerManager;
            mMainExecutor = mainExecutor;
            mBgExecutor = bgExecutor;
        }


@@ -643,7 +655,8 @@ public class CarrierTextController {

        public CarrierTextController build() {
            return new CarrierTextController(
                    mContext, mSeparator, mShowAirplaneMode, mShowMissingSim);
                    mContext, mSeparator, mShowAirplaneMode, mShowMissingSim, mTelephonyManager,
                    mTelephonyListenerManager, mMainExecutor, mBgExecutor);
        }
    }
    /**
+9 −6
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_STOPPED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
@@ -76,11 +75,11 @@ import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.SparseArray;
@@ -107,6 +106,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.Assert;
import com.android.systemui.util.RingerModeTracker;

@@ -290,6 +290,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private boolean mDeviceInteractive;
    private boolean mScreenOn;
    private SubscriptionManager mSubscriptionManager;
    private final TelephonyListenerManager mTelephonyListenerManager;
    private List<SubscriptionInfo> mSubscriptionInfo;
    private TrustManager mTrustManager;
    private UserManager mUserManager;
@@ -358,7 +359,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            };

    @VisibleForTesting
    public PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    public TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener =
            new TelephonyCallback.ActiveDataSubscriptionIdListener() {
        @Override
        public void onActiveDataSubscriptionIdChanged(int subId) {
            mActiveMobileDataSubscription = subId;
@@ -1614,9 +1616,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            StatusBarStateController statusBarStateController,
            LockPatternUtils lockPatternUtils,
            AuthController authController,
            TelephonyListenerManager telephonyListenerManager,
            FeatureFlags featureFlags) {
        mContext = context;
        mSubscriptionManager = SubscriptionManager.from(context);
        mTelephonyListenerManager = telephonyListenerManager;
        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
        mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
        mBackgroundExecutor = backgroundExecutor;
@@ -1865,8 +1869,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        mTelephonyManager =
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager != null) {
            mTelephonyManager.listen(mPhoneStateListener,
                    LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
            mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
            // Set initial sim states values.
            for (int slot = 0; slot < mTelephonyManager.getActiveModemCount(); slot++) {
                int state = mTelephonyManager.getSimState(slot);
@@ -3123,7 +3126,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        TelephonyManager telephony =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if (telephony != null) {
            telephony.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
            mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
        }

        mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
+3 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
import com.android.systemui.tuner.TunerService;
@@ -350,6 +351,7 @@ public class Dependency {
    @Inject Lazy<MediaOutputDialogFactory> mMediaOutputDialogFactory;
    @Inject Lazy<DeviceConfigProxy> mDeviceConfigProxy;
    @Inject Lazy<NavigationBarOverlayController> mNavbarButtonsControllerLazy;
    @Inject Lazy<TelephonyListenerManager> mTelephonyListenerManager;

    @Inject
    public Dependency() {
@@ -545,6 +547,7 @@ public class Dependency {
        mProviders.put(StatusBar.class, mStatusBar::get);
        mProviders.put(ProtoTracer.class, mProtoTracer::get);
        mProviders.put(DeviceConfigProxy.class, mDeviceConfigProxy::get);
        mProviders.put(TelephonyListenerManager.class, mTelephonyListenerManager::get);

        // TODO(b/118592525): to support multi-display , we start to add something which is
        //                    per-display, while others may be global. I think it's time to add
+7 −4
Original line number Diff line number Diff line
@@ -73,8 +73,8 @@ import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.sysprop.TelephonyProperties;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.transition.AutoTransition;
import android.transition.TransitionManager;
@@ -138,6 +138,7 @@ import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.RingerModeTracker;
import com.android.systemui.util.leak.RotationUtils;
@@ -303,7 +304,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
            AudioManager audioManager, IDreamManager iDreamManager,
            DevicePolicyManager devicePolicyManager, LockPatternUtils lockPatternUtils,
            BroadcastDispatcher broadcastDispatcher,
            ConnectivityManager connectivityManager, TelephonyManager telephonyManager,
            ConnectivityManager connectivityManager,
            TelephonyListenerManager telephonyListenerManager,
            ContentResolver contentResolver, @Nullable Vibrator vibrator, @Main Resources resources,
            ConfigurationController configurationController, ActivityStarter activityStarter,
            KeyguardStateController keyguardStateController, UserManager userManager,
@@ -361,7 +363,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);

        // get notified of phone state changes
        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
        telephonyListenerManager.addServiceStateListener(mPhoneStateListener);
        contentResolver.registerContentObserver(
                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
                mAirplaneModeObserver);
@@ -2049,7 +2051,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
        }
    };

    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    private final TelephonyCallback.ServiceStateListener mPhoneStateListener =
            new TelephonyCallback.ServiceStateListener() {
        @Override
        public void onServiceStateChanged(ServiceState serviceState) {
            if (!mHasTelephony) return;
Loading