diff options
| -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) { |
