Merge "Make sure to send HOVER_EXIT when starting touch exploration if we haven't sent it already." into main
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 9b16949..c8dbfc9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -53,6 +53,7 @@
import android.graphics.drawable.DrawableInflater;
import android.os.Build;
import android.os.Bundle;
+import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -132,6 +133,11 @@
private static final Object sSync = new Object();
private final Object mUpdateLock = new Object();
+ /**
+ * Controls whether we should preload resources during zygote init.
+ */
+ private static final boolean PRELOAD_RESOURCES = true;
+
// Used by BridgeResources in layoutlib
@UnsupportedAppUsage
static Resources mSystem = null;
@@ -2666,6 +2672,98 @@
}
}
+ /**
+ * Load in commonly used resources, so they can be shared across processes.
+ *
+ * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
+ * larger.
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public static void preloadResources() {
+ try {
+ final Resources sysRes = Resources.getSystem();
+ sysRes.startPreloading();
+ if (PRELOAD_RESOURCES) {
+ Log.i(TAG, "Preloading resources...");
+
+ long startTime = SystemClock.uptimeMillis();
+ TypedArray ar = sysRes.obtainTypedArray(
+ com.android.internal.R.array.preloaded_drawables);
+ int numberOfEntries = preloadDrawables(sysRes, ar);
+ ar.recycle();
+ Log.i(TAG, "...preloaded " + numberOfEntries + " resources in "
+ + (SystemClock.uptimeMillis() - startTime) + "ms.");
+
+ startTime = SystemClock.uptimeMillis();
+ ar = sysRes.obtainTypedArray(
+ com.android.internal.R.array.preloaded_color_state_lists);
+ numberOfEntries = preloadColorStateLists(sysRes, ar);
+ ar.recycle();
+ Log.i(TAG, "...preloaded " + numberOfEntries + " resources in "
+ + (SystemClock.uptimeMillis() - startTime) + "ms.");
+
+ if (sysRes.getBoolean(
+ com.android.internal.R.bool.config_freeformWindowManagement)) {
+ startTime = SystemClock.uptimeMillis();
+ ar = sysRes.obtainTypedArray(
+ com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
+ numberOfEntries = preloadDrawables(sysRes, ar);
+ ar.recycle();
+ Log.i(TAG, "...preloaded " + numberOfEntries + " resource in "
+ + (SystemClock.uptimeMillis() - startTime) + "ms.");
+ }
+ }
+ sysRes.finishPreloading();
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Failure preloading resources", e);
+ }
+ }
+
+ private static int preloadColorStateLists(Resources resources, TypedArray ar) {
+ final int numberOfEntries = ar.length();
+ for (int i = 0; i < numberOfEntries; i++) {
+ int id = ar.getResourceId(i, 0);
+
+ if (id != 0) {
+ if (resources.getColorStateList(id, null) == null) {
+ throw new IllegalArgumentException(
+ "Unable to find preloaded color resource #0x"
+ + Integer.toHexString(id)
+ + " (" + ar.getString(i) + ")");
+ }
+ }
+ }
+ return numberOfEntries;
+ }
+
+ private static int preloadDrawables(Resources resources, TypedArray ar) {
+ final int numberOfEntries = ar.length();
+ for (int i = 0; i < numberOfEntries; i++) {
+ int id = ar.getResourceId(i, 0);
+
+ if (id != 0) {
+ if (resources.getDrawable(id, null) == null) {
+ throw new IllegalArgumentException(
+ "Unable to find preloaded drawable resource #0x"
+ + Integer.toHexString(id)
+ + " (" + ar.getString(i) + ")");
+ }
+ }
+ }
+ return numberOfEntries;
+ }
+
+ /**
+ * Clear the cache when the framework resources packages is changed.
+ * @hide
+ */
+ @VisibleForTesting
+ public static void resetPreloadDrawableStateCache() {
+ ResourcesImpl.resetDrawableStateCache();
+ preloadResources();
+ }
+
/** @hide */
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "class=" + getClass());
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 3bb237a..480e43e 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -52,6 +52,7 @@
import android.util.Xml;
import android.view.DisplayAdjustments;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.GrowingArrayUtils;
import libcore.util.NativeAllocationRegistry;
@@ -159,6 +160,23 @@
}
/**
+ * Clear the cache when the framework resources packages is changed.
+ *
+ * It's only used in the test initial function instead of regular app behaviors. It doesn't
+ * guarantee the thread-safety so mark this with @VisibleForTesting.
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ static void resetDrawableStateCache() {
+ synchronized (sSync) {
+ sPreloadedDrawables[0].clear();
+ sPreloadedDrawables[1].clear();
+ sPreloadedColorDrawables.clear();
+ sPreloadedComplexColors.clear();
+ sPreloaded = false;
+ }
+ }
+
+ /**
* Creates a new ResourcesImpl object with CompatibilityInfo.
*
* @param assets Previously created AssetManager.
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 5d0a723..3f04ca4 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -943,16 +943,19 @@
* @hide
*/
@VisibleForTesting
- public final @NonNull String getTransactionTraceName(int transactionCode) {
+ public final @Nullable String getTransactionTraceName(int transactionCode) {
+ final boolean isInterfaceUserDefined = getMaxTransactionId() == 0;
if (mTransactionTraceNames == null) {
- final int highestId = Math.min(getMaxTransactionId(), TRANSACTION_TRACE_NAME_ID_LIMIT);
+ final int highestId = isInterfaceUserDefined ? TRANSACTION_TRACE_NAME_ID_LIMIT
+ : Math.min(getMaxTransactionId(), TRANSACTION_TRACE_NAME_ID_LIMIT);
mSimpleDescriptor = getSimpleDescriptor();
mTransactionTraceNames = new AtomicReferenceArray(highestId + 1);
}
- final int index = transactionCode - FIRST_CALL_TRANSACTION;
- if (index < 0 || index >= mTransactionTraceNames.length()) {
- return mSimpleDescriptor + "#" + transactionCode;
+ final int index = isInterfaceUserDefined
+ ? transactionCode : transactionCode - FIRST_CALL_TRANSACTION;
+ if (index >= mTransactionTraceNames.length() || index < 0) {
+ return null;
}
String transactionTraceName = mTransactionTraceNames.getAcquire(index);
@@ -1317,19 +1320,9 @@
final boolean hasFullyQualifiedName = getMaxTransactionId() > 0;
final String transactionTraceName;
- if (tagEnabled && hasFullyQualifiedName) {
+ if (tagEnabled) {
// If tracing enabled and we have a fully qualified name, fetch the name
transactionTraceName = getTransactionTraceName(code);
- } else if (tagEnabled && isStackTrackingEnabled()) {
- // If tracing is enabled and we *don't* have a fully qualified name, fetch the
- // 'best effort' name only for stack tracking. This works around noticeable perf impact
- // on low latency binder calls (<100us). The tracing call itself is between (1-10us) and
- // the perf impact can be quite noticeable while benchmarking such binder calls.
- // The primary culprits are ContentProviders and Cursors which convenienty don't
- // autogenerate their AIDL and hence will not have a fully qualified name.
- //
- // TODO(b/253426478): Relax this constraint after a more robust fix
- transactionTraceName = getTransactionTraceName(code);
} else {
transactionTraceName = null;
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 85cb15b..b3938b4 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -26,7 +26,6 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.SharedLibraryInfo;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.os.Build;
import android.os.Environment;
import android.os.IInstalld;
@@ -102,21 +101,10 @@
private static final String SOCKET_NAME_ARG = "--socket-name=";
/**
- * Used to pre-load resources.
- */
- @UnsupportedAppUsage
- private static Resources mResources;
-
- /**
* The path of a file that contains classes to preload.
*/
private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
- /**
- * Controls whether we should preload resources during zygote init.
- */
- private static final boolean PRELOAD_RESOURCES = true;
-
private static final int UNPRIVILEGED_UID = 9999;
private static final int UNPRIVILEGED_GID = 9999;
@@ -143,7 +131,7 @@
cacheNonBootClasspathClassLoaders();
bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
bootTimingsTraceLog.traceBegin("PreloadResources");
- preloadResources();
+ Resources.preloadResources();
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
nativePreloadAppProcessHALs();
@@ -414,87 +402,6 @@
}
/**
- * Load in commonly used resources, so they can be shared across processes.
- *
- * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
- * larger.
- */
- private static void preloadResources() {
- try {
- mResources = Resources.getSystem();
- mResources.startPreloading();
- if (PRELOAD_RESOURCES) {
- Log.i(TAG, "Preloading resources...");
-
- long startTime = SystemClock.uptimeMillis();
- TypedArray ar = mResources.obtainTypedArray(
- com.android.internal.R.array.preloaded_drawables);
- int N = preloadDrawables(ar);
- ar.recycle();
- Log.i(TAG, "...preloaded " + N + " resources in "
- + (SystemClock.uptimeMillis() - startTime) + "ms.");
-
- startTime = SystemClock.uptimeMillis();
- ar = mResources.obtainTypedArray(
- com.android.internal.R.array.preloaded_color_state_lists);
- N = preloadColorStateLists(ar);
- ar.recycle();
- Log.i(TAG, "...preloaded " + N + " resources in "
- + (SystemClock.uptimeMillis() - startTime) + "ms.");
-
- if (mResources.getBoolean(
- com.android.internal.R.bool.config_freeformWindowManagement)) {
- startTime = SystemClock.uptimeMillis();
- ar = mResources.obtainTypedArray(
- com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
- N = preloadDrawables(ar);
- ar.recycle();
- Log.i(TAG, "...preloaded " + N + " resource in "
- + (SystemClock.uptimeMillis() - startTime) + "ms.");
- }
- }
- mResources.finishPreloading();
- } catch (RuntimeException e) {
- Log.w(TAG, "Failure preloading resources", e);
- }
- }
-
- private static int preloadColorStateLists(TypedArray ar) {
- int N = ar.length();
- for (int i = 0; i < N; i++) {
- int id = ar.getResourceId(i, 0);
-
- if (id != 0) {
- if (mResources.getColorStateList(id, null) == null) {
- throw new IllegalArgumentException(
- "Unable to find preloaded color resource #0x"
- + Integer.toHexString(id)
- + " (" + ar.getString(i) + ")");
- }
- }
- }
- return N;
- }
-
-
- private static int preloadDrawables(TypedArray ar) {
- int N = ar.length();
- for (int i = 0; i < N; i++) {
- int id = ar.getResourceId(i, 0);
-
- if (id != 0) {
- if (mResources.getDrawable(id, null) == null) {
- throw new IllegalArgumentException(
- "Unable to find preloaded drawable resource #0x"
- + Integer.toHexString(id)
- + " (" + ar.getString(i) + ")");
- }
- }
- }
- return N;
- }
-
- /**
* Runs several special GCs to try to clean up a few generations of softly- and final-reachable
* objects, along with any other garbage. This is only useful just before a fork().
*/
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index c198797..9dce5e3 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -40,7 +40,6 @@
#include <binder/Stability.h>
#include <binderthreadstate/CallerUtils.h>
#include <cutils/atomic.h>
-#include <cutils/threads.h>
#include <log/log.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
diff --git a/core/tests/coretests/src/android/os/AidlTest.java b/core/tests/coretests/src/android/os/AidlTest.java
index 5f54b09..d0c3470 100644
--- a/core/tests/coretests/src/android/os/AidlTest.java
+++ b/core/tests/coretests/src/android/os/AidlTest.java
@@ -28,12 +28,14 @@
private IAidlTest mRemote;
private AidlObject mLocal;
+ private NonAutoGeneratedObject mNonAutoGenerated;
@Override
protected void setUp() throws Exception {
super.setUp();
mLocal = new AidlObject();
mRemote = IAidlTest.Stub.asInterface(mLocal);
+ mNonAutoGenerated = new NonAutoGeneratedObject("NonAutoGeneratedObject");
}
private static boolean check(TestParcelable p, int n, String s) {
@@ -84,6 +86,12 @@
}
}
+ private static class NonAutoGeneratedObject extends Binder {
+ NonAutoGeneratedObject(String descriptor) {
+ super(descriptor);
+ }
+ }
+
private static class AidlObject extends IAidlTest.Stub {
public IInterface queryLocalInterface(String descriptor) {
// overriding this to return null makes asInterface always
@@ -194,7 +202,7 @@
TestParcelable[] a1, TestParcelable[] a2) {
return null;
}
-
+
public void voidSecurityException() {
throw new SecurityException("gotcha!");
}
@@ -396,7 +404,7 @@
assertEquals("s2[1]", s2[1]);
assertEquals("s2[2]", s2[2]);
}
-
+
@SmallTest
public void testVoidSecurityException() throws Exception {
boolean good = false;
@@ -407,7 +415,7 @@
}
assertEquals(good, true);
}
-
+
@SmallTest
public void testIntSecurityException() throws Exception {
boolean good = false;
@@ -420,7 +428,7 @@
}
@SmallTest
- public void testGetTransactionName() throws Exception {
+ public void testGetTransactionNameAutoGenerated() throws Exception {
assertEquals(15, mLocal.getMaxTransactionId());
assertEquals("booleanArray",
@@ -430,12 +438,21 @@
assertEquals("parcelableIn",
mLocal.getTransactionName(IAidlTest.Stub.TRANSACTION_parcelableIn));
- assertEquals("IAidlTest:booleanArray",
+ assertEquals("AIDL::java::IAidlTest::booleanArray::server",
mLocal.getTransactionTraceName(IAidlTest.Stub.TRANSACTION_booleanArray));
- assertEquals("IAidlTest:voidSecurityException",
+ assertEquals("AIDL::java::IAidlTest::voidSecurityException::server",
mLocal.getTransactionTraceName(IAidlTest.Stub.TRANSACTION_voidSecurityException));
- assertEquals("IAidlTest:parcelableIn",
+ assertEquals("AIDL::java::IAidlTest::parcelableIn::server",
mLocal.getTransactionTraceName(IAidlTest.Stub.TRANSACTION_parcelableIn));
}
-}
+ @SmallTest
+ public void testGetTransactionNameNonAutoGenerated() throws Exception {
+ assertEquals(0, mNonAutoGenerated.getMaxTransactionId());
+
+ assertEquals("AIDL::java::NonAutoGeneratedObject::#0::server",
+ mNonAutoGenerated.getTransactionTraceName(0));
+ assertEquals("AIDL::java::NonAutoGeneratedObject::#1::server",
+ mNonAutoGenerated.getTransactionTraceName(1));
+ }
+}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index b83ab38..4c234a0 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3449,8 +3449,14 @@
hdmiClient = mHdmiTvClient;
}
- if (((mHdmiPlaybackClient != null && isFullVolumeDevice(device))
- || (mHdmiTvClient != null && mHdmiSystemAudioSupported))
+ boolean playbackDeviceConditions = mHdmiPlaybackClient != null
+ && isFullVolumeDevice(device);
+ boolean tvConditions = mHdmiTvClient != null
+ && mHdmiSystemAudioSupported
+ && !isAbsoluteVolumeDevice(device)
+ && !isA2dpAbsoluteVolumeDevice(device);
+
+ if ((playbackDeviceConditions || tvConditions)
&& mHdmiCecVolumeControlEnabled
&& streamTypeAlias == AudioSystem.STREAM_MUSIC) {
int keyCode = KeyEvent.KEYCODE_UNKNOWN;
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index c0e191f..5a941fe 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -80,6 +80,8 @@
// Append targetSdkVersion=n to existing seinfo label where n is the app's targetSdkVersion
private static final String TARGETSDKVERSION_STR = ":targetSdkVersion=";
+ private static final String PARTITION_STR = ":partition=";
+
/**
* Allows opt-in to the latest targetSdkVersion enforced changes without changing target SDK.
* Turning this change on for an app targeting the latest SDK or higher is a no-op.
@@ -370,6 +372,23 @@
return pkg.getTargetSdkVersion();
}
+ private static String getPartition(AndroidPackage pkg) {
+ if (pkg.isSystemExt()) {
+ return "system_ext";
+ } else if (pkg.isProduct()) {
+ return "product";
+ } else if (pkg.isVendor()) {
+ return "vendor";
+ } else if (pkg.isOem()) {
+ return "oem";
+ } else if (pkg.isOdm()) {
+ return "odm";
+ } else if (pkg.isSystem()) {
+ return "system";
+ }
+ return "";
+ }
+
/**
* Selects a security label to a package based on input parameters and the seinfo tag taken
* from a matched policy. All signature based policy stanzas are consulted and, if no match
@@ -433,6 +452,11 @@
seInfo += TARGETSDKVERSION_STR + targetSdkVersion;
+ String partition = getPartition(pkg);
+ if (!partition.isEmpty()) {
+ seInfo += PARTITION_STR + partition;
+ }
+
if (DEBUG_POLICY_INSTALL) {
Slog.i(TAG, "package (" + pkg.getPackageName() + ") labeled with "
+ "seinfo=" + seInfo);
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 9ed5aa7..5221cfa 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2116,6 +2116,12 @@
if (!isStorageOrMedia) {
continue;
}
+ boolean isSystemOrPolicyFixed = (getPermissionFlags(newPackage.getPackageName(),
+ permInfo.name, userId) & (FLAG_PERMISSION_SYSTEM_FIXED
+ | FLAG_PERMISSION_POLICY_FIXED)) != 0;
+ if (isSystemOrPolicyFixed) {
+ continue;
+ }
EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(),
"Revoking permission " + permInfo.name + " from package "
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index d947168..15bc60c 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1089,21 +1089,13 @@
}
final int otherWindowingMode = other.getWindowingMode();
- if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN) {
- if (isTranslucent(other, starting)) {
- // Can be visible behind a translucent fullscreen TaskFragment.
- gotTranslucentFullscreen = true;
- continue;
- }
- return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
- } else if (otherWindowingMode == WINDOWING_MODE_MULTI_WINDOW
- && other.matchParentBounds()) {
+ if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN
+ || (otherWindowingMode != WINDOWING_MODE_PINNED && other.matchParentBounds())) {
if (isTranslucent(other, starting)) {
// Can be visible behind a translucent TaskFragment.
gotTranslucentFullscreen = true;
continue;
}
- // Multi-window TaskFragment that matches parent bounds would occlude other children
return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 45c092e..59a5b7e 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -174,7 +174,7 @@
/**
* Key to the backup & restore data byte array in the Bundle that is returned by {@link
* #getAllSimSpecificSettingsForBackup()} or to be pass in to {@link
- * #restoreAllSimSpecificSettings()}.
+ * #restoreAllSimSpecificSettingsFromBackup(byte[])}.
*
* @hide
*/
@@ -2218,46 +2218,46 @@
}
/**
- * Get an array of subscription ids for specified logical SIM slot Index.
+ * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
+ * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
+ * which is not possible in the current Android telephony architecture.
*
* @param slotIndex The logical SIM slot index.
*
- * @return subscription Ids or {@code null} if the given slot index is not valid or there are
- * no active subscription in the slot. In the implementation today, there will be no more
- * than one subscriptions per logical SIM slot.
+ * @return Subscription id of the active subscription on the specified logical SIM slot index.
+ * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
+ * be returned. {@code null} if the provided {@code slotIndex} is not valid.
*
* @deprecated Use {@link #getSubscriptionId(int)} instead.
*/
@Deprecated
@Nullable
public int[] getSubscriptionIds(int slotIndex) {
- int subId = getSubscriptionId(slotIndex);
- if (!isValidSubscriptionId(subId)) {
+ if (!isValidSlotIndex(slotIndex)) {
return null;
}
return new int[]{getSubscriptionId(slotIndex)};
}
- /** @hide */
- @UnsupportedAppUsage
+ /**
+ * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
+ * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
+ * which is not possible in the current Android telephony architecture.
+ *
+ * @param slotIndex The logical SIM slot index.
+ *
+ * @return Subscription id of the active subscription on the specified logical SIM slot index.
+ * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
+ * be returned. {@code null} if the provided {@code slotIndex} is not valid.
+ *
+ * @deprecated Use {@link #getSubscriptionId(int)} instead.
+ * @hide
+ */
public static int[] getSubId(int slotIndex) {
if (!isValidSlotIndex(slotIndex)) {
- logd("[getSubId]- fail");
return null;
}
-
- int[] subId = null;
-
- try {
- ISub iSub = TelephonyManager.getSubscriptionService();
- if (iSub != null) {
- subId = iSub.getSubIds(slotIndex);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return subId;
+ return new int[]{getSubscriptionId(slotIndex)};
}
/**
@@ -4027,39 +4027,16 @@
}
/**
- * Called to attempt to restore the backed up sim-specific configs to device for specific sim.
- * This will try to restore the data that was stored internally when {@link
- * #restoreAllSimSpecificSettingsFromBackup(byte[] data)} was called during setup wizard.
- * End result is SimInfoDB is modified to match any backed up configs for the requested
- * inserted sim.
- *
- * <p>
- * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
- * entry is updated as the result of this method call.
- *
- * @param iccId of the sim that a restore is requested for.
- *
- * @hide
- */
- @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
- public void restoreSimSpecificSettingsForIccIdFromBackup(@NonNull String iccId) {
- mContext.getContentResolver().call(
- SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
- RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
- iccId, null);
- }
-
- /**
* Called during setup wizard restore flow to attempt to restore the backed up sim-specific
- * configs to device for all existing SIMs in SimInfoDB. Internally, it will store the backup
- * data in an internal file. This file will persist on device for device's lifetime and will be
- * used later on when a SIM is inserted to restore that specific SIM's settings by calling
- * {@link #restoreSimSpecificSettingsForIccIdFromBackup(String iccId)}. End result is
- * SimInfoDB is modified to match any backed up configs for the appropriate inserted SIMs.
+ * configs to device for all existing SIMs in the subscription database {@link SimInfo}.
+ * Internally, it will store the backup data in an internal file. This file will persist on
+ * device for device's lifetime and will be used later on when a SIM is inserted to restore that
+ * specific SIM's settings. End result is subscription database is modified to match any backed
+ * up configs for the appropriate inserted SIMs.
*
* <p>
- * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
- * entry is updated as the result of this method call.
+ * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
+ * {@link SimInfo} entry is updated as the result of this method call.
*
* @param data with the sim specific configs to be backed up.
*
@@ -4068,12 +4045,18 @@
@SystemApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
- Bundle bundle = new Bundle();
- bundle.putByteArray(KEY_SIM_SPECIFIC_SETTINGS_DATA, data);
- mContext.getContentResolver().call(
- SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
- RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
- null, bundle);
+ try {
+ ISub iSub = TelephonyManager.getSubscriptionService();
+ if (iSub != null) {
+ iSub.restoreAllSimSpecificSettingsFromBackup(data);
+ } else {
+ throw new IllegalStateException("subscription service unavailable.");
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
}
/**
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index defa046..632a687 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -236,8 +236,6 @@
int getSlotIndex(int subId);
- int[] getSubIds(int slotIndex);
-
int getSubId(int slotIndex);
int getDefaultSubId();
@@ -363,4 +361,20 @@
*/
//TODO: Removed before U AOSP public release.
boolean isSubscriptionManagerServiceEnabled();
+
+ /**
+ * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
+ * configs to device for all existing SIMs in the subscription database
+ * {@link Telephony.SimInfo}. Internally, it will store the backup data in an internal file.
+ * This file will persist on device for device's lifetime and will be used later on when a SIM
+ * is inserted to restore that specific SIM's settings. End result is subscription database is
+ * modified to match any backed up configs for the appropriate inserted SIMs.
+ *
+ * <p>
+ * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
+ * {@link Telephony.SimInfo} entry is updated as the result of this method call.
+ *
+ * @param data with the sim specific configs to be backed up.
+ */
+ void restoreAllSimSpecificSettingsFromBackup(in byte[] data);
}