diff options
61 files changed, 760 insertions, 272 deletions
diff --git a/api/Android.bp b/api/Android.bp index c16bce5a1aea..e9cc40513221 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -83,6 +83,7 @@ combined_apis { "framework-configinfrastructure", "framework-connectivity", "framework-connectivity-t", + "framework-crashrecovery", "framework-devicelock", "framework-graphics", "framework-healthfitness", @@ -104,6 +105,7 @@ combined_apis { system_server_classpath: [ "service-art", "service-configinfrastructure", + "service-crashrecovery", "service-healthfitness", "service-media-s", "service-permission", diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp index 7142eb5bef53..e1621008cc33 100644 --- a/api/ApiDocs.bp +++ b/api/ApiDocs.bp @@ -131,13 +131,7 @@ droidstubs { defaults: ["framework-doc-stubs-sources-default"], args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ", - api_levels_annotations_enabled: true, - api_levels_annotations_dirs: [ - "sdk-dir", - "api-versions-jars-dir", - ], - api_levels_sdk_type: "system", - extensions_info_file: ":sdk-extensions-info", + api_levels_module: "api_versions_system", } ///////////////////////////////////////////////////////////////////// diff --git a/boot/Android.bp b/boot/Android.bp index 8a3d35e2d0eb..b33fab6e1a9f 100644 --- a/boot/Android.bp +++ b/boot/Android.bp @@ -84,6 +84,10 @@ custom_platform_bootclasspath { module: "com.android.conscrypt-bootclasspath-fragment", }, { + apex: "com.android.crashrecovery", + module: "com.android.crashrecovery-bootclasspath-fragment", + }, + { apex: "com.android.devicelock", module: "com.android.devicelock-bootclasspath-fragment", }, diff --git a/core/api/current.txt b/core/api/current.txt index e8988dcf3f17..4c1d51d2e9d8 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android { public final class Manifest { @@ -5677,6 +5675,7 @@ package android.app { ctor @Deprecated public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet); ctor @Deprecated public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet, int); method @Deprecated public void onBackStackChanged(); + method @Deprecated protected void onLayout(boolean, int, int, int, int); method @Deprecated public void setActivity(android.app.Activity); method @Deprecated public void setMaxVisible(int); method @Deprecated public void setOnBreadCrumbClickListener(android.app.FragmentBreadCrumbs.OnBreadCrumbClickListener); @@ -13542,6 +13541,7 @@ package android.content.res { public interface XmlResourceParser extends org.xmlpull.v1.XmlPullParser android.util.AttributeSet java.lang.AutoCloseable { method public void close(); + method public String getAttributeNamespace(int); } } @@ -18375,12 +18375,12 @@ package android.hardware.biometrics { ctor @Deprecated public BiometricPrompt.CryptoObject(@NonNull android.security.identity.IdentityCredential); ctor public BiometricPrompt.CryptoObject(@NonNull android.security.identity.PresentationSession); ctor @FlaggedApi("android.hardware.biometrics.add_key_agreement_crypto_object") public BiometricPrompt.CryptoObject(@NonNull javax.crypto.KeyAgreement); - method public javax.crypto.Cipher getCipher(); + method @Nullable public javax.crypto.Cipher getCipher(); method @Deprecated @Nullable public android.security.identity.IdentityCredential getIdentityCredential(); method @FlaggedApi("android.hardware.biometrics.add_key_agreement_crypto_object") @Nullable public javax.crypto.KeyAgreement getKeyAgreement(); - method public javax.crypto.Mac getMac(); + method @Nullable public javax.crypto.Mac getMac(); method @Nullable public android.security.identity.PresentationSession getPresentationSession(); - method public java.security.Signature getSignature(); + method @Nullable public java.security.Signature getSignature(); } } @@ -20227,7 +20227,7 @@ package android.inputmethodservice { method @Deprecated public boolean isPreviewEnabled(); method @Deprecated public boolean isProximityCorrectionEnabled(); method @Deprecated public boolean isShifted(); - method public void onClick(android.view.View); + method @Deprecated public void onClick(android.view.View); method @Deprecated public void onDetachedFromWindow(); method @Deprecated public void onDraw(android.graphics.Canvas); method @Deprecated protected boolean onLongPress(android.inputmethodservice.Keyboard.Key); @@ -24759,7 +24759,7 @@ package android.media { @Deprecated public class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor { method @Deprecated public void apply(); - method public Object clone() throws java.lang.CloneNotSupportedException; + method @Deprecated public Object clone() throws java.lang.CloneNotSupportedException; method @Deprecated public android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException; method @Deprecated public android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException; method @Deprecated public android.media.RemoteControlClient.MetadataEditor putObject(int, Object) throws java.lang.IllegalArgumentException; @@ -27613,6 +27613,7 @@ package android.media.tv { method @NonNull public java.util.List<android.media.AudioPresentation> getAudioPresentations(); method public String getSelectedTrack(int); method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int); + method protected void onLayout(boolean, int, int, int, int); method public boolean onUnhandledInputEvent(android.view.InputEvent); method public void overrideTvAppAttributionSource(@NonNull android.content.AttributionSource); method public void reset(); @@ -44040,7 +44041,6 @@ package android.telephony { method public int getLongitude(); method public int getNetworkId(); method public int getSystemId(); - method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR; } @@ -44056,7 +44056,6 @@ package android.telephony { method @Nullable public String getMncString(); method @Nullable public String getMobileNetworkOperator(); method @Deprecated public int getPsc(); - method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityGsm> CREATOR; } @@ -44074,7 +44073,6 @@ package android.telephony { method @Nullable public String getMobileNetworkOperator(); method public int getPci(); method public int getTac(); - method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityLte> CREATOR; } @@ -44087,7 +44085,6 @@ package android.telephony { method @IntRange(from=0, to=3279165) public int getNrarfcn(); method @IntRange(from=0, to=1007) public int getPci(); method @IntRange(from=0, to=16777215) public int getTac(); - method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR; } @@ -44101,7 +44098,6 @@ package android.telephony { method @Nullable public String getMncString(); method @Nullable public String getMobileNetworkOperator(); method public int getUarfcn(); - method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityTdscdma> CREATOR; } @@ -44117,7 +44113,6 @@ package android.telephony { method @Nullable public String getMobileNetworkOperator(); method public int getPsc(); method public int getUarfcn(); - method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR; } @@ -44201,6 +44196,7 @@ package android.telephony { public final class CellSignalStrengthCdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); + method public boolean equals(Object); method public int getAsuLevel(); method public int getCdmaDbm(); method public int getCdmaEcio(); @@ -44211,24 +44207,28 @@ package android.telephony { method public int getEvdoLevel(); method public int getEvdoSnr(); method @IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) public int getLevel(); + method public int hashCode(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthCdma> CREATOR; } public final class CellSignalStrengthGsm extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); + method public boolean equals(Object); method public int getAsuLevel(); method public int getBitErrorRate(); method public int getDbm(); method @IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) public int getLevel(); method public int getRssi(); method public int getTimingAdvance(); + method public int hashCode(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthGsm> CREATOR; } public final class CellSignalStrengthLte extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); + method public boolean equals(Object); method public int getAsuLevel(); method @IntRange(from=0, to=15) public int getCqi(); method @IntRange(from=1, to=6) public int getCqiTableIndex(); @@ -44239,12 +44239,14 @@ package android.telephony { method public int getRssi(); method public int getRssnr(); method public int getTimingAdvance(); + method public int hashCode(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthLte> CREATOR; } public final class CellSignalStrengthNr extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); + method public boolean equals(Object); method public int getAsuLevel(); method @IntRange(from=0, to=15) @NonNull public java.util.List<java.lang.Integer> getCsiCqiReport(); method @IntRange(from=1, to=3) public int getCsiCqiTableIndex(); @@ -44257,26 +44259,31 @@ package android.telephony { method public int getSsRsrq(); method public int getSsSinr(); method @IntRange(from=0, to=1282) public int getTimingAdvanceMicros(); + method public int hashCode(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthNr> CREATOR; } public final class CellSignalStrengthTdscdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); + method public boolean equals(Object); method public int getAsuLevel(); method public int getDbm(); method @IntRange(from=0, to=4) public int getLevel(); method public int getRscp(); + method public int hashCode(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthTdscdma> CREATOR; } public final class CellSignalStrengthWcdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); + method public boolean equals(Object); method public int getAsuLevel(); method public int getDbm(); method public int getEcNo(); method @IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) public int getLevel(); + method public int hashCode(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthWcdma> CREATOR; } @@ -47056,6 +47063,7 @@ package android.text { method @Deprecated public int length(); method @Deprecated public static android.text.AlteredCharSequence make(CharSequence, char[], int, int); method @Deprecated public CharSequence subSequence(int, int); + method @Deprecated public String toString(); } @Deprecated public class AndroidCharacter { @@ -47469,6 +47477,7 @@ package android.text { method public void removeSpan(Object); method public void setSpan(Object, int, int, int); method public CharSequence subSequence(int, int); + method public String toString(); } public static final class PrecomputedText.Params { @@ -47598,6 +47607,7 @@ package android.text { method public void setFilters(android.text.InputFilter[]); method public void setSpan(Object, int, int, int); method public CharSequence subSequence(int, int); + method public String toString(); method public static android.text.SpannableStringBuilder valueOf(CharSequence); } @@ -49224,7 +49234,9 @@ package android.util { method public boolean containsValue(Object); method public void ensureCapacity(int); method public java.util.Set<java.util.Map.Entry<K,V>> entrySet(); + method public boolean equals(@Nullable Object); method public V get(Object); + method public int hashCode(); method public int indexOfKey(Object); method public int indexOfValue(Object); method public boolean isEmpty(); @@ -49256,7 +49268,9 @@ package android.util { method public boolean contains(Object); method public boolean containsAll(java.util.Collection<?>); method public void ensureCapacity(int); + method public boolean equals(@Nullable Object); method public void forEach(java.util.function.Consumer<? super E>); + method public int hashCode(); method public int indexOf(Object); method public boolean isEmpty(); method public java.util.Iterator<E> iterator(); @@ -57952,6 +57966,7 @@ package android.widget { ctor @Deprecated public AbsoluteLayout(android.content.Context, android.util.AttributeSet); ctor @Deprecated public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int); ctor @Deprecated public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int, int); + method @Deprecated protected void onLayout(boolean, int, int, int, int); } @Deprecated public static class AbsoluteLayout.LayoutParams extends android.view.ViewGroup.LayoutParams { @@ -58030,6 +58045,7 @@ package android.widget { method public long getSelectedItemId(); method public int getSelectedItemPosition(); method public abstract android.view.View getSelectedView(); + method protected void onLayout(boolean, int, int, int, int); method public boolean performItemClick(android.view.View, int, long); method public abstract void setAdapter(T); method public void setEmptyView(android.view.View); @@ -58676,6 +58692,7 @@ package android.widget { method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet); method @Deprecated public boolean getConsiderGoneChildrenWhenMeasuring(); method public boolean getMeasureAllChildren(); + method protected void onLayout(boolean, int, int, int, int); method public void setMeasureAllChildren(boolean); } @@ -58729,6 +58746,7 @@ package android.widget { method public boolean getUseDefaultMargins(); method public boolean isColumnOrderPreserved(); method public boolean isRowOrderPreserved(); + method protected void onLayout(boolean, int, int, int, int); method public void setAlignmentMode(int); method public void setColumnCount(int); method public void setColumnOrderPreserved(boolean); @@ -58951,6 +58969,7 @@ package android.widget { method public float getWeightSum(); method public boolean isBaselineAligned(); method public boolean isMeasureWithLargestChildEnabled(); + method protected void onLayout(boolean, int, int, int, int); method public void setBaselineAligned(boolean); method public void setBaselineAlignedChildIndex(int); method public void setDividerDrawable(android.graphics.drawable.Drawable); @@ -59499,6 +59518,7 @@ package android.widget { method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet); method public int getGravity(); method public int getIgnoreGravity(); + method protected void onLayout(boolean, int, int, int, int); method public void setGravity(int); method public void setHorizontalGravity(int); method public void setIgnoreGravity(int); @@ -59953,6 +59973,7 @@ package android.widget { method @Deprecated public boolean isMoving(); method @Deprecated public boolean isOpened(); method @Deprecated public void lock(); + method @Deprecated protected void onLayout(boolean, int, int, int, int); method @Deprecated public void open(); method @Deprecated public void setOnDrawerCloseListener(android.widget.SlidingDrawer.OnDrawerCloseListener); method @Deprecated public void setOnDrawerOpenListener(android.widget.SlidingDrawer.OnDrawerOpenListener); @@ -60597,6 +60618,7 @@ package android.widget { method public boolean hideOverflowMenu(); method public void inflateMenu(@MenuRes int); method public boolean isOverflowMenuShowing(); + method protected void onLayout(boolean, int, int, int, int); method public void setCollapseContentDescription(@StringRes int); method public void setCollapseContentDescription(@Nullable CharSequence); method public void setCollapseIcon(@DrawableRes int); @@ -60751,7 +60773,7 @@ package android.widget { method @Deprecated public android.view.View getZoomControls(); method @Deprecated public boolean isAutoDismissed(); method @Deprecated public boolean isVisible(); - method public boolean onTouch(android.view.View, android.view.MotionEvent); + method @Deprecated public boolean onTouch(android.view.View, android.view.MotionEvent); method @Deprecated public void setAutoDismissed(boolean); method @Deprecated public void setFocusable(boolean); method @Deprecated public void setOnZoomListener(android.widget.ZoomButtonsController.OnZoomListener); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 01cf77abd3ed..7cfa1e377933 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android { public static final class Manifest.permission { diff --git a/core/api/module-lib-removed.txt b/core/api/module-lib-removed.txt index 14191ebcb080..d802177e249b 100644 --- a/core/api/module-lib-removed.txt +++ b/core/api/module-lib-removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/core/api/removed.txt b/core/api/removed.txt index ede88a29624d..8b3696a1e6d9 100644 --- a/core/api/removed.txt +++ b/core/api/removed.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.app { public class Notification implements android.os.Parcelable { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 40eee4c277ac..64734f4dc762 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android { public static final class Manifest.permission { @@ -4042,7 +4040,9 @@ package android.content.pm { } public static final class PackageManager.UninstallCompleteCallback implements android.os.Parcelable { + method public int describeContents(); method public void onUninstallComplete(@NonNull String, int, @Nullable String); + method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.PackageManager.UninstallCompleteCallback> CREATOR; } @@ -5941,6 +5941,7 @@ package android.hardware.soundtrigger { public static final class SoundTrigger.Keyphrase implements android.os.Parcelable { ctor public SoundTrigger.Keyphrase(int, int, @NonNull java.util.Locale, @NonNull String, @Nullable int[]); + method public int describeContents(); method public int getId(); method @NonNull public java.util.Locale getLocale(); method public int getRecognitionModes(); @@ -5963,6 +5964,7 @@ package android.hardware.soundtrigger { public static final class SoundTrigger.KeyphraseSoundModel extends android.hardware.soundtrigger.SoundTrigger.SoundModel implements android.os.Parcelable { ctor public SoundTrigger.KeyphraseSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], @Nullable android.hardware.soundtrigger.SoundTrigger.Keyphrase[], int); ctor public SoundTrigger.KeyphraseSoundModel(@NonNull java.util.UUID, @NonNull java.util.UUID, @Nullable byte[], @Nullable android.hardware.soundtrigger.SoundTrigger.Keyphrase[]); + method public int describeContents(); method @NonNull public android.hardware.soundtrigger.SoundTrigger.Keyphrase[] getKeyphrases(); method @NonNull public static android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel readFromParcel(@NonNull android.os.Parcel); method public void writeToParcel(@NonNull android.os.Parcel, int); @@ -5970,6 +5972,7 @@ package android.hardware.soundtrigger { } public static final class SoundTrigger.ModelParamRange implements android.os.Parcelable { + method public int describeContents(); method public int getEnd(); method public int getStart(); method public void writeToParcel(@NonNull android.os.Parcel, int); @@ -7412,6 +7415,7 @@ package android.media.musicrecognition { public abstract class MusicRecognitionService extends android.app.Service { ctor public MusicRecognitionService(); + method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent); method public abstract void onRecognize(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @NonNull android.media.musicrecognition.MusicRecognitionService.Callback); } @@ -7470,6 +7474,7 @@ package android.media.soundtrigger { public abstract class SoundTriggerDetectionService extends android.app.Service { ctor public SoundTriggerDetectionService(); + method public final android.os.IBinder onBind(android.content.Intent); method @MainThread public void onConnected(@NonNull java.util.UUID, @Nullable android.os.Bundle); method @MainThread public void onDisconnected(@NonNull java.util.UUID, @Nullable android.os.Bundle); method @MainThread public void onError(@NonNull java.util.UUID, @Nullable android.os.Bundle, int, int); @@ -8183,6 +8188,7 @@ package android.media.tv.tuner.filter { } public class MediaEvent extends android.media.tv.tuner.filter.FilterEvent { + method protected void finalize(); method public long getAudioHandle(); method @NonNull public java.util.List<android.media.AudioPresentation> getAudioPresentations(); method public long getAvDataId(); @@ -9577,6 +9583,8 @@ package android.net { package android.net.metrics { @Deprecated public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event { + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); } @Deprecated public static final class ApfProgramEvent.Builder { @@ -9591,6 +9599,8 @@ package android.net.metrics { } @Deprecated public final class ApfStats implements android.net.metrics.IpConnectivityLog.Event { + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); } @Deprecated public static final class ApfStats.Builder { @@ -9609,6 +9619,8 @@ package android.net.metrics { } @Deprecated public final class DhcpClientEvent implements android.net.metrics.IpConnectivityLog.Event { + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); } @Deprecated public static final class DhcpClientEvent.Builder { @@ -9620,7 +9632,9 @@ package android.net.metrics { @Deprecated public final class DhcpErrorEvent implements android.net.metrics.IpConnectivityLog.Event { ctor @Deprecated public DhcpErrorEvent(int); + method @Deprecated public int describeContents(); method @Deprecated public static int errorCodeWithOption(int, int); + method @Deprecated public void writeToParcel(android.os.Parcel, int); field @Deprecated public static final int BOOTP_TOO_SHORT = 67174400; // 0x4010000 field @Deprecated public static final int BUFFER_UNDERFLOW = 83951616; // 0x5010000 field @Deprecated public static final int DHCP_BAD_MAGIC_COOKIE = 67239936; // 0x4020000 @@ -9658,6 +9672,8 @@ package android.net.metrics { @Deprecated public final class IpManagerEvent implements android.net.metrics.IpConnectivityLog.Event { ctor @Deprecated public IpManagerEvent(int, long); + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); field @Deprecated public static final int COMPLETE_LIFECYCLE = 3; // 0x3 field @Deprecated public static final int ERROR_INTERFACE_NOT_FOUND = 8; // 0x8 field @Deprecated public static final int ERROR_INVALID_PROVISIONING = 7; // 0x7 @@ -9670,6 +9686,8 @@ package android.net.metrics { @Deprecated public final class IpReachabilityEvent implements android.net.metrics.IpConnectivityLog.Event { ctor @Deprecated public IpReachabilityEvent(int); + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); field @Deprecated public static final int NUD_FAILED = 512; // 0x200 field @Deprecated public static final int NUD_FAILED_ORGANIC = 1024; // 0x400 field @Deprecated public static final int PROBE = 256; // 0x100 @@ -9680,6 +9698,8 @@ package android.net.metrics { @Deprecated public final class NetworkEvent implements android.net.metrics.IpConnectivityLog.Event { ctor @Deprecated public NetworkEvent(int, long); ctor @Deprecated public NetworkEvent(int); + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); field @Deprecated public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4 field @Deprecated public static final int NETWORK_CONNECTED = 1; // 0x1 field @Deprecated public static final int NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND = 12; // 0xc @@ -9696,6 +9716,8 @@ package android.net.metrics { } @Deprecated public final class RaEvent implements android.net.metrics.IpConnectivityLog.Event { + method @Deprecated public int describeContents(); + method @Deprecated public void writeToParcel(android.os.Parcel, int); } @Deprecated public static final class RaEvent.Builder { @@ -9710,7 +9732,9 @@ package android.net.metrics { } @Deprecated public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event { + method @Deprecated public int describeContents(); method @Deprecated @NonNull public static String getProbeName(int); + method @Deprecated public void writeToParcel(android.os.Parcel, int); field @Deprecated public static final int DNS_FAILURE = 0; // 0x0 field @Deprecated public static final int DNS_SUCCESS = 1; // 0x1 field @Deprecated public static final int PROBE_DNS = 0; // 0x0 @@ -12108,6 +12132,7 @@ package android.service.assist.classification { public abstract class FieldClassificationService extends android.app.Service { ctor public FieldClassificationService(); + method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onClassificationRequest(@NonNull android.service.assist.classification.FieldClassificationRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.assist.classification.FieldClassificationResponse,java.lang.Exception>); method public void onConnected(); method public void onDisconnected(); @@ -12186,6 +12211,7 @@ package android.service.autofill.augmented { method protected final void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]); method protected void dump(@NonNull java.io.PrintWriter, @NonNull String[]); method @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory(); + method public final android.os.IBinder onBind(android.content.Intent); method public void onConnected(); method public void onDisconnected(); method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback); @@ -12224,6 +12250,7 @@ package android.service.autofill.augmented { public final class FillWindow implements java.lang.AutoCloseable { ctor public FillWindow(); + method public void close(); method public void destroy(); method public boolean update(@NonNull android.service.autofill.augmented.PresentationParams.Area, @NonNull android.view.View, long); } @@ -12249,6 +12276,7 @@ package android.service.carrier { public final class CarrierMessagingServiceWrapper implements java.lang.AutoCloseable { ctor public CarrierMessagingServiceWrapper(); method public boolean bindToCarrierMessagingService(@NonNull android.content.Context, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull Runnable); + method public void close(); method public void disconnect(); method public void downloadMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback); method public void receiveSms(@NonNull android.service.carrier.MessagePdu, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback); @@ -12299,6 +12327,7 @@ package android.service.contentcapture { method public final void disableSelf(); method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent); method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData); + method public final android.os.IBinder onBind(android.content.Intent); method public void onConnected(); method public void onContentCaptureEvent(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.view.contentcapture.ContentCaptureEvent); method public void onCreateContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureContext, @NonNull android.view.contentcapture.ContentCaptureSessionId); @@ -12337,6 +12366,7 @@ package android.service.contentsuggestions { public abstract class ContentSuggestionsService extends android.app.Service { ctor public ContentSuggestionsService(); + method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onClassifyContentSelections(@NonNull android.app.contentsuggestions.ClassificationsRequest, @NonNull android.app.contentsuggestions.ContentSuggestionsManager.ClassificationsCallback); method public abstract void onNotifyInteraction(@NonNull String, @NonNull android.os.Bundle); method public abstract void onProcessContextImage(int, @Nullable android.graphics.Bitmap, @NonNull android.os.Bundle); @@ -12350,6 +12380,7 @@ package android.service.dataloader { public abstract class DataLoaderService extends android.app.Service { ctor public DataLoaderService(); + method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); method @Nullable public android.service.dataloader.DataLoaderService.DataLoader onCreateDataLoader(@NonNull android.content.pm.DataLoaderParams); } @@ -13022,6 +13053,7 @@ package android.service.tracing { public class TraceReportService extends android.app.Service { ctor public TraceReportService(); + method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); method public void onReportTrace(@NonNull android.service.tracing.TraceReportService.TraceParams); } @@ -13610,6 +13642,7 @@ package android.telecom { method @Nullable public android.content.ComponentName getCallScreeningComponent(); method public boolean isBlocked(); method public boolean isInContacts(); + method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telecom.Connection.CallFilteringCompletionInfo> CREATOR; } @@ -13918,6 +13951,7 @@ package android.telephony { method public int getReason(); method public int getTimeoutSeconds(); method public boolean isEnabled(); + method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR; field public static final int REASON_ALL = 4; // 0x4 field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5 @@ -14202,6 +14236,7 @@ package android.telephony { method public int getDownlinkCapacityKbps(); method public int getType(); method public int getUplinkCapacityKbps(); + method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LinkCapacityEstimate> CREATOR; field public static final int INVALID = -1; // 0xffffffff field public static final int LCE_TYPE_COMBINED = 2; // 0x2 @@ -14211,8 +14246,10 @@ package android.telephony { public final class LteVopsSupportInfo extends android.telephony.VopsSupportInfo { ctor public LteVopsSupportInfo(int, int); + method public boolean equals(@Nullable Object); method public int getEmcBearerSupport(); method public int getVopsSupport(); + method public int hashCode(); method public boolean isEmergencyServiceFallbackSupported(); method public boolean isEmergencyServiceSupported(); method public boolean isVopsSupported(); @@ -14312,9 +14349,11 @@ package android.telephony { public final class NrVopsSupportInfo extends android.telephony.VopsSupportInfo { ctor public NrVopsSupportInfo(int, int, int); + method public boolean equals(@Nullable Object); method public int getEmcSupport(); method public int getEmfSupport(); method public int getVopsSupport(); + method public int hashCode(); method public boolean isEmergencyServiceFallbackSupported(); method public boolean isEmergencyServiceSupported(); method public boolean isVopsSupported(); @@ -15427,6 +15466,7 @@ package android.telephony.data { public abstract class QualifiedNetworksService extends android.app.Service { ctor public QualifiedNetworksService(); + method public android.os.IBinder onBind(android.content.Intent); method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int); field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService"; } @@ -15618,6 +15658,7 @@ package android.telephony.gba { public class GbaService extends android.app.Service { ctor public GbaService(); method public void onAuthenticationRequest(int, int, int, @NonNull android.net.Uri, @NonNull byte[], boolean); + method public android.os.IBinder onBind(android.content.Intent); method public final void reportAuthenticationFailure(int, int) throws java.lang.RuntimeException; method public final void reportKeysAvailable(int, @NonNull byte[], @NonNull String) throws java.lang.RuntimeException; field public static final String SERVICE_INTERFACE = "android.telephony.gba.GbaService"; @@ -16120,6 +16161,7 @@ package android.telephony.ims { method @Deprecated public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int); method @NonNull public android.telephony.ims.stub.ImsRegistrationImplBase getRegistrationForSubscription(int, int); method @Nullable public android.telephony.ims.stub.SipTransportImplBase getSipTransport(int); + method public android.os.IBinder onBind(android.content.Intent); method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException; method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures(); method public void readyForFeatureCreation(); diff --git a/core/api/system-removed.txt b/core/api/system-removed.txt index 4161330dcb37..1c10356c6b03 100644 --- a/core/api/system-removed.txt +++ b/core/api/system-removed.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.app { public class AppOpsManager { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 8d0e396f110d..7742b86447e6 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android { public static final class Manifest.permission { @@ -3932,7 +3930,9 @@ package android.widget.inline { package android.window { public final class BackNavigationInfo implements android.os.Parcelable { + method public int describeContents(); method @NonNull public static String typeToString(int); + method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.BackNavigationInfo> CREATOR; field public static final String KEY_TRIGGER_BACK = "TriggerBack"; field public static final int TYPE_CALLBACK = 4; // 0x4 @@ -3993,11 +3993,13 @@ package android.window { } public final class TaskFragmentCreationParams implements android.os.Parcelable { + method public int describeContents(); method @NonNull public android.os.IBinder getFragmentToken(); method @NonNull public android.graphics.Rect getInitialRelativeBounds(); method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizer(); method @NonNull public android.os.IBinder getOwnerToken(); method public int getWindowingMode(); + method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentCreationParams> CREATOR; } @@ -4009,6 +4011,7 @@ package android.window { } public final class TaskFragmentInfo implements android.os.Parcelable { + method public int describeContents(); method public boolean equalsForTaskFragmentOrganizer(@Nullable android.window.TaskFragmentInfo); method @NonNull public java.util.List<android.os.IBinder> getActivities(); method @NonNull public java.util.List<android.os.IBinder> getActivitiesRequestedInTaskFragment(); @@ -4022,6 +4025,7 @@ package android.window { method public boolean isEmpty(); method public boolean isTaskClearedForReuse(); method public boolean isVisible(); + method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentInfo> CREATOR; } @@ -4044,6 +4048,8 @@ package android.window { } public final class TaskFragmentOrganizerToken implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentOrganizerToken> CREATOR; } diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt index cf0264353159..726871eccc6c 100644 --- a/core/api/test-lint-baseline.txt +++ b/core/api/test-lint-baseline.txt @@ -761,6 +761,8 @@ MissingNullability: android.widget.TimePicker#getMinuteView(): Missing nullability on method `getMinuteView` return MissingNullability: android.widget.TimePicker#getPmView(): Missing nullability on method `getPmView` return +MissingNullability: android.window.TaskFragmentOrganizerToken#writeToParcel(android.os.Parcel, int) parameter #0: + Missing nullability on parameter `dest` in method `writeToParcel` MutableBareField: android.content.AutofillOptions#appDisabledExpiration: diff --git a/core/api/test-removed.txt b/core/api/test-removed.txt index 14191ebcb080..d802177e249b 100644 --- a/core/api/test-removed.txt +++ b/core/api/test-removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/core/java/android/hardware/HardwareBuffer.aidl b/core/java/android/hardware/HardwareBuffer.aidl index 1333f0da725f..a9742cb6c084 100644 --- a/core/java/android/hardware/HardwareBuffer.aidl +++ b/core/java/android/hardware/HardwareBuffer.aidl @@ -16,4 +16,4 @@ package android.hardware; -@JavaOnlyStableParcelable @NdkOnlyStableParcelable parcelable HardwareBuffer ndk_header "android/hardware_buffer_aidl.h"; +@JavaOnlyStableParcelable @NdkOnlyStableParcelable @RustOnlyStableParcelable parcelable HardwareBuffer ndk_header "android/hardware_buffer_aidl.h" rust_type "nativewindow::HardwareBuffer"; diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index 294813d76b99..35ae11c7397c 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -786,7 +786,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * Get {@link Signature} object. * @return {@link Signature} object or null if this doesn't contain one. */ - public Signature getSignature() { + public @Nullable Signature getSignature() { return super.getSignature(); } @@ -794,7 +794,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * Get {@link Cipher} object. * @return {@link Cipher} object or null if this doesn't contain one. */ - public Cipher getCipher() { + public @Nullable Cipher getCipher() { return super.getCipher(); } @@ -802,7 +802,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * Get {@link Mac} object. * @return {@link Mac} object or null if this doesn't contain one. */ - public Mac getMac() { + public @Nullable Mac getMac() { return super.getMac(); } diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java index 6ac1efb49839..39fbe83b6abb 100644 --- a/core/java/android/hardware/biometrics/CryptoObject.java +++ b/core/java/android/hardware/biometrics/CryptoObject.java @@ -20,6 +20,7 @@ import static android.hardware.biometrics.Flags.FLAG_ADD_KEY_AGREEMENT_CRYPTO_OB import android.annotation.FlaggedApi; import android.annotation.NonNull; +import android.annotation.Nullable; import android.security.identity.IdentityCredential; import android.security.identity.PresentationSession; import android.security.keystore2.AndroidKeyStoreProvider; @@ -33,20 +34,35 @@ import javax.crypto.Mac; /** * A wrapper class for the crypto objects supported by BiometricPrompt and FingerprintManager. * Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac}, - * {@link IdentityCredential}, and {@link PresentationSession} objects. + * {@link KeyAgreement}, {@link IdentityCredential}, and {@link PresentationSession} objects. * @hide */ public class CryptoObject { private final Object mCrypto; + /** + * Create from a {@link Signature} object. + * + * @param signature a {@link Signature} object. + */ public CryptoObject(@NonNull Signature signature) { mCrypto = signature; } + /** + * Create from a {@link Cipher} object. + * + * @param cipher a {@link Cipher} object. + */ public CryptoObject(@NonNull Cipher cipher) { mCrypto = cipher; } + /** + * Create from a {@link Mac} object. + * + * @param mac a {@link Mac} object. + */ public CryptoObject(@NonNull Mac mac) { mCrypto = mac; } @@ -62,10 +78,20 @@ public class CryptoObject { mCrypto = credential; } + /** + * Create from a {@link PresentationSession} object. + * + * @param session a {@link PresentationSession} object. + */ public CryptoObject(@NonNull PresentationSession session) { mCrypto = session; } + /** + * Create from a {@link KeyAgreement} object. + * + * @param keyAgreement a {@link KeyAgreement} object. + */ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT) public CryptoObject(@NonNull KeyAgreement keyAgreement) { mCrypto = keyAgreement; @@ -75,7 +101,7 @@ public class CryptoObject { * Get {@link Signature} object. * @return {@link Signature} object or null if this doesn't contain one. */ - public Signature getSignature() { + public @Nullable Signature getSignature() { return mCrypto instanceof Signature ? (Signature) mCrypto : null; } @@ -83,7 +109,7 @@ public class CryptoObject { * Get {@link Cipher} object. * @return {@link Cipher} object or null if this doesn't contain one. */ - public Cipher getCipher() { + public @Nullable Cipher getCipher() { return mCrypto instanceof Cipher ? (Cipher) mCrypto : null; } @@ -91,7 +117,7 @@ public class CryptoObject { * Get {@link Mac} object. * @return {@link Mac} object or null if this doesn't contain one. */ - public Mac getMac() { + public @Nullable Mac getMac() { return mCrypto instanceof Mac ? (Mac) mCrypto : null; } @@ -101,7 +127,7 @@ public class CryptoObject { * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}. */ @Deprecated - public IdentityCredential getIdentityCredential() { + public @Nullable IdentityCredential getIdentityCredential() { return mCrypto instanceof IdentityCredential ? (IdentityCredential) mCrypto : null; } @@ -109,16 +135,18 @@ public class CryptoObject { * Get {@link PresentationSession} object. * @return {@link PresentationSession} object or null if this doesn't contain one. */ - public PresentationSession getPresentationSession() { + public @Nullable PresentationSession getPresentationSession() { return mCrypto instanceof PresentationSession ? (PresentationSession) mCrypto : null; } /** - * Get {@link KeyAgreement} object. + * Get {@link KeyAgreement} object. A key-agreement protocol is a protocol whereby + * two or more parties can agree on a shared secret using public key cryptography. + * * @return {@link KeyAgreement} object or null if this doesn't contain one. */ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT) - public KeyAgreement getKeyAgreement() { + public @Nullable KeyAgreement getKeyAgreement() { return mCrypto instanceof KeyAgreement ? (KeyAgreement) mCrypto : null; } diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index c9073fa4b72c..e6bdfe1b95c4 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -116,6 +116,8 @@ public class GraphicsEnvironment { private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = "angle"; private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = "native"; + private static final String PROPERTY_RO_ANGLE_SUPPORTED = "ro.gfx.angle.supported"; + private ClassLoader mClassLoader; private String mLibrarySearchPaths; private String mLibraryPermittedPaths; @@ -501,10 +503,12 @@ public class GraphicsEnvironment { final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY); if (resolveInfos.size() != 1) { - Log.e(TAG, "Invalid number of ANGLE packages. Required: 1, Found: " + Log.v(TAG, "Invalid number of ANGLE packages. Required: 1, Found: " + resolveInfos.size()); - for (ResolveInfo resolveInfo : resolveInfos) { - Log.e(TAG, "Found ANGLE package: " + resolveInfo.activityInfo.packageName); + if (DEBUG) { + for (ResolveInfo resolveInfo : resolveInfos) { + Log.d(TAG, "Found ANGLE package: " + resolveInfo.activityInfo.packageName); + } } return ""; } @@ -539,26 +543,42 @@ public class GraphicsEnvironment { } /** - * Determine whether ANGLE should be used, set it up if so, and pass ANGLE details down to - * the C++ GraphicsEnv class. + * Determine whether ANGLE should be used, attempt to set up from apk first, if ANGLE can be + * set up from apk, pass ANGLE details down to the C++ GraphicsEnv class via + * GraphicsEnv::setAngleInfo(). If apk setup fails, attempt to set up to use system ANGLE. + * Return false if both fail. * - * If ANGLE will be used, GraphicsEnv::setAngleInfo() will be called to enable ANGLE to be - * properly used. - * - * @param context - * @param bundle - * @param pm + * @param context - Context of the application. + * @param bundle - Bundle of the application. + * @param packageManager - PackageManager of the application process. * @param packageName - package name of the application. - * @return true: ANGLE setup successfully - * false: ANGLE not setup (not on allowlist, ANGLE not present, etc.) + * @return true: can set up to use ANGLE successfully. + * false: can not set up to use ANGLE (not on allowlist, ANGLE not present, etc.) */ - private boolean setupAngle(Context context, Bundle bundle, PackageManager pm, + private boolean setupAngle(Context context, Bundle bundle, PackageManager packageManager, String packageName) { if (!shouldUseAngle(context, bundle, packageName)) { return false; } + return setupAngleFromApk(context, bundle, packageManager, packageName) + || setupAngleFromSystem(context, bundle, packageName); + } + + /** + * Attempt to set up ANGLE from the packaged apk, if the apk can be found, pass ANGLE details to + * the C++ GraphicsEnv class. + * + * @param context - Context of the application. + * @param bundle - Bundle of the application. + * @param packageManager - PackageManager of the application process. + * @param packageName - package name of the application. + * @return true: can set up to use ANGLE apk. + * false: can not set up to use ANGLE apk (ANGLE apk not present, etc.) + */ + private boolean setupAngleFromApk(Context context, Bundle bundle, PackageManager packageManager, + String packageName) { ApplicationInfo angleInfo = null; // If the developer has specified a debug package over ADB, attempt to find it @@ -567,7 +587,7 @@ public class GraphicsEnvironment { Log.v(TAG, "ANGLE debug package enabled: " + anglePkgName); try { // Note the debug package does not have to be pre-installed - angleInfo = pm.getApplicationInfo(anglePkgName, 0); + angleInfo = packageManager.getApplicationInfo(anglePkgName, 0); } catch (PackageManager.NameNotFoundException e) { // If the debug package is specified but not found, abort. Log.v(TAG, "ANGLE debug package '" + anglePkgName + "' not installed"); @@ -577,7 +597,7 @@ public class GraphicsEnvironment { // Otherwise, check to see if ANGLE is properly installed if (angleInfo == null) { - anglePkgName = getAnglePackageName(pm); + anglePkgName = getAnglePackageName(packageManager); if (TextUtils.isEmpty(anglePkgName)) { Log.v(TAG, "Failed to find ANGLE package."); return false; @@ -586,7 +606,7 @@ public class GraphicsEnvironment { Log.v(TAG, "ANGLE package enabled: " + anglePkgName); try { // Production ANGLE libraries must be pre-installed as a system app - angleInfo = pm.getApplicationInfo(anglePkgName, + angleInfo = packageManager.getApplicationInfo(anglePkgName, PackageManager.MATCH_SYSTEM_ONLY); } catch (PackageManager.NameNotFoundException e) { Log.v(TAG, "ANGLE package '" + anglePkgName + "' not installed"); @@ -610,8 +630,32 @@ public class GraphicsEnvironment { // If we make it to here, ANGLE will be used. Call setAngleInfo() with the package name, // and features to use. final String[] features = getAngleEglFeatures(context, bundle); - setAngleInfo(paths, packageName, ANGLE_GL_DRIVER_CHOICE_ANGLE, features); + setAngleInfo(paths, false, packageName, features); + + return true; + } + /** + * Attempt to set up ANGLE from system, if the apk can be found, pass ANGLE details to + * the C++ GraphicsEnv class. + * + * @param context - Context of the application. + * @param bundle - Bundle of the application. + * @param packageName - package name of the application. + * @return true: can set up to use system ANGLE. + * false: can not set up to use system ANGLE because it doesn't exist. + */ + private boolean setupAngleFromSystem(Context context, Bundle bundle, String packageName) { + final boolean systemAngleSupported = SystemProperties + .getBoolean(PROPERTY_RO_ANGLE_SUPPORTED, false); + if (!systemAngleSupported) { + return false; + } + + // If we make it to here, ANGLE will be used. Call setAngleInfo() with the package name, + // and features to use. + final String[] features = getAngleEglFeatures(context, bundle); + setAngleInfo("", true, packageName, features); return true; } @@ -651,7 +695,9 @@ public class GraphicsEnvironment { final Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE); final String anglePkg = getAnglePackageName(context.getPackageManager()); - intent.setPackage(anglePkg); + if (anglePkg.isEmpty()) { + return; + } context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { @Override @@ -890,8 +936,8 @@ public class GraphicsEnvironment { private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries); private static native void setGpuStats(String driverPackageName, String driverVersionName, long driverVersionCode, long driverBuildTime, String appPackageName, int vulkanVersion); - private static native void setAngleInfo(String path, String packageName, - String devOptIn, String[] features); + private static native void setAngleInfo(String path, boolean useSystemAngle, String packageName, + String[] features); private static native boolean setInjectLayersPrSetDumpable(); private static native void nativeToggleAngleAsSystemDriver(boolean enabled); diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 1a3dcee427d8..a49ee7d00751 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -104,16 +104,6 @@ interface INetworkManagementService void setIPv6AddrGenMode(String iface, int mode); /** - * Add the specified route to the interface. - */ - void addRoute(int netId, in RouteInfo route); - - /** - * Remove the specified route from the interface. - */ - void removeRoute(int netId, in RouteInfo route); - - /** * Shuts down the service */ @EnforcePermission("SHUTDOWN") diff --git a/core/java/android/service/rotationresolver/OWNERS b/core/java/android/service/rotationresolver/OWNERS index 5b57fc7fa528..dce874dcd982 100644 --- a/core/java/android/service/rotationresolver/OWNERS +++ b/core/java/android/service/rotationresolver/OWNERS @@ -1,9 +1,7 @@ # Bug component: 814982 asalo@google.com -augale@google.com eejiang@google.com payamp@google.com siddikap@google.com -svetoslavganov@google.com tgadh@google.com diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java index 4e7bfe50cd30..71bbccb3d989 100644 --- a/core/java/com/android/internal/app/PlatLogoActivity.java +++ b/core/java/com/android/internal/app/PlatLogoActivity.java @@ -259,7 +259,7 @@ public class PlatLogoActivity extends Activity { } return true; } - return false; + return super.onKeyDown(keyCode,event); } @Override @@ -268,7 +268,7 @@ public class PlatLogoActivity extends Activity { stopWarp(); return true; } - return false; + return super.onKeyUp(keyCode,event); } private void startWarp() { diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 406505517bcc..82367834f93d 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -108,4 +108,5 @@ interface ILockSettings { boolean removeWeakEscrowToken(long handle, int userId); boolean isWeakEscrowTokenActive(long handle, int userId); boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId); + void unlockUserKeyIfUnsecured(int userId); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index d5b8f62aaf2b..a3e27062fa7b 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1933,8 +1933,23 @@ public class LockPatternUtils { } } + /** + * Unlocks the credential-encrypted storage for the given user if the user is not secured, i.e. + * doesn't have an LSKF. + * <p> + * Whether the storage has been unlocked can be determined by + * {@link StorageManager#isUserKeyUnlocked()}. + * + * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. + * + * @param userId the ID of the user whose storage to unlock + */ public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { - getLockSettingsInternal().unlockUserKeyIfUnsecured(userId); + try { + getLockSettings().unlockUserKeyIfUnsecured(userId); + } catch (RemoteException re) { + re.rethrowFromSystemServer(); + } } public void createNewUser(@UserIdInt int userId, int userSerialNumber) { diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java index 6063c90d6ab9..8114e1fd3bb0 100644 --- a/core/java/com/android/internal/widget/LockSettingsInternal.java +++ b/core/java/com/android/internal/widget/LockSettingsInternal.java @@ -60,17 +60,6 @@ public abstract class LockSettingsInternal { public abstract void onThirdPartyAppsStarted(); /** - * Unlocks the credential-encrypted storage for the given user if the user is not secured, i.e. - * doesn't have an LSKF. - * <p> - * This doesn't throw an exception on failure; whether the storage has been unlocked can be - * determined by {@link StorageManager#isUserKeyUnlocked()}. - * - * @param userId the ID of the user whose storage to unlock - */ - public abstract void unlockUserKeyIfUnsecured(@UserIdInt int userId); - - /** * Creates the locksettings state for a new user. * <p> * This includes creating a synthetic password and protecting it with an empty LSKF. diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp index d94b9828808b..afc3cbd15f88 100644 --- a/core/jni/android_os_GraphicsEnvironment.cpp +++ b/core/jni/android_os_GraphicsEnvironment.cpp @@ -16,11 +16,12 @@ #define LOG_TAG "GraphicsEnvironment" -#include <vector> - #include <graphicsenv/GraphicsEnv.h> #include <nativehelper/ScopedUtfChars.h> #include <nativeloader/native_loader.h> + +#include <vector> + #include "core_jni_helpers.h" namespace { @@ -49,11 +50,10 @@ void setGpuStats_native(JNIEnv* env, jobject clazz, jstring driverPackageName, appPackageNameChars.c_str(), vulkanVersion); } -void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring packageName, - jstring devOptIn, jobjectArray featuresObj) { +void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jboolean useSystemAngle, + jstring packageName, jobjectArray featuresObj) { ScopedUtfChars pathChars(env, path); ScopedUtfChars packageNameChars(env, packageName); - ScopedUtfChars devOptInChars(env, devOptIn); std::vector<std::string> features; if (featuresObj != nullptr) { @@ -73,8 +73,8 @@ void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring packa } } - android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), packageNameChars.c_str(), - devOptInChars.c_str(), features); + android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), useSystemAngle, + packageNameChars.c_str(), features); } void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) { @@ -118,8 +118,7 @@ const JNINativeMethod g_methods[] = { reinterpret_cast<void*>(setGpuStats_native)}, {"setInjectLayersPrSetDumpable", "()Z", reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native)}, - {"setAngleInfo", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V", + {"setAngleInfo", "(Ljava/lang/String;ZLjava/lang/String;[Ljava/lang/String;)V", reinterpret_cast<void*>(setAngleInfo_native)}, {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native)}, diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index af8c69ea1441..3a2e50aa06e8 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -54,6 +54,9 @@ <!-- Azerbaijan: 4-5 digits, known premium codes listed --> <shortcode country="az" pattern="\\d{4,5}" premium="330[12]|87744|901[234]|93(?:94|101)|9426|9525" /> + <!-- Bangladesh: 1-5 digits (standard system default, not country specific) --> + <shortcode country="bd" pattern="\\d{1,5}" free="16672" /> + <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp --> <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" /> @@ -145,7 +148,7 @@ <shortcode country="in" pattern="\\d{1,5}" free="59336|53969" /> <!-- Indonesia: 1-5 digits (standard system default, not country specific) --> - <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363" /> + <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363|93457" /> <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU: http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf --> @@ -190,7 +193,7 @@ <shortcode country="mk" pattern="\\d{1,6}" free="129005|122" /> <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed --> - <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101" /> + <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453" /> <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf --> <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668" /> @@ -205,7 +208,7 @@ <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" /> <!-- New Zealand: 3-4 digits, known premium codes listed --> - <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|176|2141|3067|3068|3110|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" /> + <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|176|2141|3067|3068|3110|3876|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" /> <!-- Peru: 4-5 digits (not confirmed), known premium codes listed --> <shortcode country="pe" pattern="\\d{4,5}" free="9963|40778" /> diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS index 2ca99943a8a0..23668a4b2afb 100644 --- a/core/tests/coretests/src/android/view/OWNERS +++ b/core/tests/coretests/src/android/view/OWNERS @@ -20,4 +20,7 @@ per-file *ContentRecord* = file:/services/core/java/com/android/server/wm/OWNER per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS # Stylus -per-file stylus/* = file:/core/java/android/text/OWNERS
\ No newline at end of file +per-file stylus/* = file:/core/java/android/text/OWNERS + +# View +file:/core/java/android/view/OWNERS
\ No newline at end of file diff --git a/libs/hwui/api/current.txt b/libs/hwui/api/current.txt index 794082124344..c396a2032eed 100644 --- a/libs/hwui/api/current.txt +++ b/libs/hwui/api/current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.graphics { public class ColorMatrix { diff --git a/libs/hwui/api/module-lib-current.txt b/libs/hwui/api/module-lib-current.txt index 14191ebcb080..d802177e249b 100644 --- a/libs/hwui/api/module-lib-current.txt +++ b/libs/hwui/api/module-lib-current.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/libs/hwui/api/module-lib-removed.txt b/libs/hwui/api/module-lib-removed.txt index 14191ebcb080..d802177e249b 100644 --- a/libs/hwui/api/module-lib-removed.txt +++ b/libs/hwui/api/module-lib-removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/libs/hwui/api/removed.txt b/libs/hwui/api/removed.txt index 14191ebcb080..d802177e249b 100644 --- a/libs/hwui/api/removed.txt +++ b/libs/hwui/api/removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/libs/hwui/api/system-current.txt b/libs/hwui/api/system-current.txt index 14191ebcb080..d802177e249b 100644 --- a/libs/hwui/api/system-current.txt +++ b/libs/hwui/api/system-current.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/libs/hwui/api/system-removed.txt b/libs/hwui/api/system-removed.txt index 14191ebcb080..d802177e249b 100644 --- a/libs/hwui/api/system-removed.txt +++ b/libs/hwui/api/system-removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp index 06ec949e6736..bdd7afeb2f65 100644 --- a/media/tests/MediaFrameworkTest/Android.bp +++ b/media/tests/MediaFrameworkTest/Android.bp @@ -20,7 +20,9 @@ android_test { "androidx.test.ext.junit", "androidx.test.rules", "android-ex-camera2", + "testables", "testng", + "truth", ], jni_libs: [ "libdexmakerjvmtiagent", diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index f21ad2204d74..579d35ccc9d0 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -2712,8 +2712,7 @@ public class OomAdjuster { } } - if (ppr.getLastProviderTime() > 0 - && (ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { + if ((ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { if (adj > PREVIOUS_APP_ADJ) { adj = PREVIOUS_APP_ADJ; schedGroup = SCHED_GROUP_BACKGROUND; diff --git a/services/core/java/com/android/server/am/ProcessProviderRecord.java b/services/core/java/com/android/server/am/ProcessProviderRecord.java index 751e8a821ab1..9b72a3afcfd9 100644 --- a/services/core/java/com/android/server/am/ProcessProviderRecord.java +++ b/services/core/java/com/android/server/am/ProcessProviderRecord.java @@ -34,7 +34,7 @@ final class ProcessProviderRecord { /** * The last time someone else was using a provider in this process. */ - private long mLastProviderTime; + private long mLastProviderTime = Long.MIN_VALUE; /** * class (String) -> ContentProviderRecord. diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java index db341d253818..265ab0496f4d 100644 --- a/services/core/java/com/android/server/am/ProcessStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessStateRecord.java @@ -280,7 +280,7 @@ final class ProcessStateRecord { * The last time the process was in the TOP state or greater. */ @GuardedBy("mService") - private long mLastTopTime; + private long mLastTopTime = Long.MIN_VALUE; /** * Is this an empty background process? diff --git a/services/core/java/com/android/server/biometrics/BiometricCameraManager.java b/services/core/java/com/android/server/biometrics/BiometricCameraManager.java new file mode 100644 index 000000000000..058ea6bbb696 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/BiometricCameraManager.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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.biometrics; + +/** + * Interface for biometrics to get camera status. + */ +public interface BiometricCameraManager { + /** + * Returns true if any camera is in use. + */ + boolean isAnyCameraUnavailable(); + + /** + * Returns true if privacy is enabled and camera access is disabled. + */ + boolean isCameraPrivacyEnabled(); +} diff --git a/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java b/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java new file mode 100644 index 000000000000..000ee5446962 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/BiometricCameraManagerImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023 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.biometrics; + +import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; + +import android.annotation.NonNull; +import android.hardware.SensorPrivacyManager; +import android.hardware.camera2.CameraManager; + +import java.util.concurrent.ConcurrentHashMap; + +public class BiometricCameraManagerImpl implements BiometricCameraManager { + + private final CameraManager mCameraManager; + private final SensorPrivacyManager mSensorPrivacyManager; + private final ConcurrentHashMap<String, Boolean> mIsCameraAvailable = new ConcurrentHashMap<>(); + + private final CameraManager.AvailabilityCallback mCameraAvailabilityCallback = + new CameraManager.AvailabilityCallback() { + @Override + public void onCameraAvailable(@NonNull String cameraId) { + mIsCameraAvailable.put(cameraId, true); + } + + @Override + public void onCameraUnavailable(@NonNull String cameraId) { + mIsCameraAvailable.put(cameraId, false); + } + }; + + public BiometricCameraManagerImpl(@NonNull CameraManager cameraManager, + @NonNull SensorPrivacyManager sensorPrivacyManager) { + mCameraManager = cameraManager; + mSensorPrivacyManager = sensorPrivacyManager; + mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, null); + } + + @Override + public boolean isAnyCameraUnavailable() { + for (String cameraId : mIsCameraAvailable.keySet()) { + if (!mIsCameraAvailable.get(cameraId)) { + return true; + } + } + return false; + } + + @Override + public boolean isCameraPrivacyEnabled() { + return mSensorPrivacyManager != null && mSensorPrivacyManager + .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, CAMERA); + } +} diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 0942d8527565..e8ffe4feb458 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -33,6 +33,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.database.ContentObserver; +import android.hardware.SensorPrivacyManager; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricPrompt; @@ -47,6 +48,7 @@ import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; +import android.hardware.camera2.CameraManager; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.net.Uri; @@ -124,6 +126,8 @@ public class BiometricService extends SystemService { AuthSession mAuthSession; private final Handler mHandler = new Handler(Looper.getMainLooper()); + private final BiometricCameraManager mBiometricCameraManager; + /** * Tracks authenticatorId invalidation. For more details, see * {@link com.android.server.biometrics.sensors.InvalidationRequesterClient}. @@ -933,7 +937,7 @@ public class BiometricService extends SystemService { return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */, - getContext()); + getContext(), mBiometricCameraManager); } /** @@ -1026,6 +1030,11 @@ public class BiometricService extends SystemService { public UserManager getUserManager(Context context) { return context.getSystemService(UserManager.class); } + + public BiometricCameraManager getBiometricCameraManager(Context context) { + return new BiometricCameraManagerImpl(context.getSystemService(CameraManager.class), + context.getSystemService(SensorPrivacyManager.class)); + } } /** @@ -1054,6 +1063,7 @@ public class BiometricService extends SystemService { mRequestCounter = mInjector.getRequestGenerator(); mBiometricContext = injector.getBiometricContext(context); mUserManager = injector.getUserManager(context); + mBiometricCameraManager = injector.getBiometricCameraManager(context); try { injector.getActivityManagerService().registerUserSwitchObserver( @@ -1290,7 +1300,7 @@ public class BiometricService extends SystemService { final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(), - getContext()); + getContext(), mBiometricCameraManager); final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus(); @@ -1300,9 +1310,7 @@ public class BiometricService extends SystemService { + promptInfo.isIgnoreEnrollmentState()); // BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED is added so that BiometricPrompt can // be shown for this case. - if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS - || preAuthStatus.second - == BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED) { + if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) { // If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but // CREDENTIAL is requested and available, set the bundle to only request // CREDENTIAL. diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java index 3813fd1971a6..b603fcb498be 100644 --- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java +++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java @@ -27,7 +27,6 @@ import android.annotation.NonNull; import android.app.admin.DevicePolicyManager; import android.app.trust.ITrustManager; import android.content.Context; -import android.hardware.SensorPrivacyManager; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.PromptInfo; @@ -73,13 +72,16 @@ class PreAuthInfo { final Context context; private final boolean mBiometricRequested; private final int mBiometricStrengthRequested; + private final BiometricCameraManager mBiometricCameraManager; + private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested, boolean credentialRequested, List<BiometricSensor> eligibleSensors, List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable, boolean confirmationRequested, boolean ignoreEnrollmentState, int userId, - Context context) { + Context context, BiometricCameraManager biometricCameraManager) { mBiometricRequested = biometricRequested; mBiometricStrengthRequested = biometricStrengthRequested; + mBiometricCameraManager = biometricCameraManager; this.credentialRequested = credentialRequested; this.eligibleSensors = eligibleSensors; @@ -96,7 +98,8 @@ class PreAuthInfo { BiometricService.SettingObserver settingObserver, List<BiometricSensor> sensors, int userId, PromptInfo promptInfo, String opPackageName, - boolean checkDevicePolicyManager, Context context) + boolean checkDevicePolicyManager, Context context, + BiometricCameraManager biometricCameraManager) throws RemoteException { final boolean confirmationRequested = promptInfo.isConfirmationRequested(); @@ -124,7 +127,7 @@ class PreAuthInfo { checkDevicePolicyManager, requestedStrength, promptInfo.getAllowedSensorIds(), promptInfo.isIgnoreEnrollmentState(), - context); + biometricCameraManager); Slog.d(TAG, "Package: " + opPackageName + " Sensor ID: " + sensor.id @@ -138,7 +141,7 @@ class PreAuthInfo { // // Note: if only a certain sensor is required and the privacy is enabled, // canAuthenticate() will return false. - if (status == AUTHENTICATOR_OK || status == BIOMETRIC_SENSOR_PRIVACY_ENABLED) { + if (status == AUTHENTICATOR_OK) { eligibleSensors.add(sensor); } else { ineligibleSensors.add(new Pair<>(sensor, status)); @@ -148,7 +151,7 @@ class PreAuthInfo { return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested, eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested, - promptInfo.isIgnoreEnrollmentState(), userId, context); + promptInfo.isIgnoreEnrollmentState(), userId, context, biometricCameraManager); } /** @@ -165,12 +168,16 @@ class PreAuthInfo { BiometricSensor sensor, int userId, String opPackageName, boolean checkDevicePolicyManager, int requestedStrength, @NonNull List<Integer> requestedSensorIds, - boolean ignoreEnrollmentState, Context context) { + boolean ignoreEnrollmentState, BiometricCameraManager biometricCameraManager) { if (!requestedSensorIds.isEmpty() && !requestedSensorIds.contains(sensor.id)) { return BIOMETRIC_NO_HARDWARE; } + if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) { + return BIOMETRIC_HARDWARE_NOT_DETECTED; + } + final boolean wasStrongEnough = Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength); final boolean isStrongEnough = @@ -191,12 +198,10 @@ class PreAuthInfo { && !ignoreEnrollmentState) { return BIOMETRIC_NOT_ENROLLED; } - final SensorPrivacyManager sensorPrivacyManager = context - .getSystemService(SensorPrivacyManager.class); - if (sensorPrivacyManager != null && sensor.modality == TYPE_FACE) { - if (sensorPrivacyManager - .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, userId)) { + if (biometricCameraManager != null && sensor.modality == TYPE_FACE) { + if (biometricCameraManager.isCameraPrivacyEnabled()) { + //Camera privacy is enabled as the access is disabled return BIOMETRIC_SENSOR_PRIVACY_ENABLED; } } @@ -292,13 +297,9 @@ class PreAuthInfo { @AuthenticatorStatus final int status; @BiometricAuthenticator.Modality int modality = TYPE_NONE; - final SensorPrivacyManager sensorPrivacyManager = context - .getSystemService(SensorPrivacyManager.class); - boolean cameraPrivacyEnabled = false; - if (sensorPrivacyManager != null) { - cameraPrivacyEnabled = sensorPrivacyManager - .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, userId); + if (mBiometricCameraManager != null) { + cameraPrivacyEnabled = mBiometricCameraManager.isCameraPrivacyEnabled(); } if (mBiometricRequested && credentialRequested) { @@ -315,7 +316,7 @@ class PreAuthInfo { // and the face sensor privacy is enabled then return // BIOMETRIC_SENSOR_PRIVACY_ENABLED. // - // Note: This sensor will still be eligible for calls to authenticate. + // Note: This sensor will not be eligible for calls to authenticate. status = BIOMETRIC_SENSOR_PRIVACY_ENABLED; } else { status = AUTHENTICATOR_OK; @@ -340,7 +341,7 @@ class PreAuthInfo { // If the only modality requested is face and the privacy is enabled // then return BIOMETRIC_SENSOR_PRIVACY_ENABLED. // - // Note: This sensor will still be eligible for calls to authenticate. + // Note: This sensor will not be eligible for calls to authenticate. status = BIOMETRIC_SENSOR_PRIVACY_ENABLED; } else { status = AUTHENTICATOR_OK; diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index f7ef513f085e..4ccc554f1fe1 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -240,6 +240,10 @@ public class LockSettingsService extends ILockSettings.Stub { private static final String LSKF_LAST_CHANGED_TIME_KEY = "sp-handle-ts"; private static final String USER_SERIAL_NUMBER_KEY = "serial-number"; + private static final String MIGRATED_FRP2 = "migrated_frp2"; + private static final String MIGRATED_KEYSTORE_NS = "migrated_keystore_namespace"; + private static final String MIGRATED_SP_CE_ONLY = "migrated_all_users_to_sp_and_bound_ce"; + // Duration that LockSettingsService will store the gatekeeper password for. This allows // multiple biometric enrollments without prompting the user to enter their password via // ConfirmLockPassword/ConfirmLockPattern multiple times. This needs to be at least the duration @@ -906,14 +910,14 @@ public class LockSettingsService extends ILockSettings.Stub { } private void migrateOldData() { - if (getString("migrated_keystore_namespace", null, 0) == null) { + if (getString(MIGRATED_KEYSTORE_NS, null, 0) == null) { boolean success = true; synchronized (mSpManager) { success &= mSpManager.migrateKeyNamespace(); } success &= migrateProfileLockKeys(); if (success) { - setString("migrated_keystore_namespace", "true", 0); + setString(MIGRATED_KEYSTORE_NS, "true", 0); Slog.i(TAG, "Migrated keys to LSS namespace"); } else { Slog.w(TAG, "Failed to migrate keys to LSS namespace"); @@ -933,9 +937,9 @@ public class LockSettingsService extends ILockSettings.Stub { // "migrated_frp" to "migrated_frp2" to cause migrateFrpCredential() to run again on devices // where it had run before. if (LockPatternUtils.frpCredentialEnabled(mContext) - && !getBoolean("migrated_frp2", false, 0)) { + && !getBoolean(MIGRATED_FRP2, false, 0)) { migrateFrpCredential(); - setBoolean("migrated_frp2", true, 0); + setBoolean(MIGRATED_FRP2, true, 0); } } @@ -1025,14 +1029,14 @@ public class LockSettingsService extends ILockSettings.Stub { // If this gets interrupted (e.g. by the device powering off), there shouldn't be a // problem since this will run again on the next boot, and setUserKeyProtection() is // okay with the key being already protected by the given secret. - if (getString("migrated_all_users_to_sp_and_bound_ce", null, 0) == null) { + if (getString(MIGRATED_SP_CE_ONLY, null, 0) == null) { for (UserInfo user : mUserManager.getAliveUsers()) { removeStateForReusedUserIdIfNecessary(user.id, user.serialNumber); synchronized (mSpManager) { migrateUserToSpWithBoundCeKeyLocked(user.id); } } - setString("migrated_all_users_to_sp_and_bound_ce", "true", 0); + setString(MIGRATED_SP_CE_ONLY, "true", 0); } mThirdPartyAppsStarted = true; @@ -1059,7 +1063,7 @@ public class LockSettingsService extends ILockSettings.Stub { Slogf.wtf(TAG, "Failed to unwrap synthetic password for unsecured user %d", userId); return; } - setUserKeyProtection(userId, result.syntheticPassword.deriveFileBasedEncryptionKey()); + setUserKeyProtection(userId, result.syntheticPassword); } } @@ -1344,8 +1348,8 @@ public class LockSettingsService extends ILockSettings.Stub { AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password); } - private void unlockKeystore(byte[] password, int userHandle) { - Authorization.onLockScreenEvent(false, userHandle, password, null); + private void unlockKeystore(int userId, SyntheticPassword sp) { + Authorization.onLockScreenEvent(false, userId, sp.deriveKeyStorePassword(), null); } @VisibleForTesting /** Note: this method is overridden in unit tests */ @@ -1998,7 +2002,8 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage.writeChildProfileLock(profileUserId, ArrayUtils.concat(iv, ciphertext)); } - private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) { + private void setUserKeyProtection(@UserIdInt int userId, SyntheticPassword sp) { + final byte[] secret = sp.deriveFileBasedEncryptionKey(); final long callingId = Binder.clearCallingIdentity(); try { mStorageManager.setUserKeyProtection(userId, secret); @@ -2042,7 +2047,9 @@ public class LockSettingsService extends ILockSettings.Stub { } } - private void unlockUserKeyIfUnsecured(@UserIdInt int userId) { + @Override + public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { + checkPasswordReadPermission(); synchronized (mSpManager) { if (isUserKeyUnlocked(userId)) { Slogf.d(TAG, "CE storage for user %d is already unlocked", userId); @@ -2765,7 +2772,7 @@ public class LockSettingsService extends ILockSettings.Stub { final long protectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(), LockscreenCredential.createNone(), sp, userId); setCurrentLskfBasedProtectorId(protectorId, userId); - setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey()); + setUserKeyProtection(userId, sp); onSyntheticPasswordCreated(userId, sp); Slogf.i(TAG, "Successfully initialized synthetic password for user %d", userId); return sp; @@ -2824,7 +2831,7 @@ public class LockSettingsService extends ILockSettings.Stub { } } - unlockKeystore(sp.deriveKeyStorePassword(), userId); + unlockKeystore(userId, sp); unlockUserKey(userId, sp); @@ -2891,7 +2898,7 @@ public class LockSettingsService extends ILockSettings.Stub { mSpManager.clearSidForUser(userId); gateKeeperClearSecureUserId(userId); unlockUserKey(userId, sp); - unlockKeystore(sp.deriveKeyStorePassword(), userId); + unlockKeystore(userId, sp); setKeystorePassword(null, userId); removeBiometricsForUser(userId); } @@ -3451,11 +3458,6 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override - public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { - LockSettingsService.this.unlockUserKeyIfUnsecured(userId); - } - - @Override public void createNewUser(@UserIdInt int userId, int userSerialNumber) { LockSettingsService.this.createNewUser(userId, userSerialNumber); } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java index df95c69e7271..4bac872dbaa9 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java @@ -174,7 +174,7 @@ class LockSettingsShellCommand extends ShellCommand { pw.println(" Sets the lock screen as PIN, using the given PIN to unlock."); pw.println(""); pw.println(" set-password [--old <CREDENTIAL>] [--user USER_ID] <PASSWORD>"); - pw.println(" Sets the lock screen as password, using the given PASSOWRD to unlock."); + pw.println(" Sets the lock screen as password, using the given PASSWORD to unlock."); pw.println(""); pw.println(" clear [--old <CREDENTIAL>] [--user USER_ID]"); pw.println(" Clears the lock credentials."); diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java index ec0d9856486d..77a60289d7a9 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java @@ -123,7 +123,7 @@ public class KeySyncTask implements Runnable { * @param userId The uid of the user whose profile has been unlocked. * @param credentialType The type of credential as defined in {@code LockPatternUtils} * @param credential The credential, encoded as a byte array - * @param credentialUpdated signals weather credentials were updated. + * @param credentialUpdated indicates credentials change. * @param platformKeyManager platform key manager * @param testOnlyInsecureCertificateHelper utility class used for end-to-end tests */ @@ -143,7 +143,7 @@ public class KeySyncTask implements Runnable { mRecoverableKeyStoreDb = recoverableKeyStoreDb; mUserId = userId; mCredentialType = credentialType; - mCredential = credential; + mCredential = credential != null ? Arrays.copyOf(credential, credential.length) : null; mCredentialUpdated = credentialUpdated; mPlatformKeyManager = platformKeyManager; mRecoverySnapshotStorage = snapshotStorage; @@ -160,6 +160,10 @@ public class KeySyncTask implements Runnable { } } catch (Exception e) { Log.e(TAG, "Unexpected exception thrown during KeySyncTask", e); + } finally { + if (mCredential != null) { + Arrays.fill(mCredential, (byte) 0); // no longer needed. + } } } diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java index 7009a41726e2..ce3fb850b517 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java @@ -166,6 +166,7 @@ public class PlatformKeyManager { * @param userId The ID of the user to whose lock screen the platform key must be bound. * @throws NoSuchAlgorithmException if AES is unavailable - should never happen. * @throws KeyStoreException if there is an error in AndroidKeyStore. + * @throws InsecureUserException if the user does not have a lock screen set. * @throws IOException if there was an issue with local database update. * @throws RemoteException if there was an issue communicating with {@link IGateKeeperService}. * @@ -174,7 +175,7 @@ public class PlatformKeyManager { @VisibleForTesting void regenerate(int userId) throws NoSuchAlgorithmException, KeyStoreException, IOException, - RemoteException { + RemoteException, InsecureUserException { int generationId = getGenerationId(userId); int nextId; if (generationId == -1) { @@ -195,13 +196,14 @@ public class PlatformKeyManager { * @throws UnrecoverableKeyException if the key could not be recovered. * @throws NoSuchAlgorithmException if AES is unavailable - should never occur. * @throws IOException if there was an issue with local database update. + * @throws InsecureUserException if the user does not have a lock screen set. * @throws RemoteException if there was an issue communicating with {@link IGateKeeperService}. * * @hide */ public PlatformEncryptionKey getEncryptKey(int userId) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, - IOException, RemoteException { + IOException, RemoteException, InsecureUserException { init(userId); try { // Try to see if the decryption key is still accessible before using the encryption key. @@ -254,7 +256,7 @@ public class PlatformKeyManager { */ public PlatformDecryptionKey getDecryptKey(int userId) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, - IOException, RemoteException { + IOException, InsecureUserException, RemoteException { init(userId); try { PlatformDecryptionKey decryptionKey = getDecryptKeyInternal(userId); @@ -328,7 +330,7 @@ public class PlatformKeyManager { */ void init(int userId) throws KeyStoreException, NoSuchAlgorithmException, IOException, - RemoteException { + RemoteException, InsecureUserException { int generationId = getGenerationId(userId); if (isKeyLoaded(userId, generationId)) { Log.i(TAG, String.format( @@ -414,7 +416,8 @@ public class PlatformKeyManager { * @throws RemoteException if there was an issue communicating with {@link IGateKeeperService}. */ private void generateAndLoadKey(int userId, int generationId) - throws NoSuchAlgorithmException, KeyStoreException, IOException, RemoteException { + throws NoSuchAlgorithmException, KeyStoreException, IOException, RemoteException, + InsecureUserException { String encryptAlias = getEncryptAlias(userId, generationId); String decryptAlias = getDecryptAlias(userId, generationId); // SecretKey implementation doesn't provide reliable way to destroy the secret @@ -427,23 +430,31 @@ public class PlatformKeyManager { .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE); // Skip UserAuthenticationRequired for main user if (userId == UserHandle.USER_SYSTEM) { + // attempt to store key will fail if screenlock is not set. decryptionKeyProtection.setUnlockedDeviceRequired(true); } else { // Don't set protection params to prevent losing key. } // Store decryption key first since it is more likely to fail. - mKeyStore.setEntry( - decryptAlias, - new KeyStore.SecretKeyEntry(secretKey), - decryptionKeyProtection.build()); - mKeyStore.setEntry( - encryptAlias, - new KeyStore.SecretKeyEntry(secretKey), - new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) - .build()); - + try { + mKeyStore.setEntry( + decryptAlias, + new KeyStore.SecretKeyEntry(secretKey), + decryptionKeyProtection.build()); + mKeyStore.setEntry( + encryptAlias, + new KeyStore.SecretKeyEntry(secretKey), + new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .build()); + } catch (KeyStoreException e) { + if (!isDeviceSecure(userId)) { + throw new InsecureUserException("Screenlock is not set"); + } else { + throw e; + } + } setGenerationId(userId, generationId); } @@ -477,4 +488,8 @@ public class PlatformKeyManager { return keyStore; } + private boolean isDeviceSecure(int userId) { + return mContext.getSystemService(KeyguardManager.class).isDeviceSecure(userId); + } + } diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java index 24dbce49eace..10b6052bec69 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -19,6 +19,7 @@ package com.android.server.locksettings.recoverablekeystore; import static android.security.keystore.recovery.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT; import static android.security.keystore.recovery.RecoveryController.ERROR_DECRYPTION_FAILED; import static android.security.keystore.recovery.RecoveryController.ERROR_DOWNGRADE_CERTIFICATE; +import static android.security.keystore.recovery.RecoveryController.ERROR_INSECURE_USER; import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_CERTIFICATE; import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_KEY_FORMAT; import static android.security.keystore.recovery.RecoveryController.ERROR_NO_SNAPSHOT_PENDING; @@ -194,8 +195,12 @@ public class RecoverableKeyStoreManager { mApplicationKeyStorage = applicationKeyStorage; mTestCertHelper = testOnlyInsecureCertificateHelper; mCleanupManager = cleanupManager; - // Clears data for removed users. - mCleanupManager.verifyKnownUsers(); + try { + // Clears data for removed users. + mCleanupManager.verifyKnownUsers(); + } catch (Exception e) { + Log.e(TAG, "Failed to verify known users", e); + } try { mRecoverableKeyGenerator = RecoverableKeyGenerator.newInstance(mDatabase); } catch (NoSuchAlgorithmException e) { @@ -750,6 +755,8 @@ public class RecoverableKeyStoreManager { throw new RuntimeException(e); } catch (KeyStoreException | UnrecoverableKeyException | IOException e) { throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage()); + } catch (InsecureUserException e) { + throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage()); } try { @@ -817,6 +824,8 @@ public class RecoverableKeyStoreManager { throw new RuntimeException(e); } catch (KeyStoreException | UnrecoverableKeyException | IOException e) { throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage()); + } catch (InsecureUserException e) { + throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage()); } try { diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java index 06db6b8a38f8..ef56a1e26854 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java @@ -138,7 +138,7 @@ public class ApplicationKeyStorage { } catch (android.security.KeyStoreException e) { if (e.getNumericErrorCode() == android.security.KeyStoreException.ERROR_KEY_DOES_NOT_EXIST) { - Log.e(TAG, "Failed to get grant for KeyStore key - key not found", e); + Log.w(TAG, "Failed to get grant for KeyStore key - key not found"); throw new ServiceSpecificException(ERROR_KEY_NOT_FOUND, e.getMessage()); } Log.e(TAG, "Failed to get grant for KeyStore key.", e); diff --git a/services/core/java/com/android/server/net/NetworkManagementService.java b/services/core/java/com/android/server/net/NetworkManagementService.java index 36adea7e0112..a5a934f78420 100644 --- a/services/core/java/com/android/server/net/NetworkManagementService.java +++ b/services/core/java/com/android/server/net/NetworkManagementService.java @@ -75,7 +75,6 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.HexDump; import com.android.modules.utils.build.SdkLevel; import com.android.net.module.util.NetdUtils; -import com.android.net.module.util.NetdUtils.ModifyOperation; import com.android.net.module.util.PermissionUtils; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -758,18 +757,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } - @Override - public void addRoute(int netId, RouteInfo route) { - PermissionUtils.enforceNetworkStackPermission(mContext); - NetdUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route); - } - - @Override - public void removeRoute(int netId, RouteInfo route) { - PermissionUtils.enforceNetworkStackPermission(mContext); - NetdUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route); - } - @android.annotation.EnforcePermission(android.Manifest.permission.SHUTDOWN) @Override public void shutdown() { diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java index 9cf08340f613..749cd8e55bb7 100644 --- a/services/core/java/com/android/server/vibrator/VibrationSettings.java +++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java @@ -731,18 +731,24 @@ final class VibrationSettings { private final SparseArray<Integer> mProcStatesCache = new SparseArray<>(); public boolean isUidForeground(int uid) { - return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) - <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + synchronized (this) { + return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) + <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + } } @Override public void onUidGone(int uid, boolean disabled) { - mProcStatesCache.delete(uid); + synchronized (this) { + mProcStatesCache.delete(uid); + } } @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { - mProcStatesCache.put(uid, procState); + synchronized (this) { + mProcStatesCache.put(uid, procState); + } } } diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS index f6c364008c62..f8c39d0906a0 100644 --- a/services/core/java/com/android/server/wm/OWNERS +++ b/services/core/java/com/android/server/wm/OWNERS @@ -16,6 +16,7 @@ lihongyu@google.com mariiasand@google.com rgl@google.com yunfanc@google.com +wilsonshih@google.com per-file BackgroundActivityStartController.java = set noparent per-file BackgroundActivityStartController.java = brufino@google.com, topjohnwu@google.com, achim@google.com, ogunwale@google.com, louischang@google.com, lus@google.com diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index c6a914b37206..ccbaf78bfc95 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -2530,7 +2530,7 @@ public class MockingOomAdjusterTests { PROCESS_STATE_NONEXISTENT, PROCESS_STATE_NONEXISTENT, 0, 0, false, false, false, ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE, false, false, false, hasShownUi, false, false, false, false, false, false, null, - 0, 0, 0, true, 0, null, false); + 0, Long.MIN_VALUE, Long.MIN_VALUE, true, 0, null, false); } private ProcessRecord makeProcessRecord(ActivityManagerService service, int pid, int uid, diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java index 662477ddbbe9..2aabb1bc24b2 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java @@ -104,6 +104,7 @@ public class AuthSessionTest { @Mock private KeyStore mKeyStore; @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver; @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger; + @Mock private BiometricCameraManager mBiometricCameraManager; private Random mRandom; private IBinder mToken; @@ -571,7 +572,8 @@ public class AuthSessionTest { promptInfo, TEST_PACKAGE, checkDevicePolicyManager, - mContext); + mContext, + mBiometricCameraManager); } private AuthSession createAuthSession(List<BiometricSensor> sensors, diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java index 67be37616d5f..6f4791af43f0 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java @@ -152,6 +152,8 @@ public class BiometricServiceTest { private AuthSessionCoordinator mAuthSessionCoordinator; @Mock private UserManager mUserManager; + @Mock + private BiometricCameraManager mBiometricCameraManager; BiometricContextProvider mBiometricContextProvider; @@ -178,6 +180,7 @@ public class BiometricServiceTest { when(mInjector.getDevicePolicyManager(any())).thenReturn(mDevicePolicyManager); when(mInjector.getRequestGenerator()).thenReturn(() -> TEST_REQUEST_ID); when(mInjector.getUserManager(any())).thenReturn(mUserManager); + when(mInjector.getBiometricCameraManager(any())).thenReturn(mBiometricCameraManager); when(mResources.getString(R.string.biometric_error_hw_unavailable)) .thenReturn(ERROR_HW_UNAVAILABLE); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java new file mode 100644 index 000000000000..c2bdf501198e --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2023 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.biometrics; + +import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE; +import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; + +import static com.android.server.biometrics.sensors.LockoutTracker.LOCKOUT_NONE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.when; + +import android.app.admin.DevicePolicyManager; +import android.app.trust.ITrustManager; +import android.content.Context; +import android.hardware.biometrics.BiometricManager; +import android.hardware.biometrics.IBiometricAuthenticator; +import android.hardware.biometrics.PromptInfo; +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.List; + +@Presubmit +@SmallTest +public class PreAuthInfoTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + private static final int SENSOR_ID_FACE = 1; + private static final String TEST_PACKAGE_NAME = "PreAuthInfoTestPackage"; + + @Mock + IBiometricAuthenticator mFaceAuthenticator; + @Mock + Context mContext; + @Mock + ITrustManager mTrustManager; + @Mock + DevicePolicyManager mDevicePolicyManager; + @Mock + BiometricService.SettingObserver mSettingObserver; + @Mock + BiometricCameraManager mBiometricCameraManager; + + @Before + public void setup() throws RemoteException { + when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true); + when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt())) + .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE); + when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true); + when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); + when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true); + when(mFaceAuthenticator.getLockoutModeForUser(anyInt())) + .thenReturn(LOCKOUT_NONE); + when(mBiometricCameraManager.isCameraPrivacyEnabled()).thenReturn(false); + when(mBiometricCameraManager.isAnyCameraUnavailable()).thenReturn(false); + } + + @Test + public void testFaceAuthentication_whenCameraPrivacyIsEnabled() throws Exception { + when(mBiometricCameraManager.isCameraPrivacyEnabled()).thenReturn(true); + + BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE, + BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) { + @Override + boolean confirmationAlwaysRequired(int userId) { + return false; + } + + @Override + boolean confirmationSupported() { + return false; + } + }; + PromptInfo promptInfo = new PromptInfo(); + promptInfo.setConfirmationRequested(false /* requireConfirmation */); + promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); + promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */); + PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, + mSettingObserver, List.of(sensor), + 0 /* userId */, promptInfo, TEST_PACKAGE_NAME, + false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager); + + assertThat(preAuthInfo.eligibleSensors).isEmpty(); + } + + @Test + public void testFaceAuthentication_whenCameraPrivacyIsDisabledAndCameraIsAvailable() + throws Exception { + BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE, + BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) { + @Override + boolean confirmationAlwaysRequired(int userId) { + return false; + } + + @Override + boolean confirmationSupported() { + return false; + } + }; + PromptInfo promptInfo = new PromptInfo(); + promptInfo.setConfirmationRequested(false /* requireConfirmation */); + promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); + promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */); + PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, + mSettingObserver, List.of(sensor), + 0 /* userId */, promptInfo, TEST_PACKAGE_NAME, + false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager); + + assertThat(preAuthInfo.eligibleSensors).hasSize(1); + } + + @Test + public void testFaceAuthentication_whenCameraIsUnavailable() throws RemoteException { + when(mBiometricCameraManager.isAnyCameraUnavailable()).thenReturn(true); + BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE, + BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) { + @Override + boolean confirmationAlwaysRequired(int userId) { + return false; + } + + @Override + boolean confirmationSupported() { + return false; + } + }; + PromptInfo promptInfo = new PromptInfo(); + promptInfo.setConfirmationRequested(false /* requireConfirmation */); + promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); + promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */); + PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, + mSettingObserver, List.of(sensor), + 0 /* userId */, promptInfo, TEST_PACKAGE_NAME, + false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager); + + assertThat(preAuthInfo.eligibleSensors).hasSize(0); + } +} diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java index 37a6d22f038b..eca19c8e8c4d 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java @@ -255,7 +255,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { public void testUnlockUserKeyIfUnsecuredPassesPrimaryUserAuthSecret() throws RemoteException { initSpAndSetCredential(PRIMARY_USER_ID, newPassword(null)); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); + mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class)); } @@ -267,7 +267,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { mService.setLockCredential(nonePassword(), password, PRIMARY_USER_ID); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); + mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class)); } @@ -285,39 +285,39 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { @Test public void testHeadlessSystemUserDoesNotPassAuthSecret() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); + mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); verify(mAuthSecretService, never()).setPrimaryUserCredential(any(byte[].class)); } @Test public void testHeadlessSecondaryUserPassesAuthSecret() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); + mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class)); } @Test public void testHeadlessTertiaryUserPassesSameAuthSecret() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); + mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); var captor = ArgumentCaptor.forClass(byte[].class); verify(mAuthSecretService).setPrimaryUserCredential(captor.capture()); var value = captor.getValue(); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); + mService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(eq(value)); } @Test public void testHeadlessTertiaryUserPassesSameAuthSecretAfterReset() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); + mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); var captor = ArgumentCaptor.forClass(byte[].class); verify(mAuthSecretService).setPrimaryUserCredential(captor.capture()); var value = captor.getValue(); mService.clearAuthSecret(); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); + mService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(eq(value)); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java index 5654c89196f2..80fb5e3f950d 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java @@ -36,6 +36,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -297,13 +298,15 @@ public class KeySyncTaskTest { TestData.getInsecureCertPathForEndpoint1()); addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, appKeyAlias); + setExpectedScryptArgument(password.getBytes()); + mKeySyncTask.run(); KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID); assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1); assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()). isEqualTo(UI_FORMAT_PASSWORD); - verify(mMockScrypt).scrypt(eq(password.getBytes()), any(), + verify(mMockScrypt).scrypt(any(), any(), eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R), eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES)); KeyDerivationParams keyDerivationParams = @@ -314,6 +317,44 @@ public class KeySyncTaskTest { } @Test + public void run_zeroizedCredential() throws Exception { + String password = TrustedRootCertificates.INSECURE_PASSWORD_PREFIX + "123"; + String appKeyAlias = TrustedRootCertificates.INSECURE_KEY_ALIAS_PREFIX + "alias"; + byte[] zeroizedCredential = password.getBytes(); + mKeySyncTask = new KeySyncTask( + mRecoverableKeyStoreDb, + mRecoverySnapshotStorage, + mSnapshotListenersStorage, + TEST_USER_ID, + CREDENTIAL_TYPE_PASSWORD, + /*credential=*/ zeroizedCredential, + /*credentialUpdated=*/ false, + mPlatformKeyManager, + mTestOnlyInsecureCertificateHelper, + mMockScrypt); + mRecoverableKeyStoreDb.setServerParams( + TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE); + mRecoverableKeyStoreDb.setPlatformKeyGenerationId(TEST_USER_ID, TEST_GENERATION_ID); + mRecoverableKeyStoreDb.setActiveRootOfTrust(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, + TrustedRootCertificates.TEST_ONLY_INSECURE_CERTIFICATE_ALIAS); + mRecoverableKeyStoreDb.setRecoveryServiceCertPath( + TEST_USER_ID, TEST_RECOVERY_AGENT_UID, + TrustedRootCertificates.TEST_ONLY_INSECURE_CERTIFICATE_ALIAS, + TestData.getInsecureCertPathForEndpoint1()); + addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, appKeyAlias); + + // Need to check array value during method call since it is modified later. + setExpectedScryptArgument(password.getBytes()); + + Arrays.fill(zeroizedCredential, (byte) 0); + mKeySyncTask.run(); + + verify(mMockScrypt).scrypt(any(), any(), + eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R), + eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES)); + } + + @Test public void run_useSha256ToHashPatternInProdMode() throws Exception { String pattern = "123456"; mKeySyncTask = new KeySyncTask( @@ -368,13 +409,15 @@ public class KeySyncTaskTest { mRecoverableKeyStoreDb.setRecoveryServiceCertPath( TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, TestData.CERT_PATH_1); + setExpectedScryptArgument(shortPassword.getBytes()); + mKeySyncTask.run(); KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID); assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1); assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()). isEqualTo(UI_FORMAT_PASSWORD); - verify(mMockScrypt).scrypt(eq(shortPassword.getBytes()), any(), + verify(mMockScrypt).scrypt(any(), any(), eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R), eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES)); KeyDerivationParams keyDerivationParams = @@ -650,13 +693,15 @@ public class KeySyncTaskTest { when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true); addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS); + setExpectedScryptArgument(password.getBytes()); + mKeySyncTask.run(); KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID); assertThat(keyChainSnapshot.getKeyChainProtectionParams()).hasSize(1); assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()). isEqualTo(UI_FORMAT_PASSWORD); - verify(mMockScrypt).scrypt(eq(password.getBytes()), any(), + verify(mMockScrypt).scrypt(any(), any(), eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R), eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES)); } @@ -681,6 +726,8 @@ public class KeySyncTaskTest { when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true); addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS); + setExpectedScryptArgument(pin.getBytes()); + mKeySyncTask.run(); KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID); @@ -688,7 +735,7 @@ public class KeySyncTaskTest { // Password with only digits is changed to pin. assertThat(keyChainSnapshot.getKeyChainProtectionParams().get(0).getLockScreenUiFormat()). isEqualTo(UI_FORMAT_PIN); - verify(mMockScrypt).scrypt(eq(pin.getBytes()), any(), + verify(mMockScrypt).scrypt(any(), any(), eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R), eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES)); } @@ -868,4 +915,14 @@ public class KeySyncTaskTest { new Random().nextBytes(bytes); return bytes; } + + private void setExpectedScryptArgument(byte[] credentials) { + doAnswer(invocation -> { + assertThat((byte[]) invocation.getArguments()[0]).isEqualTo(credentials); + return invocation.callRealMethod(); + }).when(mMockScrypt).scrypt(any(), any(), + eq(KeySyncTask.SCRYPT_PARAM_N), eq(KeySyncTask.SCRYPT_PARAM_R), + eq(KeySyncTask.SCRYPT_PARAM_P), eq(KeySyncTask.SCRYPT_PARAM_OUTLEN_BYTES)); + + } } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java index c546a741e76a..c09e09c8404f 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.testng.Assert.assertThrows; import android.app.KeyguardManager; import android.content.Context; @@ -54,6 +55,7 @@ import org.mockito.MockitoAnnotations; import java.io.File; import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.UnrecoverableKeyException; import java.util.List; @@ -393,6 +395,18 @@ public class PlatformKeyManagerTest { } @Test + public void getEncryptKey_noScreenlock() throws Exception { + when(mKeyguardManager.isDeviceSecure(USER_ID_FIXTURE)).thenReturn(false); + doThrow(new KeyStoreException()).when(mKeyStoreProxy).setEntry( + anyString(), + any(), + any()); + + assertThrows(InsecureUserException.class, + () -> mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE)); + } + + @Test public void getDecryptKey_generatesNewKeyIfOldOneIsInvalid() throws Exception { doThrow(new UnrecoverableKeyException()).when(mKeyStoreProxy).getKey( eq(DECRYPTION_KEY_ALIAS_1), diff --git a/test-mock/api/current.txt b/test-mock/api/current.txt index 241e69106718..f61cce666cca 100644 --- a/test-mock/api/current.txt +++ b/test-mock/api/current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.test.mock { @Deprecated public class MockAccountManager { @@ -202,7 +200,7 @@ package android.test.mock { method @Deprecated public int checkPermission(String, String); method @Deprecated public int checkSignatures(String, String); method @Deprecated public int checkSignatures(int, int); - method public void clearInstantAppCookie(); + method @Deprecated public void clearInstantAppCookie(); method @Deprecated public void clearPackagePreferredActivities(String); method @Deprecated public String[] currentToCanonicalPackageNames(String[]); method @Deprecated public void extendVerificationTimeout(int, int, long); @@ -224,15 +222,15 @@ package android.test.mock { method @Deprecated public CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method @Deprecated public android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method @Deprecated public android.graphics.drawable.Drawable getApplicationLogo(String) throws android.content.pm.PackageManager.NameNotFoundException; - method public android.content.pm.ChangedPackages getChangedPackages(int); + method @Deprecated public android.content.pm.ChangedPackages getChangedPackages(int); method @Deprecated public int getComponentEnabledSetting(android.content.ComponentName); method @Deprecated public android.graphics.drawable.Drawable getDefaultActivityIcon(); method @Deprecated public android.graphics.drawable.Drawable getDrawable(String, int, android.content.pm.ApplicationInfo); method @Deprecated public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int); method @Deprecated public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int); method @Deprecated public String getInstallerPackageName(String); - method public byte[] getInstantAppCookie(); - method public int getInstantAppCookieMaxBytes(); + method @Deprecated public byte[] getInstantAppCookie(); + method @Deprecated public int getInstantAppCookieMaxBytes(); method @Deprecated public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Deprecated public android.content.Intent getLaunchIntentForPackage(String); method @Deprecated public android.content.Intent getLeanbackLaunchIntentForPackage(String); @@ -241,7 +239,7 @@ package android.test.mock { method @Deprecated public int[] getPackageGids(String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Deprecated public android.content.pm.PackageInfo getPackageInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Deprecated public android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public android.content.pm.PackageInstaller getPackageInstaller(); + method @Deprecated public android.content.pm.PackageInstaller getPackageInstaller(); method @Deprecated public int getPackageUid(String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Deprecated public String[] getPackagesForUid(int); method @Deprecated public java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(String[], int); @@ -265,8 +263,8 @@ package android.test.mock { method @Deprecated public android.content.res.XmlResourceParser getXml(String, int, android.content.pm.ApplicationInfo); method @Deprecated public boolean hasSystemFeature(String); method @Deprecated public boolean hasSystemFeature(String, int); - method public boolean isInstantApp(); - method public boolean isInstantApp(String); + method @Deprecated public boolean isInstantApp(); + method @Deprecated public boolean isInstantApp(String); method @Deprecated public boolean isPermissionRevokedByPolicy(String, String); method @Deprecated public boolean isSafeMode(); method @Deprecated public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int); @@ -283,11 +281,12 @@ package android.test.mock { method @Deprecated public android.content.pm.ProviderInfo resolveContentProvider(String, int); method @Deprecated public android.content.pm.ResolveInfo resolveService(android.content.Intent, int); method @Deprecated public android.content.pm.ResolveInfo resolveServiceAsUser(android.content.Intent, int, int); - method public void setApplicationCategoryHint(String, int); + method @Deprecated public void setApplicationCategoryHint(String, int); method @Deprecated public void setApplicationEnabledSetting(String, int, int); method @Deprecated public void setComponentEnabledSetting(android.content.ComponentName, int, int); method @Deprecated public void setInstallerPackageName(String, String); - method public void updateInstantAppCookie(@NonNull byte[]); + method @Deprecated public boolean setInstantAppCookie(@NonNull byte[]); + method @Deprecated public void updateInstantAppCookie(@NonNull byte[]); method @Deprecated public void verifyPendingInstall(int, int); } diff --git a/test-mock/api/removed.txt b/test-mock/api/removed.txt index fa2fbd276e9a..0c800b6f82b5 100644 --- a/test-mock/api/removed.txt +++ b/test-mock/api/removed.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.test.mock { public class MockContext extends android.content.Context { @@ -11,7 +9,7 @@ package android.test.mock { @Deprecated public class MockPackageManager extends android.content.pm.PackageManager { method @Deprecated public String getDefaultBrowserPackageName(int); method @Deprecated public boolean setDefaultBrowserPackageName(String, int); - method public boolean setInstantAppCookie(@NonNull byte[]); + method @Deprecated public boolean setInstantAppCookie(@NonNull byte[]); } } diff --git a/test-mock/api/system-current.txt b/test-mock/api/system-current.txt index 2b5132ecd14f..f35095743738 100644 --- a/test-mock/api/system-current.txt +++ b/test-mock/api/system-current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.test.mock { public class MockContext extends android.content.Context { @@ -11,30 +9,30 @@ package android.test.mock { } @Deprecated public class MockPackageManager extends android.content.pm.PackageManager { - method public void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); - method public boolean arePermissionsIndividuallyControlled(); + method @Deprecated public void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); + method @Deprecated public boolean arePermissionsIndividuallyControlled(); method @Deprecated public java.util.List<android.content.IntentFilter> getAllIntentFilters(String); - method public String getDefaultBrowserPackageNameAsUser(int); - method public java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); - method public android.graphics.drawable.Drawable getInstantAppIcon(String); - method public android.content.ComponentName getInstantAppInstallerComponent(); - method public android.content.ComponentName getInstantAppResolverSettingsComponent(); - method public java.util.List<android.content.pm.InstantAppInfo> getInstantApps(); - method public java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(String); - method public int getIntentVerificationStatusAsUser(String, int); - method public int getPermissionFlags(String, String, android.os.UserHandle); - method public void grantRuntimePermission(String, String, android.os.UserHandle); - method public int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException; - method public int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public void registerDexModule(String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback); - method public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); - method public void revokeRuntimePermission(String, String, android.os.UserHandle); - method public boolean setDefaultBrowserPackageNameAsUser(String, int); + method @Deprecated public String getDefaultBrowserPackageNameAsUser(int); + method @Deprecated public java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); + method @Deprecated public android.graphics.drawable.Drawable getInstantAppIcon(String); + method @Deprecated public android.content.ComponentName getInstantAppInstallerComponent(); + method @Deprecated public android.content.ComponentName getInstantAppResolverSettingsComponent(); + method @Deprecated public java.util.List<android.content.pm.InstantAppInfo> getInstantApps(); + method @Deprecated public java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(String); + method @Deprecated public int getIntentVerificationStatusAsUser(String, int); + method @Deprecated public int getPermissionFlags(String, String, android.os.UserHandle); + method @Deprecated public void grantRuntimePermission(String, String, android.os.UserHandle); + method @Deprecated public int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException; + method @Deprecated public int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @Deprecated public void registerDexModule(String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback); + method @Deprecated public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); + method @Deprecated public void revokeRuntimePermission(String, String, android.os.UserHandle); + method @Deprecated public boolean setDefaultBrowserPackageNameAsUser(String, int); method public String[] setPackagesSuspended(String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, String); - method public void setUpdateAvailable(String, boolean); - method public boolean updateIntentVerificationStatusAsUser(String, int, int); - method public void updatePermissionFlags(String, String, int, int, android.os.UserHandle); - method public void verifyIntentFilter(int, int, java.util.List<java.lang.String>); + method @Deprecated public void setUpdateAvailable(String, boolean); + method @Deprecated public boolean updateIntentVerificationStatusAsUser(String, int, int); + method @Deprecated public void updatePermissionFlags(String, String, int, int, android.os.UserHandle); + method @Deprecated public void verifyIntentFilter(int, int, java.util.List<java.lang.String>); } } diff --git a/test-mock/api/system-removed.txt b/test-mock/api/system-removed.txt index 14191ebcb080..d802177e249b 100644 --- a/test-mock/api/system-removed.txt +++ b/test-mock/api/system-removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt index 1752edcd469e..9ed010881067 100644 --- a/test-mock/api/test-current.txt +++ b/test-mock/api/test-current.txt @@ -1,6 +1,4 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 package android.test.mock { public class MockContext extends android.content.Context { @@ -8,13 +6,13 @@ package android.test.mock { } @Deprecated public class MockPackageManager extends android.content.pm.PackageManager { - method public void addCrossProfileIntentFilter(android.content.IntentFilter, int, int, int); - method public void clearCrossProfileIntentFilters(int); - method public int getInstallReason(String, android.os.UserHandle); - method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); - method public String[] getNamesForUids(int[]); - method @NonNull public String getServicesSystemSharedLibraryPackageName(); - method @NonNull public String getSharedSystemSharedLibraryPackageName(); + method @Deprecated public void addCrossProfileIntentFilter(android.content.IntentFilter, int, int, int); + method @Deprecated public void clearCrossProfileIntentFilters(int); + method @Deprecated public int getInstallReason(String, android.os.UserHandle); + method @Deprecated public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); + method @Deprecated public String[] getNamesForUids(int[]); + method @Deprecated @NonNull public String getServicesSystemSharedLibraryPackageName(); + method @Deprecated @NonNull public String getSharedSystemSharedLibraryPackageName(); } } diff --git a/test-mock/api/test-removed.txt b/test-mock/api/test-removed.txt index 14191ebcb080..d802177e249b 100644 --- a/test-mock/api/test-removed.txt +++ b/test-mock/api/test-removed.txt @@ -1,3 +1 @@ // Signature format: 2.0 -// - add-additional-overrides=no -// - migrating=Migration in progress see b/299366704 |