Merge "Update set|getRetryIntervalsMs to Millis"
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 00d0771..5a0439b 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -471,6 +471,22 @@
},
}
+java_library {
+ name: "android_system_server_stubs_current",
+ defaults: ["android_stubs_dists_default"],
+ srcs: [":services-non-updatable-stubs"],
+ installable: false,
+ static_libs: [
+ "android_module_lib_stubs_current",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+ java_version: "1.8",
+ dist: {
+ dir: "apistubs/android/system-server",
+ },
+}
+
/////////////////////////////////////////////////////////////////////
// hwbinder.stubs provides APIs required for building HIDL Java
// libraries.
diff --git a/api/Android.bp b/api/Android.bp
index 6e83c08..2df31ec 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -341,7 +341,7 @@
{
targets: ["sdk", "win_sdk"],
dir: "apistubs/android/system-server/api",
- dest: "merge-android.txt",
+ dest: "android.txt",
},
],
}
@@ -364,7 +364,7 @@
{
targets: ["sdk", "win_sdk"],
dir: "apistubs/android/system-server/api",
- dest: "merge-removed.txt",
+ dest: "removed.txt",
},
],
}
diff --git a/core/api/current.txt b/core/api/current.txt
index c592891..d82cd72 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40406,7 +40406,6 @@
method @IntRange(from=1, to=261) public int getBand();
method @IntRange(from=1) public int getCellBandwidthDownlinkKhz();
method @IntRange(from=1) public int getCellBandwidthUplinkKhz();
- method @Deprecated public int getChannelNumber();
method public int getConnectionStatus();
method @IntRange(from=0) public int getDownlinkChannelNumber();
method @IntRange(from=0) public int getDownlinkFrequencyKhz();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index fd6d47e..e8f8f3a 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1683,6 +1683,7 @@
public class TelephonyManager {
method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting);
method public int getCarrierIdListVersion();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCertsFromCarrierPrivilegeAccessRules();
method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index 59b3555..fad6cd3 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.content.pm.PackageInfo;
import android.os.Parcel;
import java.lang.annotation.Retention;
@@ -101,12 +102,20 @@
return VALUE_UNDEFINED;
}
- /** Returns the minimum version code the override applies to. */
+ /**
+ * Returns the minimum APK version code the override applies to.
+ *
+ * @see PackageInfo#getLongVersionCode()
+ */
public long getMinVersionCode() {
return mMinVersionCode;
}
- /** Returns the minimum version code the override applies from. */
+ /**
+ * Returns the maximum APK version code the override applies from.
+ *
+ * @see PackageInfo#getLongVersionCode()
+ */
public long getMaxVersionCode() {
return mMaxVersionCode;
}
@@ -146,9 +155,11 @@
private boolean mEnabled;
/**
- * Sets the minimum version code the override should apply from.
+ * Sets the minimum APK version code the override should apply from.
*
* default value: {@code Long.MIN_VALUE}.
+ *
+ * @see PackageInfo#getLongVersionCode()
*/
@NonNull
public Builder setMinVersionCode(long minVersionCode) {
@@ -157,9 +168,11 @@
}
/**
- * Sets the maximum version code the override should apply to.
+ * Sets the maximum APK version code the override should apply to.
*
* default value: {@code Long.MAX_VALUE}.
+ *
+ * @see PackageInfo#getLongVersionCode()
*/
@NonNull
public Builder setMaxVersionCode(long maxVersionCode) {
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
index f0def805..4e674f6 100644
--- a/core/java/android/content/pm/OWNERS
+++ b/core/java/android/content/pm/OWNERS
@@ -4,7 +4,8 @@
toddke@google.com
patb@google.com
-per-file PackageParser.java = chiuwinson@google.com
+per-file PackageParser.java = set noparent
+per-file PackageParser.java = chiuwinson@google.com,patb@google.com,toddke@google.com
per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
per-file AppSearchPerson.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS
per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index e385cd2..362a205 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -26,6 +26,7 @@
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.util.Slog;
@@ -334,11 +335,23 @@
* in Keystore land as SIDs, and are used during key generation.
* @hide
*/
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
public long[] getAuthenticatorIds() {
+ return getAuthenticatorIds(UserHandle.myUserId());
+ }
+
+ /**
+ * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates,
+ * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known
+ * in Keystore land as SIDs, and are used during key generation.
+ *
+ * @param userId Android user ID for user to look up.
+ *
+ * @hide
+ */
+ public long[] getAuthenticatorIds(int userId) {
if (mService != null) {
try {
- return mService.getAuthenticatorIds();
+ return mService.getAuthenticatorIds(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -347,6 +360,5 @@
return new long[0];
}
}
-
}
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index a6f6c1e..35424829 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -55,5 +55,7 @@
// Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet
// the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
// land as SIDs, and are used during key generation.
- long[] getAuthenticatorIds();
+ // If userId is not equal to the calling user ID, the caller must have the
+ // USE_BIOMETRIC_INTERNAL permission.
+ long[] getAuthenticatorIds(in int userId);
}
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java
index 4d8cf91..0e9ccf1 100644
--- a/core/java/android/net/vcn/VcnTransportInfo.java
+++ b/core/java/android/net/vcn/VcnTransportInfo.java
@@ -16,14 +16,23 @@
package android.net.vcn;
+import static android.net.NetworkCapabilities.REDACT_ALL;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.net.NetworkCapabilities;
import android.net.TransportInfo;
import android.net.wifi.WifiInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.SubscriptionManager;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.Objects;
/**
@@ -37,28 +46,41 @@
* SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
* will be {@code null}.
*
+ * <p>Receipt of a VcnTransportInfo requires the NETWORK_SETTINGS permission; else the entire
+ * VcnTransportInfo instance will be redacted.
+ *
* @hide
*/
public class VcnTransportInfo implements TransportInfo, Parcelable {
@Nullable private final WifiInfo mWifiInfo;
private final int mSubId;
+ /**
+ * The redaction scheme to use when parcelling.
+ *
+ * <p>The TransportInfo/NetworkCapabilities redaction mechanisms rely on redaction being
+ * performed at parcelling time. This means that the redaction scheme must be stored for later
+ * use.
+ *
+ * <p>Since the redaction scheme itself is not parcelled, this field is listed as a transient.
+ *
+ * <p>Defaults to REDACT_ALL when constructed using public constructors, or creating from
+ * parcels.
+ */
+ private final transient long mRedactions;
+
public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
- this(wifiInfo, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ this(wifiInfo, INVALID_SUBSCRIPTION_ID, REDACT_ALL);
}
public VcnTransportInfo(int subId) {
- this(null /* wifiInfo */, subId);
+ this(null /* wifiInfo */, subId, REDACT_ALL);
}
- private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) {
- if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- throw new IllegalArgumentException(
- "VcnTransportInfo requires either non-null WifiInfo or valid subId");
- }
-
+ private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) {
mWifiInfo = wifiInfo;
mSubId = subId;
+ mRedactions = redactions;
}
/**
@@ -86,8 +108,19 @@
return mSubId;
}
+ /**
+ * Gets the redaction scheme
+ *
+ * @hide
+ */
+ @VisibleForTesting(visibility = PRIVATE)
+ public long getRedaction() {
+ return mRedactions;
+ }
+
@Override
public int hashCode() {
+ // mRedactions not hashed, as it is a transient, for control of parcelling
return Objects.hash(mWifiInfo, mSubId);
}
@@ -96,6 +129,7 @@
if (!(o instanceof VcnTransportInfo)) return false;
final VcnTransportInfo that = (VcnTransportInfo) o;
+ // mRedactions not compared, as it is a transient, for control of parcelling
return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
}
@@ -105,17 +139,59 @@
return 0;
}
+ @Override
+ @NonNull
+ public TransportInfo makeCopy(long redactions) {
+ return new VcnTransportInfo(
+ mWifiInfo == null ? null : mWifiInfo.makeCopy(redactions), mSubId, redactions);
+ }
+
+ @Override
+ public long getApplicableRedactions() {
+ long redactions = REDACT_FOR_NETWORK_SETTINGS;
+
+ // Add additional wifi redactions if necessary
+ if (mWifiInfo != null) {
+ redactions |= mWifiInfo.getApplicableRedactions();
+ }
+
+ return redactions;
+ }
+
+ private boolean shouldParcelNetworkSettingsFields() {
+ return (mRedactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) == 0;
+ }
+
/** {@inheritDoc} */
@Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {}
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(shouldParcelNetworkSettingsFields() ? mSubId : INVALID_SUBSCRIPTION_ID);
+ dest.writeParcelable(
+ shouldParcelNetworkSettingsFields() ? (Parcelable) mWifiInfo : null, flags);
+ }
+
+ @Override
+ public String toString() {
+ return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }";
+ }
/** Implement the Parcelable interface */
public static final @NonNull Creator<VcnTransportInfo> CREATOR =
new Creator<VcnTransportInfo>() {
public VcnTransportInfo createFromParcel(Parcel in) {
- // return null instead of a default VcnTransportInfo to avoid leaking
- // information about this being a VCN Network (instead of macro cellular, etc)
- return null;
+ final int subId = in.readInt();
+ final WifiInfo wifiInfo = in.readParcelable(null);
+
+ // If all fields are their null values, return null TransportInfo to avoid
+ // leaking information about this being a VCN Network (instead of macro
+ // cellular, etc)
+ if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) {
+ return null;
+ }
+
+ // Prevent further forwarding by redacting everything in future parcels from
+ // this VcnTransportInfo
+ return new VcnTransportInfo(wifiInfo, subId, REDACT_ALL);
}
public VcnTransportInfo[] newArray(int size) {
diff --git a/core/java/android/nfc/NfcControllerAlwaysOnListener.java b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
index 96707bb..6ae58fd 100644
--- a/core/java/android/nfc/NfcControllerAlwaysOnListener.java
+++ b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
@@ -52,6 +52,14 @@
*/
public void register(@NonNull Executor executor,
@NonNull ControllerAlwaysOnListener listener) {
+ try {
+ if (!mAdapter.isControllerAlwaysOnSupported()) {
+ return;
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to register");
+ return;
+ }
synchronized (this) {
if (mListenerMap.containsKey(listener)) {
return;
@@ -75,6 +83,14 @@
* @param listener user implementation of the {@link ControllerAlwaysOnListener}
*/
public void unregister(@NonNull ControllerAlwaysOnListener listener) {
+ try {
+ if (!mAdapter.isControllerAlwaysOnSupported()) {
+ return;
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to unregister");
+ return;
+ }
synchronized (this) {
if (!mListenerMap.containsKey(listener)) {
return;
diff --git a/core/java/com/android/internal/graphics/OWNERS b/core/java/com/android/internal/graphics/OWNERS
new file mode 100644
index 0000000..5851cbb
--- /dev/null
+++ b/core/java/com/android/internal/graphics/OWNERS
@@ -0,0 +1 @@
+include /graphics/java/android/graphics/OWNERS
\ No newline at end of file
diff --git a/core/jni/include/android_runtime/AndroidRuntime.h b/core/jni/include/android_runtime/AndroidRuntime.h
index d86d934..bf2ba77 100644
--- a/core/jni/include/android_runtime/AndroidRuntime.h
+++ b/core/jni/include/android_runtime/AndroidRuntime.h
@@ -19,7 +19,6 @@
#ifndef _RUNTIME_ANDROID_RUNTIME_H
#define _RUNTIME_ANDROID_RUNTIME_H
-#include <binder/IBinder.h>
#include <jni.h>
#include <pthread.h>
#include <utils/Errors.h>
diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
index 43f9b6f..48f4288 100644
--- a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
+++ b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
@@ -19,6 +19,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -62,7 +63,36 @@
}
@Test
+ public void testRegister_RegisterUnregisterWhenNotSupported() throws RemoteException {
+ // isControllerAlwaysOnSupported() returns false, not supported.
+ doReturn(false).when(mNfcAdapter).isControllerAlwaysOnSupported();
+ NfcControllerAlwaysOnListener mListener =
+ new NfcControllerAlwaysOnListener(mNfcAdapter);
+ ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
+ ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
+
+ // Verify that the state listener will not registered with the NFC Adapter
+ mListener.register(getExecutor(), mockListener1);
+ verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+
+ // Register a second client and no any call to NFC Adapter
+ mListener.register(getExecutor(), mockListener2);
+ verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+
+ // Unregister first listener, and no any call to NFC Adapter
+ mListener.unregister(mockListener1);
+ verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+ verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+
+ // Unregister second listener, and no any call to NFC Adapter
+ mListener.unregister(mockListener2);
+ verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
+ verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+ }
+
+ @Test
public void testRegister_RegisterUnregister() throws RemoteException {
+ doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
NfcControllerAlwaysOnListener mListener =
new NfcControllerAlwaysOnListener(mNfcAdapter);
ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
@@ -89,6 +119,7 @@
@Test
public void testRegister_FirstRegisterFails() throws RemoteException {
+ doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
NfcControllerAlwaysOnListener mListener =
new NfcControllerAlwaysOnListener(mNfcAdapter);
ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
@@ -116,6 +147,7 @@
@Test
public void testRegister_RegisterSameListenerTwice() throws RemoteException {
+ doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
NfcControllerAlwaysOnListener mListener =
new NfcControllerAlwaysOnListener(mNfcAdapter);
ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
@@ -132,7 +164,7 @@
@Test
public void testNotify_AllListenersNotified() throws RemoteException {
-
+ doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
for (int i = 0; i < 10; i++) {
@@ -149,7 +181,8 @@
}
@Test
- public void testStateChange_CorrectValue() {
+ public void testStateChange_CorrectValue() throws RemoteException {
+ doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
runStateChangeValue(true, true);
runStateChangeValue(false, false);
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index bd72d45..00219e7 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -74,16 +74,19 @@
* @param locked - whether it is a lock (true) or unlock (false) event
* @param syntheticPassword - if it is an unlock event with the password, pass the synthetic
* password provided by the LockSettingService
+ * @param unlockingSids - KeyMint secure user IDs that should be permitted to unlock
+ * UNLOCKED_DEVICE_REQUIRED keys.
*
* @return 0 if successful or a {@code ResponseCode}.
*/
public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
- @Nullable byte[] syntheticPassword) {
+ @Nullable byte[] syntheticPassword, @Nullable long[] unlockingSids) {
try {
if (locked) {
- getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null);
+ getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null, unlockingSids);
} else {
- getService().onLockScreenEvent(LockScreenEvent.UNLOCK, userId, syntheticPassword);
+ getService().onLockScreenEvent(
+ LockScreenEvent.UNLOCK, userId, syntheticPassword, unlockingSids);
}
return 0;
} catch (RemoteException | NullPointerException e) {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
index 2a95cfe..44d5a0c 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm
@@ -85,14 +85,14 @@
key 9 {
label: '9'
base: '\u0669'
- shift: '('
+ shift: ')'
capslock: '9'
}
key 0 {
label: '0'
base: '\u0660'
- shift: ')'
+ shift: '('
capslock: '0'
}
diff --git a/services/Android.bp b/services/Android.bp
index 0a01c95..57a7bc5 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -146,68 +146,12 @@
" --hide-package com.google.android.startop.iorap" +
" --hide DeprecationMismatch" +
" --hide HiddenTypedefConstant",
- visibility: ["//visibility:private"],
+ visibility: ["//frameworks/base:__subpackages__"],
filter_packages: ["com.android."],
}
droidstubs {
- name: "services-stubs.sources",
- srcs: [":services-all-sources"],
- defaults: ["services-stubs-default"],
- check_api: {
- current: {
- api_file: "api/current.txt",
- removed_api_file: "api/removed.txt",
- },
- last_released: {
- api_file: ":android.api.system-server.latest",
- removed_api_file: ":removed.api.system-server.latest",
- baseline_file: ":android-incompatibilities.api.system-server.latest",
- },
- api_lint: {
- enabled: true,
- new_since: ":android.api.system-server.latest",
- baseline_file: "api/lint-baseline.txt",
- },
- },
- dists: [
- {
- targets: [
- "sdk",
- "win_sdk",
- ],
- dir: "apistubs/android/system-server/api",
- dest: "android.txt",
- tag: ".api.txt",
- },
- {
- targets: [
- "sdk",
- "win_sdk",
- ],
- dir: "apistubs/android/system-server/api",
- dest: "removed.txt",
- tag: ".removed-api.txt",
- },
- ],
-}
-
-java_library {
- name: "android_system_server_stubs_current",
- defaults: ["android_stubs_dists_default"],
- srcs: [":services-stubs.sources"],
- installable: false,
- static_libs: ["android_module_lib_stubs_current"],
- sdk_version: "none",
- system_modules: "none",
- java_version: "1.8",
- dist: {
- dir: "apistubs/android/system-server",
- },
-}
-
-droidstubs {
- name: "services-non-updatable-stubs.sources",
+ name: "services-non-updatable-stubs",
srcs: [":services-non-updatable-sources"],
defaults: ["services-stubs-default"],
check_api: {
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 1312679..8fd8b5c 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -289,7 +289,7 @@
}
@Override
- public long[] getAuthenticatorIds() throws RemoteException {
+ public long[] getAuthenticatorIds(int userId) throws RemoteException {
// In this method, we're not checking whether the caller is permitted to use face
// API because current authenticator ID is leaked (in a more contrived way) via Android
// Keystore (android.security.keystore package): the user of that API can create a key
@@ -307,9 +307,13 @@
// method from inside app processes.
final int callingUserId = UserHandle.getCallingUserId();
+ if (userId != callingUserId) {
+ getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
+ "Must have " + USE_BIOMETRIC_INTERNAL + " permission.");
+ }
final long identity = Binder.clearCallingIdentity();
try {
- return mBiometricService.getAuthenticatorIds(callingUserId);
+ return mBiometricService.getAuthenticatorIds(userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 117c85b..ea1c68d 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1266,7 +1266,7 @@
private void unlockKeystore(byte[] password, int userHandle) {
if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
- Authorization.onLockScreenEvent(false, userHandle, password);
+ Authorization.onLockScreenEvent(false, userHandle, password, null);
}
@VisibleForTesting /** Note: this method is overridden in unit tests */
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index ff763fc..90b095b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -39,6 +39,7 @@
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
import android.net.Uri;
import android.os.Binder;
@@ -185,8 +186,6 @@
private boolean mTrustAgentsCanRun = false;
private int mCurrentUser = UserHandle.USER_SYSTEM;
- private Authorization mAuthorizationService;
-
public TrustManagerService(Context context) {
super(context);
mContext = context;
@@ -196,7 +195,6 @@
mStrongAuthTracker = new StrongAuthTracker(context);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mSettingsObserver = new SettingsObserver(mHandler);
- mAuthorizationService = new Authorization();
}
@Override
@@ -698,13 +696,14 @@
}
if (changed) {
dispatchDeviceLocked(userId, locked);
-
- Authorization.onLockScreenEvent(locked, userId, null);
+ Authorization.onLockScreenEvent(locked, userId, null,
+ getBiometricSids(userId));
// Also update the user's profiles who have unified challenge, since they
// share the same unlocked state (see {@link #isDeviceLocked(int)})
for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
- mAuthorizationService.onLockScreenEvent(locked, profileHandle, null);
+ Authorization.onLockScreenEvent(locked, profileHandle, null,
+ getBiometricSids(profileHandle));
}
}
}
@@ -1044,6 +1043,14 @@
}
}
+ private long[] getBiometricSids(int userId) {
+ BiometricManager biometricManager = mContext.getSystemService(BiometricManager.class);
+ if (biometricManager == null) {
+ return null;
+ }
+ return biometricManager.getAuthenticatorIds(userId);
+ }
+
// User lifecycle
@Override
@@ -1255,7 +1262,8 @@
mDeviceLockedForUser.put(userId, locked);
}
- Authorization.onLockScreenEvent(locked, userId, null);
+ Authorization.onLockScreenEvent(locked, userId, null,
+ getBiometricSids(userId));
if (locked) {
try {
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index dc2b576..65b947c 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -1558,8 +1558,22 @@
teardownAsynchronously();
} /* networkUnwantedCallback */,
(status) -> {
- if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
- clearFailedAttemptCounterAndSafeModeAlarm();
+ switch (status) {
+ case NetworkAgent.VALIDATION_STATUS_VALID:
+ clearFailedAttemptCounterAndSafeModeAlarm();
+ break;
+ case NetworkAgent.VALIDATION_STATUS_NOT_VALID:
+ // Will only set a new alarm if no safe mode alarm is
+ // currently scheduled.
+ setSafeModeAlarm();
+ break;
+ default:
+ Slog.wtf(
+ TAG,
+ "Unknown validation status "
+ + status
+ + "; ignoring");
+ break;
}
} /* validationStatusCallback */);
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index bbcc2c1..e8050fa 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -29,3 +29,4 @@
per-file com_android_server_security_* = file:/core/java/android/security/OWNERS
per-file com_android_server_tv_* = file:/media/java/android/media/tv/OWNERS
per-file com_android_server_vibrator_* = file:/services/core/java/com/android/server/vibrator/OWNERS
+per-file com_android_server_am_CachedAppOptimizer.cpp = timmurray@google.com, edgararriaga@google.com, dualli@google.com, carmenjackson@google.com, philipcuadra@google.com
\ No newline at end of file
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 1208ecc..9706d7f 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -23,11 +23,13 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ResolveInfo;
import android.os.Handler;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UpdateEngine;
import android.os.UpdateEngineCallback;
import android.os.UserHandle;
@@ -42,6 +44,9 @@
import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
import com.android.server.wm.ActivityTaskManagerInternal;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@@ -75,7 +80,7 @@
*/
public static boolean enabled() {
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "enabled",
- false);
+ false) || SystemProperties.getBoolean("persist.profcollectd.enabled_override", false);
}
@Override
@@ -297,24 +302,20 @@
return;
}
- final boolean uploadReport =
- DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
- "upload_report", false);
-
new Thread(() -> {
try {
String reportUuid = mIProfcollect.report();
- if (!uploadReport) {
+ final int profileId = getBBProfileId();
+ String reportDir = "/data/user/" + profileId
+ + "/com.google.android.apps.internal.betterbug/cache/";
+ String reportPath = reportDir + reportUuid + ".zip";
+
+ if (!Files.exists(Paths.get(reportDir))) {
+ Log.i(LOG_TAG, "Destination directory does not exist, abort upload.");
return;
}
- final int profileId = getBBProfileId();
- mIProfcollect.copy_report_to_bb(profileId, reportUuid);
- String reportPath =
- "/data/user/" + profileId
- + "/com.google.android.apps.internal.betterbug/cache/"
- + reportUuid + ".zip";
Intent uploadIntent =
new Intent("com.google.android.apps.betterbug.intent.action.UPLOAD_PROFILE")
.setPackage("com.google.android.apps.internal.betterbug")
@@ -323,9 +324,15 @@
.putExtra("EXTRA_PROFILE_PATH", reportPath)
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Context context = getContext();
- if (context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0) != null) {
- context.sendBroadcast(uploadIntent);
+
+ List<ResolveInfo> receivers =
+ context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0);
+ if (receivers == null || receivers.isEmpty()) {
+ Log.i(LOG_TAG, "No one to receive upload intent, abort upload.");
+ return;
}
+ mIProfcollect.copy_report_to_bb(profileId, reportUuid);
+ context.sendBroadcast(uploadIntent);
mIProfcollect.delete_report(reportUuid);
} catch (RemoteException e) {
Log.e(LOG_TAG, e.getMessage());
diff --git a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
index 179248d..33b0bbd2 100644
--- a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
+++ b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
@@ -81,6 +81,15 @@
}
/**
+ * @return true if the SIP message start line is considered a response.
+ */
+ public static boolean isSipResponse(String startLine) {
+ String[] splitLine = splitStartLineAndVerify(startLine);
+ if (splitLine == null) return false;
+ return verifySipResponse(splitLine);
+ }
+
+ /**
* Return the via branch parameter, which is used to identify the transaction ID (request and
* response pair) in a SIP transaction.
* @param headerString The string containing the headers of the SIP message.
@@ -140,7 +149,12 @@
return !headers.isEmpty() ? headers.get(0).second : null;
}
- private static String[] splitStartLineAndVerify(String startLine) {
+ /**
+ * Validate that the start line is correct and split into its three segments.
+ * @param startLine The start line to verify and split.
+ * @return The split start line, which will always have three segments.
+ */
+ public static String[] splitStartLineAndVerify(String startLine) {
String[] splitLine = startLine.split(" ");
if (isStartLineMalformed(splitLine)) return null;
return splitLine;
@@ -184,7 +198,7 @@
* (This is internally an equalsIgnoreMatch comparison).
* @return the matched header keys and values.
*/
- private static List<Pair<String, String>> parseHeaders(String headerString,
+ public static List<Pair<String, String>> parseHeaders(String headerString,
boolean stopAtFirstMatch, String... matchingHeaderKeys) {
// Ensure there is no leading whitespace
headerString = removeLeadingWhitespace(headerString);
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 1c9cd94..8a4bb46 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -182,16 +182,6 @@
}
/**
- * @return the absolute radio frequency channel number for this physical channel,
- * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
- * @deprecated Use {@link #getDownlinkChannelNumber()} to get the channel number.
- */
- @Deprecated
- public int getChannelNumber() {
- return getDownlinkChannelNumber();
- }
-
- /**
* @return the rough frequency range for this physical channel,
* {@link ServiceState#FREQUENCY_RANGE_UNKNOWN} if unknown.
* @see {@link ServiceState#FREQUENCY_RANGE_LOW}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1cfb1d4..ae6a3e8 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -11205,26 +11205,26 @@
}
/**
- * Return a list of certs in hex string from loaded carrier privileges access rules.
+ * Return a list of certs as hex strings from loaded carrier privileges access rules.
*
- * @return a list of certificate in hex string. return {@code null} if there is no certs
- * or privilege rules are not loaded yet.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+ * @return a list of certificates as hex strings, or an empty list if there are no certs or
+ * privilege rules are not loaded yet.
* @hide
*/
+ @TestApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @NonNull
public List<String> getCertsFromCarrierPrivilegeAccessRules() {
+ List<String> certs = null;
try {
ITelephony service = getITelephony();
if (service != null) {
- return service.getCertsFromCarrierPrivilegeAccessRules(getSubId());
+ certs = service.getCertsFromCarrierPrivilegeAccessRules(getSubId());
}
} catch (RemoteException ex) {
// This could happen if binder process crashes.
}
- return null;
+ return certs == null ? Collections.emptyList() : certs;
}
/**
diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java
index 625364b..9258e44 100644
--- a/telephony/java/android/telephony/ims/SipDelegateManager.java
+++ b/telephony/java/android/telephony/ims/SipDelegateManager.java
@@ -80,13 +80,18 @@
public static final int MESSAGE_FAILURE_REASON_DELEGATE_CLOSED = 2;
/**
- * The SIP message has an invalid start line and the message can not be sent.
+ * The SIP message has an invalid start line and the message can not be sent or the start line
+ * failed validation due to the request containing a restricted SIP request method.
+ * {@link SipDelegateConnection}s can not send SIP requests for the methods: REGISTER, PUBLISH,
+ * or OPTIONS.
*/
public static final int MESSAGE_FAILURE_REASON_INVALID_START_LINE = 3;
/**
* One or more of the header fields in the header section of the outgoing SIP message is invalid
- * and the SIP message can not be sent.
+ * or contains a restricted header value and the SIP message can not be sent.
+ * {@link SipDelegateConnection}s can not send SIP SUBSCRIBE requests for the "Event" header
+ * value of "presence".
*/
public static final int MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS = 4;
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 3156190..582275d 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -16,6 +16,8 @@
package android.net.vcn;
+import static android.net.NetworkCapabilities.REDACT_ALL;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.junit.Assert.assertEquals;
@@ -37,6 +39,12 @@
private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
@Test
+ public void testRedactionDefaults() {
+ assertEquals(REDACT_ALL, CELL_UNDERLYING_INFO.getRedaction());
+ assertEquals(REDACT_ALL, WIFI_UNDERLYING_INFO.getRedaction());
+ }
+
+ @Test
public void testGetWifiInfo() {
assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo());
@@ -51,6 +59,18 @@
}
@Test
+ public void testMakeCopySetsRedactions() {
+ assertEquals(
+ REDACT_FOR_NETWORK_SETTINGS,
+ ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
+ .getRedaction());
+ assertEquals(
+ REDACT_FOR_NETWORK_SETTINGS,
+ ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
+ .getRedaction());
+ }
+
+ @Test
public void testEquals() {
assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO);
assertEquals(WIFI_UNDERLYING_INFO, WIFI_UNDERLYING_INFO);
@@ -64,8 +84,29 @@
}
private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) {
+ // Verify redacted by default
Parcel parcel = Parcel.obtain();
vcnTransportInfo.writeToParcel(parcel, 0 /* flags */);
+ parcel.setDataPosition(0);
+
assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel));
}
+
+ @Test
+ public void testParcelUnparcelNotRedactedForSysUi() {
+ verifyParcelingForSysUi(CELL_UNDERLYING_INFO);
+ verifyParcelingForSysUi(WIFI_UNDERLYING_INFO);
+ }
+
+ private void verifyParcelingForSysUi(VcnTransportInfo vcnTransportInfo) {
+ // Allow fully unredacted; SysUI will have all the relevant permissions.
+ final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy(0);
+ final Parcel parcel = Parcel.obtain();
+ unRedacted.writeToParcel(parcel, 0 /* flags */);
+ parcel.setDataPosition(0);
+
+ final VcnTransportInfo unparceled = VcnTransportInfo.CREATOR.createFromParcel(parcel);
+ assertEquals(vcnTransportInfo, unparceled);
+ assertEquals(REDACT_ALL, unparceled.getRedaction());
+ }
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 90ee738..eedaac4 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -343,6 +343,31 @@
assertFalse(mGatewayConnection.isInSafeMode());
}
+ @Test
+ public void testSubsequentFailedValidationTriggersSafeMode() throws Exception {
+ triggerChildOpened();
+ mTestLooper.dispatchAll();
+
+ triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);
+ assertFalse(mGatewayConnection.isInSafeMode());
+
+ // Trigger a failed validation, and the subsequent safemode timeout.
+ triggerValidation(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ mTestLooper.dispatchAll();
+
+ final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mDeps, times(2))
+ .newWakeupMessage(
+ eq(mVcnContext),
+ any(),
+ eq(VcnGatewayConnection.SAFEMODE_TIMEOUT_ALARM),
+ runnableCaptor.capture());
+ runnableCaptor.getValue().run();
+ mTestLooper.dispatchAll();
+
+ assertTrue(mGatewayConnection.isInSafeMode());
+ }
+
private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() {
triggerChildOpened();
mTestLooper.dispatchAll();