summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/module-lib-current.txt1
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/content/pm/PackageManager.java8
-rw-r--r--core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java6
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java6
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java8
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java26
-rw-r--r--services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java24
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java46
-rw-r--r--telephony/java/com/android/internal/telephony/ISub.aidl4
-rw-r--r--tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java53
13 files changed, 133 insertions, 103 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 13a48993f68f..6a4c67b71250 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -90,6 +90,7 @@ package android.content {
public abstract class Context {
method @NonNull public android.os.UserHandle getUser();
field public static final String PAC_PROXY_SERVICE = "pac_proxy";
+ field public static final String REMOTE_AUTH_SERVICE = "remote_auth";
field public static final String TEST_NETWORK_SERVICE = "test_network";
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7de7c676706b..21d4b6461214 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -6059,6 +6059,18 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.remoteauth.RemoteAuthManager} to discover,
+ * register and authenticate via remote authenticator devices.
+ *
+ * @see #getSystemService(String)
+ * @see android.remoteauth.RemoteAuthManager
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final String REMOTE_AUTH_SERVICE = "remote_auth";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.app.ambientcontext.AmbientContextManager}.
*
* @see #getSystemService(String)
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d738d9eec4cb..db4a684b667e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1561,6 +1561,14 @@ public abstract class PackageManager {
*/
public static final int INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK = 0x01000000;
+ /**
+ * Flag parameter for {@link #installPackage} to force a non-staged update of an APEX. This is
+ * a development-only feature and should not be used on end user devices.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FORCE_NON_STAGED_APEX_UPDATE = 0x02000000;
+
/** @hide */
@IntDef(flag = true, value = {
DONT_KILL_APP,
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index 02e7f6036b34..c8e2cccfd2f6 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -221,7 +221,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
List<CameraOutputConfig> outputConfigs = sessionConfig.outputConfigs;
ArrayList<OutputConfiguration> outputList = new ArrayList<>();
for (CameraOutputConfig output : outputConfigs) {
- Surface outputSurface = initializeSurfrace(output);
+ Surface outputSurface = initializeSurface(output);
if (outputSurface == null) {
continue;
}
@@ -234,7 +234,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
if ((output.sharedSurfaceConfigs != null) && !output.sharedSurfaceConfigs.isEmpty()) {
cameraOutput.enableSurfaceSharing();
for (CameraOutputConfig sharedOutputConfig : output.sharedSurfaceConfigs) {
- Surface sharedSurface = initializeSurfrace(sharedOutputConfig);
+ Surface sharedSurface = initializeSurface(sharedOutputConfig);
if (sharedSurface == null) {
continue;
}
@@ -989,7 +989,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
return ret;
}
- private Surface initializeSurfrace(CameraOutputConfig output) {
+ private Surface initializeSurface(CameraOutputConfig output) {
switch(output.type) {
case CameraOutputConfig.TYPE_SURFACE:
if (output.surface == null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 2156c1220a52..efb3510dfebf 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -1942,10 +1942,10 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
HashMap<Integer, Pair<Image, TotalCaptureResult>> captureMap, Integer jpegOrientation,
Byte jpegQuality) {
ArrayList<CaptureBundle> ret = new ArrayList<>();
- for (Integer stagetId : captureMap.keySet()) {
- Pair<Image, TotalCaptureResult> entry = captureMap.get(stagetId);
+ for (Integer stageId : captureMap.keySet()) {
+ Pair<Image, TotalCaptureResult> entry = captureMap.get(stageId);
CaptureBundle bundle = new CaptureBundle();
- bundle.stage = stagetId;
+ bundle.stage = stageId;
bundle.captureImage = initializeParcelImage(entry.first);
bundle.sequenceId = entry.second.getSequenceId();
bundle.captureResult = entry.second.getNativeMetadata();
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 1a6155b43f6b..a085b95d8e77 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -424,7 +424,7 @@ public abstract class ApexManager {
/**
* Performs a non-staged install of the given {@code apexFile}.
*/
- abstract void installPackage(File apexFile, PackageParser2 packageParser)
+ abstract void installPackage(File apexFile, PackageParser2 packageParser, boolean force)
throws PackageManagerException;
/**
@@ -1136,7 +1136,7 @@ public abstract class ApexManager {
}
@Override
- void installPackage(File apexFile, PackageParser2 packageParser)
+ void installPackage(File apexFile, PackageParser2 packageParser, boolean force)
throws PackageManagerException {
try {
final int flags = PackageManager.GET_META_DATA
@@ -1159,7 +1159,7 @@ public abstract class ApexManager {
}
checkApexSignature(existingApexPkg, newApexPkg);
ApexInfo apexInfo = waitForApexService().installAndActivatePackage(
- apexFile.getAbsolutePath());
+ apexFile.getAbsolutePath(), force);
final ParsedPackage parsedPackage2 = packageParser.parsePackage(
new File(apexInfo.modulePath), flags, /* useCaches= */ false);
final PackageInfo finalApexPkg = PackageInfoWithoutStateUtils.generate(
@@ -1505,7 +1505,7 @@ public abstract class ApexManager {
}
@Override
- void installPackage(File apexFile, PackageParser2 packageParser) {
+ void installPackage(File apexFile, PackageParser2 packageParser, boolean force) {
throw new UnsupportedOperationException("APEX updates are not supported");
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 293f7e9941e3..703ae11ae99b 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -872,8 +872,10 @@ final class InstallPackageHelper {
"Expected exactly one .apex file under " + dir.getAbsolutePath()
+ " got: " + apexes.length);
}
+ boolean force = (request.mArgs.mInstallFlags
+ & PackageManager.INSTALL_FORCE_NON_STAGED_APEX_UPDATE) != 0;
try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
- mApexManager.installPackage(apexes[0], packageParser);
+ mApexManager.installPackage(apexes[0], packageParser, force);
}
} catch (PackageManagerException e) {
request.mInstallResult.setError("APEX installation failed", e);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index be842b96843c..38b79e5612ef 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -86,7 +86,6 @@ import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.ShellCommand;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -3053,6 +3052,13 @@ class PackageManagerShellCommand extends ShellCommand {
// Set package source to other by default
sessionParams.setPackageSource(PackageInstaller.PACKAGE_SOURCE_OTHER);
+ // Encodes one of the states:
+ // 1. Install request explicitly specified --staged, then value will be true.
+ // 2. Install request explicitly specified --non-staged, then value will be false.
+ // 3. Install request did not specify either --staged or --non-staged, then for APEX
+ // installs the value will be true, and for apk installs it will be false.
+ Boolean staged = null;
+
String opt;
boolean replaceExisting = true;
boolean forceNonStaged = false;
@@ -3151,7 +3157,6 @@ class PackageManagerShellCommand extends ShellCommand {
break;
case "--apex":
sessionParams.setInstallAsApex();
- sessionParams.setStaged();
break;
case "--force-non-staged":
forceNonStaged = true;
@@ -3160,7 +3165,10 @@ class PackageManagerShellCommand extends ShellCommand {
sessionParams.setMultiPackage();
break;
case "--staged":
- sessionParams.setStaged();
+ staged = true;
+ break;
+ case "--non-staged":
+ staged = false;
break;
case "--force-queryable":
sessionParams.setForceQueryable();
@@ -3192,11 +3200,17 @@ class PackageManagerShellCommand extends ShellCommand {
throw new IllegalArgumentException("Unknown option " + opt);
}
}
+ if (staged == null) {
+ staged = (sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
+ }
if (replaceExisting) {
sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
}
if (forceNonStaged) {
sessionParams.isStaged = false;
+ sessionParams.installFlags |= PackageManager.INSTALL_FORCE_NON_STAGED_APEX_UPDATE;
+ } else if (staged) {
+ sessionParams.setStaged();
}
return params;
}
@@ -3978,7 +3992,8 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" [--preload] [--instant] [--full] [--dont-kill]");
pw.println(" [--enable-rollback]");
pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
- pw.println(" [--apex] [--force-non-staged] [--staged-ready-timeout TIMEOUT]");
+ pw.println(" [--apex] [--non-staged] [--force-non-staged]");
+ pw.println(" [--staged-ready-timeout TIMEOUT]");
pw.println(" [PATH [SPLIT...]|-]");
pw.println(" Install an application. Must provide the apk data to install, either as");
pw.println(" file path(s) or '-' to read from stdin. Options are:");
@@ -4006,6 +4021,9 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" 3=device setup, 4=user request");
pw.println(" --force-uuid: force install on to disk volume with given UUID");
pw.println(" --apex: install an .apex file, not an .apk");
+ pw.println(" --non-staged: explicitly set this installation to be non-staged.");
+ pw.println(" This flag is only useful for APEX installs that are implicitly");
+ pw.println(" assumed to be staged.");
pw.println(" --force-non-staged: force the installation to run under a non-staged");
pw.println(" session, which may complete without requiring a reboot");
pw.println(" --staged-ready-timeout: By default, staged sessions wait "
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index ca4a32f553ae..099c9ae33bfb 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -16,9 +16,6 @@
package com.android.server.vcn;
-import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
-import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
-import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
@@ -48,7 +45,6 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.vcn.util.PersistableBundleUtils;
import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
import java.util.ArrayList;
@@ -109,6 +105,12 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
@NonNull private TelephonySubscriptionSnapshot mCurrentSnapshot;
+ @NonNull
+ private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+ (int logicalSlotIndex, int subscriptionId, int carrierId, int specificCarrierId) ->
+ handleActionCarrierConfigChanged(logicalSlotIndex, subscriptionId);
+
+
public TelephonySubscriptionTracker(
@NonNull Context context,
@NonNull Handler handler,
@@ -149,13 +151,14 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
public void register() {
final HandlerExecutor executor = new HandlerExecutor(mHandler);
final IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED);
mContext.registerReceiver(this, filter, null, mHandler);
mSubscriptionManager.addOnSubscriptionsChangedListener(
executor, mSubscriptionChangedListener);
mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
+ mCarrierConfigManager.registerCarrierConfigChangeListener(executor,
+ mCarrierConfigChangeListener);
registerCarrierPrivilegesCallbacks();
}
@@ -197,6 +200,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
mContext.unregisterReceiver(this);
mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener);
+ mCarrierConfigManager.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
unregisterCarrierPrivilegesCallbacks();
}
@@ -273,7 +277,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
}
/**
- * Broadcast receiver for ACTION_CARRIER_CONFIG_CHANGED
+ * Broadcast receiver for ACTION_MULTI_SIM_CONFIG_CHANGED
*
* <p>The broadcast receiver is registered with mHandler, so callbacks & broadcasts are all
* serialized on mHandler, avoiding the need for locking.
@@ -281,9 +285,6 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
- case ACTION_CARRIER_CONFIG_CHANGED:
- handleActionCarrierConfigChanged(context, intent);
- break;
case ACTION_MULTI_SIM_CONFIG_CHANGED:
handleActionMultiSimConfigChanged(context, intent);
break;
@@ -310,26 +311,21 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
handleSubscriptionsChanged();
}
- private void handleActionCarrierConfigChanged(Context context, Intent intent) {
- // Accept sticky broadcasts; if CARRIER_CONFIG_CHANGED was previously broadcast and it
- // already was for an identified carrier, we can stop waiting for initial load to complete
- final int subId = intent.getIntExtra(EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID);
- final int slotId = intent.getIntExtra(EXTRA_SLOT_INDEX, INVALID_SIM_SLOT_INDEX);
-
+ private void handleActionCarrierConfigChanged(int slotId, int subId) {
if (slotId == INVALID_SIM_SLOT_INDEX) {
return;
}
if (SubscriptionManager.isValidSubscriptionId(subId)) {
- final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
+ // Get only configs as needed to save memory.
+ final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId,
+ VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) {
mReadySubIdsBySlotId.put(slotId, subId);
- final PersistableBundle minimized =
- PersistableBundleUtils.minimizeBundle(
- carrierConfig, VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
- if (minimized != null) {
- mSubIdToCarrierConfigMap.put(subId, new PersistableBundleWrapper(minimized));
+ if (!carrierConfig.isEmpty()) {
+ mSubIdToCarrierConfigMap.put(subId,
+ new PersistableBundleWrapper(carrierConfig));
}
handleSubscriptionsChanged();
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index ab292ab5381e..872e438c6b8d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -19,6 +19,7 @@ package com.android.server.pm;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
@@ -362,7 +363,7 @@ public class ApexManagerTest {
File apex = extractResource("test.apex_rebootless_v1", "test.rebootless_apex_v1.apex");
PackageManagerException e = expectThrows(PackageManagerException.class,
- () -> mApexManager.installPackage(apex, mPackageParser2));
+ () -> mApexManager.installPackage(apex, mPackageParser2, /* force= */ false));
assertThat(e).hasMessageThat().contains("It is forbidden to install new APEX packages");
}
@@ -378,10 +379,11 @@ public class ApexManagerTest {
File finalApex = extractResource("test.rebootles_apex_v2", "test.rebootless_apex_v2.apex");
ApexInfo newApexInfo = createApexInfo("test.apex_rebootless", 2, /* isActive= */ true,
/* isFactory= */ false, finalApex);
- when(mApexService.installAndActivatePackage(anyString())).thenReturn(newApexInfo);
+ when(mApexService.installAndActivatePackage(anyString(), anyBoolean())).thenReturn(
+ newApexInfo);
File installedApex = extractResource("installed", "test.rebootless_apex_v2.apex");
- mApexManager.installPackage(installedApex, mPackageParser2);
+ mApexManager.installPackage(installedApex, mPackageParser2, /* force= */ false);
PackageInfo newInfo = mApexManager.getPackageInfo("test.apex.rebootless",
ApexManager.MATCH_ACTIVE_PACKAGE);
@@ -416,10 +418,11 @@ public class ApexManagerTest {
File finalApex = extractResource("test.rebootles_apex_v2", "test.rebootless_apex_v2.apex");
ApexInfo newApexInfo = createApexInfo("test.apex_rebootless", 2, /* isActive= */ true,
/* isFactory= */ false, finalApex);
- when(mApexService.installAndActivatePackage(anyString())).thenReturn(newApexInfo);
+ when(mApexService.installAndActivatePackage(anyString(), anyBoolean())).thenReturn(
+ newApexInfo);
File installedApex = extractResource("installed", "test.rebootless_apex_v2.apex");
- mApexManager.installPackage(installedApex, mPackageParser2);
+ mApexManager.installPackage(installedApex, mPackageParser2, /* force= */ false);
PackageInfo newInfo = mApexManager.getPackageInfo("test.apex.rebootless",
ApexManager.MATCH_ACTIVE_PACKAGE);
@@ -447,13 +450,14 @@ public class ApexManagerTest {
mApexManager.scanApexPackagesTraced(mPackageParser2,
ParallelPackageParser.makeExecutorService());
- when(mApexService.installAndActivatePackage(anyString())).thenThrow(
+ when(mApexService.installAndActivatePackage(anyString(), anyBoolean())).thenThrow(
new RuntimeException("install failed :("));
File installedApex = extractResource("test.apex_rebootless_v1",
"test.rebootless_apex_v1.apex");
assertThrows(PackageManagerException.class,
- () -> mApexManager.installPackage(installedApex, mPackageParser2));
+ () -> mApexManager.installPackage(installedApex, mPackageParser2, /* force= */
+ false));
}
@Test
@@ -468,7 +472,8 @@ public class ApexManagerTest {
File installedApex = extractResource("shim_different_certificate",
"com.android.apex.cts.shim.v2_different_certificate.apex");
PackageManagerException e = expectThrows(PackageManagerException.class,
- () -> mApexManager.installPackage(installedApex, mPackageParser2));
+ () -> mApexManager.installPackage(installedApex, mPackageParser2, /* force= */
+ false));
assertThat(e).hasMessageThat().contains("APK container signature of ");
assertThat(e).hasMessageThat().contains(
"is not compatible with currently installed on device");
@@ -486,7 +491,8 @@ public class ApexManagerTest {
File installedApex = extractResource("shim_unsigned_apk_container",
"com.android.apex.cts.shim.v2_unsigned_apk_container.apex");
PackageManagerException e = expectThrows(PackageManagerException.class,
- () -> mApexManager.installPackage(installedApex, mPackageParser2));
+ () -> mApexManager.installPackage(installedApex, mPackageParser2, /* force= */
+ false));
assertThat(e).hasMessageThat().contains("Failed to collect certificates from ");
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 59a5b7ea7847..96dc44a5f9fa 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -3628,17 +3628,10 @@ public class SubscriptionManager {
}
/**
- * Enables or disables a subscription. This is currently used in the settings page. It will
- * fail and return false if operation is not supported or failed.
+ * Enable or disable a subscription. This method is same as
+ * {@link #setUiccApplicationsEnabled(int, boolean)}.
*
- * To disable an active subscription on a physical (non-Euicc) SIM,
- * {@link #canDisablePhysicalSubscription} needs to be true.
- *
- * <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 subscriptionId Subscription to be enabled or disabled.
* @param enable whether user is turning it on or off.
*
* @return whether the operation is successful.
@@ -3648,19 +3641,15 @@ public class SubscriptionManager {
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
- if (VDBG) {
- logd("setSubscriptionActivated subId= " + subscriptionId + " enable " + enable);
- }
try {
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
- return iSub.setSubscriptionEnabled(enable, subscriptionId);
+ iSub.setUiccApplicationsEnabled(enable, subscriptionId);
}
} catch (RemoteException ex) {
- // ignore it
+ return false;
}
-
- return false;
+ return true;
}
/**
@@ -3683,11 +3672,7 @@ public class SubscriptionManager {
logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
}
try {
- ISub iSub = ISub.Stub.asInterface(
- TelephonyFrameworkInitializer
- .getTelephonyServiceManager()
- .getSubscriptionServiceRegisterer()
- .get());
+ ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
}
@@ -3715,11 +3700,7 @@ public class SubscriptionManager {
logd("canDisablePhysicalSubscription");
}
try {
- ISub iSub = ISub.Stub.asInterface(
- TelephonyFrameworkInitializer
- .getTelephonyServiceManager()
- .getSubscriptionServiceRegisterer()
- .get());
+ ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
return iSub.canDisablePhysicalSubscription();
}
@@ -3843,10 +3824,15 @@ public class SubscriptionManager {
}
/**
- * DO NOT USE.
- * This API is designed for features that are not finished at this point. Do not call this API.
+ * Get the active subscription id by logical SIM slot index.
+ *
+ * @param slotIndex The logical SIM slot index.
+ * @return The active subscription id.
+ *
+ * @throws IllegalArgumentException if the provided slot index is invalid.
+ * @throws SecurityException if callers do not hold the required permission.
+ *
* @hide
- * TODO b/135547512: further clean up
*/
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 632a6874b5f5..6a5380ddb36e 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -265,8 +265,6 @@ interface ISub {
String getSubscriptionProperty(int subId, String propKey, String callingPackage,
String callingFeatureId);
- boolean setSubscriptionEnabled(boolean enable, int subId);
-
boolean isSubscriptionEnabled(int subId);
int getEnabledSubscriptionId(int slotIndex);
@@ -277,7 +275,7 @@ interface ISub {
boolean canDisablePhysicalSubscription();
- int setUiccApplicationsEnabled(boolean enabled, int subscriptionId);
+ void setUiccApplicationsEnabled(boolean enabled, int subscriptionId);
int setDeviceToDeviceStatusSharing(int sharing, int subId);
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 965b073ff0db..34f884b94296 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -19,9 +19,6 @@ package com.android.server.vcn;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
-import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
-import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
-import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
@@ -143,6 +140,8 @@ public class TelephonySubscriptionTrackerTest {
@NonNull private TelephonySubscriptionTrackerCallback mCallback;
@NonNull private TelephonySubscriptionTracker mTelephonySubscriptionTracker;
+ @NonNull private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
+
public TelephonySubscriptionTrackerTest() {
mContext = mock(Context.class);
mTestLooper = new TestLooper();
@@ -173,7 +172,7 @@ public class TelephonySubscriptionTrackerTest {
.getSystemService(Context.CARRIER_CONFIG_SERVICE);
doReturn(TEST_CARRIER_CONFIG)
.when(mCarrierConfigManager)
- .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
+ .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1), any());
// subId 1, 2 are in same subGrp, only subId 1 is active
doReturn(TEST_PARCEL_UUID).when(TEST_SUBINFO_1).getGroupUuid();
@@ -189,9 +188,15 @@ public class TelephonySubscriptionTrackerTest {
doReturn(2).when(mTelephonyManager).getActiveModemCount();
mCallback = mock(TelephonySubscriptionTrackerCallback.class);
+ // Capture CarrierConfigChangeListener to emulate the carrier config change notification
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
mTelephonySubscriptionTracker =
new TelephonySubscriptionTracker(mContext, mHandler, mCallback, mDeps);
mTelephonySubscriptionTracker.register();
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+ listenerArgumentCaptor.capture());
+ mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
doReturn(true).when(mDeps).isConfigForIdentifiedCarrier(any());
doReturn(Arrays.asList(TEST_SUBINFO_1, TEST_SUBINFO_2))
@@ -239,14 +244,11 @@ public class TelephonySubscriptionTrackerTest {
return intent;
}
- private Intent buildTestBroadcastIntent(boolean hasValidSubscription) {
- Intent intent = new Intent(ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(EXTRA_SLOT_INDEX, TEST_SIM_SLOT_INDEX);
- intent.putExtra(
- EXTRA_SUBSCRIPTION_INDEX,
- hasValidSubscription ? TEST_SUBSCRIPTION_ID_1 : INVALID_SUBSCRIPTION_ID);
-
- return intent;
+ private void sendCarrierConfigChange(boolean hasValidSubscription) {
+ mCarrierConfigChangeListener.onCarrierConfigChanged(
+ TEST_SIM_SLOT_INDEX,
+ hasValidSubscription ? TEST_SUBSCRIPTION_ID_1 : INVALID_SUBSCRIPTION_ID,
+ TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
}
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
@@ -302,14 +304,15 @@ public class TelephonySubscriptionTrackerTest {
any(),
eq(mHandler));
final IntentFilter filter = getIntentFilter();
- assertEquals(2, filter.countActions());
- assertTrue(filter.hasAction(ACTION_CARRIER_CONFIG_CHANGED));
+ assertEquals(1, filter.countActions());
assertTrue(filter.hasAction(ACTION_MULTI_SIM_CONFIG_CHANGED));
verify(mSubscriptionManager)
.addOnSubscriptionsChangedListener(any(HandlerExecutor.class), any());
assertNotNull(getOnSubscriptionsChangedListener());
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(), any());
+
verify(mTelephonyManager, times(2))
.registerCarrierPrivilegesCallback(anyInt(), any(HandlerExecutor.class), any());
verify(mTelephonyManager)
@@ -442,7 +445,7 @@ public class TelephonySubscriptionTrackerTest {
@Test
public void testReceiveBroadcast_ConfigReadyWithSubscriptions() throws Exception {
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
@@ -454,7 +457,7 @@ public class TelephonySubscriptionTrackerTest {
.when(mSubscriptionManager)
.getAllSubscriptionInfoList();
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
// Expect an empty snapshot
@@ -465,7 +468,7 @@ public class TelephonySubscriptionTrackerTest {
public void testReceiveBroadcast_SlotCleared() throws Exception {
setupReadySubIds();
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
+ sendCarrierConfigChange(false /* hasValidSubscription */);
mTestLooper.dispatchAll();
verifyNoActiveSubscriptions();
@@ -476,7 +479,7 @@ public class TelephonySubscriptionTrackerTest {
public void testReceiveBroadcast_ConfigNotReady() throws Exception {
doReturn(false).when(mDeps).isConfigForIdentifiedCarrier(any());
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
// No interactions expected; config was not loaded
@@ -485,21 +488,21 @@ public class TelephonySubscriptionTrackerTest {
@Test
public void testSubscriptionsClearedAfterValidTriggersCallbacks() throws Exception {
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
assertNotNull(
mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
doReturn(Collections.emptyList()).when(mSubscriptionManager).getAllSubscriptionInfoList();
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(emptyMap(), emptyMap())));
}
@Test
public void testCarrierConfigUpdatedAfterValidTriggersCallbacks() throws Exception {
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
reset(mCallback);
@@ -510,12 +513,12 @@ public class TelephonySubscriptionTrackerTest {
new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR});
doReturn(updatedConfig)
.when(mCarrierConfigManager)
- .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
+ .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1), any());
Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>();
subIdToCarrierConfigMap.put(
TEST_SUBSCRIPTION_ID_1, new PersistableBundleWrapper(updatedConfig));
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback)
@@ -530,13 +533,13 @@ public class TelephonySubscriptionTrackerTest {
@Test
public void testSlotClearedAfterValidTriggersCallbacks() throws Exception {
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+ sendCarrierConfigChange(true /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
assertNotNull(
mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
- mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
+ sendCarrierConfigChange(false /* hasValidSubscription */);
mTestLooper.dispatchAll();
verify(mCallback)
.onNewSnapshot(