Merge changes from topic "icu65.1-upgrade"
* changes:
Regenerate LocaleDataTables.cpp
Update API surface for ICU 65.1
diff --git a/Android.bp b/Android.bp
index 561166e..ec379379 100644
--- a/Android.bp
+++ b/Android.bp
@@ -460,6 +460,7 @@
installable: false, // this lib is a build-only library
static_libs: [
"framework-minus-apex",
+ "updatable_media_stubs",
"framework-sdkext-stubs-systemapi",
// TODO(jiyong): add more stubs for APEXes here
],
diff --git a/api/current.txt b/api/current.txt
index ab3cf97..ec9f2ee 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -99,6 +99,7 @@
field public static final String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
field public static final String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
field public static final String NFC = "android.permission.NFC";
+ field public static final String NFC_PREFERRED_PAYMENT_INFO = "android.permission.NFC_PREFERRED_PAYMENT_INFO";
field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
field public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
@@ -30712,6 +30713,7 @@
method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
+ field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED";
@@ -30720,6 +30722,7 @@
field public static final String EXTRA_DATA = "android.nfc.extra.DATA";
field public static final String EXTRA_ID = "android.nfc.extra.ID";
field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
+ field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
field public static final String EXTRA_TAG = "android.nfc.extra.TAG";
@@ -30730,6 +30733,9 @@
field public static final int FLAG_READER_NFC_V = 8; // 0x8
field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
+ field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2
+ field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1
+ field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3
field public static final int STATE_OFF = 1; // 0x1
field public static final int STATE_ON = 3; // 0x3
field public static final int STATE_TURNING_OFF = 4; // 0x4
@@ -30785,8 +30791,11 @@
public final class CardEmulation {
method public boolean categoryAllowsForegroundPreference(String);
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getDescriptionForPreferredPaymentService();
method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
method public int getSelectionModeForCategory(String);
method public boolean isDefaultServiceForAid(android.content.ComponentName, String);
method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
@@ -35020,11 +35029,12 @@
method public boolean isIgnoringBatteryOptimizations(String);
method public boolean isInteractive();
method public boolean isPowerSaveMode();
+ method public boolean isRebootingUserspaceSupported();
method @Deprecated public boolean isScreenOn();
method public boolean isSustainedPerformanceModeSupported();
method public boolean isWakeLockLevelSupported(int);
method public android.os.PowerManager.WakeLock newWakeLock(int, String);
- method public void reboot(String);
+ method public void reboot(@Nullable String);
method public void removeThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED";
@@ -44331,6 +44341,11 @@
field public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
+ public static final class CarrierConfigManager.Gps {
+ field public static final String KEY_PERSIST_LPP_MODE_BOOL = "gps.persist_lpp_mode_bool";
+ field public static final String KEY_PREFIX = "gps.";
+ }
+
public static final class CarrierConfigManager.Ims {
field public static final String KEY_PREFIX = "ims.";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 62c2d79..f2424e1 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1573,6 +1573,7 @@
field public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
field public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
field public static final String ACTION_DEVICE_CUSTOMIZATION_READY = "android.intent.action.DEVICE_CUSTOMIZATION_READY";
+ field public static final String ACTION_DIAL_EMERGENCY = "android.intent.action.DIAL_EMERGENCY";
field public static final String ACTION_FACTORY_RESET = "android.intent.action.FACTORY_RESET";
field public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
field public static final String ACTION_INCIDENT_REPORT_READY = "android.intent.action.INCIDENT_REPORT_READY";
@@ -5994,6 +5995,7 @@
method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int);
field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
+ field public static final String REBOOT_USERSPACE = "userspace";
field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
@@ -7839,6 +7841,7 @@
method public void addNewUnknownCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
method @Deprecated public void clearAccounts();
method public void clearPhoneAccounts();
+ method @NonNull public android.content.Intent createLaunchEmergencyDialerIntent(@Nullable String);
method @RequiresPermission(android.Manifest.permission.DUMP) public android.telecom.TelecomAnalytics dumpAnalytics();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean);
method public java.util.List<android.telecom.PhoneAccountHandle> getAllPhoneAccountHandles();
@@ -8445,6 +8448,24 @@
field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
}
+ public final class ModemActivityInfo implements android.os.Parcelable {
+ ctor public ModemActivityInfo(long, int, int, @NonNull int[], int);
+ method public int describeContents();
+ method public int getIdleTimeMillis();
+ method public int getReceiveTimeMillis();
+ method public int getSleepTimeMillis();
+ method public long getTimestamp();
+ method @NonNull public java.util.List<android.telephony.ModemActivityInfo.TransmitPower> getTransmitPowerInfo();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR;
+ field public static final int TX_POWER_LEVELS = 5; // 0x5
+ }
+
+ public class ModemActivityInfo.TransmitPower {
+ method @NonNull public android.util.Range<java.lang.Integer> getPowerRangeInDbm();
+ method public int getTimeInMillis();
+ }
+
public final class NetworkRegistrationInfo implements android.os.Parcelable {
method public int describeContents();
method public int getAccessNetworkTechnology();
diff --git a/cmds/incidentd/src/WorkDirectory.cpp b/cmds/incidentd/src/WorkDirectory.cpp
index 7e7c642..9963533 100644
--- a/cmds/incidentd/src/WorkDirectory.cpp
+++ b/cmds/incidentd/src/WorkDirectory.cpp
@@ -666,7 +666,7 @@
clock_gettime(CLOCK_REALTIME, &spec);
timestampNs = int64_t(spec.tv_sec) * 1000 + spec.tv_nsec;
} while (file_exists_locked(timestampNs));
- return timestampNs;
+ return (timestampNs >= 0)? timestampNs : -timestampNs;
}
/**
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 4440bf8..c923156 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -3957,7 +3957,7 @@
// rx time in ms at power level 5
optional uint64 controller_rx_time_millis = 9;
// product of current(mA), voltage(V) and time(ms)
- optional uint64 energy_used = 10;
+ optional uint64 energy_used = 10 [deprecated=true];
}
/**
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 9061ed1..1987440 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -25,8 +25,8 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import android.os.UserHandle;
+import android.sysprop.TelephonyProperties;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
@@ -35,7 +35,6 @@
import com.android.internal.os.BaseCommand;
import com.android.internal.telecom.ITelecomService;
-import com.android.internal.telephony.TelephonyProperties;
import java.io.PrintStream;
@@ -363,7 +362,7 @@
* "" (empty string) for a phone in SS mode
*/
private void runGetSimConfig() throws RemoteException {
- System.out.println(SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG));
+ System.out.println(TelephonyProperties.multi_sim_config().orElse(""));
}
private void runGetMaxPhones() throws RemoteException {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e9a4762..a6867ff 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1134,6 +1134,18 @@
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
/**
+ * Activity Action: Dial a emergency number specified by the data. This shows a
+ * UI with the number being dialed, allowing the user to explicitly
+ * initiate the call.
+ * <p>Input: If nothing, an empty emergency dialer is started; else {@link #getData}
+ * is a tel: URI of an explicit emergency phone number.
+ * <p>Output: nothing.
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_DIAL_EMERGENCY = "android.intent.action.DIAL_EMERGENCY";
+ /**
* Activity action: Perform a call to any number (emergency or not)
* specified by the data.
* <p>Input: {@link #getData} is URI of a phone number to be dialed or a
diff --git a/core/java/android/nfc/INfcCardEmulation.aidl b/core/java/android/nfc/INfcCardEmulation.aidl
index dd2c0d4..848b6d5 100644
--- a/core/java/android/nfc/INfcCardEmulation.aidl
+++ b/core/java/android/nfc/INfcCardEmulation.aidl
@@ -39,4 +39,5 @@
boolean setPreferredService(in ComponentName service);
boolean unsetPreferredService();
boolean supportsAidPrefixRegistration();
+ ApduServiceInfo getPreferredPaymentService(int userHandle);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index bc698f9..7ab984f 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -151,7 +151,7 @@
public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
/**
- * Broadcast Action: Intent to notify an application that an transaction event has occurred
+ * Broadcast Action: Intent to notify an application that a transaction event has occurred
* on the Secure Element.
*
* <p>This intent will only be sent if the application has requested permission for
@@ -164,6 +164,18 @@
"android.nfc.action.TRANSACTION_DETECTED";
/**
+ * Broadcast Action: Intent to notify if the preferred payment service changed.
+ *
+ * <p>This intent will only be sent to the application has requested permission for
+ * {@link android.Manifest.permission#NFC_PREFERRED_PAYMENT_INFO} and if the application
+ * has the necessary access to Secure Element which witnessed the particular event.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PREFERRED_PAYMENT_CHANGED =
+ "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
+
+ /**
* Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
* @hide
*/
@@ -231,6 +243,17 @@
*/
public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
+ /**
+ * Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
+ * Indicates the condition when trigger this event.
+ */
+ public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
+ "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
+
+ public static final int PREFERRED_PAYMENT_LOADED = 1;
+ public static final int PREFERRED_PAYMENT_CHANGED = 2;
+ public static final int PREFERRED_PAYMENT_UPDATED = 3;
+
public static final int STATE_OFF = 1;
public static final int STATE_TURNING_ON = 2;
public static final int STATE_ON = 3;
@@ -1410,7 +1433,7 @@
/**
* Enable foreground dispatch to the given Activity.
*
- * <p>This will give give priority to the foreground activity when
+ * <p>This will give priority to the foreground activity when
* dispatching a discovered {@link Tag} to an application.
*
* <p>If any IntentFilters are provided to this method they are used to match dispatch Intents
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index aa93611..f1c74a6 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -17,6 +17,7 @@
package android.nfc.cardemulation;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -657,6 +658,109 @@
}
/**
+ * Retrieves the registered AIDs for the preferred payment service.
+ *
+ * @return The list of AIDs registered for this category, or null if it couldn't be found.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @Nullable
+ public List<String> getAidsForPreferredPaymentService() {
+ try {
+ ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getAids() : null);
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ ApduServiceInfo serviceInfo =
+ sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getAids() : null);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the route destination for the preferred payment service.
+ *
+ * @return The route destination secure element name of the preferred payment service.
+ * HCE payment: "Host"
+ * OffHost payment: prefix SIM or prefix eSE string.
+ * "OffHost" if the payment service does not specify secure element
+ * name.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @Nullable
+ public String getRouteDestinationForPreferredPaymentService() {
+ try {
+ ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
+ if (serviceInfo != null) {
+ if (!serviceInfo.isOnHost()) {
+ return serviceInfo.getOffHostSecureElement() == null ?
+ "OffHost" : serviceInfo.getOffHostSecureElement();
+ }
+ return "Host";
+ }
+ return null;
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ ApduServiceInfo serviceInfo =
+ sService.getPreferredPaymentService(mContext.getUserId());
+ if (serviceInfo != null) {
+ if (!serviceInfo.isOnHost()) {
+ return serviceInfo.getOffHostSecureElement() == null ?
+ "Offhost" : serviceInfo.getOffHostSecureElement();
+ }
+ return "Host";
+ }
+ return null;
+
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Returns a user-visible description of the preferred payment service.
+ *
+ * @return the preferred payment service description
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @Nullable
+ public String getDescriptionForPreferredPaymentService() {
+ try {
+ ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getDescription() : null);
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ ApduServiceInfo serviceInfo =
+ sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getDescription() : null);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
* @hide
*/
public boolean setDefaultServiceForCategory(ComponentName service, String category) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1eda4d9..1d25bc1 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -26,17 +26,17 @@
import android.app.ActivityThread;
import android.app.Application;
import android.content.Context;
+import android.sysprop.TelephonyProperties;
import android.text.TextUtils;
import android.util.Slog;
import android.view.View;
-import com.android.internal.telephony.TelephonyProperties;
-
import dalvik.system.VMRuntime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.stream.Collectors;
/**
* Information about the current build, extracted from system properties.
@@ -99,7 +99,8 @@
* {@link #getRadioVersion} instead.
*/
@Deprecated
- public static final String RADIO = getString(TelephonyProperties.PROPERTY_BASEBAND_VERSION);
+ public static final String RADIO = joinListOrElse(
+ TelephonyProperties.baseband_version(), UNKNOWN);
/** The name of the hardware (from the kernel command line or /proc). */
public static final String HARDWARE = getString("ro.hardware");
@@ -1088,7 +1089,8 @@
final String requiredBootloader = SystemProperties.get("ro.build.expect.bootloader");
final String currentBootloader = SystemProperties.get("ro.bootloader");
final String requiredRadio = SystemProperties.get("ro.build.expect.baseband");
- final String currentRadio = SystemProperties.get("gsm.version.baseband");
+ final String currentRadio = joinListOrElse(
+ TelephonyProperties.baseband_version(), "");
if (TextUtils.isEmpty(system)) {
Slog.e(TAG, "Required ro.system.build.fingerprint is empty!");
@@ -1262,8 +1264,7 @@
* null (if, for instance, the radio is not currently on).
*/
public static String getRadioVersion() {
- String propVal = SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION);
- return TextUtils.isEmpty(propVal) ? null : propVal;
+ return joinListOrElse(TelephonyProperties.baseband_version(), null);
}
@UnsupportedAppUsage
@@ -1288,4 +1289,10 @@
return -1;
}
}
+
+ private static <T> String joinListOrElse(List<T> list, String defaultValue) {
+ String ret = list.stream().map(elem -> elem == null ? "" : elem.toString())
+ .collect(Collectors.joining(","));
+ return ret.isEmpty() ? defaultValue : ret;
+ }
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index bf26a41..422761c 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2503,4 +2503,27 @@
* @hide
*/
public static native long getZramFreeKb();
+
+ /**
+ * Return memory size in kilobytes allocated for ION heaps.
+ *
+ * @hide
+ */
+ public static native long getIonHeapsSizeKb();
+
+ /**
+ * Return memory size in kilobytes allocated for ION pools.
+ *
+ * @hide
+ */
+ public static native long getIonPoolsSizeKb();
+
+ /**
+ * Return ION memory mapped by processes in kB.
+ * Notes:
+ * * Warning: Might impact performance as it reads /proc/<pid>/maps files for each process.
+ *
+ * @hide
+ */
+ public static native long getIonMappedSizeKb();
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index ab4d424..c618dbc 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -20,6 +20,7 @@
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
@@ -605,6 +606,13 @@
public static final String REBOOT_SAFE_MODE = "safemode";
/**
+ * The 'reason' value used for rebooting userspace.
+ * @hide
+ */
+ @SystemApi
+ public static final String REBOOT_USERSPACE = "userspace";
+
+ /**
* The 'reason' value used when rebooting the device without turning on the screen.
* @hide
*/
@@ -1383,6 +1391,14 @@
}
/**
+ * Returns {@code true} if this device supports rebooting userspace.
+ */
+ // TODO(b/138605180): add link to documentation once it's ready.
+ public boolean isRebootingUserspaceSupported() {
+ return SystemProperties.getBoolean("ro.init.userspace_reboot.is_supported", false);
+ }
+
+ /**
* Reboot the device. Will not return if the reboot is successful.
* <p>
* Requires the {@link android.Manifest.permission#REBOOT} permission.
@@ -1390,8 +1406,14 @@
*
* @param reason code to pass to the kernel (e.g., "recovery") to
* request special boot modes, or null.
+ * @throws UnsupportedOperationException if userspace reboot was requested on a device that
+ * doesn't support it.
*/
- public void reboot(String reason) {
+ public void reboot(@Nullable String reason) {
+ if (REBOOT_USERSPACE.equals(reason) && !isRebootingUserspaceSupported()) {
+ throw new UnsupportedOperationException(
+ "Attempted userspace reboot on a device that doesn't support it");
+ }
try {
mService.reboot(false, reason, true);
} catch (RemoteException e) {
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 1c78b08..7af8f71 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -17,6 +17,7 @@
package android.os;
import android.annotation.TestApi;
+import android.util.Slog;
import java.util.Map;
@@ -28,6 +29,8 @@
@TestApi
public class VintfObject {
+ private static final String LOG_TAG = "VintfObject";
+
/**
* Slurps all device information (both manifests and both matrices)
* and report them.
@@ -46,12 +49,33 @@
* @param packageInfo a list of serialized form of HalManifest's /
* CompatibilityMatri'ces (XML).
* @return = 0 if success (compatible)
- * > 0 if incompatible
- * < 0 if any error (mount partition fails, illformed XML, etc.)
+ * > 0 if incompatible
+ * < 0 if any error (mount partition fails, illformed XML, etc.)
+ *
+ * @deprecated Checking compatibility against an OTA package is no longer
+ * supported because the format of VINTF metadata in the OTA package may not
+ * be recognized by the current system.
+ *
+ * <p>
+ * <ul>
+ * <li>This function always returns 0 for non-empty {@code packageInfo}.
+ * </li>
+ * <li>This function returns the result of {@link #verifyWithoutAvb} for
+ * null or empty {@code packageInfo}.</li>
+ * </ul>
*
* @hide
*/
- public static native int verify(String[] packageInfo);
+ @Deprecated
+ public static int verify(String[] packageInfo) {
+ if (packageInfo != null && packageInfo.length > 0) {
+ Slog.w(LOG_TAG, "VintfObject.verify() with non-empty packageInfo is deprecated. "
+ + "Skipping compatibility checks for update package.");
+ return 0;
+ }
+ Slog.w(LOG_TAG, "VintfObject.verify() is deprecated. Call verifyWithoutAvb() instead.");
+ return verifyWithoutAvb();
+ }
/**
* Verify Vintf compatibility on the device without checking AVB
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 7754666..df36f14 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1352,7 +1352,6 @@
for (int i = 0; i < pduCount; i++) {
byte[] pdu = (byte[]) messages[i];
msgs[i] = SmsMessage.createFromPdu(pdu, format);
- if (msgs[i] != null) msgs[i].setSubId(subId);
}
return msgs;
}
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index f7077bb..ae9966b 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -224,12 +224,25 @@
/**
* Write an event to stats log using the raw format.
*
- * @param buffer The encoded buffer of data to write..
+ * @param buffer The encoded buffer of data to write.
* @param size The number of bytes from the buffer to write.
* @hide
*/
+ // TODO(b/144935988): Mark deprecated.
@SystemApi
- public static native void writeRaw(@NonNull byte[] buffer, int size);
+ public static void writeRaw(@NonNull byte[] buffer, int size) {
+ // TODO(b/144935988): make this no-op once clients have migrated to StatsEvent.
+ writeImpl(buffer, size, 0);
+ }
+
+ /**
+ * Write an event to stats log using the raw format.
+ *
+ * @param buffer The encoded buffer of data to write.
+ * @param size The number of bytes from the buffer to write.
+ * @param atomId The id of the atom to which the event belongs.
+ */
+ private static native void writeImpl(@NonNull byte[] buffer, int size, int atomId);
private static void enforceDumpCallingPermission(Context context) {
context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission.");
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index c859f11..3bd0fd2 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -61,6 +61,7 @@
import android.telephony.CellSignalStrength;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.ModemActivityInfo;
+import android.telephony.ModemActivityInfo.TransmitPower;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
@@ -10978,7 +10979,7 @@
}
private ModemActivityInfo mLastModemActivityInfo =
- new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
+ new ModemActivityInfo(0, 0, 0, new int[0], 0);
private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) {
if (activityInfo == null) {
@@ -10986,15 +10987,14 @@
}
int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) {
- txTimeMs[i] = activityInfo.getTxTimeMillis()[i]
- - mLastModemActivityInfo.getTxTimeMillis()[i];
+ txTimeMs[i] = activityInfo.getTransmitPowerInfo().get(i).getTimeInMillis()
+ - mLastModemActivityInfo.getTransmitPowerInfo().get(i).getTimeInMillis();
}
ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(),
activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(),
activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(),
txTimeMs,
- activityInfo.getRxTimeMillis() - mLastModemActivityInfo.getRxTimeMillis(),
- activityInfo.getEnergyUsed() - mLastModemActivityInfo.getEnergyUsed());
+ activityInfo.getReceiveTimeMillis() - mLastModemActivityInfo.getReceiveTimeMillis());
mLastModemActivityInfo = activityInfo;
return deltaInfo;
}
@@ -11037,10 +11037,11 @@
deltaInfo.getIdleTimeMillis());
mModemActivity.getSleepTimeCounter().addCountLocked(
deltaInfo.getSleepTimeMillis());
- mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getRxTimeMillis());
+ mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis());
for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
mModemActivity.getTxTimeCounters()[lvl]
- .addCountLocked(deltaInfo.getTxTimeMillis()[lvl]);
+ .addCountLocked(deltaInfo.getTransmitPowerInfo()
+ .get(lvl).getTimeInMillis());
}
// POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
@@ -11052,13 +11053,14 @@
mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP)
+ deltaInfo.getIdleTimeMillis() *
mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE)
- + deltaInfo.getRxTimeMillis() *
+ + deltaInfo.getReceiveTimeMillis() *
mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX);
- int[] txTimeMs = deltaInfo.getTxTimeMillis();
- for (int i = 0; i < Math.min(txTimeMs.length,
- CellSignalStrength.getNumSignalStrengthLevels()); i++) {
- energyUsed += txTimeMs[i] * mPowerProfile.getAveragePower(
- PowerProfile.POWER_MODEM_CONTROLLER_TX, i);
+
+ List<TransmitPower> txPowerInfo = deltaInfo.getTransmitPowerInfo();
+ for (int i = 0; i < Math.min(txPowerInfo.size(),
+ SignalStrength.NUM_SIGNAL_STRENGTH_BINS); i++) {
+ energyUsed += txPowerInfo.get(i).getTimeInMillis() * mPowerProfile
+ .getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, i);
}
// We store the power drain as mAms.
@@ -11147,15 +11149,16 @@
ControllerActivityCounterImpl activityCounter =
u.getOrCreateModemControllerActivityLocked();
if (totalRxPackets > 0 && entry.rxPackets > 0) {
- final long rxMs = (entry.rxPackets * deltaInfo.getRxTimeMillis())
- / totalRxPackets;
+ final long rxMs = (entry.rxPackets
+ * deltaInfo.getReceiveTimeMillis()) / totalRxPackets;
activityCounter.getRxTimeCounter().addCountLocked(rxMs);
}
if (totalTxPackets > 0 && entry.txPackets > 0) {
for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
long txMs =
- entry.txPackets * deltaInfo.getTxTimeMillis()[lvl];
+ entry.txPackets * deltaInfo.getTransmitPowerInfo()
+ .get(lvl).getTimeInMillis();
txMs /= totalTxPackets;
activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
}
@@ -11186,15 +11189,16 @@
if (activityInfo == null) {
return;
}
- int[] txTimeMs = activityInfo.getTxTimeMillis();
- if (txTimeMs == null || txTimeMs.length != ModemActivityInfo.TX_POWER_LEVELS) {
+ List<TransmitPower> txPowerInfo = activityInfo.getTransmitPowerInfo();
+ if (txPowerInfo == null || txPowerInfo.size() != ModemActivityInfo.TX_POWER_LEVELS) {
return;
}
final long elapsedRealtime = mClocks.elapsedRealtime();
final long uptime = mClocks.uptimeMillis();
int levelMaxTimeSpent = 0;
- for (int i = 1; i < txTimeMs.length; i++) {
- if (txTimeMs[i] > txTimeMs[levelMaxTimeSpent]) {
+ for (int i = 1; i < txPowerInfo.size(); i++) {
+ if (txPowerInfo.get(i).getTimeInMillis() > txPowerInfo.get(levelMaxTimeSpent)
+ .getTimeInMillis()) {
levelMaxTimeSpent = i;
}
}
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index c1d129b..362bc92 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -91,7 +91,15 @@
* that are mapped in to processes.
*/
public long getCachedSizeKb() {
- return mInfos[Debug.MEMINFO_BUFFERS] + mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE]
+ long kReclaimable = mInfos[Debug.MEMINFO_KRECLAIMABLE];
+
+ // Note: MEMINFO_KRECLAIMABLE includes MEMINFO_SLAB_RECLAIMABLE and ION pools.
+ // Fall back to using MEMINFO_SLAB_RECLAIMABLE in case of older kernels that do
+ // not include KReclaimable meminfo field.
+ if (kReclaimable == 0) {
+ kReclaimable = mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE];
+ }
+ return mInfos[Debug.MEMINFO_BUFFERS] + kReclaimable
+ mInfos[Debug.MEMINFO_CACHED] - mInfos[Debug.MEMINFO_MAPPED];
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 49c029c..f68fd57 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -233,6 +233,7 @@
static_libs: [
"libasync_safe",
+ "libdmabufinfo",
"libgif",
"libseccomp_policy",
"libgrallocusage",
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 6aed1e8..1ff28fe 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -43,6 +43,7 @@
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
#include "jni.h"
+#include <dmabufinfo/dmabufinfo.h>
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <memtrack/memtrack.h>
@@ -779,6 +780,59 @@
return zramFreeKb;
}
+static jlong android_os_Debug_getIonHeapsSizeKb(JNIEnv* env, jobject clazz) {
+ jlong heapsSizeKb = 0;
+ uint64_t size;
+
+ if (meminfo::ReadIonHeapsSizeKb(&size)) {
+ heapsSizeKb = size;
+ }
+
+ return heapsSizeKb;
+}
+
+static jlong android_os_Debug_getIonPoolsSizeKb(JNIEnv* env, jobject clazz) {
+ jlong poolsSizeKb = 0;
+ uint64_t size;
+
+ if (meminfo::ReadIonPoolsSizeKb(&size)) {
+ poolsSizeKb = size;
+ }
+
+ return poolsSizeKb;
+}
+
+static jlong android_os_Debug_getIonMappedSizeKb(JNIEnv* env, jobject clazz) {
+ jlong ionPss = 0;
+ std::vector<dmabufinfo::DmaBuffer> dmabufs;
+
+ std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
+ if (!dir) {
+ LOG(ERROR) << "Failed to open /proc directory";
+ return false;
+ }
+
+ struct dirent* dent;
+ while ((dent = readdir(dir.get()))) {
+ if (dent->d_type != DT_DIR) continue;
+
+ int pid = atoi(dent->d_name);
+ if (pid == 0) {
+ continue;
+ }
+
+ if (!AppendDmaBufInfo(pid, &dmabufs, false)) {
+ LOG(ERROR) << "Failed to read maps for pid " << pid;
+ }
+ }
+
+ for (dmabufinfo::DmaBuffer buf : dmabufs) {
+ ionPss += buf.size() / 1024;
+ }
+
+ return ionPss;
+}
+
/*
* JNI registration.
*/
@@ -822,6 +876,12 @@
(void*)android_os_Debug_getUnreachableMemory },
{ "getZramFreeKb", "()J",
(void*)android_os_Debug_getFreeZramKb },
+ { "getIonHeapsSizeKb", "()J",
+ (void*)android_os_Debug_getIonHeapsSizeKb },
+ { "getIonPoolsSizeKb", "()J",
+ (void*)android_os_Debug_getIonPoolsSizeKb },
+ { "getIonMappedSizeKb", "()J",
+ (void*)android_os_Debug_getIonMappedSizeKb },
};
int register_android_os_Debug(JNIEnv *env)
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index ee11b61..25ffbab 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -96,28 +96,9 @@
return toJavaStringArray(env, cStrings);
}
-static jint android_os_VintfObject_verify(JNIEnv* env, jclass, jobjectArray packageInfo) {
- std::vector<std::string> cPackageInfo;
- if (packageInfo) {
- size_t count = env->GetArrayLength(packageInfo);
- cPackageInfo.resize(count);
- for (size_t i = 0; i < count; ++i) {
- jstring element = (jstring)env->GetObjectArrayElement(packageInfo, i);
- const char *cString = env->GetStringUTFChars(element, NULL /* isCopy */);
- cPackageInfo[i] = cString;
- env->ReleaseStringUTFChars(element, cString);
- }
- }
- std::string error;
- int32_t status = VintfObject::CheckCompatibility(cPackageInfo, &error);
- if (status)
- LOG(WARNING) << "VintfObject.verify() returns " << status << ": " << error;
- return status;
-}
-
static jint android_os_VintfObject_verifyWithoutAvb(JNIEnv* env, jclass) {
std::string error;
- int32_t status = VintfObject::CheckCompatibility({}, &error,
+ int32_t status = VintfObject::GetInstance()->checkCompatibility(&error,
::android::vintf::CheckFlags::DISABLE_AVB_CHECK);
if (status)
LOG(WARNING) << "VintfObject.verifyWithoutAvb() returns " << status << ": " << error;
@@ -170,7 +151,6 @@
static const JNINativeMethod gVintfObjectMethods[] = {
{"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
- {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
{"verifyWithoutAvb", "()I", (void*)android_os_VintfObject_verifyWithoutAvb},
{"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions},
{"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion},
diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp
index e749d34..9225fc2 100644
--- a/core/jni/android_util_StatsLog.cpp
+++ b/core/jni/android_util_StatsLog.cpp
@@ -18,18 +18,17 @@
#define LOG_TAG "StatsLog_println"
#include <assert.h>
-#include <cutils/properties.h>
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "utils/misc.h"
#include "core_jni_helpers.h"
-#include "stats_event_list.h"
+#include "stats_buffer_writer.h"
namespace android {
-static void android_util_StatsLog_writeRaw(JNIEnv* env, jobject clazz, jbyteArray buf, jint size)
-{
+static void android_util_StatsLog_write(JNIEnv* env, jobject clazz, jbyteArray buf, jint size,
+ jint atomId) {
if (buf == NULL) {
return;
}
@@ -42,13 +41,8 @@
if (bufferArray == NULL) {
return;
}
- const uint32_t statsEventTag = 1937006964;
- struct iovec vec[2];
- vec[0].iov_base = (void*) &statsEventTag;
- vec[0].iov_len = sizeof(statsEventTag);
- vec[1].iov_base = (void*) bufferArray;
- vec[1].iov_len = size;
- write_to_statsd(vec, 2);
+
+ write_buffer_to_statsd((void*) bufferArray, size, atomId);
env->ReleaseByteArrayElements(buf, bufferArray, 0);
}
@@ -58,7 +52,7 @@
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- { "writeRaw", "([BI)V", (void*) android_util_StatsLog_writeRaw },
+ { "writeImpl", "([BII)V", (void*) android_util_StatsLog_write },
};
int register_android_util_StatsLog(JNIEnv* env)
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 0c21076..c8e901e 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -39,6 +39,7 @@
"/apex/com.android.sdkext/javalib/framework-sdkext.jar",
"/apex/com.android.telephony/javalib/telephony-common.jar",
"/apex/com.android.telephony/javalib/ims-common.jar",
+ "/apex/com.android.tethering/javalib/framework-tethering.jar",
"/dev/null",
"/dev/socket/zygote",
"/dev/socket/zygote_secondary",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9ce29e3..31ac2bc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -306,6 +306,7 @@
<protected-broadcast android:name="android.net.nsd.STATE_CHANGED" />
<protected-broadcast android:name="android.nfc.action.ADAPTER_STATE_CHANGED" />
+ <protected-broadcast android:name="android.nfc.action.PREFERRED_PAYMENT_CHANGED" />
<protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
<protected-broadcast android:name="com.android.nfc.action.LLCP_UP" />
<protected-broadcast android:name="com.android.nfc.action.LLCP_DOWN" />
@@ -1767,6 +1768,14 @@
<p>Protection level: normal
-->
<permission android:name="android.permission.NFC_TRANSACTION_EVENT"
+ android:protectionLevel="normal" />
+
+ <!-- Allows applications to receive NFC preferred payment service information.
+ <p>Protection level: normal
+ -->
+ <permission android:name="android.permission.NFC_PREFERRED_PAYMENT_INFO"
+ android:description="@string/permdesc_preferredPaymentInfo"
+ android:label="@string/permlab_preferredPaymentInfo"
android:protectionLevel="normal" />
<!-- @deprecated This permission used to allow too broad access to sensitive methods and all its
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b516c41..a404e2e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3538,6 +3538,9 @@
<!-- emergency call number for the emergency affordance -->
<string name="config_emergency_call_number" translatable="false">112</string>
+ <!-- Package name that provides Emergency Dialer -->
+ <string name="config_emergency_dialer_package">com.android.phone</string>
+
<!-- Do not translate. Mcc codes whose existence trigger the presence of emergency
affordances-->
<integer-array name="config_emergency_mcc_codes" translatable="false">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fdfedea..4aa44fc 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1392,6 +1392,12 @@
connections with paired devices.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preferredPaymentInfo">Preferred NFC Payment Service Information</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preferredPaymentInfo">Allows the app to get preferred nfc payment service information like
+ registered aids and route destination.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_nfc">control Near Field Communication</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_nfc">Allows the app to communicate
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5cd5c8c..2507787 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3153,6 +3153,7 @@
<java-symbol type="string" name="global_action_emergency" />
<java-symbol type="string" name="config_emergency_call_number" />
+ <java-symbol type="string" name="config_emergency_dialer_package" />
<java-symbol type="array" name="config_emergency_mcc_codes" />
<java-symbol type="string" name="config_dozeDoubleTapSensorType" />
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 576ac73..5cb7852 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -239,4 +239,17 @@
verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
}
+
+ @Test
+ public void testUserspaceRebootNotSupported_throwsUnsupportedOperationException() {
+ // Can't use assumption framework with AndroidTestCase :(
+ if (mPm.isRebootingUserspaceSupported()) {
+ return;
+ }
+ try {
+ mPm.reboot(PowerManager.REBOOT_USERSPACE);
+ fail("UnsupportedOperationException not thrown");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
}
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index 87b1467..8cffd6a 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -3,3 +3,4 @@
rtmitchell@google.com
per-file CursorWindow.cpp=omakoto@google.com
+per-file LocaleDataTables.cpp=vichang@google.com,tobiast@google.com,nikitai@google.com
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
index baa779c..f5ba92e 100644
--- a/media/jni/android_media_MediaExtractor.h
+++ b/media/jni/android_media_MediaExtractor.h
@@ -19,7 +19,7 @@
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AudioPresentationInfo.h>
-#include <media/MediaSource.h>
+#include <media/stagefright/MediaSource.h>
#include <media/DataSource.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 177f2b8..203adfc 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -40,6 +40,7 @@
AConfiguration_getOrientation;
AConfiguration_getScreenHeightDp; # introduced-arm=13 introduced-arm64=21 introduced-mips=13 introduced-mips64=21 introduced-x86=13 introduced-x86_64=21
AConfiguration_getScreenLong;
+ AConfiguration_getScreenRound; # introduced=30
AConfiguration_getScreenSize;
AConfiguration_getScreenWidthDp; # introduced-arm=13 introduced-arm64=21 introduced-mips=13 introduced-mips64=21 introduced-x86=13 introduced-x86_64=21
AConfiguration_getSdkVersion;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 35774ed..1c4f1e3 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12799,14 +12799,31 @@
pw.println(totalPss - cachedPss);
}
}
- long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
+ long kernelUsed = memInfo.getKernelUsedSizeKb();
+ final long ionHeap = Debug.getIonHeapsSizeKb();
+ if (ionHeap > 0) {
+ final long ionMapped = Debug.getIonMappedSizeKb();
+ final long ionUnmapped = ionHeap - ionMapped;
+ final long ionPool = Debug.getIonPoolsSizeKb();
+ pw.print(" ION: ");
+ pw.print(stringifyKBSize(ionHeap + ionPool));
+ pw.print(" (");
+ pw.print(stringifyKBSize(ionMapped));
+ pw.print(" mapped + ");
+ pw.print(stringifyKBSize(ionUnmapped));
+ pw.print(" unmapped + ");
+ pw.print(stringifyKBSize(ionPool));
+ pw.println(" pools)");
+ kernelUsed += ionUnmapped;
+ }
+ final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
+ - kernelUsed - memInfo.getZramTotalSizeKb();
if (!opts.isCompact) {
pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
- + memInfo.getKernelUsedSizeKb())); pw.print(" (");
+ + kernelUsed)); pw.print(" (");
pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
- pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
+ pw.print(stringifyKBSize(kernelUsed)); pw.print(" kernel)\n");
pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
} else {
pw.print("lostram,"); pw.println(lostRAM);
@@ -13525,14 +13542,25 @@
memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
+ memInfo.getFreeSizeKb()));
memInfoBuilder.append("\n");
+ long kernelUsed = memInfo.getKernelUsedSizeKb();
+ final long ionHeap = Debug.getIonHeapsSizeKb();
+ if (ionHeap > 0) {
+ final long ionMapped = Debug.getIonMappedSizeKb();
+ final long ionUnmapped = ionHeap - ionMapped;
+ final long ionPool = Debug.getIonPoolsSizeKb();
+ memInfoBuilder.append(" ION: ");
+ memInfoBuilder.append(stringifyKBSize(ionHeap + ionPool));
+ memInfoBuilder.append("\n");
+ kernelUsed += ionUnmapped;
+ }
memInfoBuilder.append(" Used RAM: ");
memInfoBuilder.append(stringifyKBSize(
- totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
+ totalPss - cachedPss + kernelUsed));
memInfoBuilder.append("\n");
memInfoBuilder.append(" Lost RAM: ");
memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
- (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
+ - kernelUsed - memInfo.getZramTotalSizeKb()));
memInfoBuilder.append("\n");
Slog.i(TAG, "Low on memory:");
Slog.i(TAG, shortNativeBuilder.toString());
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 135f199d..4a5a212 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -195,15 +195,17 @@
} else {
makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
}
+ } else if (state == BluetoothProfile.STATE_CONNECTED) {
+ // device is not already connected
+ if (a2dpVolume != -1) {
+ mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
+ // convert index to internal representation in VolumeStreamState
+ a2dpVolume * 10,
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
+ }
+ makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
+ "onSetA2dpSinkConnectionState", a2dpCodec);
}
- if (a2dpVolume != -1) {
- mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
- // convert index to internal representation in VolumeStreamState
- a2dpVolume * 10,
- AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
- }
- makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
- "onSetA2dpSinkConnectionState", a2dpCodec);
}
}
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index 9cb2441..68ba8a4 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -16,24 +16,6 @@
package com.android.server.policy;
-import com.android.internal.app.AlertController;
-import com.android.internal.globalactions.Action;
-import com.android.internal.globalactions.ActionsAdapter;
-import com.android.internal.globalactions.ActionsDialog;
-import com.android.internal.globalactions.LongPressAction;
-import com.android.internal.globalactions.SinglePressAction;
-import com.android.internal.globalactions.ToggleAction;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.R;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.util.EmergencyAffordanceManager;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.policy.PowerAction;
-import com.android.server.policy.RestartAction;
-import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
-
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -57,6 +39,7 @@
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
+import android.sysprop.TelephonyProperties;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
@@ -69,6 +52,21 @@
import android.view.WindowManagerGlobal;
import android.widget.AdapterView;
+import com.android.internal.R;
+import com.android.internal.app.AlertController;
+import com.android.internal.globalactions.Action;
+import com.android.internal.globalactions.ActionsAdapter;
+import com.android.internal.globalactions.ActionsDialog;
+import com.android.internal.globalactions.LongPressAction;
+import com.android.internal.globalactions.SinglePressAction;
+import com.android.internal.globalactions.ToggleAction;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.EmergencyAffordanceManager;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
+
import java.util.ArrayList;
import java.util.List;
@@ -229,8 +227,7 @@
@Override
public void onToggle(boolean on) {
- if (mHasTelephony && Boolean.parseBoolean(
- SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+ if (mHasTelephony && TelephonyProperties.in_ecm_mode().orElse(false)) {
mIsWaitingForEcmExit = true;
// Launch ECM exit dialog
Intent ecmDialogIntent =
@@ -247,8 +244,7 @@
if (!mHasTelephony) return;
// In ECM mode airplane state cannot be changed
- if (!(Boolean.parseBoolean(
- SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
+ if (!TelephonyProperties.in_ecm_mode().orElse(false)) {
mState = buttonOn ? State.TurningOn : State.TurningOff;
mAirplaneState = mState;
}
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index c76bbb0..0d28b46 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -1112,13 +1112,12 @@
e.writeLong(modemInfo.getTimestamp());
e.writeLong(modemInfo.getSleepTimeMillis());
e.writeLong(modemInfo.getIdleTimeMillis());
- e.writeLong(modemInfo.getTxTimeMillis()[0]);
- e.writeLong(modemInfo.getTxTimeMillis()[1]);
- e.writeLong(modemInfo.getTxTimeMillis()[2]);
- e.writeLong(modemInfo.getTxTimeMillis()[3]);
- e.writeLong(modemInfo.getTxTimeMillis()[4]);
- e.writeLong(modemInfo.getRxTimeMillis());
- e.writeLong(modemInfo.getEnergyUsed());
+ e.writeLong(modemInfo.getTransmitPowerInfo().get(0).getTimeInMillis());
+ e.writeLong(modemInfo.getTransmitPowerInfo().get(1).getTimeInMillis());
+ e.writeLong(modemInfo.getTransmitPowerInfo().get(2).getTimeInMillis());
+ e.writeLong(modemInfo.getTransmitPowerInfo().get(3).getTimeInMillis());
+ e.writeLong(modemInfo.getTransmitPowerInfo().get(4).getTimeInMillis());
+ e.writeLong(modemInfo.getReceiveTimeMillis());
pulledData.add(e);
}
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index d99e03b..c50248d 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -24,7 +24,6 @@
import android.app.timedetector.PhoneTimeSuggestion;
import android.content.Intent;
import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Slog;
import android.util.TimestampedValue;
@@ -32,12 +31,11 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.timezonedetector.ArrayMapWithHistory;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.LinkedList;
-import java.util.Map;
/**
* An implementation of TimeDetectorStrategy that passes phone and manual suggestions to
@@ -99,14 +97,12 @@
private TimestampedValue<Long> mLastAutoSystemClockTimeSet;
/**
- * A mapping from phoneId to a linked list of time suggestions (the "first" being the latest).
- * We typically expect one or two entries in this Map: devices will have a small number
- * of telephony devices and phoneIds are assumed to be stable. The LinkedList associated with
- * the ID will not exceed {@link #KEEP_SUGGESTION_HISTORY_SIZE} in size.
+ * A mapping from phoneId to a time suggestion. We typically expect one or two mappings: devices
+ * will have a small number of telephony devices and phoneIds are assumed to be stable.
*/
@GuardedBy("this")
- private ArrayMap<Integer, LinkedList<PhoneTimeSuggestion>> mSuggestionByPhoneId =
- new ArrayMap<>();
+ private ArrayMapWithHistory<Integer, PhoneTimeSuggestion> mSuggestionByPhoneId =
+ new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
@Override
public void initialize(@NonNull Callback callback) {
@@ -179,16 +175,7 @@
ipw.println("Phone suggestion history:");
ipw.increaseIndent(); // level 2
- for (Map.Entry<Integer, LinkedList<PhoneTimeSuggestion>> entry
- : mSuggestionByPhoneId.entrySet()) {
- ipw.println("Phone " + entry.getKey());
-
- ipw.increaseIndent(); // level 3
- for (PhoneTimeSuggestion suggestion : entry.getValue()) {
- ipw.println(suggestion);
- }
- ipw.decreaseIndent(); // level 3
- }
+ mSuggestionByPhoneId.dump(ipw);
ipw.decreaseIndent(); // level 2
ipw.decreaseIndent(); // level 1
@@ -205,20 +192,10 @@
}
int phoneId = suggestion.getPhoneId();
- LinkedList<PhoneTimeSuggestion> phoneSuggestions = mSuggestionByPhoneId.get(phoneId);
- if (phoneSuggestions == null) {
- // The first time we've seen this phoneId.
- phoneSuggestions = new LinkedList<>();
- mSuggestionByPhoneId.put(phoneId, phoneSuggestions);
- } else if (phoneSuggestions.isEmpty()) {
- Slog.w(LOG_TAG, "Suggestions unexpectedly empty when adding suggestion=" + suggestion);
- }
-
- if (!phoneSuggestions.isEmpty()) {
+ PhoneTimeSuggestion previousSuggestion = mSuggestionByPhoneId.get(phoneId);
+ if (previousSuggestion != null) {
// We can log / discard suggestions with obvious issues with the reference time clock.
- PhoneTimeSuggestion previousSuggestion = phoneSuggestions.getFirst();
- if (previousSuggestion == null
- || previousSuggestion.getUtcTime() == null
+ if (previousSuggestion.getUtcTime() == null
|| previousSuggestion.getUtcTime().getValue() == null) {
// This should be impossible given we only store validated suggestions.
Slog.w(LOG_TAG, "Previous suggestion is null or has a null time."
@@ -240,10 +217,7 @@
}
// Store the latest suggestion.
- phoneSuggestions.addFirst(suggestion);
- if (phoneSuggestions.size() > KEEP_SUGGESTION_HISTORY_SIZE) {
- phoneSuggestions.removeLast();
- }
+ mSuggestionByPhoneId.put(phoneId, suggestion);
return true;
}
@@ -331,15 +305,7 @@
int bestScore = PHONE_INVALID_SCORE;
for (int i = 0; i < mSuggestionByPhoneId.size(); i++) {
Integer phoneId = mSuggestionByPhoneId.keyAt(i);
- LinkedList<PhoneTimeSuggestion> phoneSuggestions = mSuggestionByPhoneId.valueAt(i);
- if (phoneSuggestions == null) {
- // Unexpected - map is missing a value.
- Slog.w(LOG_TAG, "Suggestions unexpectedly missing for phoneId."
- + " phoneId=" + phoneId);
- continue;
- }
-
- PhoneTimeSuggestion candidateSuggestion = phoneSuggestions.getFirst();
+ PhoneTimeSuggestion candidateSuggestion = mSuggestionByPhoneId.valueAt(i);
if (candidateSuggestion == null) {
// Unexpected - null suggestions should never be stored.
Slog.w(LOG_TAG, "Latest suggestion unexpectedly null for phoneId."
@@ -540,10 +506,6 @@
@VisibleForTesting
@Nullable
public synchronized PhoneTimeSuggestion getLatestPhoneSuggestion(int phoneId) {
- LinkedList<PhoneTimeSuggestion> suggestions = mSuggestionByPhoneId.get(phoneId);
- if (suggestions == null) {
- return null;
- }
- return suggestions.getFirst();
+ return mSuggestionByPhoneId.get(phoneId);
}
}
diff --git a/services/core/java/com/android/server/timezonedetector/ArrayMapWithHistory.java b/services/core/java/com/android/server/timezonedetector/ArrayMapWithHistory.java
new file mode 100644
index 0000000..3274f0e
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/ArrayMapWithHistory.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+
+/**
+ * A partial decorator for {@link ArrayMap} that records historic values for each mapping for
+ * debugging later with {@link #dump(IndentingPrintWriter)}.
+ *
+ * <p>This class is only intended for use in {@link TimeZoneDetectorStrategy} and
+ * {@link com.android.server.timedetector.TimeDetectorStrategy} so only provides the parts of the
+ * {@link ArrayMap} API needed. If it is ever extended to include deletion methods like
+ * {@link ArrayMap#remove(Object)} some thought would need to be given to the correct
+ * {@link ArrayMap#containsKey(Object)} behavior for the history. Like {@link ArrayMap}, it is not
+ * thread-safe.
+ *
+ * @param <K> the type of the key
+ * @param <V> the type of the value
+ */
+public final class ArrayMapWithHistory<K, V> {
+ private static final String TAG = "ArrayMapWithHistory";
+
+ /** The size the linked list against each value is allowed to grow to. */
+ private final int mMaxHistorySize;
+
+ @Nullable
+ private ArrayMap<K, ReferenceWithHistory<V>> mMap;
+
+ /**
+ * Creates an instance that records, at most, the specified number of values against each key.
+ */
+ public ArrayMapWithHistory(@IntRange(from = 1) int maxHistorySize) {
+ if (maxHistorySize < 1) {
+ throw new IllegalArgumentException("maxHistorySize < 1: " + maxHistorySize);
+ }
+ mMaxHistorySize = maxHistorySize;
+ }
+
+ /**
+ * See {@link ArrayMap#put(K, V)}.
+ */
+ @Nullable
+ public V put(@Nullable K key, @Nullable V value) {
+ if (mMap == null) {
+ mMap = new ArrayMap<>();
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.get(key);
+ if (valueHolder == null) {
+ valueHolder = new ReferenceWithHistory<>(mMaxHistorySize);
+ mMap.put(key, valueHolder);
+ } else if (valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "History for \"" + key + "\" was unexpectedly empty");
+ }
+
+ return valueHolder.set(value);
+ }
+
+ /**
+ * See {@link ArrayMap#get(Object)}.
+ */
+ @Nullable
+ public V get(@Nullable Object key) {
+ if (mMap == null) {
+ return null;
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.get(key);
+ if (valueHolder == null) {
+ return null;
+ } else if (valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "History for \"" + key + "\" was unexpectedly empty");
+ }
+ return valueHolder.get();
+ }
+
+ /**
+ * See {@link ArrayMap#size()}.
+ */
+ public int size() {
+ return mMap == null ? 0 : mMap.size();
+ }
+
+ /**
+ * See {@link ArrayMap#keyAt(int)}.
+ */
+ @Nullable
+ public K keyAt(int index) {
+ if (mMap == null) {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+ return mMap.keyAt(index);
+ }
+
+ /**
+ * See {@link ArrayMap#valueAt(int)}.
+ */
+ @Nullable
+ public V valueAt(int index) {
+ if (mMap == null) {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.valueAt(index);
+ if (valueHolder == null || valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "valueAt(" + index + ") was unexpectedly null or empty");
+ return null;
+ }
+ return valueHolder.get();
+ }
+
+ /**
+ * Dumps the content of the map, including historic values, using the supplied writer.
+ */
+ public void dump(@NonNull IndentingPrintWriter ipw) {
+ if (mMap == null) {
+ ipw.println("{Empty}");
+ } else {
+ for (int i = 0; i < mMap.size(); i++) {
+ ipw.println("key idx: " + i + "=" + mMap.keyAt(i));
+ ReferenceWithHistory<V> value = mMap.valueAt(i);
+ ipw.println("val idx: " + i + "=" + value);
+ ipw.increaseIndent();
+
+ ipw.println("Historic values=[");
+ ipw.increaseIndent();
+ value.dump(ipw);
+ ipw.decreaseIndent();
+ ipw.println("]");
+
+ ipw.decreaseIndent();
+ }
+ }
+ ipw.flush();
+ }
+
+ /**
+ * Internal method intended for tests that returns the number of historic values associated with
+ * the supplied key currently. If there is no mapping for the key then {@code 0} is returned.
+ */
+ @VisibleForTesting
+ public int getHistoryCountForKeyForTests(@Nullable K key) {
+ if (mMap == null) {
+ return 0;
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.get(key);
+ if (valueHolder == null) {
+ return 0;
+ } else if (valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "getValuesSizeForKeyForTests(\"" + key + "\") was unexpectedly empty");
+ return 0;
+ } else {
+ return valueHolder.getHistoryCount();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ArrayMapWithHistory{"
+ + "mHistorySize=" + mMaxHistorySize
+ + ", mMap=" + mMap
+ + '}';
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/ReferenceWithHistory.java b/services/core/java/com/android/server/timezonedetector/ReferenceWithHistory.java
new file mode 100644
index 0000000..8bd1035
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/ReferenceWithHistory.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.util.LinkedList;
+
+/**
+ * A class that behaves like the following definition, except it stores the history of values set
+ * that can be dumped for debugging with {@link #dump(IndentingPrintWriter)}.
+ *
+ * <pre>{@code
+ * private static class Ref<V> {
+ * private V mValue;
+ *
+ * public V get() {
+ * return mValue;
+ * }
+ *
+ * public V set(V value) {
+ * V previous = mValue;
+ * mValue = value;
+ * return previous;
+ * }
+ * }
+ * }</pre>
+ *
+ * <p>This class is not thread-safe.
+ *
+ * @param <V> the type of the value
+ */
+public final class ReferenceWithHistory<V> {
+
+ /** The size the history linked list is allowed to grow to. */
+ private final int mMaxHistorySize;
+
+ @Nullable
+ private LinkedList<V> mValues;
+
+ /**
+ * Creates an instance that records, at most, the specified number of values.
+ */
+ public ReferenceWithHistory(@IntRange(from = 1) int maxHistorySize) {
+ if (maxHistorySize < 1) {
+ throw new IllegalArgumentException("maxHistorySize < 1: " + maxHistorySize);
+ }
+ this.mMaxHistorySize = maxHistorySize;
+ }
+
+ /** Returns the current value, or {@code null} if it has never been set. */
+ @Nullable
+ public V get() {
+ return (mValues == null || mValues.isEmpty()) ? null : mValues.getFirst();
+ }
+
+ /** Sets the current value. Returns the previous value, or {@code null}. */
+ @Nullable
+ public V set(@Nullable V newValue) {
+ if (mValues == null) {
+ mValues = new LinkedList<>();
+ }
+
+ V previous = get();
+
+ mValues.addFirst(newValue);
+ if (mValues.size() > mMaxHistorySize) {
+ mValues.removeLast();
+ }
+ return previous;
+ }
+
+ /**
+ * Dumps the content of the reference, including historic values, using the supplied writer.
+ */
+ public void dump(@NonNull IndentingPrintWriter ipw) {
+ if (mValues == null) {
+ ipw.println("{Empty}");
+ } else {
+ int i = 0;
+ for (V value : mValues) {
+ ipw.println(i + ": " + value);
+ i++;
+ }
+ }
+ ipw.flush();
+ }
+
+ /**
+ * Returns the number of historic entries stored currently.
+ */
+ public int getHistoryCount() {
+ return mValues == null ? 0 : mValues.size();
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(get());
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index b3013c7..b4a4399 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -27,7 +27,6 @@
import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion;
import android.content.Context;
-import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Slog;
@@ -38,8 +37,6 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.LinkedList;
-import java.util.Map;
import java.util.Objects;
/**
@@ -175,14 +172,13 @@
private final LocalLog mTimeZoneChangesLog = new LocalLog(30, false /* useLocalTimestamps */);
/**
- * A mapping from phoneId to a linked list of phone time zone suggestions (the head being the
- * latest). We typically expect one or two entries in this Map: devices will have a small number
- * of telephony devices and phoneIds are assumed to be stable. The LinkedList associated with
- * the ID will not exceed {@link #KEEP_PHONE_SUGGESTION_HISTORY_SIZE} in size.
+ * A mapping from phoneId to a phone time zone suggestion. We typically expect one or two
+ * mappings: devices will have a small number of telephony devices and phoneIds are assumed to
+ * be stable.
*/
@GuardedBy("this")
- private ArrayMap<Integer, LinkedList<QualifiedPhoneTimeZoneSuggestion>> mSuggestionByPhoneId =
- new ArrayMap<>();
+ private ArrayMapWithHistory<Integer, QualifiedPhoneTimeZoneSuggestion> mSuggestionByPhoneId =
+ new ArrayMapWithHistory<>(KEEP_PHONE_SUGGESTION_HISTORY_SIZE);
/**
* Creates a new instance of {@link TimeZoneDetectorStrategy}.
@@ -226,16 +222,7 @@
new QualifiedPhoneTimeZoneSuggestion(suggestion, score);
// Store the suggestion against the correct phoneId.
- LinkedList<QualifiedPhoneTimeZoneSuggestion> suggestions =
- mSuggestionByPhoneId.get(suggestion.getPhoneId());
- if (suggestions == null) {
- suggestions = new LinkedList<>();
- mSuggestionByPhoneId.put(suggestion.getPhoneId(), suggestions);
- }
- suggestions.addFirst(scoredSuggestion);
- if (suggestions.size() > KEEP_PHONE_SUGGESTION_HISTORY_SIZE) {
- suggestions.removeLast();
- }
+ mSuggestionByPhoneId.put(suggestion.getPhoneId(), scoredSuggestion);
// Now perform auto time zone detection. The new suggestion may be used to modify the time
// zone setting.
@@ -398,13 +385,7 @@
// rate-limit so age is not a strong indicator of confidence. Instead, the callers are
// expected to withdraw suggestions they no longer have confidence in.
for (int i = 0; i < mSuggestionByPhoneId.size(); i++) {
- LinkedList<QualifiedPhoneTimeZoneSuggestion> phoneSuggestions =
- mSuggestionByPhoneId.valueAt(i);
- if (phoneSuggestions == null) {
- // Unexpected
- continue;
- }
- QualifiedPhoneTimeZoneSuggestion candidateSuggestion = phoneSuggestions.getFirst();
+ QualifiedPhoneTimeZoneSuggestion candidateSuggestion = mSuggestionByPhoneId.valueAt(i);
if (candidateSuggestion == null) {
// Unexpected
continue;
@@ -474,16 +455,7 @@
ipw.println("Phone suggestion history:");
ipw.increaseIndent(); // level 2
- for (Map.Entry<Integer, LinkedList<QualifiedPhoneTimeZoneSuggestion>> entry
- : mSuggestionByPhoneId.entrySet()) {
- ipw.println("Phone " + entry.getKey());
-
- ipw.increaseIndent(); // level 3
- for (QualifiedPhoneTimeZoneSuggestion suggestion : entry.getValue()) {
- ipw.println(suggestion);
- }
- ipw.decreaseIndent(); // level 3
- }
+ mSuggestionByPhoneId.dump(ipw);
ipw.decreaseIndent(); // level 2
ipw.decreaseIndent(); // level 1
ipw.flush();
@@ -494,12 +466,7 @@
*/
@VisibleForTesting
public synchronized QualifiedPhoneTimeZoneSuggestion getLatestPhoneSuggestion(int phoneId) {
- LinkedList<QualifiedPhoneTimeZoneSuggestion> suggestions =
- mSuggestionByPhoneId.get(phoneId);
- if (suggestions == null) {
- return null;
- }
- return suggestions.getFirst();
+ return mSuggestionByPhoneId.get(phoneId);
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/ArrayMapWithHistoryTest.java b/services/tests/servicestests/src/com/android/server/timedetector/ArrayMapWithHistoryTest.java
new file mode 100644
index 0000000..b6eea46
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/ArrayMapWithHistoryTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.util.ArrayMap;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.timezonedetector.ArrayMapWithHistory;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.StringWriter;
+import java.util.concurrent.Callable;
+
+@RunWith(AndroidJUnit4.class)
+public class ArrayMapWithHistoryTest {
+
+ @Test
+ public void testValueHistoryBehavior() {
+ // Create a map that will retain 2 values per key.
+ ArrayMapWithHistory<String, String> historyMap = new ArrayMapWithHistory<>(2 /* history */);
+ ArrayMap<String, String> arrayMap = new ArrayMap<>();
+
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", null));
+
+ assertEquals(0, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V1");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V1"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ // put() a new value for the same key.
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V2");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V2"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+
+ assertEquals(2, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ // put() a new value for the same key. We should have hit the limit of "2 values retained
+ // per key".
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V3");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V3"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+
+ assertEquals(2, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+ }
+
+ @Test
+ public void testMapBehavior() throws Exception {
+ ArrayMapWithHistory<String, String> historyMap = new ArrayMapWithHistory<>(2);
+ ArrayMap<String, String> arrayMap = new ArrayMap<>();
+
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", null), entry("K2", null));
+ assertIndexAccessThrowsException(0, historyMap, arrayMap);
+
+ assertEquals(0, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertEquals(0, historyMap.getHistoryCountForKeyForTests("K2"));
+
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V1");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V1"), entry("K2", null));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+ // TODO Restore after http://b/146563025 is fixed and ArrayMap behaves properly in tests.
+ // assertIndexAccessThrowsException(1, historyMap, arrayMap);
+
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ putAndCompareReturnValue(historyMap, arrayMap, "K2", "V2");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V1"), entry("K2", "V2"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+ compareKeyAtAndValueAtForIndex(1, historyMap, arrayMap);
+ // TODO Restore after http://b/146563025 is fixed and ArrayMap behaves properly in tests.
+ // assertIndexAccessThrowsException(2, historyMap, arrayMap);
+
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K2"));
+ assertToStringAndDumpNotNull(historyMap);
+ }
+
+ private static String dumpHistoryMap(ArrayMapWithHistory<?, ?> historyMap) {
+ StringWriter stringWriter = new StringWriter();
+ try (IndentingPrintWriter ipw = new IndentingPrintWriter(stringWriter, " ")) {
+ historyMap.dump(ipw);
+ return stringWriter.toString();
+ }
+ }
+
+ private static <K, V> void putAndCompareReturnValue(ArrayMapWithHistory<K, V> historyMap,
+ ArrayMap<K, V> arrayMap, K key, V value) {
+ assertEquals(arrayMap.put(key, value), historyMap.put(key, value));
+ }
+
+ private static class Entry<K, V> {
+ public final K key;
+ public final V value;
+
+ Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+ }
+
+ private static <K, V> Entry<K, V> entry(K key, V value) {
+ return new Entry<>(key, value);
+ }
+
+ @SafeVarargs
+ private static <K, V> void compareGetAndSizeForKeys(ArrayMapWithHistory<K, V> historyMap,
+ ArrayMap<K, V> arrayMap, Entry<K, V>... expectedEntries) {
+ for (Entry<K, V> expectedEntry : expectedEntries) {
+ assertEquals(arrayMap.get(expectedEntry.key), historyMap.get(expectedEntry.key));
+ assertEquals(expectedEntry.value, historyMap.get(expectedEntry.key));
+ }
+ assertEquals(arrayMap.size(), historyMap.size());
+ }
+
+ private static void compareKeyAtAndValueAtForIndex(
+ int index, ArrayMapWithHistory<?, ?> historyMap, ArrayMap<?, ?> arrayMap) {
+ assertEquals(arrayMap.keyAt(index), historyMap.keyAt(index));
+ assertEquals(arrayMap.valueAt(index), historyMap.valueAt(index));
+ }
+
+ private static void assertIndexAccessThrowsException(
+ int index, ArrayMapWithHistory<?, ?> historyMap, ArrayMap<?, ?> arrayMap)
+ throws Exception {
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMap.keyAt(" + index + ")", () -> arrayMap.keyAt(index));
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMapWithHistory.keyAt(" + index + ")", () -> historyMap.keyAt(index));
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMap.keyAt(" + index + ")", () -> arrayMap.valueAt(index));
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMapWithHistory.keyAt(" + index + ")", () -> historyMap.valueAt(index));
+ }
+
+ private static void assertThrowsArrayIndexOutOfBoundsException(
+ String description, Callable<?> callable) throws Exception {
+ try {
+ callable.call();
+ fail("Expected exception for " + description);
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ // This is fine.
+ } catch (Exception e) {
+ // Any other exception is just rethrown.
+ throw e;
+ }
+ }
+
+ private static void assertToStringAndDumpNotNull(ArrayMapWithHistory<?, ?> historyMap) {
+ assertNotNull(historyMap.toString());
+ assertNotNull(dumpHistoryMap(historyMap));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/ReferenceWithHistoryTest.java b/services/tests/servicestests/src/com/android/server/timedetector/ReferenceWithHistoryTest.java
new file mode 100644
index 0000000..ce72499
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/ReferenceWithHistoryTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.timezonedetector.ReferenceWithHistory;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.StringWriter;
+
+@RunWith(AndroidJUnit4.class)
+public class ReferenceWithHistoryTest {
+
+ @Test
+ public void testBasicReferenceBehavior() {
+ // Create a reference that will retain 2 history values.
+ ReferenceWithHistory<String> referenceWithHistory =
+ new ReferenceWithHistory<>(2 /* history */);
+ TestRef<String> reference = new TestRef<>();
+
+ // Check unset behavior.
+ compareGet(referenceWithHistory, reference, null);
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "null");
+
+ // Try setting null.
+ setAndCompareReturnValue(referenceWithHistory, reference, null);
+ compareGet(referenceWithHistory, reference, null);
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "null");
+
+ // Try setting a non-null value.
+ setAndCompareReturnValue(referenceWithHistory, reference, "Foo");
+ compareGet(referenceWithHistory, reference, "Foo");
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "Foo");
+
+ // Try setting null again.
+ setAndCompareReturnValue(referenceWithHistory, reference, "Foo");
+ compareGet(referenceWithHistory, reference, "Foo");
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "Foo");
+
+ // Try a non-null value again.
+ setAndCompareReturnValue(referenceWithHistory, reference, "Bar");
+ compareGet(referenceWithHistory, reference, "Bar");
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "Bar");
+ }
+
+ @Test
+ public void testValueHistoryBehavior() {
+ // Create a reference that will retain 2 history values.
+ ReferenceWithHistory<String> referenceWithHistory =
+ new ReferenceWithHistory<>(2 /* history */);
+ TestRef<String> reference = new TestRef<>();
+
+ // Assert behavior before anything is set.
+ assertEquals(0, referenceWithHistory.getHistoryCount());
+
+ // Set a value (1).
+ setAndCompareReturnValue(referenceWithHistory, reference, "V1");
+ assertEquals(1, referenceWithHistory.getHistoryCount());
+
+ // Set a value (2).
+ setAndCompareReturnValue(referenceWithHistory, reference, "V2");
+ assertEquals(2, referenceWithHistory.getHistoryCount());
+
+ // Set a value (3).
+ // We should have hit the limit of "2 history values retained per key".
+ setAndCompareReturnValue(referenceWithHistory, reference, "V3");
+ assertEquals(2, referenceWithHistory.getHistoryCount());
+ }
+
+ /**
+ * A simple class that has the same behavior as ReferenceWithHistory without the history. Used
+ * in tests for comparison.
+ */
+ private static class TestRef<V> {
+ private V mValue;
+
+ public V get() {
+ return mValue;
+ }
+
+ public V set(V value) {
+ V previous = mValue;
+ mValue = value;
+ return previous;
+ }
+
+ public String toString() {
+ return String.valueOf(mValue);
+ }
+ }
+
+ private static void compareGet(
+ ReferenceWithHistory<?> referenceWithHistory, TestRef<?> reference, Object value) {
+ assertEquals(reference.get(), referenceWithHistory.get());
+ assertEquals(value, reference.get());
+ }
+
+ private static <T> void setAndCompareReturnValue(
+ ReferenceWithHistory<T> referenceWithHistory, TestRef<T> reference, T newValue) {
+ assertEquals(reference.set(newValue), referenceWithHistory.set(newValue));
+ }
+
+ private static void compareToString(
+ ReferenceWithHistory<?> referenceWithHistory, TestRef<?> reference, String expected) {
+ assertEquals(reference.toString(), referenceWithHistory.toString());
+ assertEquals(expected, referenceWithHistory.toString());
+ }
+
+ private static String dumpReferenceWithHistory(ReferenceWithHistory<?> referenceWithHistory) {
+ StringWriter stringWriter = new StringWriter();
+ try (IndentingPrintWriter ipw = new IndentingPrintWriter(stringWriter, " ")) {
+ referenceWithHistory.dump(ipw);
+ return stringWriter.toString();
+ }
+ }
+}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 8f62bcb..af3c55a 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2056,6 +2056,29 @@
return result;
}
+
+ /**
+ * Creates the {@link Intent} which can be used with {@link Context#startActivity(Intent)} to
+ * launch the activity for emergency dialer.
+ *
+ * @param number Optional number to call in emergency dialer
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public Intent createLaunchEmergencyDialerIntent(@Nullable String number) {
+ ITelecomService service = getTelecomService();
+ Intent result = null;
+ if (service != null) {
+ try {
+ result = service.createLaunchEmergencyDialerIntent(number);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error createLaunchEmergencyDialerIntent", e);
+ }
+ }
+ return result;
+ }
+
/**
* Determines whether Telecom would permit an incoming call to be added via the
* {@link #addNewIncomingCall(PhoneAccountHandle, Bundle)} API for the specified
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index cedc4b9..204c37e 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -266,6 +266,11 @@
**/
Intent createManageBlockedNumbersIntent();
+ /**
+ * @see TelecomServiceImpl#createLaunchEmergencyDialerIntent
+ */
+ Intent createLaunchEmergencyDialerIntent(in String number);
+
/**
* @see TelecomServiceImpl#isIncomingCallPermitted
*/
diff --git a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
index 367aad1..06c08f5 100644
--- a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
+++ b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
@@ -20,8 +20,8 @@
import android.database.Cursor;
import android.database.SQLException;
import android.os.Binder;
-import android.os.Build;
import android.os.PersistableBundle;
+import android.os.SystemProperties;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
@@ -43,7 +43,7 @@
*/
public class SmsNumberUtils {
private static final String TAG = "SmsNumberUtils";
- private static final boolean DBG = Build.IS_DEBUGGABLE;
+ private static final boolean DBG = SystemProperties.getInt("ro.debuggable", 0) == 1;
private static final String PLUS_SIGN = "+";
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0388580..5e8cba7 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -854,13 +854,6 @@
"always_show_emergency_alert_onoff_bool";
/**
- * The flag to disable cell broadcast severe alert when extreme alert is disabled.
- * @hide
- */
- public static final String KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL =
- "disable_severe_when_extreme_disabled_bool";
-
- /**
* The data call retry configuration for different types of APN.
* @hide
*/
@@ -3010,16 +3003,18 @@
"data_switch_validation_timeout_long";
/**
- * GPS configs. See android.hardware.gnss@1.0 IGnssConfiguration.
- * @hide
+ * GPS configs. See the GNSS HAL documentation for more details.
*/
public static final class Gps {
+ private Gps() {}
+
/** Prefix of all Gps.KEY_* constants. */
public static final String KEY_PREFIX = "gps.";
/**
* Location information during (and after) an emergency call is only provided over control
* plane signaling from the network.
+ * @hide
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_CP_ONLY = 0;
@@ -3027,6 +3022,7 @@
* Location information during (and after) an emergency call is provided over the data
* plane and serviced by the framework GNSS service, but if it fails, the carrier also
* supports control plane backup signaling.
+ * @hide
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK = 1;
@@ -3034,6 +3030,7 @@
* Location information during (and after) an emergency call is provided over the data plane
* and serviced by the framework GNSS service only. There is no backup signalling over the
* control plane if it fails.
+ * @hide
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_DP_ONLY = 2;
@@ -3050,10 +3047,14 @@
/**
* SUPL server host for SET Initiated & non-ES Network-Initiated SUPL requests.
* Default to supl.google.com
+ * @hide
*/
public static final String KEY_SUPL_HOST_STRING = KEY_PREFIX + "supl_host";
- /** SUPL server port. Default to 7275. */
+ /**
+ * SUPL server port. Default to 7275.
+ * @hide
+ */
public static final String KEY_SUPL_PORT_STRING = KEY_PREFIX + "supl_port";
/**
@@ -3061,6 +3062,7 @@
* with bits 0:7 representing a service indicator field, bits 8:15
* representing the minor version and bits 16:23 representing the
* major version. Default to 0x20000.
+ * @hide
*/
public static final String KEY_SUPL_VER_STRING = KEY_PREFIX + "supl_ver";
@@ -3068,6 +3070,7 @@
* SUPL_MODE configuration bit mask
* 1 - Mobile Station Based. This is default.
* 2 - Mobile Station Assisted.
+ * @hide
*/
public static final String KEY_SUPL_MODE_STRING = KEY_PREFIX + "supl_mode";
@@ -3076,6 +3079,7 @@
* (e.g. E911), and SUPL non-ES requests to only outside of non user emergency sessions.
* 0 - no.
* 1 - yes. This is default.
+ * @hide
*/
// TODO(b/119567985): name this key properly
public static final String KEY_SUPL_ES_STRING = KEY_PREFIX + "supl_es";
@@ -3085,6 +3089,7 @@
* 0 - Radio Resource Location Protocol in user plane and control plane. This is default.
* 1 - Enable LTE Positioning Protocol in user plane.
* 2 - Enable LTE Positioning Protocol in control plane.
+ * @hide
*/
public static final String KEY_LPP_PROFILE_STRING = KEY_PREFIX + "lpp_profile";
@@ -3092,6 +3097,7 @@
* Determine whether to use emergency PDN for emergency SUPL.
* 0 - no.
* 1 - yes. This is default.
+ * @hide
*/
public static final String KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING =
KEY_PREFIX + "use_emergency_pdn_for_emergency_supl";
@@ -3102,6 +3108,7 @@
* 1 - Use A-GLONASS in Radio Resource Control(RRC) control-plane.
* 2 - Use A-GLONASS in Radio Resource Location user-plane.
* 4 - Use A-GLONASS in LTE Positioning Protocol User plane.
+ * @hide
*/
public static final String KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING =
KEY_PREFIX + "a_glonass_pos_protocol_select";
@@ -3113,11 +3120,13 @@
* "1" - Lock Mobile Originated GPS functionalities.
* "2" - Lock Network initiated GPS functionalities.
* "3" - Lock both. This is default.
+ * @hide
*/
public static final String KEY_GPS_LOCK_STRING = KEY_PREFIX + "gps_lock";
/**
* Control Plane / SUPL NI emergency extension time in seconds. Default to "0".
+ * @hide
*/
public static final String KEY_ES_EXTENSION_SEC_STRING = KEY_PREFIX + "es_extension_sec";
@@ -3126,6 +3135,7 @@
* the non-framework entities requesting location directly from GNSS without involving
* the framework, as managed by IGnssVisibilityControl.hal. For example,
* "com.example.mdt com.example.ims".
+ * @hide
*/
public static final String KEY_NFW_PROXY_APPS_STRING = KEY_PREFIX + "nfw_proxy_apps";
@@ -3141,6 +3151,7 @@
* {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
* <p>
* The default value for this configuration is {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
+ * @hide
*/
public static final String KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT = KEY_PREFIX
+ "es_supl_control_plane_support_int";
@@ -3152,6 +3163,7 @@
* <p>
* A string array of PLMNs that do not support a control-plane mechanism for getting a
* user's location for SUPL ES.
+ * @hide
*/
public static final String KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY =
KEY_PREFIX + "es_supl_data_plane_only_roaming_plmn_string_array";
@@ -3177,59 +3189,6 @@
}
}
- /**
- * Wi-Fi configs used in Carrier Wi-Fi application.
- * TODO(b/132059890): Expose it in a future release as systemapi.
- *
- * @hide
- */
- public static final class Wifi {
- /** Prefix of all Wifi.KEY_* constants. */
- public static final String KEY_PREFIX = "wifi.";
-
- /**
- * Whenever any information under wifi namespace is changed, the version should be
- * incremented by 1 so that the device is able to figure out the latest profiles based on
- * the version.
- */
- public static final String KEY_CARRIER_PROFILES_VERSION_INT =
- KEY_PREFIX + "carrier_profiles_version_int";
-
- /**
- * It contains the package name of connection manager that the carrier owns.
- *
- * <P>Once it is installed, the profiles installed by Carrier Wi-Fi Application
- * will be deleted.
- * Once it is uninstalled, Carrier Wi-Fi Application will re-install the latest profiles.
- */
- public static final String KEY_CARRIER_CONNECTION_MANAGER_PACKAGE_STRING =
- KEY_PREFIX + "carrier_connection_manager_package_string";
- /**
- * It is to have the list of wifi networks profiles which contain the information about
- * the wifi-networks to which carrier wants the device to connect.
- */
- public static final String KEY_NETWORK_PROFILES_STRING_ARRAY =
- KEY_PREFIX + "network_profiles_string_array";
-
- /**
- * It is to have the list of Passpoint profiles which contain the information about
- * the Passpoint networks to which carrier wants the device to connect.
- */
- public static final String KEY_PASSPOINT_PROFILES_STRING_ARRAY =
- KEY_PREFIX + "passpoint_profiles_string_array";
-
- private static PersistableBundle getDefaults() {
- PersistableBundle defaults = new PersistableBundle();
- defaults.putInt(KEY_CARRIER_PROFILES_VERSION_INT, -1);
- defaults.putString(KEY_CARRIER_CONNECTION_MANAGER_PACKAGE_STRING, null);
- defaults.putStringArray(KEY_NETWORK_PROFILES_STRING_ARRAY, null);
- defaults.putStringArray(KEY_PASSPOINT_PROFILES_STRING_ARRAY, null);
- return defaults;
- }
-
- private Wifi() {}
- }
-
/**
* An int array containing CDMA enhanced roaming indicator values for Home (non-roaming) network.
* The default values come from 3GPP2 C.R1001 table 8.1-1.
@@ -3492,7 +3451,6 @@
sDefaults.putStringArray(KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
- sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
sDefaults.putStringArray(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS, new String[]{
"default:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
+ "320000:5000,640000:5000,1280000:5000,1800000:5000",
@@ -3806,7 +3764,6 @@
sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000);
sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true);
sDefaults.putAll(Gps.getDefaults());
- sDefaults.putAll(Wifi.getDefaults());
sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
new int[] {
1 /* Roaming Indicator Off */
diff --git a/telephony/java/android/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java
index eb8f672..84be4e8 100644
--- a/telephony/java/android/telephony/CbGeoUtils.java
+++ b/telephony/java/android/telephony/CbGeoUtils.java
@@ -18,14 +18,14 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.os.Build;
import android.text.TextUtils;
+import com.android.internal.telephony.util.TelephonyUtils;
+
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
-
/**
* This utils class is used for geo-fencing of CellBroadcast messages and is used by the cell
* broadcast module.
@@ -274,7 +274,7 @@
@Override
public String toString() {
String str = "Polygon: ";
- if (Build.IS_DEBUGGABLE) {
+ if (TelephonyUtils.IS_DEBUGGABLE) {
str += mVertices;
}
return str;
@@ -328,7 +328,7 @@
@Override
public String toString() {
String str = "Circle: ";
- if (Build.IS_DEBUGGABLE) {
+ if (TelephonyUtils.IS_DEBUGGABLE) {
str += mCenter + ", radius = " + mRadiusMeter;
}
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index a0af392..aee7cca 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -16,43 +16,65 @@
package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
+import android.util.Range;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
- * Reports modem activity information
+ * Reports modem activity information.
* @hide
*/
-public class ModemActivityInfo implements Parcelable {
+@SystemApi
+public final class ModemActivityInfo implements Parcelable {
/**
- * Tx power index
- * index 0 = tx_power < 0dBm
- * index 1 = 0dBm < tx_power < 5dBm
- * index 2 = 5dBm < tx_power < 15dBm
- * index 3 = 15dBm < tx_power < 20dBm
- * index 4 = tx_power > 20dBm
+ * Tx(transmit) power level. see power index below
+ * <ul>
+ * <li> index 0 = tx_power < 0dBm. </li>
+ * <li> index 1 = 0dBm < tx_power < 5dBm. </li>
+ * <li> index 2 = 5dBm < tx_power < 15dBm. </li>
+ * <li> index 3 = 15dBm < tx_power < 20dBm. </li>
+ * <li> index 4 = tx_power > 20dBm. </li>
+ * </ul>
*/
public static final int TX_POWER_LEVELS = 5;
+ private static final Range<Integer>[] TX_POWER_RANGES = new Range[] {
+ new Range<>(Integer.MIN_VALUE, 0),
+ new Range<>(0, 5),
+ new Range<>(5, 15),
+ new Range<>(15, 20),
+ new Range<>(20, Integer.MAX_VALUE)
+
+ };
private long mTimestamp;
private int mSleepTimeMs;
private int mIdleTimeMs;
- private int [] mTxTimeMs = new int[TX_POWER_LEVELS];
+ private List<TransmitPower> mTransmitPowerInfo = new ArrayList<>(TX_POWER_LEVELS);
private int mRxTimeMs;
- private int mEnergyUsed;
public ModemActivityInfo(long timestamp, int sleepTimeMs, int idleTimeMs,
- int[] txTimeMs, int rxTimeMs, int energyUsed) {
+ @NonNull int[] txTimeMs, int rxTimeMs) {
mTimestamp = timestamp;
mSleepTimeMs = sleepTimeMs;
mIdleTimeMs = idleTimeMs;
if (txTimeMs != null) {
- System.arraycopy(txTimeMs, 0, mTxTimeMs, 0, Math.min(txTimeMs.length, TX_POWER_LEVELS));
+ populateTransmitPowerRange(txTimeMs);
}
mRxTimeMs = rxTimeMs;
- mEnergyUsed = energyUsed;
+ }
+
+ /** helper API to populate tx power range for each bucket **/
+ private void populateTransmitPowerRange(@NonNull int[] transmitPowerMs) {
+ for (int i = 0; i < Math.min(transmitPowerMs.length, TX_POWER_LEVELS); i++) {
+ mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], transmitPowerMs[i]));
+ }
}
@Override
@@ -61,9 +83,8 @@
+ " mTimestamp=" + mTimestamp
+ " mSleepTimeMs=" + mSleepTimeMs
+ " mIdleTimeMs=" + mIdleTimeMs
- + " mTxTimeMs[]=" + Arrays.toString(mTxTimeMs)
+ + " mTransmitPowerInfo[]=" + mTransmitPowerInfo.toString()
+ " mRxTimeMs=" + mRxTimeMs
- + " mEnergyUsed=" + mEnergyUsed
+ "}";
}
@@ -82,9 +103,8 @@
txTimeMs[i] = in.readInt();
}
int rxTimeMs = in.readInt();
- int energyUsed = in.readInt();
return new ModemActivityInfo(timestamp, sleepTimeMs, idleTimeMs,
- txTimeMs, rxTimeMs, energyUsed);
+ txTimeMs, rxTimeMs);
}
public ModemActivityInfo[] newArray(int size) {
@@ -92,107 +112,158 @@
}
};
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeLong(mTimestamp);
dest.writeInt(mSleepTimeMs);
dest.writeInt(mIdleTimeMs);
for (int i = 0; i < TX_POWER_LEVELS; i++) {
- dest.writeInt(mTxTimeMs[i]);
+ dest.writeInt(mTransmitPowerInfo.get(i).getTimeInMillis());
}
dest.writeInt(mRxTimeMs);
- dest.writeInt(mEnergyUsed);
}
/**
- * @return timestamp of record creation
+ * @return milliseconds since boot, including mTimeInMillis spent in sleep.
+ * @see SystemClock#elapsedRealtime()
*/
public long getTimestamp() {
return mTimestamp;
}
+ /** @hide */
public void setTimestamp(long timestamp) {
mTimestamp = timestamp;
}
/**
- * @return tx time in ms. It's an array of tx times
- * with each index...
+ * @return an arrayList of {@link TransmitPower} with each element representing the total time where
+ * transmitter is awake time (in ms) for a given power range (in dbm).
+ *
+ * @see #TX_POWER_LEVELS
*/
- public int [] getTxTimeMillis() {
- return mTxTimeMs;
+ @NonNull
+ public List<TransmitPower> getTransmitPowerInfo() {
+ return mTransmitPowerInfo;
}
- public void setTxTimeMillis(int[] txTimeMs) {
- mTxTimeMs = txTimeMs;
+ /** @hide */
+ public void setTransmitTimeMillis(int[] txTimeMs) {
+ populateTransmitPowerRange(txTimeMs);
+ }
+
+ /** @hide */
+ @NonNull
+ public int[] getTransmitTimeMillis() {
+ int[] transmitTimeMillis = new int[TX_POWER_LEVELS];
+ for (int i = 0; i < transmitTimeMillis.length; i++) {
+ transmitTimeMillis[i] = mTransmitPowerInfo.get(i).getTimeInMillis();
+ }
+ return transmitTimeMillis;
}
/**
- * @return sleep time in ms.
+ * @return total mTimeInMillis (in ms) when modem is in a low power or sleep state.
*/
public int getSleepTimeMillis() {
return mSleepTimeMs;
}
+ /** @hide */
public void setSleepTimeMillis(int sleepTimeMillis) {
mSleepTimeMs = sleepTimeMillis;
}
/**
- * @return idle time in ms.
+ * @return total mTimeInMillis (in ms) when modem is awake but neither the transmitter nor receiver are
+ * active.
*/
public int getIdleTimeMillis() {
return mIdleTimeMs;
}
+ /** @hide */
public void setIdleTimeMillis(int idleTimeMillis) {
mIdleTimeMs = idleTimeMillis;
}
/**
- * @return rx time in ms.
+ * @return rx(receive) mTimeInMillis in ms.
*/
- public int getRxTimeMillis() {
+ public int getReceiveTimeMillis() {
return mRxTimeMs;
}
- public void setRxTimeMillis(int rxTimeMillis) {
+ /** @hide */
+ public void setReceiveTimeMillis(int rxTimeMillis) {
mRxTimeMs = rxTimeMillis;
}
/**
- * product of current(mA), voltage(V) and time(ms)
- * @return energy used
- */
- public int getEnergyUsed () {
- return mEnergyUsed;
- }
-
- public void setEnergyUsed(int energyUsed) {
- mEnergyUsed = energyUsed;
- }
-
- /**
- * @return if the record is valid
+ * @return {@code true} if this {@link ModemActivityInfo} record is valid,
+ * {@code false} otherwise.
+ *
+ * @hide
*/
public boolean isValid() {
- for (int txVal : getTxTimeMillis()) {
- if(txVal < 0) {
+ for (TransmitPower powerInfo : getTransmitPowerInfo()) {
+ if(powerInfo.getTimeInMillis() < 0) {
return false;
}
}
return ((getIdleTimeMillis() >= 0) && (getSleepTimeMillis() >= 0)
- && (getRxTimeMillis() >= 0) && (getEnergyUsed() >= 0) && !isEmpty());
+ && (getReceiveTimeMillis() >= 0) && !isEmpty());
}
private boolean isEmpty() {
- for (int txVal : getTxTimeMillis()) {
- if(txVal != 0) {
+ for (TransmitPower txVal : getTransmitPowerInfo()) {
+ if(txVal.getTimeInMillis() != 0) {
return false;
}
}
return ((getIdleTimeMillis() == 0) && (getSleepTimeMillis() == 0)
- && (getRxTimeMillis() == 0) && (getEnergyUsed() == 0));
+ && (getReceiveTimeMillis() == 0));
+ }
+
+ /**
+ * Transmit power Information, including the power range in dbm and the total time (in ms) where
+ * the transmitter is active/awake for this power range.
+ * e.g, range: 0dbm(lower) ~ 5dbm(upper)
+ * time: 5ms
+ */
+ public class TransmitPower {
+ private int mTimeInMillis;
+ private Range<Integer> mPowerRangeInDbm;
+ /** @hide */
+ public TransmitPower(@NonNull Range<Integer> range, int time) {
+ this.mTimeInMillis = time;
+ this.mPowerRangeInDbm = range;
+ }
+
+ /**
+ * @return the total time in ms where the transmitter is active/wake for this power range
+ * {@link #getPowerRangeInDbm()}.
+ */
+ public int getTimeInMillis() {
+ return mTimeInMillis;
+ }
+
+ /**
+ * @return the power range in dbm. e.g, range: 0dbm(lower) ~ 5dbm(upper)
+ */
+ @NonNull
+ public Range<Integer> getPowerRangeInDbm() {
+ return mPowerRangeInDbm;
+ }
+
+ @Override
+ public String toString() {
+ return "TransmitPower{"
+ + " mTimeInMillis=" + mTimeInMillis
+ + " mPowerRangeInDbm={" + mPowerRangeInDbm.getLower()
+ + "," + mPowerRangeInDbm.getUpper()
+ + "}}";
+ }
}
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 4a1bc1f..67afa7d 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,8 +16,6 @@
package android.telephony;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
-
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,9 +29,9 @@
import android.location.CountryDetector;
import android.net.Uri;
import android.os.PersistableBundle;
-import android.os.SystemProperties;
import android.provider.Contacts;
import android.provider.ContactsContract;
+import android.sysprop.TelephonyProperties;
import android.telecom.PhoneAccount;
import android.text.Editable;
import android.text.Spannable;
@@ -2659,7 +2657,7 @@
ps = NANP_IDP_STRING;
} else {
// in case, there is no IDD is found, we shouldn't convert it.
- ps = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, PLUS_SIGN_STRING);
+ ps = TelephonyProperties.operator_idp_string().orElse(PLUS_SIGN_STRING);
}
return ps;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c67ebfe..6cd75c6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -62,6 +62,7 @@
import android.os.WorkSource;
import android.provider.Settings.SettingNotFoundException;
import android.service.carrier.CarrierIdentifier;
+import android.sysprop.TelephonyProperties;
import android.telecom.CallScreeningService;
import android.telecom.InCallService;
import android.telecom.PhoneAccount;
@@ -101,7 +102,6 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.SmsApplication;
-import com.android.internal.telephony.TelephonyProperties;
import dalvik.system.VMRuntime;
@@ -390,7 +390,7 @@
@UnsupportedAppUsage
public MultiSimVariants getMultiSimConfiguration() {
String mSimConfig =
- SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
+ TelephonyProperties.multi_sim_config().orElse("");
if (mSimConfig.equals("dsds")) {
return MultiSimVariants.DSDS;
} else if (mSimConfig.equals("dsda")) {
@@ -456,8 +456,7 @@
* {@link #getActiveModemCount} returns 1 while this API returns 2.
*/
public @ModemCount int getSupportedModemCount() {
- return SystemProperties.getInt(TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS,
- getActiveModemCount());
+ return TelephonyProperties.max_active_modems().orElse(getActiveModemCount());
}
/**
@@ -2084,12 +2083,10 @@
/** {@hide} */
@UnsupportedAppUsage
private int getPhoneTypeFromProperty(int phoneId) {
- String type = getTelephonyProperty(phoneId,
- TelephonyProperties.CURRENT_ACTIVE_PHONE, null);
- if (type == null || type.isEmpty()) {
- return getPhoneTypeFromNetworkType(phoneId);
- }
- return Integer.parseInt(type);
+ Integer type = getTelephonyProperty(
+ phoneId, TelephonyProperties.current_active_phone(), null);
+ if (type != null) return type;
+ return getPhoneTypeFromNetworkType(phoneId);
}
private int getPhoneTypeFromNetworkType() {
@@ -2101,9 +2098,9 @@
// When the system property CURRENT_ACTIVE_PHONE, has not been set,
// use the system property for default network type.
// This is a fail safe, and can only happen at first boot.
- String mode = getTelephonyProperty(phoneId, "ro.telephony.default_network", null);
- if (mode != null && !mode.isEmpty()) {
- return TelephonyManager.getPhoneType(Integer.parseInt(mode));
+ Integer mode = getTelephonyProperty(phoneId, TelephonyProperties.default_network(), null);
+ if (mode != null) {
+ return TelephonyManager.getPhoneType(mode);
}
return TelephonyManager.PHONE_TYPE_NONE;
}
@@ -2207,7 +2204,7 @@
/** The ProductType used for LTE on CDMA devices */
private static final String sLteOnCdmaProductType =
- SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
+ TelephonyProperties.lte_on_cdma_product_type().orElse("");
/**
* Return if the current radio is LTE on CDMA. This
@@ -2225,8 +2222,8 @@
int curVal;
String productType = "";
- curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
- PhoneConstants.LTE_ON_CDMA_UNKNOWN);
+ curVal = TelephonyProperties.lte_on_cdma_device().orElse(
+ PhoneConstants.LTE_ON_CDMA_UNKNOWN);
retVal = curVal;
if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
@@ -2278,7 +2275,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public String getNetworkOperatorName(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, "");
+ return getTelephonyProperty(phoneId, TelephonyProperties.operator_alpha(), "");
}
/**
@@ -2322,7 +2319,7 @@
**/
@UnsupportedAppUsage
public String getNetworkOperatorForPhone(int phoneId) {
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
+ return getTelephonyProperty(phoneId, TelephonyProperties.operator_numeric(), "");
}
@@ -2386,8 +2383,7 @@
@UnsupportedAppUsage
public boolean isNetworkRoaming(int subId) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- return Boolean.parseBoolean(getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null));
+ return getTelephonyProperty(subId, TelephonyProperties.operator_is_roaming(), false);
}
/**
@@ -3344,8 +3340,7 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public String getSimOperatorNumericForPhone(int phoneId) {
- return getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
+ return getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_numeric(), "");
}
/**
@@ -3382,8 +3377,7 @@
*/
@UnsupportedAppUsage
public String getSimOperatorNameForPhone(int phoneId) {
- return getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "");
+ return getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_alpha(), "");
}
/**
@@ -3415,8 +3409,7 @@
*/
@UnsupportedAppUsage
public String getSimCountryIsoForPhone(int phoneId) {
- return getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
+ return getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_iso_country(), "");
}
/**
@@ -6495,6 +6488,15 @@
}
/**
+ * Inserts or updates a list property. Expands the list if its length is not enough.
+ */
+ private static <T> List<T> updateTelephonyProperty(List<T> prop, int phoneId, T value) {
+ List<T> ret = new ArrayList<>(prop);
+ while (ret.size() <= phoneId) ret.add(null);
+ ret.set(phoneId, value);
+ return ret;
+ }
+ /**
* Convenience function for retrieving a value from the secure settings
* value list as an integer. Note that internally setting values are
* always stored as strings; this function converts the string to an
@@ -6585,7 +6587,7 @@
}
/**
- * Gets a per-phone telephony property.
+ * Gets a per-phone telephony property from a property name.
*
* @hide
*/
@@ -6603,6 +6605,15 @@
}
/**
+ * Gets a typed per-phone telephony property from a schematized list property.
+ */
+ private static <T> T getTelephonyProperty(int phoneId, List<T> prop, T defaultValue) {
+ T ret = null;
+ if (phoneId >= 0 && phoneId < prop.size()) ret = prop.get(phoneId);
+ return ret != null ? ret : defaultValue;
+ }
+
+ /**
* Gets a global telephony property.
*
* See also getTelephonyProperty(phoneId, property, defaultVal). Most telephony properties are
@@ -8979,7 +8990,7 @@
}
/**
- * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the default phone.
+ * Set TelephonyProperties.icc_operator_numeric for the default phone.
*
* @hide
*/
@@ -8989,18 +9000,21 @@
}
/**
- * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the given phone.
+ * Set TelephonyProperties.icc_operator_numeric for the given phone.
*
* @hide
*/
@UnsupportedAppUsage
public void setSimOperatorNumericForPhone(int phoneId, String numeric) {
- setTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, numeric);
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.icc_operator_numeric(), phoneId, numeric);
+ TelephonyProperties.icc_operator_numeric(newList);
+ }
}
/**
- * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the default phone.
+ * Set TelephonyProperties.icc_operator_alpha for the default phone.
*
* @hide
*/
@@ -9010,18 +9024,21 @@
}
/**
- * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the given phone.
+ * Set TelephonyProperties.icc_operator_alpha for the given phone.
*
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public void setSimOperatorNameForPhone(int phoneId, String name) {
- setTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, name);
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.icc_operator_alpha(), phoneId, name);
+ TelephonyProperties.icc_operator_alpha(newList);
+ }
}
/**
- * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY for the default phone.
+ * Set TelephonyProperties.icc_operator_iso_country for the default phone.
*
* @hide
*/
@@ -9031,18 +9048,21 @@
}
/**
- * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY for the given phone.
+ * Set TelephonyProperties.icc_operator_iso_country for the given phone.
*
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public void setSimCountryIsoForPhone(int phoneId, String iso) {
- setTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso);
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.icc_operator_iso_country(), phoneId, iso);
+ TelephonyProperties.icc_operator_iso_country(newList);
+ }
}
/**
- * Set TelephonyProperties.PROPERTY_SIM_STATE for the default phone.
+ * Set TelephonyProperties.sim_state for the default phone.
*
* @hide
*/
@@ -9052,14 +9072,17 @@
}
/**
- * Set TelephonyProperties.PROPERTY_SIM_STATE for the given phone.
+ * Set TelephonyProperties.sim_state for the given phone.
*
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public void setSimStateForPhone(int phoneId, String state) {
- setTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_SIM_STATE, state);
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.sim_state(), phoneId, state);
+ TelephonyProperties.sim_state(newList);
+ }
}
/**
@@ -9164,7 +9187,11 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public void setBasebandVersionForPhone(int phoneId, String version) {
- setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_BASEBAND_VERSION, version);
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.baseband_version(), phoneId, version);
+ TelephonyProperties.baseband_version(newList);
+ }
}
/**
@@ -9187,8 +9214,8 @@
*/
private String getBasebandVersionLegacy(int phoneId) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- String prop = TelephonyProperties.PROPERTY_BASEBAND_VERSION +
- ((phoneId == 0) ? "" : Integer.toString(phoneId));
+ String prop = "gsm.version.baseband"
+ + ((phoneId == 0) ? "" : Integer.toString(phoneId));
return SystemProperties.get(prop);
}
return null;
@@ -9205,7 +9232,7 @@
if (version != null && !version.isEmpty()) {
setBasebandVersionForPhone(phoneId, version);
}
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_BASEBAND_VERSION, "");
+ return getTelephonyProperty(phoneId, TelephonyProperties.baseband_version(), "");
}
/**
@@ -9231,8 +9258,9 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public void setPhoneType(int phoneId, int type) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- TelephonyManager.setTelephonyProperty(phoneId,
- TelephonyProperties.CURRENT_ACTIVE_PHONE, String.valueOf(type));
+ List<Integer> newList = updateTelephonyProperty(
+ TelephonyProperties.current_active_phone(), phoneId, type);
+ TelephonyProperties.current_active_phone(newList);
}
}
@@ -9261,8 +9289,8 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public String getOtaSpNumberSchemaForPhone(int phoneId, String defaultValue) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- return TelephonyManager.getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA, defaultValue);
+ return getTelephonyProperty(
+ phoneId, TelephonyProperties.otasp_num_schema(), defaultValue);
}
return defaultValue;
@@ -9292,8 +9320,7 @@
*/
public boolean getSmsReceiveCapableForPhone(int phoneId, boolean defaultValue) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- return Boolean.parseBoolean(TelephonyManager.getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_SMS_RECEIVE, String.valueOf(defaultValue)));
+ return getTelephonyProperty(phoneId, TelephonyProperties.sms_receive(), defaultValue);
}
return defaultValue;
@@ -9323,8 +9350,7 @@
*/
public boolean getSmsSendCapableForPhone(int phoneId, boolean defaultValue) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- return Boolean.parseBoolean(TelephonyManager.getTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_SMS_SEND, String.valueOf(defaultValue)));
+ return getTelephonyProperty(phoneId, TelephonyProperties.sms_send(), defaultValue);
}
return defaultValue;
@@ -9364,7 +9390,9 @@
@UnsupportedAppUsage
public void setNetworkOperatorNameForPhone(int phoneId, String name) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, name);
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.operator_alpha(), phoneId, name);
+ TelephonyProperties.operator_alpha(newList);
}
}
@@ -9386,7 +9414,11 @@
*/
@UnsupportedAppUsage
public void setNetworkOperatorNumericForPhone(int phoneId, String numeric) {
- setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, numeric);
+ if (SubscriptionManager.isValidPhoneId(phoneId)) {
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.operator_numeric(), phoneId, numeric);
+ TelephonyProperties.operator_numeric(newList);
+ }
}
/**
@@ -9408,8 +9440,9 @@
@UnsupportedAppUsage
public void setNetworkRoamingForPhone(int phoneId, boolean isRoaming) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
- isRoaming ? "true" : "false");
+ List<Boolean> newList = updateTelephonyProperty(
+ TelephonyProperties.operator_is_roaming(), phoneId, isRoaming);
+ TelephonyProperties.operator_is_roaming(newList);
}
}
@@ -9436,9 +9469,10 @@
@UnsupportedAppUsage
public void setDataNetworkTypeForPhone(int phoneId, int type) {
if (SubscriptionManager.isValidPhoneId(phoneId)) {
- setTelephonyProperty(phoneId,
- TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
+ List<String> newList = updateTelephonyProperty(
+ TelephonyProperties.data_network_type(), phoneId,
ServiceState.rilRadioTechnologyToString(type));
+ TelephonyProperties.data_network_type(newList);
}
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 4421c77..9cbcd7f 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -16,10 +16,12 @@
package com.android.internal.telephony;
-import android.telephony.TelephonyManager;
+import android.sysprop.TelephonyProperties;
import dalvik.annotation.compat.UnsupportedAppUsage;
+import java.util.Optional;
+
/**
* {@hide}
*/
@@ -233,8 +235,10 @@
int NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 33;
@UnsupportedAppUsage
- int PREFERRED_NETWORK_MODE = Integer.parseInt(TelephonyManager.getTelephonyProperty(0,
- "ro.telephony.default_network", Integer.toString(NETWORK_MODE_WCDMA_PREF)));
+ int PREFERRED_NETWORK_MODE = Optional.of(TelephonyProperties.default_network())
+ .filter(list -> !list.isEmpty())
+ .map(list -> list.get(0))
+ .orElse(NETWORK_MODE_WCDMA_PREF);
int BAND_MODE_UNSPECIFIED = 0; //"unspecified" (selected by baseband automatically)
int BAND_MODE_EURO = 1; //"EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000)
diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
index dcea9bb..d672642 100644
--- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
+++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
@@ -18,11 +18,11 @@
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
-import android.os.Build;
import android.telephony.Rlog;
import android.util.SparseIntArray;
import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.internal.telephony.util.TelephonyUtils;
import com.android.internal.telephony.util.XmlUtils;
import dalvik.annotation.compat.UnsupportedAppUsage;
@@ -30,7 +30,7 @@
public class Sms7BitEncodingTranslator {
private static final String TAG = "Sms7BitEncodingTranslator";
@UnsupportedAppUsage
- private static final boolean DBG = Build.IS_DEBUGGABLE ;
+ private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE;
private static boolean mIs7BitTranslationTableLoaded = false;
private static SparseIntArray mTranslationTable = null;
@UnsupportedAppUsage
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 8b95617..1f7715b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -16,10 +16,8 @@
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
-
import android.content.res.Resources;
-import android.os.SystemProperties;
+import android.sysprop.TelephonyProperties;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
import android.telephony.SmsCbLocation;
@@ -34,7 +32,6 @@
import com.android.internal.telephony.SmsConstants;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.sms.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
@@ -862,7 +859,7 @@
// TODO: Skip it for EF SMS(SUBMIT and DELIVER) because the IDD depends on current network?
// 2) Adds the '+' prefix if TON is International
// 3) Keeps the '+' if address starts with the '+'
- String idd = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, null);
+ String idd = TelephonyProperties.operator_idp_string().orElse(null);
addr.address = new String(addr.origBytes);
if (!TextUtils.isEmpty(idd) && addr.address.startsWith(idd)) {
addr.address = "+" + addr.address.substring(idd.length());
@@ -940,14 +937,13 @@
// msgId==0 is (sometimes?) treated specially by lower levels.
// Specifically, the ID is not preserved for delivery ACKs.
// Hence, avoid 0 -- constraining the range to 1..65535.
- int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1);
- String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1);
+ int msgId = TelephonyProperties.cdma_msg_id().orElse(1);
+ int nextMsgId = msgId % 0xFFFF + 1;
try{
- SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId);
+ TelephonyProperties.cdma_msg_id(nextMsgId);
if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
- Rlog.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId);
- Rlog.d(LOG_TAG, "readback gets " +
- SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID));
+ Rlog.d(LOG_TAG, "next persist.radio.cdma.msgid = " + nextMsgId);
+ Rlog.d(LOG_TAG, "readback gets " + TelephonyProperties.cdma_msg_id().orElse(1));
}
} catch(RuntimeException ex) {
Rlog.e(LOG_TAG, "set nextMessage ID failed: " + ex);