Merge "Fix javadoc error for MediaFormat.KEY_BITRATE_MODE"
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7eedbc3..f7fd03a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -762,11 +762,9 @@
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/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e709a1a..30a2303 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3434,8 +3434,13 @@
if (mLastProcessState == processState) {
return;
}
+ // Do not issue a transitional GC if we are transitioning between 2 cached states.
+ // Only update if the state flips between cached and uncached or vice versa
+ if (ActivityManager.isProcStateCached(mLastProcessState)
+ != ActivityManager.isProcStateCached(processState)) {
+ updateVmProcessState(processState);
+ }
mLastProcessState = processState;
- updateVmProcessState(processState);
if (localLOGV) {
Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
+ (fromIpc ? " (from ipc" : ""));
@@ -3444,12 +3449,16 @@
}
/** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
+ // Currently ART VM only uses state updates for Transitional GC, and thus
+ // this function initiates a Transitional GC for transitions into Cached apps states.
private void updateVmProcessState(int processState) {
- // TODO: Tune this since things like gmail sync are important background but not jank
- // perceptible.
- final int state = processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
- ? VM_PROCESS_STATE_JANK_PERCEPTIBLE
- : VM_PROCESS_STATE_JANK_IMPERCEPTIBLE;
+ // Only a transition into Cached state should result in a Transitional GC request
+ // to the ART runtime. Update VM state to JANK_IMPERCEPTIBLE in that case.
+ // Note that there are 4 possible cached states currently, all of which are
+ // JANK_IMPERCEPTIBLE from GC point of view.
+ final int state = ActivityManager.isProcStateCached(processState)
+ ? VM_PROCESS_STATE_JANK_IMPERCEPTIBLE
+ : VM_PROCESS_STATE_JANK_PERCEPTIBLE;
VMRuntime.getRuntime().updateProcessState(state);
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index aa253f2..bccbb38 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -782,9 +782,7 @@
}
/** {@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 @@
}
/** {@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 a2b0486..f2b60a4 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 @@
/**
* 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 fad9e0e..42255bf 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1799,10 +1799,15 @@
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 a1d73ff..94cf1b2 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 0eff5f2..b5e5b25 100644
--- a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java
+++ b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java
@@ -97,7 +97,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 4b12590..852edef 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 0000000..4417209
--- /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/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 73d9cc7..2aa9378 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1483,6 +1483,7 @@
public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
enforceSystemUid();
synchronized (mQuotaLock) {
+ final int[] applicableUidsForChain;
synchronized (mRulesLock) {
SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
SparseIntArray newRules = new SparseIntArray();
@@ -1506,10 +1507,15 @@
int uid = rulesToRemove.keyAt(index);
updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT);
}
+ // Copy the keys for the firewall rules chain, which is guaranteed not to include
+ // default rules. We must not include default rules in the UIDs we send to
+ // ConnectivityManager#replaceFirewallChain, as this would have the opposite effect
+ // intended, leading such UIDs to be blocked or allowed erroneously.
+ applicableUidsForChain = uidFirewallRules.copyKeys();
}
final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
try {
- cm.replaceFirewallChain(chain, uids);
+ cm.replaceFirewallChain(chain, applicableUidsForChain);
} catch (RuntimeException e) {
Slog.w(TAG, "Error flushing firewall chain " + chain, e);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 2c0e909..ea07fe7 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.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 @@
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 @@
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 af0008c..63f26b6 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 80de823..3f83d4e 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 @@
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 49ad585..7c60f81 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -82,7 +82,7 @@
* 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 1ba997f..fdf69430 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -743,11 +743,23 @@
/**
* 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 @@
}
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 @@
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/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5ad5001..656a70a 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9377,7 +9377,8 @@
* Gets the configuration values of the specified keys for a particular subscription.
*
* <p>If an invalid subId is used, the returned configuration will contain default values for
- * the specified keys.
+ * the specified keys. If the value for the key can't be found, the returned configuration will
+ * filter the key out.
*
* <p>After using this method to get the configuration bundle,
* {@link #isConfigForIdentifiedCarrier(PersistableBundle)} should be called to confirm whether
@@ -9395,8 +9396,8 @@
* @param subId The subscription ID on which the carrier config should be retrieved.
* @param keys The carrier config keys to retrieve values.
* @return A {@link PersistableBundle} with key/value mapping for the specified configuration
- * on success, or an empty (but never null) bundle on failure (for example, when no value for
- * the specified key can be found).
+ * on success, or an empty (but never null) bundle on failure (for example, when the calling app
+ * has no permission).
*/
@RequiresPermission(anyOf = {
Manifest.permission.READ_PHONE_STATE,
@@ -9514,6 +9515,8 @@
* Gets the configuration values of the specified config keys applied for the default
* subscription.
*
+ * <p>If the value for the key can't be found, the returned bundle will filter the key out.
+ *
* <p>After using this method to get the configuration bundle, {@link
* #isConfigForIdentifiedCarrier(PersistableBundle)} should be called to confirm whether any
* carrier specific configuration has been applied.
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index c4d760f..dd7e2d7 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -997,7 +997,8 @@
*/
public static final int IWLAN_CONGESTION = 0x3C8C;
- /** IKE configuration error resulting in failure */
+ // Below IWLAN error codes are defined by the UE and do not relate to any 3GPP spec value
+ /** IKE configuration error resulting in failure */
public static final int IWLAN_IKEV2_CONFIG_FAILURE = 0x4000;
/**
* Sent in the response to an IKE_AUTH message when, for some reason,
@@ -1014,6 +1015,57 @@
public static final int IWLAN_DNS_RESOLUTION_TIMEOUT = 0x4005;
/** Expected to update or bring down an ePDG tunnel, but no tunnel found*/
public static final int IWLAN_TUNNEL_NOT_FOUND = 0x4006;
+ /**
+ * Failed to apply tunnel transform
+ *
+ * @hide
+ */
+ public static final int IWLAN_TUNNEL_TRANSFORM_FAILED = 0x4007;
+ /**
+ * IWLAN PDN setup failed due to Wi-Fi lost during IKE tunnel setup,
+ * match exception reported by IKE module
+ *
+ * @hide
+ */
+ public static final int IWLAN_IKE_NETWORK_LOST_EXCEPTION = 0x4008;
+ /**
+ * Carrier-specific error codes during IKEv2 SA setup
+ *
+ * @hide
+ */
+ public static final int IWLAN_IKE_PRIVATE_PROTOCOL_ERROR = 0x4009;
+ /**
+ * IKE Session closed before child session opened
+ *
+ * @hide
+ */
+ public static final int IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED = 0x400A;
+ /**
+ * IKE Init timeout, no response from EPDG
+ *
+ * @hide
+ */
+ public static final int IWLAN_IKE_INIT_TIMEOUT = 0x400B;
+ /**
+ * DPD message does not get an ack after the re-tx attempts and duration, i.e., times out.
+ *
+ * @hide
+ */
+ public static final int IWLAN_IKE_DPD_TIMEOUT = 0x400C;
+ /**
+ * The Wi-Fi to Wi-Fi handover of the IMS PDN fails because the network does not respond to the
+ * MOBIKE/rekey mobility message in the expected manner
+ *
+ * @hide
+ */
+ public static final int IWLAN_IKE_MOBILITY_TIMEOUT = 0x400D;
+ /**
+ * IKE client sent "IKE AUTH request 3" to the network but got "Internal address failure" from
+ * the network since no internal addresses can be assigned.
+ *
+ * @hide
+ */
+ public static final int IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE = 0x400E;
// OEM sepecific error codes. To be used by OEMs when they don't
// want to reveal error code which would be replaced by ERROR_UNSPECIFIED
@@ -1508,6 +1560,16 @@
sFailCauseMap.put(IWLAN_DNS_RESOLUTION_NAME_FAILURE, "IWLAN_DNS_RESOLUTION_NAME_FAILURE");
sFailCauseMap.put(IWLAN_DNS_RESOLUTION_TIMEOUT, "IWLAN_DNS_RESOLUTION_TIMEOUT");
sFailCauseMap.put(IWLAN_TUNNEL_NOT_FOUND, "IWLAN_TUNNEL_NOT_FOUND");
+ sFailCauseMap.put(IWLAN_TUNNEL_TRANSFORM_FAILED, "IWLAN_TUNNEL_TRANSFORM_FAILED");
+ sFailCauseMap.put(IWLAN_IKE_INIT_TIMEOUT, "IWLAN_IKE_INIT_TIMEOUT");
+ sFailCauseMap.put(IWLAN_IKE_NETWORK_LOST_EXCEPTION, "IWLAN_IKE_NETWORK_LOST_EXCEPTION");
+ sFailCauseMap.put(IWLAN_IKE_PRIVATE_PROTOCOL_ERROR, "IWLAN_IKE_PRIVATE_PROTOCOL_ERROR");
+ sFailCauseMap.put(IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED,
+ "IWLAN_IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED");
+ sFailCauseMap.put(IWLAN_IKE_DPD_TIMEOUT, "IWLAN_IKE_DPD_TIMEOUT");
+ sFailCauseMap.put(IWLAN_IKE_MOBILITY_TIMEOUT, "IWLAN_IKE_MOBILITY_TIMEOUT");
+ sFailCauseMap.put(IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE,
+ "IWLAN_EPDG_INTERNAL_ADDRESS_FAILURE");
sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1");
sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2");
sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3");
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 6fe9bf9..ac74016 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1207,13 +1207,8 @@
/**
* 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 @@
.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 void setStateOutOfService() {
- init(true);
+ init();
}
public void setStateOff() {
- init(true);
+ init();
mVoiceRegState = STATE_POWER_OFF;
mDataRegState = STATE_POWER_OFF;
}
@@ -1272,14 +1265,11 @@
/**
* 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 5c1a006..59b822ebe 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -58,6 +58,7 @@
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 @@
/**
* 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 @@
* 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 @@
/** 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 @@
*
* An opportunistic subscription will default to data-centric.
*
- * {@see SubscriptionInfo#isOpportunistic}
+ * @see SubscriptionInfo#isOpportunistic
*/
public static final int USAGE_SETTING_DEFAULT = 0;
@@ -1743,8 +1756,7 @@
*
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* or that the calling app has carrier privileges (see
- * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
- * to the calling app are returned.
+ * {@link TelephonyManager#hasCarrierPrivileges}).
*
* @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
* <ul>
@@ -1762,7 +1774,6 @@
* </li>
* </ul>
*/
- @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
return getActiveSubscriptionInfoList(/* userVisibleonly */true);
@@ -1919,7 +1930,7 @@
*
* <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
*/
@@ -1949,7 +1960,7 @@
*
* @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
*/
@@ -1966,17 +1977,12 @@
}
/**
+ * Get the active subscription count.
*
- * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- * or that the calling app has carrier privileges (see
- * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, the count will include
- * only those subscriptions accessible to the caller.
+ * @return The current number of active subscriptions.
*
- * @return the current number of active subscriptions. There is no guarantee the value
- * returned by this method will be the same as the length of the list returned by
- * {@link #getActiveSubscriptionInfoList}.
+ * @see #getActiveSubscriptionInfoList()
*/
- @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
public int getActiveSubscriptionInfoCount() {
int result = 0;
@@ -2078,10 +2084,15 @@
}
/**
- * 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)
@@ -2116,7 +2127,7 @@
/**
* 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
*/
@@ -2124,7 +2135,7 @@
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)
);
}
@@ -2432,20 +2443,6 @@
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.
*
@@ -2589,48 +2586,27 @@
}
/**
- * 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.
*
- * {@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
+ * @see android.provider.Telephony.SimInfo for all the columns.
+ *
* @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
@@ -2659,118 +2635,149 @@
}
/**
- * 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
+ * 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 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
- * @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;
}
/**
@@ -3008,7 +3015,6 @@
* 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,
@@ -3069,17 +3075,14 @@
* </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,
@@ -3095,10 +3098,11 @@
*
* 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());
@@ -3111,11 +3115,13 @@
*
* 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
@@ -3428,21 +3434,20 @@
/**
* 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)
@@ -3450,7 +3455,7 @@
@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]");
}
@@ -3460,7 +3465,7 @@
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.");
@@ -3498,7 +3503,6 @@
* @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)
@@ -3538,7 +3542,8 @@
* 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
*/
@@ -3611,9 +3616,9 @@
* <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.
*
@@ -3646,8 +3651,6 @@
* 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
@@ -3680,8 +3683,6 @@
* 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
@@ -3709,10 +3710,11 @@
}
/**
- * 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)
@@ -3730,11 +3732,14 @@
}
/**
- * 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,
@@ -3751,6 +3756,8 @@
* 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) {
@@ -3762,11 +3769,14 @@
}
/**
- * 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,
@@ -3782,17 +3792,33 @@
}
/**
- * 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<>();
}
/**
@@ -3847,12 +3873,12 @@
/**
* 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()) {
@@ -4045,12 +4071,15 @@
* 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
@@ -4103,8 +4132,10 @@
* @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 7a19d36..9d418e1 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3504,7 +3504,7 @@
"state as absent");
return SIM_STATE_ABSENT;
}
- return SubscriptionManager.getSimStateForSlotIndex(slotIndex);
+ return getSimStateForSlotIndex(slotIndex);
}
/**
@@ -3651,9 +3651,7 @@
@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 @@
@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 @@
*/
@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 @@
}
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 5173405..c5f6902 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -135,11 +135,11 @@
/**
* 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 @@
int getDefaultSubId();
- int clearSubInfo();
-
int getPhoneId(int subId);
/**
@@ -274,11 +272,6 @@
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 da1ffcd..ecafe70 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2564,4 +2564,11 @@
* @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);
}