diff options
18 files changed, 376 insertions, 249 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/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index fad9e0e79899..42255bf3793e 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1799,10 +1799,15 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, if (!is_system_server && getuid() == 0) { const int rc = createProcessGroup(uid, getpid()); if (rc != 0) { - fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing " - "CONFIG_CGROUP_CPUACCT?") - : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid, - /* pid= */ 0, strerror(-rc))); + if (rc == -ESRCH) { + // If process is dead, treat this as a non-fatal error + ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc)); + } else { + fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing " + "CONFIG_CGROUP_CPUACCT?") + : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid, + /* pid= */ 0, strerror(-rc))); + } } } 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/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS index 4b125904004a..852edef544b8 100644 --- a/libs/WindowManager/Shell/OWNERS +++ b/libs/WindowManager/Shell/OWNERS @@ -1,4 +1,4 @@ xutan@google.com # Give submodule owners in shell resource approval -per-file res*/*/*.xml = hwwang@google.com, lbill@google.com, madym@google.com +per-file res*/*/*.xml = hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS new file mode 100644 index 000000000000..4417209b85ed --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS @@ -0,0 +1 @@ +jorgegil@google.com 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/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 49ad58550db8..7c60f81259c7 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -82,7 +82,7 @@ import java.util.concurrent.ConcurrentHashMap; * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no * longer used and associated resources may be recovered. * <p> - * Subclasses of {@code Connection} override the {@code on*} methods to provide the the + * Subclasses of {@code Connection} override the {@code on*} methods to provide the * {@link ConnectionService}'s implementation of calling functionality. The {@code on*} methods are * called by Telecom to inform an instance of a {@code Connection} of actions specific to that * {@code Connection} instance. 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/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 6fe9bf97c5c3..ac740166a024 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -1207,13 +1207,8 @@ public class ServiceState implements Parcelable { /** * Initialize the service state. Set everything to the default value. - * - * @param legacyMode {@code true} if the device is on IWLAN legacy mode, where IWLAN is - * considered as a RAT on WWAN {@link NetworkRegistrationInfo}. {@code false} if the device - * is on AP-assisted mode, where IWLAN should be reported through WLAN. - * {@link NetworkRegistrationInfo}. */ - private void init(boolean legacyMode) { + private void init() { if (DBG) Rlog.d(LOG_TAG, "init"); mVoiceRegState = STATE_OUT_OF_SERVICE; mDataRegState = STATE_OUT_OF_SERVICE; @@ -1245,13 +1240,11 @@ public class ServiceState implements Parcelable { .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN) .build()); - if (!legacyMode) { - addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder() - .setDomain(NetworkRegistrationInfo.DOMAIN_PS) - .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) - .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN) - .build()); - } + addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder() + .setDomain(NetworkRegistrationInfo.DOMAIN_PS) + .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) + .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN) + .build()); } mOperatorAlphaLongRaw = null; mOperatorAlphaShortRaw = null; @@ -1260,11 +1253,11 @@ public class ServiceState implements Parcelable { } public void setStateOutOfService() { - init(true); + init(); } public void setStateOff() { - init(true); + init(); mVoiceRegState = STATE_POWER_OFF; mDataRegState = STATE_POWER_OFF; } @@ -1272,14 +1265,11 @@ public class ServiceState implements Parcelable { /** * Set the service state to out-of-service * - * @param legacyMode {@code true} if the device is on IWLAN legacy mode, where IWLAN is - * considered as a RAT on WWAN {@link NetworkRegistrationInfo}. {@code false} if the device - * is on AP-assisted mode, where IWLAN should be reported through WLAN. * @param powerOff {@code true} if this is a power off case (i.e. Airplane mode on). * @hide */ - public void setOutOfService(boolean legacyMode, boolean powerOff) { - init(legacyMode); + public void setOutOfService(boolean powerOff) { + init(); if (powerOff) { mVoiceRegState = STATE_POWER_OFF; mDataRegState = STATE_POWER_OFF; 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); } |