aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/cm_current.txt15
-rw-r--r--cm/lib/main/java/org/cyanogenmod/platform/internal/CMTelephonyManagerService.java340
-rw-r--r--cm/res/AndroidManifest.xml14
-rw-r--r--cm/res/res/values/strings.xml8
-rw-r--r--src/java/cyanogenmod/app/CMContextConstants.java12
-rw-r--r--src/java/cyanogenmod/app/CMTelephonyManager.java349
-rw-r--r--src/java/cyanogenmod/app/ICMTelephonyManager.aidl38
-rw-r--r--system-api/cm_system-current.txt15
8 files changed, 791 insertions, 0 deletions
diff --git a/api/cm_current.txt b/api/cm_current.txt
index cb658b5..5ade7cb 100644
--- a/api/cm_current.txt
+++ b/api/cm_current.txt
@@ -75,6 +75,19 @@ package cyanogenmod.app {
method public void removeTileAsUser(java.lang.String, int, android.os.UserHandle);
}
+ public class CMTelephonyManager {
+ method public static cyanogenmod.app.CMTelephonyManager getInstance(android.content.Context);
+ method public java.util.List<android.telephony.SubscriptionInfo> getSubInformation();
+ method public boolean isDataConnectionEnabled();
+ method public boolean isDataConnectionSelectedOnSub(int);
+ method public boolean isSubActive(int);
+ method public void setDataConnectionState(boolean);
+ method public void setDefaultPhoneSub(int);
+ method public void setDefaultSmsSub(int);
+ method public void setSubState(int, boolean);
+ field public static final int ASK_FOR_SUBSCRIPTION_ID = 0; // 0x0
+ }
+
public class CustomTile implements android.os.Parcelable {
ctor public CustomTile(android.os.Parcel);
ctor public CustomTile();
@@ -364,9 +377,11 @@ package cyanogenmod.platform {
public static final class Manifest.permission {
ctor public Manifest.permission();
+ field public static final java.lang.String MODIFY_MSIM_PHONE_STATE = "cyanogenmod.permission.MODIFY_MSIM_PHONE_STATE";
field public static final java.lang.String MODIFY_NETWORK_SETTINGS = "cyanogenmod.permission.MODIFY_NETWORK_SETTINGS";
field public static final java.lang.String MODIFY_SOUND_SETTINGS = "cyanogenmod.permission.MODIFY_SOUND_SETTINGS";
field public static final java.lang.String PUBLISH_CUSTOM_TILE = "cyanogenmod.permission.PUBLISH_CUSTOM_TILE";
+ field public static final java.lang.String READ_MSIM_PHONE_STATE = "cyanogenmod.permission.READ_MSIM_PHONE_STATE";
}
public final class R {
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMTelephonyManagerService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMTelephonyManagerService.java
new file mode 100644
index 0000000..25ca556
--- /dev/null
+++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMTelephonyManagerService.java
@@ -0,0 +1,340 @@
+/**
+ * Copyright (c) 2015, The CyanogenMod 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 org.cyanogenmod.platform.internal;
+
+import com.android.server.SystemService;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import java.util.List;
+
+import cyanogenmod.app.CMContextConstants;
+import cyanogenmod.app.CMTelephonyManager;
+import cyanogenmod.app.ICMTelephonyManager;
+
+/**
+ * Internal service which manages interactions with the phone and data connection
+ *
+ * @hide
+ */
+public class CMTelephonyManagerService extends SystemService {
+ private static final String TAG = "CMTelephonyManagerSrv";
+ private static boolean localLOGD = Log.isLoggable(TAG, Log.DEBUG);
+
+ private TelephonyManager mTelephonyManager;
+ private final IBinder mService = new ICMTelephonyManager.Stub() {
+
+ /**
+ * Returns the available SIM subscription information.
+ *
+ * @return The list of SIM subscriptions. The returning list can be null or empty.
+ * @hide
+ */
+ @Override
+ public List<SubscriptionInfo> getSubInformation() {
+ enforceTelephonyReadPermission();
+ return getActiveSubscriptionInfoList();
+ }
+
+ /**
+ * Returns the state of the SIM by subscription ID.
+ *
+ * If the subscription ID is not valid the method will return {@code false}.
+ *
+ * @param subId The subscription ID to query.
+ * @return {@code true} if the SIM is activated (even without signal or requesting the
+ * PIN/PUK), {@code false} otherwise.
+ * @hide
+ */
+ @Override
+ public boolean isSubActive(int subId) {
+ enforceTelephonyReadPermission();
+ return CMTelephonyManagerService.this.isSubActive(subId);
+ }
+
+ /**
+ * Sets the state of one of the SIMs by subscription ID.
+ *
+ * If the subscription ID is not valid or the SIM already
+ * is in the desired state the method will do nothing.
+ *
+ * @param subId The subscription ID to set.
+ * @param state {@code true} to activate the SIM, {@code false} to disable.
+ * @hide
+ */
+ @Override
+ public void setSubState(int subId, boolean state) {
+ enforceTelephonyModifyPermission();
+ CMTelephonyManagerService.this.setSubState(subId, state);
+ }
+
+ /**
+ * Checks if the received subscription received has the data
+ * connection enabled.
+ *
+ * This method will return {@code true} (or {@code false} if inactive on the SIM)
+ * even when an internet connection is active through Wifi/BT.
+ *
+ * If the subscription ID is not valid the method will return {@code false}.
+ *
+ * @param subId The subscription ID to query.
+ * @return {@code true} if the data connection is enabled on the SIM, {@code false} otherwise.
+ * @hide
+ */
+ public boolean isDataConnectionSelectedOnSub(int subId) {
+ enforceTelephonyReadPermission();
+ return CMTelephonyManagerService.this.isDataConnectionSelectedOnSub(subId);
+ }
+
+ /**
+ * Checks if the network data connection is enabled.
+ *
+ * This method will return {@code true} (or {@code false} if inactive)
+ * even when an internet connection is active through Wifi/BT.
+ *
+ * @return {@code true} if the network data connection is enabled, {@code false} otherwise.
+ * @hide
+ */
+ public boolean isDataConnectionEnabled() {
+ enforceTelephonyReadPermission();
+ return CMTelephonyManagerService.this.isDataConnectionEnabled();
+ }
+
+ /**
+ * Sets the network data conection active or inactive.
+ *
+ * @param state If {@code true} enables the network data connection, if {@code false} disables it.
+ * @hide
+ */
+ public void setDataConnectionState(boolean state) {
+ enforceTelephonyModifyPermission();
+ CMTelephonyManagerService.this.setDataConnectionState(state);
+ }
+
+ /**
+ * Sets the data connection state on one of the SIMs by subscription ID.
+ *
+ * If the subscription ID is not valid or the data connection is already
+ * enabled on the SIM the method will do nothing.
+ *
+ * @param subId The subscription ID to set the network data connection.
+ * @hide
+ */
+ public void setDataConnectionSelectedOnSub(int subId) {
+ enforceTelephonyModifyPermission();
+ CMTelephonyManagerService.this.setDataConnectionSelectedOnSub(subId);
+ }
+
+ /**
+ * Sets the default phone used to make phone calls as the one received on subId.
+ *
+ * If 0 is used as a parameter, then the option to choose what SIM to use is
+ * selected.
+ *
+ * @param subId The subscription to set as default for phone calls.
+ * To select SIM when calling use 0.
+ * @hide
+ */
+ public void setDefaultPhoneSub(int subId) {
+ enforceTelephonyModifyPermission();
+ CMTelephonyManagerService.this.setDefaultPhoneSub(subId);
+ }
+
+ /**
+ * Sets the default phone used to send SMS as the one received on subId.
+ *
+ * If 0 is used as a parameter, then the option to choose what SIM to use is
+ * selected.
+ *
+ * @param subId The subscription to set as default for sending SMS.
+ * To select SIM when sending SMS use 0.
+ * @hide
+ */
+ public void setDefaultSmsSub(int subId) {
+ enforceTelephonyModifyPermission();
+ CMTelephonyManagerService.this.setDefaultSmsSub(subId);
+ }
+ };
+
+ public CMTelephonyManagerService(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ if (localLOGD) {
+ Log.d(TAG, "CM telephony manager service start: " + this);
+ }
+ publishBinderService(CMContextConstants.CM_TELEPHONY_MANAGER_SERVICE, mService);
+
+ mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
+ private List<SubscriptionInfo> getActiveSubscriptionInfoList() {
+ SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext);
+ List<SubscriptionInfo> subInfoList = subscriptionManager.getActiveSubscriptionInfoList();
+ if (localLOGD) {
+ Log.d(TAG, "The active subscriptions where obtained from the subscription manager.");
+ }
+ return subInfoList;
+ }
+
+ private boolean isSubActive(int subId) {
+ boolean validSubscriptionId = SubscriptionManager.isValidSubscriptionId(subId);
+
+ if (validSubscriptionId) {
+ int simState = SubscriptionManager.getSimStateForSubscriber(subId);
+ switch (simState) {
+ case TelephonyManager.SIM_STATE_ABSENT:
+ case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
+ case TelephonyManager.SIM_STATE_PERM_DISABLED:
+ case TelephonyManager.SIM_STATE_NOT_READY:
+ if (localLOGD) {
+ Log.d(TAG, "The subscription " + subId + " is NOT active: " + simState);
+ }
+ return false;
+ default:
+ if (localLOGD) {
+ Log.d(TAG, "The subscription " + subId + " is active: " + simState);
+ }
+ return true;
+ }
+ } else {
+ Log.w(TAG, "Invalid subscription identifier: " + subId);
+ return false;
+ }
+ }
+
+ private void setSubState(int subId, boolean state) {
+ if (localLOGD) {
+ Log.d(TAG, "Setting the subscription " + subId + " to inactive (false) or active (true): " + state);
+ }
+
+ if (state) {
+ SubscriptionManager.activateSubId(subId);
+ } else {
+ SubscriptionManager.deactivateSubId(subId);
+ }
+ }
+
+ private boolean isDataConnectionSelectedOnSub(int subId) {
+ boolean validSubscriptionId = SubscriptionManager.isValidSubscriptionId(subId);
+
+ if (validSubscriptionId) {
+ if (subId == SubscriptionManager.getDefaultDataSubId()) {
+ if (localLOGD) {
+ Log.d(TAG, "Data connection selected for subscription " + subId);
+ }
+ return true;
+ } else {
+ if (localLOGD) {
+ Log.d(TAG, "Data connection not selected for subscription " + subId);
+ }
+ return false;
+ }
+ } else {
+ Log.w(TAG, "Invalid subscription identifier: " + subId);
+ return false;
+ }
+ }
+
+ private boolean isDataConnectionEnabled() {
+ if (localLOGD) {
+ Log.d(TAG, "Checking if the network data connection is active");
+ }
+
+ boolean dataEnabled = mTelephonyManager.getDataEnabled();
+
+ if (localLOGD) {
+ Log.d(TAG, "Data network connection is inactive (false) or active (true): " + dataEnabled);
+ }
+
+ return dataEnabled;
+ }
+
+ private void setDataConnectionState(boolean state) {
+ if (localLOGD) {
+ Log.d(TAG, "Setting the network data connection inactive (false) or active (true): " + state);
+ }
+
+ if (state) {
+ mTelephonyManager.enableDataConnectivity();
+ } else {
+ mTelephonyManager.disableDataConnectivity();
+ }
+ }
+
+ private void setDataConnectionSelectedOnSub(int subId) {
+ if (localLOGD) {
+ Log.d(TAG, "Setting the network data connection for subscription " + subId);
+ }
+
+ SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext);
+ subscriptionManager.setDefaultDataSubId(subId);
+ }
+
+ private void setDefaultPhoneSub(int subId) {
+ if (localLOGD) {
+ Log.d(TAG, "Setting the SIM for phone calls on subscription " + subId);
+ }
+
+ SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext);
+ if (subId == CMTelephonyManager.ASK_FOR_SUBSCRIPTION_ID) {
+ if (localLOGD) {
+ Log.d(TAG, "Activates the prompt for phone calls");
+ }
+ SubscriptionManager.setVoicePromptEnabled(true);
+ } else {
+ SubscriptionManager.setVoicePromptEnabled(false);
+ subscriptionManager.setDefaultVoiceSubId(subId);
+ }
+ }
+
+ private void setDefaultSmsSub(int subId) {
+ if (localLOGD) {
+ Log.d(TAG, "Setting the SIM for phone calls on subscription " + subId);
+ }
+
+ SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext);
+ if (subId == CMTelephonyManager.ASK_FOR_SUBSCRIPTION_ID) {
+ if (localLOGD) {
+ Log.d(TAG, "Activates the prompt for SMS");
+ }
+ SubscriptionManager.setSMSPromptEnabled(true);
+ } else {
+ SubscriptionManager.setSMSPromptEnabled(false);
+ subscriptionManager.setDefaultSmsSubId(subId);
+ }
+ }
+
+ private void enforceTelephonyReadPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.READ_MSIM_PHONE_STATE,
+ "CMTelephonyManagerService");
+ }
+
+ private void enforceTelephonyModifyPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.MODIFY_MSIM_PHONE_STATE,
+ "CMTelephonyManagerService");
+ }
+}
diff --git a/cm/res/AndroidManifest.xml b/cm/res/AndroidManifest.xml
index 7a7249d..0891d7f 100644
--- a/cm/res/AndroidManifest.xml
+++ b/cm/res/AndroidManifest.xml
@@ -49,6 +49,20 @@
android:icon="@drawable/ic_launcher_cyanogenmod"
android:protectionLevel="normal" />
+ <!-- Allows a 3rd party to view the phone SIM states and data connection -->
+ <permission android:name="cyanogenmod.permission.READ_MSIM_PHONE_STATE"
+ android:label="@string/permlab_readMSPhoneState"
+ android:description="@string/permdesc_readMSPhoneState"
+ android:icon="@drawable/ic_launcher_cyanogenmod"
+ android:protectionLevel="normal" />
+
+ <!-- Allows a 3rd party to modify the phone SIM states and data connection -->
+ <permission android:name="cyanogenmod.permission.MODIFY_MSIM_PHONE_STATE"
+ android:label="@string/permlab_modifyMSPhoneState"
+ android:description="@string/permdesc_modifyMSPhoneState"
+ android:icon="@drawable/ic_launcher_cyanogenmod"
+ android:protectionLevel="normal" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/cm/res/res/values/strings.xml b/cm/res/res/values/strings.xml
index 93f0b73..758d927 100644
--- a/cm/res/res/values/strings.xml
+++ b/cm/res/res/values/strings.xml
@@ -30,6 +30,14 @@
<string name="permlab_bindCustomTileListenerService">bind to a custom tile listener service</string>
<string name="permdesc_bindCustomTileListenerService">Allows the app to bind to the top-level interface of a custom tile listener service.</string>
+ <!-- Labels for the READ_MSIM_PHONE_STATE permission. -->
+ <string name="permlab_readMSPhoneState">view the phone state and data connection with support to multiple SIMs</string>
+ <string name="permdesc_readMSPhoneState">Allows an app to view the phone state and data connection with support to multiple SIMs.</string>
+
+ <!-- Labels for the MODIFY_MSIM_PHONE_STATE permission. -->
+ <string name="permlab_modifyMSPhoneState">modify the phone state and data connection with support to multiple SIMs</string>
+ <string name="permdesc_modifyMSPhoneState">Allows an app to modify the phone state and data connection with support to multiple SIMs.</string>
+
<!-- Label to show for a service that is running because it is observing the user's custom tiles. -->
<string name="custom_tile_listener_binding_label">Custom tile listener</string>
diff --git a/src/java/cyanogenmod/app/CMContextConstants.java b/src/java/cyanogenmod/app/CMContextConstants.java
index 13dedcb..e4c6578 100644
--- a/src/java/cyanogenmod/app/CMContextConstants.java
+++ b/src/java/cyanogenmod/app/CMContextConstants.java
@@ -61,4 +61,16 @@ public final class CMContextConstants {
* @hide
*/
public static final String CM_SETTINGS_SERVICE = "cmsettings";
+
+ /**
+ * Use with {@link android.content.Context#getSystemService} to retrieve a
+ * {@link cyanogenmod.app.CMTelephonyManager} to manage the phone and
+ * data connection.
+ *
+ * @see android.content.Context#getSystemService
+ * @see cyanogenmod.app.CMTelephonyManager
+ *
+ * @hide
+ */
+ public static final String CM_TELEPHONY_MANAGER_SERVICE = "cmtelephonymanager";
}
diff --git a/src/java/cyanogenmod/app/CMTelephonyManager.java b/src/java/cyanogenmod/app/CMTelephonyManager.java
new file mode 100644
index 0000000..35466c9
--- /dev/null
+++ b/src/java/cyanogenmod/app/CMTelephonyManager.java
@@ -0,0 +1,349 @@
+/**
+ * Copyright (c) 2015, The CyanogenMod 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 cyanogenmod.app;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.SubscriptionInfo;
+import android.util.Log;
+import android.util.Slog;
+
+import java.util.List;
+
+/**
+ * The CMTelephonyManager allows you to view and manage the phone state and
+ * the data connection, with multiple SIMs support.
+ *
+ * <p>
+ * To get the instance of this class, utilize CMTelephonyManager#getInstance(Context context)
+ */
+public class CMTelephonyManager {
+
+ /**
+ * Subscription ID used to set the default Phone and SMS to "ask every time".
+ */
+ public static final int ASK_FOR_SUBSCRIPTION_ID = 0;
+
+ private static final String TAG = "CMTelephonyManager";
+ private static boolean localLOGD = Log.isLoggable(TAG, Log.DEBUG);
+
+ private static ICMTelephonyManager sService;
+ private static CMTelephonyManager sCMTelephonyManagerInstance;
+ private Context mContext;
+
+ private CMTelephonyManager(Context context) {
+ Context appContext = context.getApplicationContext();
+ if (appContext != null) {
+ mContext = appContext;
+ } else {
+ mContext = context;
+ }
+ sService = getService();
+ }
+
+ /**
+ * Get or create an instance of the {@link cyanogenmod.app.CMTelephonyManager}
+ *
+ * @return {@link cyanogenmod.app.CMTelephonyManager}
+ */
+ public static CMTelephonyManager getInstance(Context context) {
+ if (sCMTelephonyManagerInstance == null) {
+ sCMTelephonyManagerInstance = new CMTelephonyManager(context);
+ }
+ return sCMTelephonyManagerInstance;
+ }
+
+ /** @hide */
+ public ICMTelephonyManager getService() {
+ if (sService != null) {
+ return sService;
+ }
+ IBinder b = ServiceManager.getService(CMContextConstants.CM_TELEPHONY_MANAGER_SERVICE);
+ if (b != null) {
+ sService = ICMTelephonyManager.Stub.asInterface(b);
+ return sService;
+ }
+ return null;
+ }
+
+ /**
+ * Gets the list of {@link SubscriptionInfo} that are registered on the
+ * phone.
+ *
+ * @return The list of SIM subscriptions. The returning list can be null or empty.
+ * @see SubscriptionInfo
+ */
+ public List<SubscriptionInfo> getSubInformation() {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return null;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting the SIMs information");
+ }
+ List<SubscriptionInfo> subInfoList = null;
+ try {
+ subInfoList = sService.getSubInformation();
+ if (subInfoList == null) {
+ Log.w(TAG, "no subscription list was returned from the service");
+ } else if (subInfoList.isEmpty()) {
+ Log.w(TAG, "the subscription list is empty");
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+
+ return subInfoList;
+ }
+
+ /**
+ * Returns the state of the SIM by subscription ID.
+ *
+ * If the subscription ID is not valid the method will return {@code false}.
+ *
+ * @param subId The subscription ID to query.
+ * @return {@code true} if the SIM is activated (even without signal or requesting the
+ * PIN/PUK), {@code false} otherwise.
+ */
+ public boolean isSubActive(int subId) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return false;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting the state of the SIM with subscription: " + subId);
+ }
+ boolean simActive = false;
+ try {
+ simActive = sService.isSubActive(subId);
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting the SIM state with subscription " + subId + " as active: " + simActive);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+
+ return simActive;
+ }
+
+ /**
+ * Sets the state of one of the SIMs by subscription ID.
+ *
+ * If the subscription ID is not valid or the SIM already
+ * is in the desired state the method will do nothing.
+ *
+ * @param subId The subscription ID to change the state.
+ * @param state {@code true} to activate the SIM, {@code false} to disable.
+ */
+ public void setSubState(int subId, boolean state) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " setting the state of the SIM with subscription " + subId + " as active: " + state);
+ }
+
+ try {
+ sService.setSubState(subId, state);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+ }
+
+ /**
+ * Checks if the received subscription received has the data
+ * connection enabled.
+ *
+ * This method will return {@code true} (or {@code false} if inactive on the SIM)
+ * even when an internet connection is active through Wifi/BT.
+ *
+ * If the subscription ID is not valid the method will return false.
+ *
+ * @param subId The subscription ID to query.
+ * @return {@code true} if the data connection is enabled on the SIM, {@code false} otherwise.
+ */
+ public boolean isDataConnectionSelectedOnSub(int subId) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return false;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting if the data connection is enabled for SIM for subscription: " + subId);
+ }
+ boolean dataConnectionActiveOnSim = false;
+ try {
+ dataConnectionActiveOnSim = sService.isDataConnectionSelectedOnSub(subId);
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting if the data connection is enabled for SIM with subscription " +
+ subId + " as active: " + dataConnectionActiveOnSim);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+
+ return dataConnectionActiveOnSim;
+ }
+
+ /**
+ * Checks if the network data connection is enabled.
+ *
+ * This method will return {@code true} (or {@code false} if inactive)
+ * even when an internet connection is active through Wifi/BT.
+ *
+ * @return {@code true} if the network data connection is enabled, {@code false} otherwise.
+ */
+ public boolean isDataConnectionEnabled() {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return false;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting if the network data connection is enabled");
+ }
+ boolean dataConnectionEnabled = false;
+ try {
+ dataConnectionEnabled = sService.isDataConnectionEnabled();
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " getting if the network data connection is enabled: " + dataConnectionEnabled);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+
+ return dataConnectionEnabled;
+ }
+
+ /**
+ * Sets the network data conection active or inactive.
+ *
+ * @param state If {@code true} enables the network data connection, if {@code false} disables it.
+ */
+ public void setDataConnectionState(boolean state) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " setting the network data connection enabled: " + state);
+ }
+
+ try {
+ sService.setDataConnectionState(state);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+ }
+
+ /**
+ * Sets the data connection state on one of the SIMs by subscription ID.
+ *
+ * If the subscription ID is not valid or the data connection is already
+ * enabled on the SIM the method will do nothing.
+ *
+ * @param subId The subscription ID to set the network data connection.
+ * @hide
+ */
+ public void setDataConnectionSelectedOnSub(int subId) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " setting the network data connection for SIM with subscription: " + subId);
+ }
+
+ try {
+ sService.setDataConnectionSelectedOnSub(subId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+ }
+
+ /**
+ * Sets the default phone used to make phone calls as the one received on subId.
+ *
+ * If ASK_FOR_SUBSCRIPTION_ID is used as a parameter, then the option to choose
+ * what SIM to use is selected.
+ *
+ * @param subId The subscription to set as default for phone calls.
+ * To select SIM when calling use ASK_FOR_SUBSCRIPTION_ID.
+ */
+ public void setDefaultPhoneSub(int subId) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " setting the subscription used for phone calls as: " + subId);
+ }
+
+ try {
+ sService.setDefaultPhoneSub(subId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+ }
+
+ /**
+ * Sets the default phone used to send SMS as the one received on subId.
+ *
+ * If ASK_FOR_SUBSCRIPTION_ID is used as a parameter, then the option to choose
+ * what SIM to use is selected.
+ *
+ * @param subId The subscription to set as default for sending SMS.
+ * To select SIM when sending SMS use ASK_FOR_SUBSCRIPTION_ID.
+ */
+ public void setDefaultSmsSub(int subId) {
+ if (sService == null) {
+ Log.w(TAG, "not connected to CMTelephonyManager");
+ return;
+ }
+
+ if (localLOGD) {
+ String pkg = mContext.getPackageName();
+ Log.v(TAG, pkg + " setting the subscription used for SMS as: " + subId);
+ }
+
+ try {
+ sService.setDefaultSmsSub(subId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "warning: no cm telephony manager service");
+ }
+ }
+}
diff --git a/src/java/cyanogenmod/app/ICMTelephonyManager.aidl b/src/java/cyanogenmod/app/ICMTelephonyManager.aidl
new file mode 100644
index 0000000..743d61c
--- /dev/null
+++ b/src/java/cyanogenmod/app/ICMTelephonyManager.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2015, The CyanogenMod 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 cyanogenmod.app;
+
+import android.telephony.SubscriptionInfo;
+
+import java.util.List;
+
+/** @hide */
+interface ICMTelephonyManager {
+ // --- Methods below are for use by 3rd party applications to manage phone and data connection
+ // You need the READ_MSIM_PHONE_STATE permission
+ List<SubscriptionInfo> getSubInformation();
+ boolean isSubActive(int subId);
+ boolean isDataConnectionSelectedOnSub(int subId);
+ boolean isDataConnectionEnabled();
+
+ // You need the MODIFY_MSIM_PHONE_STATE permission
+ void setSubState(int subId, boolean state);
+ void setDataConnectionSelectedOnSub(int subId);
+ void setDataConnectionState(boolean state);
+ void setDefaultPhoneSub(int subId);
+ void setDefaultSmsSub(int subId);
+}
diff --git a/system-api/cm_system-current.txt b/system-api/cm_system-current.txt
index cb658b5..5ade7cb 100644
--- a/system-api/cm_system-current.txt
+++ b/system-api/cm_system-current.txt
@@ -75,6 +75,19 @@ package cyanogenmod.app {
method public void removeTileAsUser(java.lang.String, int, android.os.UserHandle);
}
+ public class CMTelephonyManager {
+ method public static cyanogenmod.app.CMTelephonyManager getInstance(android.content.Context);
+ method public java.util.List<android.telephony.SubscriptionInfo> getSubInformation();
+ method public boolean isDataConnectionEnabled();
+ method public boolean isDataConnectionSelectedOnSub(int);
+ method public boolean isSubActive(int);
+ method public void setDataConnectionState(boolean);
+ method public void setDefaultPhoneSub(int);
+ method public void setDefaultSmsSub(int);
+ method public void setSubState(int, boolean);
+ field public static final int ASK_FOR_SUBSCRIPTION_ID = 0; // 0x0
+ }
+
public class CustomTile implements android.os.Parcelable {
ctor public CustomTile(android.os.Parcel);
ctor public CustomTile();
@@ -364,9 +377,11 @@ package cyanogenmod.platform {
public static final class Manifest.permission {
ctor public Manifest.permission();
+ field public static final java.lang.String MODIFY_MSIM_PHONE_STATE = "cyanogenmod.permission.MODIFY_MSIM_PHONE_STATE";
field public static final java.lang.String MODIFY_NETWORK_SETTINGS = "cyanogenmod.permission.MODIFY_NETWORK_SETTINGS";
field public static final java.lang.String MODIFY_SOUND_SETTINGS = "cyanogenmod.permission.MODIFY_SOUND_SETTINGS";
field public static final java.lang.String PUBLISH_CUSTOM_TILE = "cyanogenmod.permission.PUBLISH_CUSTOM_TILE";
+ field public static final java.lang.String READ_MSIM_PHONE_STATE = "cyanogenmod.permission.READ_MSIM_PHONE_STATE";
}
public final class R {