summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Birg <roman@cyngn.com>2016-04-08 11:37:45 -0700
committerMiccia94 <bono.michele94@gmail.com>2016-10-26 15:12:35 +0200
commit07d1f391799d287a52d3cf5488f2af1b7d583f66 (patch)
tree0a609196cd7bbbb82dda93ffeef447d49027c5a9
parent298cc260e2744eab413231f3a8f369a0507a5431 (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.java84
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) {