summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/java/android/app/BroadcastOptions.java4
-rw-r--r--core/java/android/os/Parcelable.java7
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp13
-rw-r--r--core/res/res/values/config_telephony.xml5
-rw-r--r--core/tests/fuzzers/ParcelFuzzer/ReadUtils.java15
-rw-r--r--libs/WindowManager/Shell/OWNERS2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS1
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerShellCommand.java28
-rw-r--r--services/tests/PackageManagerServiceTests/TEST_MAPPING32
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java4
-rw-r--r--telecomm/java/android/telecom/Connection.java2
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java24
-rw-r--r--telephony/java/android/telephony/ServiceState.java30
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java400
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java38
-rw-r--r--telephony/java/com/android/internal/telephony/ISub.aidl11
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl7
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);
}