diff options
7 files changed, 136 insertions, 0 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 83a789ad0294..c92a88756391 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5324,6 +5324,11 @@ package android.telephony { field public static final int RESULT_SUCCESS = 0; // 0x0 } + public class PhoneStateListener { + method public void onRadioPowerStateChanged(int); + field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 + } + public class ServiceState implements android.os.Parcelable { method public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int); method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(); @@ -5451,6 +5456,7 @@ package android.telephony { method public boolean getEmergencyCallbackMode(); method public java.lang.String getIsimDomain(); method public int getPreferredNetworkType(int); + method public int getRadioPowerState(); method public int getSimApplicationState(); method public int getSimCardState(); method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); @@ -5514,6 +5520,9 @@ package android.telephony { field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2 field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0 + field public static final int RADIO_POWER_OFF = 0; // 0x0 + field public static final int RADIO_POWER_ON = 1; // 0x1 + field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2 field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1 field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3 diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 591ec0070ea5..65f3c035b031 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -216,6 +216,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int mPreferredDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + @TelephonyManager.RadioPowerState + private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; + private final LocalLog mLocalLog = new LocalLog(100); private PreciseDataConnectionState mPreciseDataConnectionState = @@ -762,6 +765,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) { + try { + r.callback.onRadioPowerStateChanged(mRadioPowerState); + } catch (RemoteException ex) { + remove(r.binder); + } + } } } } else { @@ -1609,6 +1619,32 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + public void notifyRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { + if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) { + return; + } + + if (VDBG) { + log("notifyRadioPowerStateChanged: state= " + state); + } + + synchronized (mRecords) { + mRadioPowerState = state; + + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED)) { + try { + r.callback.onRadioPowerStateChanged(state); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + handleRemoveListLocked(); + } + } + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -1646,6 +1682,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mVoLteServiceState=" + mVoLteServiceState); pw.println("mPhoneCapability=" + mPhoneCapability); pw.println("mPreferredDataSubId=" + mPreferredDataSubId); + pw.println("mRadioPowerState=" + mRadioPowerState); pw.decreaseIndent(); diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 3ea018af97cf..c83d6aa3897d 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.Handler; @@ -291,6 +292,15 @@ public class PhoneStateListener { */ public static final int LISTEN_PREFERRED_DATA_SUBID_CHANGE = 0x00400000; + /** + * Listen for changes to the radio power state. + * + * @see #onRadioPowerStateChanged + * @hide + */ + @SystemApi + public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 0x00800000; + /* * Subscription used to listen to the phone state changes * @hide @@ -420,6 +430,9 @@ public class PhoneStateListener { case LISTEN_PREFERRED_DATA_SUBID_CHANGE: PhoneStateListener.this.onPreferredDataSubIdChanged((int) msg.obj); break; + case LISTEN_RADIO_POWER_STATE_CHANGED: + PhoneStateListener.this.onRadioPowerStateChanged((int) msg.obj); + break; } } }; @@ -672,6 +685,17 @@ public class PhoneStateListener { } /** + * Callback invoked when modem radio power state changes. Requires + * the READ_PRIVILEGED_PHONE_STATE permission. + * @param state the modem radio power state + * @hide + */ + @SystemApi + public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { + // default implementation empty + } + + /** * Callback invoked when telephony has received notice from a carrier * app that a network action that could result in connectivity loss * has been requested by an app using @@ -807,6 +831,10 @@ public class PhoneStateListener { send(LISTEN_PREFERRED_DATA_SUBID_CHANGE, 0, 0, subId); } + public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { + send(LISTEN_RADIO_POWER_STATE_CHANGED, 0, 0, state); + } + } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index fca14c823751..079758675b61 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -6870,6 +6870,60 @@ public class TelephonyManager { } /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RADIO_POWER_"}, + value = {RADIO_POWER_OFF, + RADIO_POWER_ON, + RADIO_POWER_UNAVAILABLE, + }) + public @interface RadioPowerState {} + + /** + * Radio explicitly powered off (e.g, airplane mode). + * @hide + */ + @SystemApi + public static final int RADIO_POWER_OFF = 0; + + /** + * Radio power is on. + * @hide + */ + @SystemApi + public static final int RADIO_POWER_ON = 1; + + /** + * Radio power unavailable (eg, modem resetting or not booted). + * @hide + */ + @SystemApi + public static final int RADIO_POWER_UNAVAILABLE = 2; + + /** + * @return current modem radio state. + * + * <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or + * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling + * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = {android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + android.Manifest.permission.READ_PHONE_STATE}) + public @RadioPowerState int getRadioPowerState() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName()); + } + } catch (RemoteException ex) { + // This could happen if binder process crashes. + } + return RADIO_POWER_UNAVAILABLE; + } + + /** @hide */ @SystemApi @SuppressLint("Doclava125") public void updateServiceLocation() { diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index 38a1bc73c94d..9e42f12d685d 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -53,5 +53,6 @@ oneway interface IPhoneStateListener { void onUserMobileDataStateChanged(in boolean enabled); void onPhoneCapabilityChanged(in PhoneCapability capability); void onPreferredDataSubIdChanged(in int subId); + void onRadioPowerStateChanged(in int state); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 32eb12b49cf0..98f264b482f1 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1499,4 +1499,10 @@ interface ITelephony { * Set the default SMS app to a given package on a given user. */ void setDefaultSmsApp(int userId, String packageName); + + /** + * Return the modem radio power state for slot index. + * + */ + int getRadioPowerState(int slotIndex, String callingPackage); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index c03065c34ca8..0baf860efac4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -80,4 +80,5 @@ interface ITelephonyRegistry { void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); void notifyPhoneCapabilityChanged(in PhoneCapability capability); void notifyPreferredDataSubIdChanged(int preferredSubId); + void notifyRadioPowerStateChanged(in int state); } |