diff options
14 files changed, 417 insertions, 224 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 7eedbc341132..f7fd03a8722a 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -762,11 +762,9 @@ package android.app { public class BroadcastOptions { method public void clearRequireCompatChange(); method public int getPendingIntentBackgroundActivityStartMode(); - method @Deprecated public boolean isDeferUntilActive(); method @Deprecated public boolean isPendingIntentBackgroundActivityLaunchAllowed(); method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long); method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean); - method @Deprecated @NonNull public android.app.BroadcastOptions setDeferUntilActive(boolean); method public void setDontSendToRestrictedApps(boolean); method @Deprecated public void setPendingIntentBackgroundActivityLaunchAllowed(boolean); method @NonNull public android.app.BroadcastOptions setPendingIntentBackgroundActivityStartMode(int); diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index aa253f2ebe31..bccbb381bfb1 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -782,9 +782,7 @@ public class BroadcastOptions extends ComponentOptions { } /** {@hide} */ - @SystemApi @Deprecated - // STOPSHIP: remove entirely after this API change lands in AOSP public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) { if (shouldDefer) { setDeferralPolicy(DEFERRAL_POLICY_UNTIL_ACTIVE); @@ -795,9 +793,7 @@ public class BroadcastOptions extends ComponentOptions { } /** {@hide} */ - @SystemApi @Deprecated - // STOPSHIP: remove entirely after this API change lands in AOSP public boolean isDeferUntilActive() { return (mDeferralPolicy == DEFERRAL_POLICY_UNTIL_ACTIVE); } diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java index a2b0486c1df5..f2b60a4e3988 100644 --- a/core/java/android/os/Parcelable.java +++ b/core/java/android/os/Parcelable.java @@ -16,8 +16,8 @@ package android.os; -import android.annotation.NonNull; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.SystemApi; import java.lang.annotation.Retention; @@ -26,8 +26,9 @@ import java.lang.annotation.RetentionPolicy; /** * Interface for classes whose instances can be written to * and restored from a {@link Parcel}. Classes implementing the Parcelable - * interface must also have a non-null static field called <code>CREATOR</code> - * of a type that implements the {@link Parcelable.Creator} interface. + * interface must also have a non-null public static field called + * <code>CREATOR</code> of a type that implements the {@link Parcelable.Creator} + * interface. * * <p>A typical implementation of Parcelable is:</p> * diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index a1d73ff25cb8..94cf1b2ada0e 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -117,4 +117,9 @@ <!-- Whether using the new SubscriptionManagerService or the old SubscriptionController --> <bool name="config_using_subscription_manager_service">false</bool> <java-symbol type="bool" name="config_using_subscription_manager_service" /> + + <!-- Whether asynchronously update the subscription database or not. Async mode increases + the performance, but sync mode reduces the chance of database/cache out-of-sync. --> + <bool name="config_subscription_database_async_update">true</bool> + <java-symbol type="bool" name="config_subscription_database_async_update" /> </resources> diff --git a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java index 0eff5f24f7e0..b5e5b258b7d6 100644 --- a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java +++ b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java @@ -97,7 +97,7 @@ public class ReadUtils { public static ReadOperation[] READ_OPERATIONS = new ReadOperation[] { (parcel, provider) -> { - parcel.setDataPosition(provider.consumeInt()); + parcel.setDataPosition(provider.consumeInt(0, Integer.MAX_VALUE)); }, (parcel, provider) -> { parcel.setDataCapacity(provider.consumeInt()); @@ -155,6 +155,7 @@ public class ReadUtils { byte[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new byte[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -166,6 +167,7 @@ public class ReadUtils { char[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new char[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -177,6 +179,7 @@ public class ReadUtils { int[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new int[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -188,6 +191,7 @@ public class ReadUtils { double[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new double[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -199,6 +203,7 @@ public class ReadUtils { float[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new float[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -210,6 +215,7 @@ public class ReadUtils { boolean[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new boolean[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -221,6 +227,7 @@ public class ReadUtils { long[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new long[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -232,6 +239,7 @@ public class ReadUtils { IBinder[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new IBinder[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -274,6 +282,7 @@ public class ReadUtils { SingleDataParcelable[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new SingleDataParcelable[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -293,6 +302,7 @@ public class ReadUtils { EmptyParcelable[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new EmptyParcelable[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -312,6 +322,7 @@ public class ReadUtils { GenericDataParcelable[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new GenericDataParcelable[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -334,6 +345,7 @@ public class ReadUtils { SomeParcelable[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new SomeParcelable[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { @@ -390,6 +402,7 @@ public class ReadUtils { TestInterface[] array; if (provider.consumeBoolean()) { int pos = parcel.dataPosition(); + if (pos < 0) return; array = new TestInterface[Math.min(MAX_LEN, parcel.readInt())]; parcel.setDataPosition(pos); } else { diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index 2c0e909a5cc0..ea07fe77e588 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -42,6 +42,7 @@ import android.provider.Settings; import android.util.DisplayMetrics; import android.util.Pair; import android.view.Display; +import android.view.IWindow; import android.view.IWindowManager; import android.view.ViewDebug; @@ -553,6 +554,22 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } + private void dumpLocalWindowAsync(IWindow client, ParcelFileDescriptor pfd) { + // Make it asynchronous to avoid writer from being blocked + // by waiting for the buffer to be consumed in the same process. + IoThread.getExecutor().execute(() -> { + synchronized (mInternal.mGlobalLock) { + try { + client.executeCommand(ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd); + } catch (Exception e) { + // Ignore RemoteException for local call. Just print trace for other + // exceptions caused by RC with tolerable low possibility. + e.printStackTrace(); + } + } + }); + } + private int runDumpVisibleWindowViews(PrintWriter pw) { if (!mInternal.checkCallingPermission(android.Manifest.permission.DUMP, "runDumpVisibleWindowViews()")) { @@ -575,16 +592,7 @@ public class WindowManagerShellCommand extends ShellCommand { pipe = new ByteTransferPipe(); final ParcelFileDescriptor pfd = pipe.getWriteFd(); if (w.isClientLocal()) { - // Make it asynchronous to avoid writer from being blocked - // by waiting for the buffer to be consumed in the same process. - IoThread.getExecutor().execute(() -> { - try { - w.mClient.executeCommand( - ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd); - } catch (RemoteException e) { - // Ignore for local call. - } - }); + dumpLocalWindowAsync(w.mClient, pfd); } else { w.mClient.executeCommand( ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd); diff --git a/services/tests/PackageManagerServiceTests/TEST_MAPPING b/services/tests/PackageManagerServiceTests/TEST_MAPPING index af0008c29aaf..63f26b6c8816 100644 --- a/services/tests/PackageManagerServiceTests/TEST_MAPPING +++ b/services/tests/PackageManagerServiceTests/TEST_MAPPING @@ -9,6 +9,38 @@ "name": "PackageManagerServiceHostTests" } ], + "kernel-presubmit": [ + { + "name": "PackageManagerServiceHostTests", + "options": [ + { + // TODO(b/197552347) (crashes postsubmit) + "exclude-filter": "com.android.server.pm.test.OverlayActorVisibilityTest#testVisibilityByOverlayable" + }, + { + // TODO(b/204133664) + "exclude-filter": "com.android.server.pm.test.SdCardEjectionTests" + }, + { + // TODO(b/272575212) + "exclude-filter": "com.android.server.pm.test.SettingsTest#testWriteCorruptDataBinaryXml" + }, + { + "exclude-filter": "com.android.server.pm.test.SettingsTest#testWriteCorruptDataTextXml" + }, + { + "exclude-filter": "com.android.server.pm.test.SettingsTest#testWriteCorruptHeaderBinaryXml" + }, + { + "exclude-filter": "com.android.server.pm.test.SettingsTest#testWriteCorruptHeaderTextXml" + }, + { + // TODO(b/272714903) + "exclude-filter": "com.android.server.pm.test.OverlayPathsUninstallSystemUpdatesTest#verify" + } + ] + } + ], "imports": [ { "path": "frameworks/base/services/tests/PackageManagerServiceTests/unit" diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index 80de823a6a1b..3f83d4efc31a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -736,8 +736,8 @@ public class AlarmManagerServiceTest { verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), onFinishedCaptor.capture(), any(Handler.class), isNull(), optionsCaptor.capture()); - assertTrue(optionsCaptor.getValue() - .getBoolean(BroadcastOptions.KEY_ALARM_BROADCAST, false)); + final BroadcastOptions options = new BroadcastOptions(optionsCaptor.getValue()); + assertTrue(options.isAlarmBroadcast()); } @Test diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java index 1ba997f4c334..fdf694303dbc 100644 --- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java @@ -743,11 +743,23 @@ public final class TelephonyPermissions { /** * Given a list of permissions, check to see if the caller has at least one of them granted. If - * not, check to see if the caller has carrier privileges. If the caller does not have any of + * not, check to see if the caller has carrier privileges. If the caller does not have any of * these permissions, throw a SecurityException. */ public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, int uid, String message, String... permissions) { + enforceAnyPermissionGrantedOrCarrierPrivileges( + context, subId, uid, false, message, permissions); + } + + /** + * Given a list of permissions, check to see if the caller has at least one of them granted. If + * not, check to see if the caller has carrier privileges on the specified subscription (or any + * subscription if {@code allowCarrierPrivilegeOnAnySub} is {@code true}. If the caller does not + * have any of these permissions, throw a {@link SecurityException}. + */ + public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, + int uid, boolean allowCarrierPrivilegeOnAnySub, String message, String... permissions) { if (permissions.length == 0) return; boolean isGranted = false; for (String perm : permissions) { @@ -758,7 +770,12 @@ public final class TelephonyPermissions { } if (isGranted) return; - if (checkCarrierPrivilegeForSubId(context, subId)) return; + + if (allowCarrierPrivilegeOnAnySub) { + if (checkCarrierPrivilegeForAnySubId(context, Binder.getCallingUid())) return; + } else { + if (checkCarrierPrivilegeForSubId(context, subId)) return; + } StringBuilder b = new StringBuilder(message); b.append(": Neither user "); @@ -769,7 +786,8 @@ public final class TelephonyPermissions { b.append(" or "); b.append(permissions[i]); } - b.append(" or carrier privileges"); + b.append(" or carrier privileges. subId=" + subId + ", allowCarrierPrivilegeOnAnySub=" + + allowCarrierPrivilegeOnAnySub); throw new SecurityException(b.toString()); } diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index c4d760f8db52..dd7e2d71e8f3 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -997,7 +997,8 @@ public final class DataFailCause { */ public static final int IWLAN_CONGESTION = 0x3C8C; - /** IKE configuration error resulting in failure */ + // Below IWLAN error codes are defined by the UE and do not relate to any 3GPP spec value + /** IKE configuration error resulting in failure */ public static final int IWLAN_IKEV2_CONFIG_FAILURE = 0x4000; /** * Sent in the response to an IKE_AUTH message when, for some reason, @@ -1014,6 +1015,57 @@ public final class DataFailCause { public static final int IWLAN_DNS_RESOLUTION_TIMEOUT = 0x4005; /** Expected to update or bring down an ePDG tunnel, but no tunnel found*/ public static final int IWLAN_TUNNEL_NOT_FOUND = 0x4006; + /** + * Failed to apply tunnel transform + * + * @hide + */ + public static final int IWLAN_TUNNEL_TRANSFORM_FAILED = 0x4007; + /** + * IWLAN PDN setup failed due to Wi-Fi lost during IKE tunnel setup, + * match exception reported by IKE module + * + * @hide + */ + public static final int IWLAN_IKE_NETWORK_LOST_EXCEPTION = 0x4008; + /** + * Carrier-specific error codes during IKEv2 SA setup + * + * @hide + */ + public static final int IWLAN_IKE_PRIVATE_PROTOCOL_ERROR = 0x4009; + /** + * IKE Session closed before child session opened + * + * @hide + */ + public static final int IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED = 0x400A; + /** + * IKE Init timeout, no response from EPDG + * + * @hide + */ + public static final int IWLAN_IKE_INIT_TIMEOUT = 0x400B; + /** + * DPD message does not get an ack after the re-tx attempts and duration, i.e., times out. + * + * @hide + */ + public static final int IWLAN_IKE_DPD_TIMEOUT = 0x400C; + /** + * The Wi-Fi to Wi-Fi handover of the IMS PDN fails because the network does not respond to the + * MOBIKE/rekey mobility message in the expected manner + * + * @hide + */ + public static final int IWLAN_IKE_MOBILITY_TIMEOUT = 0x400D; + /** + * IKE client sent "IKE AUTH request 3" to the network but got "Internal address failure" from + * the network since no internal addresses can be assigned. + * + * @hide + */ + public static final int IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE = 0x400E; // OEM sepecific error codes. To be used by OEMs when they don't // want to reveal error code which would be replaced by ERROR_UNSPECIFIED @@ -1508,6 +1560,16 @@ public final class DataFailCause { sFailCauseMap.put(IWLAN_DNS_RESOLUTION_NAME_FAILURE, "IWLAN_DNS_RESOLUTION_NAME_FAILURE"); sFailCauseMap.put(IWLAN_DNS_RESOLUTION_TIMEOUT, "IWLAN_DNS_RESOLUTION_TIMEOUT"); sFailCauseMap.put(IWLAN_TUNNEL_NOT_FOUND, "IWLAN_TUNNEL_NOT_FOUND"); + sFailCauseMap.put(IWLAN_TUNNEL_TRANSFORM_FAILED, "IWLAN_TUNNEL_TRANSFORM_FAILED"); + sFailCauseMap.put(IWLAN_IKE_INIT_TIMEOUT, "IWLAN_IKE_INIT_TIMEOUT"); + sFailCauseMap.put(IWLAN_IKE_NETWORK_LOST_EXCEPTION, "IWLAN_IKE_NETWORK_LOST_EXCEPTION"); + sFailCauseMap.put(IWLAN_IKE_PRIVATE_PROTOCOL_ERROR, "IWLAN_IKE_PRIVATE_PROTOCOL_ERROR"); + sFailCauseMap.put(IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED, + "IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED"); + sFailCauseMap.put(IWLAN_IKE_DPD_TIMEOUT, "IWLAN_IKE_DPD_TIMEOUT"); + sFailCauseMap.put(IWLAN_IKE_MOBILITY_TIMEOUT, "IWLAN_IKE_MOBILITY_TIMEOUT"); + sFailCauseMap.put(IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE, + "IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE"); sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1"); sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2"); sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3"); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 35226c1817ed..59b822ebecbf 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -58,6 +58,7 @@ import android.os.UserHandle; import android.provider.Telephony.SimInfo; import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; +import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.util.Pair; @@ -347,7 +348,7 @@ public class SubscriptionManager { /** * A content {@link Uri} used to receive updates on advanced calling user setting - * @see ImsMmTelManager#isAdvancedCallingSettingEnabled(). + * * <p> * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the * subscription advanced calling enabled @@ -358,6 +359,9 @@ public class SubscriptionManager { * delivery of updates to the {@link Uri}. * To be notified of changes to a specific subId, append subId to the URI * {@link Uri#withAppendedPath(Uri, String)}. + * + * @see ImsMmTelManager#isAdvancedCallingSettingEnabled() + * * @hide */ @NonNull @@ -731,6 +735,15 @@ public class SubscriptionManager { /** Indicates that data roaming is disabled for a subscription */ public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"DATA_ROAMING_"}, + value = { + DATA_ROAMING_ENABLE, + DATA_ROAMING_DISABLE + }) + public @interface DataRoamingMode {} + /** * TelephonyProvider column name for subscription carrier id. * @see TelephonyManager#getSimCarrierId() @@ -1133,7 +1146,7 @@ public class SubscriptionManager { * * An opportunistic subscription will default to data-centric. * - * {@see SubscriptionInfo#isOpportunistic} + * @see SubscriptionInfo#isOpportunistic */ public static final int USAGE_SETTING_DEFAULT = 0; @@ -1917,7 +1930,7 @@ public class SubscriptionManager { * * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. * - * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID. + * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID. * * @hide */ @@ -1947,7 +1960,7 @@ public class SubscriptionManager { * * @param cardId the card ID of the eUICC. * - * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID. + * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID. * * @hide */ @@ -2071,10 +2084,15 @@ public class SubscriptionManager { } /** - * Remove SubscriptionInfo record from the SubscriptionInfo database + * Remove subscription info record from the subscription database. + * * @param uniqueId This is the unique identifier for the subscription within the specific - * subscription type. - * @param subscriptionType the {@link #SUBSCRIPTION_TYPE} + * subscription type. + * @param subscriptionType the type of subscription to be removed. + * + * @throws NullPointerException if {@code uniqueId} is {@code null}. + * @throws SecurityException if callers do not hold the required permission. + * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @@ -2109,7 +2127,7 @@ public class SubscriptionManager { /** * Set SIM icon tint color for subscription ID * @param tint the RGB value of icon tint color of the SIM - * @param subId the unique Subscritpion ID in database + * @param subId the unique subscription ID in database * @return the number of records updated * @hide */ @@ -2117,7 +2135,7 @@ public class SubscriptionManager { public int setIconTint(@ColorInt int tint, int subId) { if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId); return setSubscriptionPropertyHelper(subId, "setIconTint", - (iSub)-> iSub.setIconTint(tint, subId) + (iSub)-> iSub.setIconTint(subId, tint) ); } @@ -2425,20 +2443,6 @@ public class SubscriptionManager { return getActiveSubscriptionInfo(getDefaultDataSubscriptionId()); } - /** @hide */ - public void clearSubscriptionInfo() { - try { - ISub iSub = TelephonyManager.getSubscriptionService(); - if (iSub != null) { - iSub.clearSubInfo(); - } - } catch (RemoteException ex) { - // ignore it - } - - return; - } - /** * Check if the supplied subscription ID is valid. * @@ -2582,48 +2586,27 @@ public class SubscriptionManager { } /** - * Returns a constant indicating the state of sim for the slot index. + * Set a field in the subscription database. Note not all fields are supported. * - * @param slotIndex + * @param subscriptionId Subscription Id of Subscription. + * @param columnName Column name in the database. Note not all fields are supported. + * @param value Value to store in the database. * - * {@See TelephonyManager#SIM_STATE_UNKNOWN} - * {@See TelephonyManager#SIM_STATE_ABSENT} - * {@See TelephonyManager#SIM_STATE_PIN_REQUIRED} - * {@See TelephonyManager#SIM_STATE_PUK_REQUIRED} - * {@See TelephonyManager#SIM_STATE_NETWORK_LOCKED} - * {@See TelephonyManager#SIM_STATE_READY} - * {@See TelephonyManager#SIM_STATE_NOT_READY} - * {@See TelephonyManager#SIM_STATE_PERM_DISABLED} - * {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR} + * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not + * exposed. + * @throws SecurityException if callers do not hold the required permission. + * + * @see android.provider.Telephony.SimInfo for all the columns. * - * {@hide} - */ - public static int getSimStateForSlotIndex(int slotIndex) { - int simState = TelephonyManager.SIM_STATE_UNKNOWN; - - try { - ISub iSub = TelephonyManager.getSubscriptionService(); - if (iSub != null) { - simState = iSub.getSimStateForSlotIndex(slotIndex); - } - } catch (RemoteException ex) { - } - - return simState; - } - - /** - * Store properties associated with SubscriptionInfo in database - * @param subId Subscription Id of Subscription - * @param propKey Column name in database associated with SubscriptionInfo - * @param propValue Value to store in DB for particular subId & column name * @hide */ - public static void setSubscriptionProperty(int subId, String propKey, String propValue) { + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName, + @NonNull String value) { try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { - iSub.setSubscriptionProperty(subId, propKey, propValue); + iSub.setSubscriptionProperty(subscriptionId, columnName, value); } } catch (RemoteException ex) { // ignore it @@ -2652,118 +2635,149 @@ public class SubscriptionManager { } /** - * Return list of contacts uri corresponding to query result. - * @param subId Subscription Id of Subscription - * @param propKey Column name in SubscriptionInfo database - * @return list of contacts uri to be returned - * @hide - */ - private static List<Uri> getContactsFromSubscriptionProperty(int subId, String propKey, - Context context) { - String result = getSubscriptionProperty(subId, propKey, context); - if (result != null) { - try { - byte[] b = Base64.decode(result, Base64.DEFAULT); - ByteArrayInputStream bis = new ByteArrayInputStream(b); - ObjectInputStream ois = new ObjectInputStream(bis); - List<String> contacts = ArrayList.class.cast(ois.readObject()); - List<Uri> uris = new ArrayList<>(); - for (String contact : contacts) { - uris.add(Uri.parse(contact)); - } - return uris; - } catch (IOException e) { - logd("getContactsFromSubscriptionProperty IO exception"); - } catch (ClassNotFoundException e) { - logd("getContactsFromSubscriptionProperty ClassNotFound exception"); - } - } - return new ArrayList<>(); - } - - /** - * Store properties associated with SubscriptionInfo in database - * @param subId Subscription Id of Subscription - * @param propKey Column name in SubscriptionInfo database - * @return Value associated with subId and propKey column in database + * Get specific field in string format from the subscription info database. + * + * @param context The calling context. + * @param subscriptionId Subscription id of the subscription. + * @param columnName Column name in subscription database. + * + * @return Value in string format associated with {@code subscriptionId} and {@code columnName} + * from the database. + * + * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not + * exposed. + * + * @see android.provider.Telephony.SimInfo for all the columns. + * * @hide */ - private static String getSubscriptionProperty(int subId, String propKey, - Context context) { + @NonNull + @RequiresPermission(anyOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + "carrier privileges", + }) + private static String getStringSubscriptionProperty(@NonNull Context context, + int subscriptionId, @NonNull String columnName) { String resultValue = null; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { - resultValue = iSub.getSubscriptionProperty(subId, propKey, + resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName, context.getOpPackageName(), context.getAttributionTag()); } } catch (RemoteException ex) { // ignore it } - return resultValue; + return TextUtils.emptyIfNull(resultValue); } /** - * Returns boolean value corresponding to query result. - * @param subId Subscription Id of Subscription - * @param propKey Column name in SubscriptionInfo database - * @param defValue Default boolean value to be returned - * @return boolean result value to be returned + * Get specific field in {@code boolean} format from the subscription info database. + * + * @param subscriptionId Subscription id of the subscription. + * @param columnName Column name in subscription database. + * @param defaultValue Default value in case not found or error. + * @param context The calling context. + * + * @return Value in {@code boolean} format associated with {@code subscriptionId} and + * {@code columnName} from the database, or {@code defaultValue} if not found or error. + * + * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not + * exposed. + * + * @see android.provider.Telephony.SimInfo for all the columns. + * * @hide */ - public static boolean getBooleanSubscriptionProperty(int subId, String propKey, - boolean defValue, Context context) { - String result = getSubscriptionProperty(subId, propKey, context); - if (result != null) { + @RequiresPermission(anyOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + "carrier privileges", + }) + public static boolean getBooleanSubscriptionProperty(int subscriptionId, + @NonNull String columnName, boolean defaultValue, @NonNull Context context) { + String result = getStringSubscriptionProperty(context, subscriptionId, columnName); + if (!result.isEmpty()) { try { return Integer.parseInt(result) == 1; } catch (NumberFormatException err) { logd("getBooleanSubscriptionProperty NumberFormat exception"); } } - return defValue; + return defaultValue; } /** - * Returns integer value corresponding to query result. - * @param subId Subscription Id of Subscription - * @param propKey Column name in SubscriptionInfo database - * @param defValue Default integer value to be returned - * @return integer result value to be returned + * Get specific field in {@code integer} format from the subscription info database. + * + * @param subscriptionId Subscription id of the subscription. + * @param columnName Column name in subscription database. + * @param defaultValue Default value in case not found or error. + * @param context The calling context. + * + * @return Value in {@code integer} format associated with {@code subscriptionId} and + * {@code columnName} from the database, or {@code defaultValue} if not found or error. + * + * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not + * exposed. + * + * @see android.provider.Telephony.SimInfo for all the columns. + * * @hide */ - public static int getIntegerSubscriptionProperty(int subId, String propKey, int defValue, - Context context) { - String result = getSubscriptionProperty(subId, propKey, context); - if (result != null) { + @RequiresPermission(anyOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + "carrier privileges", + }) + public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, + int defaultValue, @NonNull Context context) { + String result = getStringSubscriptionProperty(context, subscriptionId, columnName); + if (!result.isEmpty()) { try { return Integer.parseInt(result); } catch (NumberFormatException err) { logd("getIntegerSubscriptionProperty NumberFormat exception"); } } - return defValue; + return defaultValue; } /** - * Returns long value corresponding to query result. - * @param subId Subscription Id of Subscription - * @param propKey Column name in SubscriptionInfo database - * @param defValue Default long value to be returned - * @return long result value to be returned + * Get specific field in {@code long} format from the subscription info database. + * + * @param subscriptionId Subscription id of the subscription. + * @param columnName Column name in subscription database. + * @param defaultValue Default value in case not found or error. + * @param context The calling context. + * + * @return Value in {@code long} format associated with {@code subscriptionId} and + * {@code columnName} from the database, or {@code defaultValue} if not found or error. + * + * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not + * exposed. + * + * @see android.provider.Telephony.SimInfo for all the columns. + * * @hide */ - public static long getLongSubscriptionProperty(int subId, String propKey, long defValue, - Context context) { - String result = getSubscriptionProperty(subId, propKey, context); - if (result != null) { + @RequiresPermission(anyOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + "carrier privileges", + }) + public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, + long defaultValue, @NonNull Context context) { + String result = getStringSubscriptionProperty(context, subscriptionId, columnName); + if (!result.isEmpty()) { try { return Long.parseLong(result); } catch (NumberFormatException err) { logd("getLongSubscriptionProperty NumberFormat exception"); } } - return defValue; + return defaultValue; } /** @@ -3001,7 +3015,6 @@ public class SubscriptionManager { * considered unmetered. * @param networkTypes the network types this override applies to. If no * network types are specified, override values will be ignored. - * {@see TelephonyManager#getAllNetworkTypes()} * @param expirationDurationMillis the duration after which the requested override * will be automatically cleared, or {@code 0} to leave in the * requested state until explicitly cleared, or the next reboot, @@ -3062,17 +3075,14 @@ public class SubscriptionManager { * </ul> * * @param subId the subscriber this override applies to. - * @param overrideCongested set if the subscription should be considered - * congested. - * @param networkTypes the network types this override applies to. If no - * network types are specified, override values will be ignored. - * {@see TelephonyManager#getAllNetworkTypes()} + * @param overrideCongested set if the subscription should be considered congested. + * @param networkTypes the network types this override applies to. If no network types are + * specified, override values will be ignored. * @param expirationDurationMillis the duration after which the requested override - * will be automatically cleared, or {@code 0} to leave in the - * requested state until explicitly cleared, or the next reboot, - * whichever happens first. - * @throws SecurityException if the caller doesn't meet the requirements - * outlined above. + * will be automatically cleared, or {@code 0} to leave in the requested state until explicitly + * cleared, or the next reboot, whichever happens first. + * + * @throws SecurityException if the caller doesn't meet the requirements outlined above. */ public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @NonNull @Annotation.NetworkType int[] networkTypes, @@ -3088,10 +3098,11 @@ public class SubscriptionManager { * * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns * true). To check for permissions for non-embedded subscription as well, - * {@see android.telephony.TelephonyManager#hasCarrierPrivileges}. * * @param info The subscription to check. * @return whether the app is authorized to manage this subscription per its metadata. + * + * @see android.telephony.TelephonyManager#hasCarrierPrivileges */ public boolean canManageSubscription(SubscriptionInfo info) { return canManageSubscription(info, mContext.getPackageName()); @@ -3104,11 +3115,13 @@ public class SubscriptionManager { * * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns * true). To check for permissions for non-embedded subscription as well, - * {@see android.telephony.TelephonyManager#hasCarrierPrivileges}. * * @param info The subscription to check. * @param packageName Package name of the app to check. + * * @return whether the app is authorized to manage this subscription per its access rules. + * + * @see android.telephony.TelephonyManager#hasCarrierPrivileges * @hide */ @SystemApi @@ -3421,21 +3434,20 @@ public class SubscriptionManager { /** * Remove a list of subscriptions from their subscription group. - * See {@link #createSubscriptionGroup(List)} for more details. * * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} - * permission or had carrier privilege permission on the subscriptions: - * {@link TelephonyManager#hasCarrierPrivileges()} or - * {@link #canManageSubscription(SubscriptionInfo)} - * - * @throws SecurityException if the caller doesn't meet the requirements - * outlined above. - * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong - * the specified group. - * @throws IllegalStateException if Telephony service is in bad state. + * permission or has carrier privilege permission on all of the subscriptions provided in + * {@code subIdList}. * * @param subIdList list of subId that need removing from their groups. + * @param groupUuid The UUID of the subscription group. * + * @throws SecurityException if the caller doesn't meet the requirements outlined above. + * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong the + * specified group. + * @throws IllegalStateException if Telephony service is in bad state. + * + * @see #createSubscriptionGroup(List) */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @@ -3443,7 +3455,7 @@ public class SubscriptionManager { @NonNull ParcelUuid groupUuid) { Preconditions.checkNotNull(subIdList, "subIdList can't be null."); Preconditions.checkNotNull(groupUuid, "groupUuid can't be null."); - String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String callingPackage = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (VDBG) { logd("[removeSubscriptionsFromGroup]"); } @@ -3453,7 +3465,7 @@ public class SubscriptionManager { try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { - iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, pkgForDebug); + iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, callingPackage); } else { if (!isSystemProcess()) { throw new IllegalStateException("telephony service is null."); @@ -3491,7 +3503,6 @@ public class SubscriptionManager { * @param groupUuid of which list of subInfo will be returned. * @return list of subscriptionInfo that belong to the same group, including the given * subscription itself. It will return an empty list if no subscription belongs to the group. - * */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(Manifest.permission.READ_PHONE_STATE) @@ -3531,7 +3542,8 @@ public class SubscriptionManager { * want to see their own hidden subscriptions. * * @param info the subscriptionInfo to check against. - * @return true if this subscription should be visible to the API caller. + * + * @return {@code true} if this subscription should be visible to the API caller. * * @hide */ @@ -3604,9 +3616,9 @@ public class SubscriptionManager { * <p> * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required * + * @param subscriptionId Subscription to be enabled or disabled. It could be a eSIM or pSIM + * subscription. * @param enable whether user is turning it on or off. - * @param subscriptionId Subscription to be enabled or disabled. - * It could be a eSIM or pSIM subscription. * * @return whether the operation is successful. * @@ -3639,8 +3651,6 @@ public class SubscriptionManager { * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated * immediately.) * - * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required - * * @param subscriptionId which subscription to operate on. * @param enabled whether uicc applications are enabled or disabled. * @hide @@ -3673,8 +3683,6 @@ public class SubscriptionManager { * It provides whether a physical SIM card can be disabled without taking it out, which is done * via {@link #setSubscriptionEnabled(int, boolean)} API. * - * Requires Permission: READ_PRIVILEGED_PHONE_STATE. - * * @return whether can disable subscriptions on physical SIMs. * * @hide @@ -3702,10 +3710,11 @@ public class SubscriptionManager { } /** - * DO NOT USE. - * This API is designed for features that are not finished at this point. Do not call this API. + * Check if the subscription is currently active in any slot. + * + * @param subscriptionId The subscription id. + * * @hide - * TODO b/135547512: further clean up */ @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @@ -3723,11 +3732,14 @@ public class SubscriptionManager { } /** - * Set the device to device status sharing user preference for a subscription ID. The setting + * Set the device to device status sharing user preference for a subscription id. The setting * app uses this method to indicate with whom they wish to share device to device status * information. - * @param sharing the status sharing preference - * @param subscriptionId the unique Subscription ID in database + * + * @param subscriptionId The subscription id. + * @param sharing The status sharing preference. + * + * @throws SecurityException if the caller doesn't have permissions required. */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharingPreference(int subscriptionId, @@ -3744,6 +3756,8 @@ public class SubscriptionManager { * Returns the user-chosen device to device status sharing preference * @param subscriptionId Subscription id of subscription * @return The device to device status sharing preference + * + * @throws SecurityException if the caller doesn't have permissions required. */ public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference( int subscriptionId) { @@ -3755,11 +3769,14 @@ public class SubscriptionManager { } /** - * Set the list of contacts that allow device to device status sharing for a subscription ID. + * Set the list of contacts that allow device to device status sharing for a subscription id. * The setting app uses this method to indicate with whom they wish to share device to device * status information. - * @param contacts The list of contacts that allow device to device status sharing - * @param subscriptionId The unique Subscription ID in database + * + * @param subscriptionId The subscription id. + * @param contacts The list of contacts that allow device to device status sharing. + * + * @throws SecurityException if the caller doesn't have permissions required. */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) public void setDeviceToDeviceStatusSharingContacts(int subscriptionId, @@ -3775,17 +3792,33 @@ public class SubscriptionManager { } /** - * Returns the list of contacts that allow device to device status sharing. - * @param subscriptionId Subscription id of subscription - * @return The list of contacts that allow device to device status sharing + * Get the list of contacts that allow device to device status sharing. + * + * @param subscriptionId Subscription id. + * + * @return The list of contacts that allow device to device status sharing. */ - public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts( - int subscriptionId) { - if (VDBG) { - logd("[getDeviceToDeviceStatusSharingContacts] + subId: " + subscriptionId); + public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) { + String result = getStringSubscriptionProperty(mContext, subscriptionId, + D2D_STATUS_SHARING_SELECTED_CONTACTS); + if (result != null) { + try { + byte[] b = Base64.decode(result, Base64.DEFAULT); + ByteArrayInputStream bis = new ByteArrayInputStream(b); + ObjectInputStream ois = new ObjectInputStream(bis); + List<String> contacts = ArrayList.class.cast(ois.readObject()); + List<Uri> uris = new ArrayList<>(); + for (String contact : contacts) { + uris.add(Uri.parse(contact)); + } + return uris; + } catch (IOException e) { + logd("getDeviceToDeviceStatusSharingContacts IO exception"); + } catch (ClassNotFoundException e) { + logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception"); + } } - return getContactsFromSubscriptionProperty(subscriptionId, - D2D_STATUS_SHARING_SELECTED_CONTACTS, mContext); + return new ArrayList<>(); } /** @@ -3840,12 +3873,12 @@ public class SubscriptionManager { /** * Get active data subscription id. Active data subscription refers to the subscription * currently chosen to provide cellular internet connection to the user. This may be - * different from getDefaultDataSubscriptionId(). Eg. Opportunistics data + * different from {@link #getDefaultDataSubscriptionId()}. * - * See {@link PhoneStateListener#onActiveDataSubscriptionIdChanged(int)} for the details. + * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if + * not. * - * @return Active data subscription id if any is chosen, or - * SubscriptionManager.INVALID_SUBSCRIPTION_ID if not. + * @see TelephonyCallback.ActiveDataSubscriptionIdListener */ public static int getActiveDataSubscriptionId() { if (isSubscriptionManagerServiceEnabled()) { @@ -4038,12 +4071,15 @@ public class SubscriptionManager { * security-related or other sensitive scenarios. * * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} - * for the default one. + * for the default one. * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants. + * * @return the phone number, or an empty string if not available. + * * @throws IllegalArgumentException if {@code source} is invalid. * @throws IllegalStateException if the telephony process is not currently available. * @throws SecurityException if the caller doesn't have permissions required. + * * @see #PHONE_NUMBER_SOURCE_UICC * @see #PHONE_NUMBER_SOURCE_CARRIER * @see #PHONE_NUMBER_SOURCE_IMS @@ -4096,8 +4132,10 @@ public class SubscriptionManager { * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID} * for the default one. * @return the phone number, or an empty string if not available. + * * @throws IllegalStateException if the telephony process is not currently available. * @throws SecurityException if the caller doesn't have permissions required. + * * @see #getPhoneNumber(int, int) */ @RequiresPermission(anyOf = { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7a19d36ba743..9d418e144f4c 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3504,7 +3504,7 @@ public class TelephonyManager { "state as absent"); return SIM_STATE_ABSENT; } - return SubscriptionManager.getSimStateForSlotIndex(slotIndex); + return getSimStateForSlotIndex(slotIndex); } /** @@ -3651,9 +3651,7 @@ public class TelephonyManager { @Deprecated public @SimState int getSimApplicationState(int physicalSlotIndex) { int activePort = getFirstActivePortIndex(physicalSlotIndex); - int simState = - SubscriptionManager.getSimStateForSlotIndex(getLogicalSlotIndex(physicalSlotIndex, - activePort)); + int simState = getSimStateForSlotIndex(getLogicalSlotIndex(physicalSlotIndex, activePort)); return getSimApplicationStateFromSimState(simState); } @@ -3679,9 +3677,7 @@ public class TelephonyManager { @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION) public @SimState int getSimApplicationState(int physicalSlotIndex, int portIndex) { - int simState = - SubscriptionManager.getSimStateForSlotIndex(getLogicalSlotIndex(physicalSlotIndex, - portIndex)); + int simState = getSimStateForSlotIndex(getLogicalSlotIndex(physicalSlotIndex, portIndex)); return getSimApplicationStateFromSimState(simState); } @@ -3750,7 +3746,7 @@ public class TelephonyManager { */ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION) public @SimState int getSimState(int slotIndex) { - int simState = SubscriptionManager.getSimStateForSlotIndex(slotIndex); + int simState = getSimStateForSlotIndex(slotIndex); if (simState == SIM_STATE_LOADED) { simState = SIM_STATE_READY; } @@ -17006,4 +17002,30 @@ public class TelephonyManager { } return false; } + + /** + * Returns a constant indicating the state of sim for the slot index. + * + * @param slotIndex Logical SIM slot index. + * + * @see TelephonyManager.SimState + * + * @hide + */ + @SimState + public static int getSimStateForSlotIndex(int slotIndex) { + try { + ITelephony telephony = ITelephony.Stub.asInterface( + TelephonyFrameworkInitializer + .getTelephonyServiceManager() + .getTelephonyServiceRegisterer() + .get()); + if (telephony != null) { + return telephony.getSimStateForSlotIndex(slotIndex); + } + } catch (RemoteException e) { + Log.e(TAG, "Error in getSimStateForSlotIndex: " + e); + } + return TelephonyManager.SIM_STATE_UNKNOWN; + } } diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 5173405ac17d..c5f6902062ff 100644 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -135,11 +135,11 @@ interface ISub { /** * Set SIM icon tint color by simInfo index - * @param tint the icon tint color of the SIM * @param subId the unique SubscriptionInfo index in database + * @param tint the icon tint color of the SIM * @return the number of records updated */ - int setIconTint(int tint, int subId); + int setIconTint(int subId, int tint); /** * Set display name by simInfo index with name source @@ -242,8 +242,6 @@ interface ISub { int getDefaultSubId(); - int clearSubInfo(); - int getPhoneId(int subId); /** @@ -274,11 +272,6 @@ interface ISub { boolean isSubscriptionEnabled(int subId); int getEnabledSubscriptionId(int slotIndex); - /** - * Get the SIM state for the slot index - * @return SIM state as the ordinal of IccCardConstants.State - */ - int getSimStateForSlotIndex(int slotIndex); boolean isActiveSubId(int subId, String callingPackage, String callingFeatureId); diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index da1ffcdea812..ecafe702ea4e 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2564,4 +2564,11 @@ interface ITelephony { * @hide */ boolean isRemovableEsimDefaultEuicc(String callingPackage); + + /** + * Get the SIM state for the logical SIM slot index. + * + * @param slotIndex Logical SIM slot index. + */ + int getSimStateForSlotIndex(int slotIndex); } |