diff options
| author | Roman Birg <roman@cyngn.com> | 2016-04-08 11:37:45 -0700 |
|---|---|---|
| committer | Miccia94 <bono.michele94@gmail.com> | 2016-10-26 15:12:35 +0200 |
| commit | 07d1f391799d287a52d3cf5488f2af1b7d583f66 (patch) | |
| tree | 0a609196cd7bbbb82dda93ffeef447d49027c5a9 | |
| parent | 298cc260e2744eab413231f3a8f369a0507a5431 (diff) | |
Global actions: fix airplane mode switch for MSIMn7.0
MSIM devices are not reporting state changes for SIM slots without SIMs,
so when toggling airplane mode it would get stuck in the intermediate
state because a phone state callback would never happen.
Now we dynamically add phone state listeners for each active SIM slot.
If there is no active SIM slot, we immediately fall back to the
setting-based behavior. When a subscription update occurs (such as
inserting or removing SIM cards, we'll reinitialize the listener and
use the proper mechanism).
Ticket: CYNGNOS-989
Change-Id: Ifa4f418dd11fda6f67ba31f3847bed225187b95c
Signed-off-by: Roman Birg <roman@cyngn.com>
| -rw-r--r-- | services/core/java/com/android/server/policy/GlobalActions.java | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java index 7ca48fc97614..0ebc222fa32c 100644 --- a/services/core/java/com/android/server/policy/GlobalActions.java +++ b/services/core/java/com/android/server/policy/GlobalActions.java @@ -50,7 +50,6 @@ import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.Manifest; import android.media.AudioManager; import android.net.ConnectivityManager; import android.os.Build; @@ -72,6 +71,8 @@ import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArraySet; @@ -98,8 +99,8 @@ import android.widget.TextView; import cyanogenmod.providers.CMSettings; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; -import java.util.UUID; import static com.android.internal.util.cm.PowerMenuConstants.*; @@ -138,6 +139,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac // Power menu customizations String mActions; + private BitSet mAirplaneModeBits; + private final List<PhoneStateListener> mPhoneStateListeners = new ArrayList<>(); + /** * @param context everything needs a context :( */ @@ -161,9 +165,15 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); // get notified of phone state changes - TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); + SubscriptionManager.from(mContext).addOnSubscriptionsChangedListener( + new SubscriptionManager.OnSubscriptionsChangedListener() { + @Override + public void onSubscriptionsChanged() { + super.onSubscriptionsChanged(); + setupAirplaneModeListeners(); + } + }); + setupAirplaneModeListeners(); mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true, mAirplaneModeObserver); @@ -173,10 +183,59 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac mShowSilentToggle = SHOW_SILENT_TOGGLE && !mContext.getResources().getBoolean( com.android.internal.R.bool.config_useFixedVolume); + updatePowerMenuActions(); + } + + /** + * Since there are two ways of handling airplane mode (with telephony, we depend on the internal + * device telephony state), and MSIM devices do not report phone state for missing SIMs, we + * need to dynamically setup listeners based on subscription changes. + * + * So if there is _any_ active SIM in the device, we can depend on the phone state, + * otherwise fall back to {@link Settings.Global#AIRPLANE_MODE_ON}. + */ + private void setupAirplaneModeListeners() { + TelephonyManager telephonyManager = + (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + + for (PhoneStateListener listener : mPhoneStateListeners) { + telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE); + } + mPhoneStateListeners.clear(); + + final List<SubscriptionInfo> subInfoList = SubscriptionManager.from(mContext) + .getActiveSubscriptionInfoList(); + if (subInfoList != null) { + mHasTelephony = true; + mAirplaneModeBits = new BitSet(subInfoList.size()); + for (int i = 0; i < subInfoList.size(); i++) { + final int finalI = i; + PhoneStateListener subListener = new PhoneStateListener(subInfoList.get(finalI) + .getSubscriptionId()) { + @Override + public void onServiceStateChanged(ServiceState serviceState) { + final boolean inAirplaneMode = serviceState.getState() + == ServiceState.STATE_POWER_OFF; + mAirplaneModeBits.set(finalI, inAirplaneMode); + + // we're in airplane mode if _any_ of the subscriptions say we are + mAirplaneState = mAirplaneModeBits.cardinality() > 0 + ? ToggleAction.State.On : ToggleAction.State.Off; + + mAirplaneModeOn.updateState(mAirplaneState); + if (mAdapter != null) { + mAdapter.notifyDataSetChanged(); + } + } + }; + mPhoneStateListeners.add(subListener); + telephonyManager.listen(subListener, PhoneStateListener.LISTEN_SERVICE_STATE); + } + } else { + mHasTelephony = false; + } // Set the initial status of airplane mode toggle mAirplaneState = getUpdatedAirplaneToggleState(); - - updatePowerMenuActions(); } /** @@ -1303,17 +1362,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac CMSettings.Secure.POWER_MENU_ACTIONS, UserHandle.USER_CURRENT); } - PhoneStateListener mPhoneStateListener = new PhoneStateListener() { - @Override - public void onServiceStateChanged(ServiceState serviceState) { - if (!mHasTelephony) return; - final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF; - mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off; - mAirplaneModeOn.updateState(mAirplaneState); - mAdapter.notifyDataSetChanged(); - } - }; - private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { |
