diff options
95 files changed, 1461 insertions, 466 deletions
diff --git a/api/current.txt b/api/current.txt index 73e7fab9546d..799ad0fd1851 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5258,7 +5258,7 @@ package android.app { } public static class NotificationManager.Policy implements android.os.Parcelable { - ctor public deprecated NotificationManager.Policy(int, int, int); + ctor public NotificationManager.Policy(int, int, int); ctor public NotificationManager.Policy(int, int, int, int); method public int describeContents(); method public static java.lang.String priorityCategoriesToString(int); @@ -10466,7 +10466,6 @@ package android.database { method public boolean hasNext(); method public java.util.Iterator<android.database.CursorJoiner.Result> iterator(); method public android.database.CursorJoiner.Result next(); - method public void remove(); } public static final class CursorJoiner.Result extends java.lang.Enum { @@ -19867,7 +19866,7 @@ package android.media { public static abstract class AudioManager.AudioRecordingCallback { ctor public AudioManager.AudioRecordingCallback(); - method public void onRecordConfigChanged(); + method public void onRecordConfigChanged(android.media.AudioRecordConfiguration[]); } public static abstract interface AudioManager.OnAudioFocusChangeListener { @@ -31715,6 +31714,7 @@ package android.provider { public static final class DocumentsContract.Root { field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes"; + field public static final java.lang.String COLUMN_CAPACITY_BYTES = "capacity_bytes"; field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id"; field public static final java.lang.String COLUMN_FLAGS = "flags"; field public static final java.lang.String COLUMN_ICON = "icon"; @@ -38478,7 +38478,6 @@ package android.text { method public boolean hasNext(); method public java.util.Iterator<java.lang.String> iterator(); method public java.lang.String next(); - method public void remove(); method public void setString(java.lang.String); } @@ -57714,9 +57713,10 @@ package java.util { } public abstract interface Iterator { + method public default void forEachRemaining(java.util.function.Consumer<? super E>); method public abstract boolean hasNext(); method public abstract E next(); - method public abstract void remove(); + method public default void remove(); } public class LinkedHashMap extends java.util.HashMap implements java.util.Map { @@ -58067,6 +58067,31 @@ package java.util { method public long orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable; } + public abstract interface PrimitiveIterator implements java.util.Iterator { + method public abstract void forEachRemaining(T_CONS); + } + + public static abstract interface PrimitiveIterator.OfDouble implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.DoubleConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>); + method public default java.lang.Double next(); + method public abstract double nextDouble(); + } + + public static abstract interface PrimitiveIterator.OfInt implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.IntConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>); + method public default java.lang.Integer next(); + method public abstract int nextInt(); + } + + public static abstract interface PrimitiveIterator.OfLong implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.LongConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>); + method public default java.lang.Long next(); + method public abstract long nextLong(); + } + public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable { ctor public PriorityQueue(); ctor public PriorityQueue(int); @@ -58238,7 +58263,6 @@ package java.util { method public short nextShort(); method public short nextShort(int); method public int radix(); - method public void remove(); method public java.util.Scanner reset(); method public java.util.Scanner skip(java.util.regex.Pattern); method public java.util.Scanner skip(java.lang.String); diff --git a/api/system-current.txt b/api/system-current.txt index e5ebe62904ae..9a84d1ade8ce 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5390,7 +5390,7 @@ package android.app { } public static class NotificationManager.Policy implements android.os.Parcelable { - ctor public deprecated NotificationManager.Policy(int, int, int); + ctor public NotificationManager.Policy(int, int, int); ctor public NotificationManager.Policy(int, int, int, int); method public int describeContents(); method public static java.lang.String priorityCategoriesToString(int); @@ -10860,7 +10860,6 @@ package android.database { method public boolean hasNext(); method public java.util.Iterator<android.database.CursorJoiner.Result> iterator(); method public android.database.CursorJoiner.Result next(); - method public void remove(); } public static final class CursorJoiner.Result extends java.lang.Enum { @@ -21356,7 +21355,7 @@ package android.media { public static abstract class AudioManager.AudioRecordingCallback { ctor public AudioManager.AudioRecordingCallback(); - method public void onRecordConfigChanged(); + method public void onRecordConfigChanged(android.media.AudioRecordConfiguration[]); } public static abstract interface AudioManager.OnAudioFocusChangeListener { @@ -34100,6 +34099,7 @@ package android.provider { public static final class DocumentsContract.Root { field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes"; + field public static final java.lang.String COLUMN_CAPACITY_BYTES = "capacity_bytes"; field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id"; field public static final java.lang.String COLUMN_FLAGS = "flags"; field public static final java.lang.String COLUMN_ICON = "icon"; @@ -41245,7 +41245,6 @@ package android.text { method public boolean hasNext(); method public java.util.Iterator<java.lang.String> iterator(); method public java.lang.String next(); - method public void remove(); method public void setString(java.lang.String); } @@ -60818,9 +60817,10 @@ package java.util { } public abstract interface Iterator { + method public default void forEachRemaining(java.util.function.Consumer<? super E>); method public abstract boolean hasNext(); method public abstract E next(); - method public abstract void remove(); + method public default void remove(); } public class LinkedHashMap extends java.util.HashMap implements java.util.Map { @@ -61171,6 +61171,31 @@ package java.util { method public long orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable; } + public abstract interface PrimitiveIterator implements java.util.Iterator { + method public abstract void forEachRemaining(T_CONS); + } + + public static abstract interface PrimitiveIterator.OfDouble implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.DoubleConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>); + method public default java.lang.Double next(); + method public abstract double nextDouble(); + } + + public static abstract interface PrimitiveIterator.OfInt implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.IntConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>); + method public default java.lang.Integer next(); + method public abstract int nextInt(); + } + + public static abstract interface PrimitiveIterator.OfLong implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.LongConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>); + method public default java.lang.Long next(); + method public abstract long nextLong(); + } + public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable { ctor public PriorityQueue(); ctor public PriorityQueue(int); @@ -61342,7 +61367,6 @@ package java.util { method public short nextShort(); method public short nextShort(int); method public int radix(); - method public void remove(); method public java.util.Scanner reset(); method public java.util.Scanner skip(java.util.regex.Pattern); method public java.util.Scanner skip(java.lang.String); diff --git a/api/test-current.txt b/api/test-current.txt index 3eae99ddaabd..f18f4e1cd1c2 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5258,7 +5258,7 @@ package android.app { } public static class NotificationManager.Policy implements android.os.Parcelable { - ctor public deprecated NotificationManager.Policy(int, int, int); + ctor public NotificationManager.Policy(int, int, int); ctor public NotificationManager.Policy(int, int, int, int); method public int describeContents(); method public static java.lang.String priorityCategoriesToString(int); @@ -10476,7 +10476,6 @@ package android.database { method public boolean hasNext(); method public java.util.Iterator<android.database.CursorJoiner.Result> iterator(); method public android.database.CursorJoiner.Result next(); - method public void remove(); } public static final class CursorJoiner.Result extends java.lang.Enum { @@ -19878,7 +19877,7 @@ package android.media { public static abstract class AudioManager.AudioRecordingCallback { ctor public AudioManager.AudioRecordingCallback(); - method public void onRecordConfigChanged(); + method public void onRecordConfigChanged(android.media.AudioRecordConfiguration[]); } public static abstract interface AudioManager.OnAudioFocusChangeListener { @@ -31730,6 +31729,7 @@ package android.provider { public static final class DocumentsContract.Root { field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes"; + field public static final java.lang.String COLUMN_CAPACITY_BYTES = "capacity_bytes"; field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id"; field public static final java.lang.String COLUMN_FLAGS = "flags"; field public static final java.lang.String COLUMN_ICON = "icon"; @@ -38497,7 +38497,6 @@ package android.text { method public boolean hasNext(); method public java.util.Iterator<java.lang.String> iterator(); method public java.lang.String next(); - method public void remove(); method public void setString(java.lang.String); } @@ -57733,9 +57732,10 @@ package java.util { } public abstract interface Iterator { + method public default void forEachRemaining(java.util.function.Consumer<? super E>); method public abstract boolean hasNext(); method public abstract E next(); - method public abstract void remove(); + method public default void remove(); } public class LinkedHashMap extends java.util.HashMap implements java.util.Map { @@ -58086,6 +58086,31 @@ package java.util { method public long orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable; } + public abstract interface PrimitiveIterator implements java.util.Iterator { + method public abstract void forEachRemaining(T_CONS); + } + + public static abstract interface PrimitiveIterator.OfDouble implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.DoubleConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>); + method public default java.lang.Double next(); + method public abstract double nextDouble(); + } + + public static abstract interface PrimitiveIterator.OfInt implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.IntConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>); + method public default java.lang.Integer next(); + method public abstract int nextInt(); + } + + public static abstract interface PrimitiveIterator.OfLong implements java.util.PrimitiveIterator { + method public default void forEachRemaining(java.util.function.LongConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>); + method public default java.lang.Long next(); + method public abstract long nextLong(); + } + public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable { ctor public PriorityQueue(); ctor public PriorityQueue(int); @@ -58257,7 +58282,6 @@ package java.util { method public short nextShort(); method public short nextShort(int); method public int radix(); - method public void remove(); method public java.util.Scanner reset(); method public java.util.Scanner skip(java.util.regex.Pattern); method public java.util.Scanner skip(java.lang.String); diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 057a4e943971..16aee786d80c 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -662,7 +662,7 @@ public class NotificationManager /** * Notification policy configuration. Represents user-preferences for notification - * filtering and prioritization. + * filtering. */ public static class Policy implements android.os.Parcelable { /** Reminder notifications are prioritized. */ @@ -707,13 +707,13 @@ public class NotificationManager */ public static final int SUPPRESSED_EFFECTS_UNSET = -1; /** - * Whether notification suppressed by DND should not interruption visually when the screen - * is off. + * Whether notifications suppressed by DND should not interrupt visually (e.g. with + * notification lights or by turning the screen on) when the screen is off. */ public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0; /** - * Whether notification suppressed by DND should not interruption visually when the screen - * is on. + * Whether notifications suppressed by DND should not interrupt visually when the screen + * is on (e.g. by peeking onto the screen). */ public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1; @@ -728,13 +728,27 @@ public class NotificationManager */ public final int suppressedVisualEffects; - - @Deprecated + /** + * Constructs a policy for Do Not Disturb priority mode behavior. + * + * @param priorityCategories bitmask of categories of notifications that can bypass DND. + * @param priorityCallSenders which callers can bypass DND. + * @param priorityMessageSenders which message senders can bypass DND. + */ public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) { this(priorityCategories, priorityCallSenders, priorityMessageSenders, SUPPRESSED_EFFECTS_UNSET); } + /** + * Constructs a policy for Do Not Disturb priority mode behavior. + * + * @param priorityCategories bitmask of categories of notifications that can bypass DND. + * @param priorityCallSenders which callers can bypass DND. + * @param priorityMessageSenders which message senders can bypass DND. + * @param suppressedVisualEffects which visual interruptions should be suppressed from + * notifications that are filtered by DND. + */ public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects) { this.priorityCategories = priorityCategories; @@ -865,7 +879,6 @@ public class NotificationManager return new Policy[size]; } }; - } /** diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index a1ad59085d8c..c4037f867f5a 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -344,6 +344,68 @@ public class DevicePolicyManager { = "android.app.action.PROVISION_FINALIZATION"; /** + * Action: Bugreport sharing with device owner has been accepted by the user. + * + * @hide + */ + public static final String ACTION_BUGREPORT_SHARING_ACCEPTED = + "com.android.server.action.BUGREPORT_SHARING_ACCEPTED"; + + /** + * Action: Bugreport sharing with device owner has been declined by the user. + * + * @hide + */ + public static final String ACTION_BUGREPORT_SHARING_DECLINED = + "com.android.server.action.BUGREPORT_SHARING_DECLINED"; + + /** + * Action: Bugreport has been collected and is dispatched to {@link DevicePolicyManagerService}. + * + * @hide + */ + public static final String ACTION_REMOTE_BUGREPORT_DISPATCH = + "android.intent.action.REMOTE_BUGREPORT_DISPATCH"; + + /** + * Extra for shared bugreport's SHA-256 hash. + * + * @hide + */ + public static final String EXTRA_REMOTE_BUGREPORT_HASH = + "android.intent.extra.REMOTE_BUGREPORT_HASH"; + + /** + * Extra for remote bugreport notification shown type. + * + * @hide + */ + public static final String EXTRA_BUGREPORT_NOTIFICATION_TYPE = + "android.app.extra.bugreport_notification_type"; + + /** + * Notification type for a started remote bugreport flow. + * + * @hide + */ + public static final int NOTIFICATION_BUGREPORT_STARTED = 1; + + /** + * Notification type for a bugreport that has already been accepted to be shared, but is still + * being taken. + * + * @hide + */ + public static final int NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED = 2; + + /** + * Notification type for a bugreport that has been taken and can be shared or declined. + * + * @hide + */ + public static final int NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED = 3; + + /** * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that * allows a mobile device management application or NFC programmer application which starts * managed provisioning to pass data to the management application instance after provisioning. diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java index 0a0d77d2a465..8cdfee5572a8 100644 --- a/core/java/android/app/admin/DevicePolicyManagerInternal.java +++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java @@ -69,4 +69,13 @@ public abstract class DevicePolicyManagerInternal { * @return true if the uid is an active admin with the given policy. */ public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy); + + /** + * Checks if a given package has a device or a profile owner for the given user + * + * @param packageName The package to check + * @param userId the userId to check for. + * @return true if package has a device or profile owner, false otherwise. + */ + public abstract boolean hasDeviceOwnerOrProfileOwner(String packageName, int userId); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 0588a9d6224e..bc28ff177a7e 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -121,6 +121,10 @@ public class PackageParser { private static final int MAX_PACKAGES_PER_APK = 5; + public static final int APK_SIGNING_UNKNOWN = 0; + public static final int APK_SIGNING_V1 = 1; + public static final int APK_SIGNING_V2 = 2; + // TODO: switch outError users to PackageParserException // TODO: refactor "codePath" to "apkPath" @@ -1058,12 +1062,24 @@ public class PackageParser { return pkg; } + public static int getApkSigningVersion(Package pkg) { + try { + if (ApkSignatureSchemeV2Verifier.hasSignature(pkg.baseCodePath)) { + return APK_SIGNING_V2; + } + return APK_SIGNING_V1; + } catch (IOException e) { + } + return APK_SIGNING_UNKNOWN; + } + /** * Collect certificates from all the APKs described in the given package, * populating {@link Package#mSignatures}. Also asserts that all APK * contents are signed correctly and consistently. */ - public static void collectCertificates(Package pkg, int parseFlags) throws PackageParserException { + public static void collectCertificates(Package pkg, int parseFlags) + throws PackageParserException { collectCertificatesInternal(pkg, parseFlags); final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; for (int i = 0; i < childCount; i++) { @@ -1074,7 +1090,8 @@ public class PackageParser { } } - private static void collectCertificatesInternal(Package pkg, int parseFlags) throws PackageParserException { + private static void collectCertificatesInternal(Package pkg, int parseFlags) + throws PackageParserException { pkg.mCertificates = null; pkg.mSignatures = null; pkg.mSigningKeys = null; diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java index 57a080b9346b..9478dc002d6c 100644 --- a/core/java/android/hardware/camera2/DngCreator.java +++ b/core/java/android/hardware/camera2/DngCreator.java @@ -137,6 +137,11 @@ public final class DngCreator implements AutoCloseable { throw new IllegalArgumentException("Orientation " + orientation + " is not a valid EXIF orientation value"); } + // ExifInterface and TIFF/EP spec differ on definition of + // "Unknown" orientation; other values map directly + if (orientation == ExifInterface.ORIENTATION_UNDEFINED) { + orientation = TAG_ORIENTATION_UNKNOWN; + } nativeSetOrientation(orientation); return this; } @@ -443,7 +448,7 @@ public final class DngCreator implements AutoCloseable { private static final String GPS_LONG_REF_WEST = "W"; private static final String GPS_DATE_FORMAT_STR = "yyyy:MM:dd"; - private static final String TIFF_DATETIME_FORMAT = "yyyy:MM:dd kk:mm:ss"; + private static final String TIFF_DATETIME_FORMAT = "yyyy:MM:dd HH:mm:ss"; private static final DateFormat sExifGPSDateStamp = new SimpleDateFormat(GPS_DATE_FORMAT_STR); private static final DateFormat sDateTimeStampFormat = new SimpleDateFormat(TIFF_DATETIME_FORMAT); @@ -458,6 +463,9 @@ public final class DngCreator implements AutoCloseable { private static final int DEFAULT_PIXEL_STRIDE = 2; // bytes per sample private static final int BYTES_PER_RGB_PIX = 3; // byts per pixel + // TIFF tag values needed to map between public API and TIFF spec + private static final int TAG_ORIENTATION_UNKNOWN = 9; + /** * Offset, rowStride, and pixelStride are given in bytes. Height and width are given in pixels. */ diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index e62df3c8c495..4c4adea838ef 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -614,14 +614,16 @@ public class LegacyCameraDevice implements AutoCloseable { return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface)); } - static void configureSurface(Surface surface, int width, int height, - int pixelFormat) throws BufferQueueAbandonedException { + static void connectSurface(Surface surface) throws BufferQueueAbandonedException { checkNotNull(surface); - checkArgumentPositive(width, "width must be positive."); - checkArgumentPositive(height, "height must be positive."); - LegacyExceptionUtils.throwOnError(nativeConfigureSurface(surface, width, height, - pixelFormat)); + LegacyExceptionUtils.throwOnError(nativeConnectSurface(surface)); + } + + static void disconnectSurface(Surface surface) throws BufferQueueAbandonedException { + if (surface == null) return; + + LegacyExceptionUtils.throwOnError(nativeDisconnectSurface(surface)); } static void produceFrame(Surface surface, byte[] pixelBuffer, int width, @@ -716,8 +718,7 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeDetectSurfaceDimens(Surface surface, /*out*/int[/*2*/] dimens); - private static native int nativeConfigureSurface(Surface surface, int width, int height, - int pixelFormat); + private static native int nativeConnectSurface(Surface surface); private static native int nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width, int height, int pixelFormat); @@ -740,5 +741,7 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeSetScalingMode(Surface surface, int scalingMode); + private static native int nativeDisconnectSurface(Surface surface); + static native int nativeGetJpegFooterSize(); } diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index 1ca7ddfc6563..e8ce3ec7aaa9 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -365,6 +365,14 @@ public class RequestThreadManager { mGLThreadManager.waitUntilIdle(); } resetJpegSurfaceFormats(mCallbackOutputs); + + for (Surface s : mCallbackOutputs) { + try { + LegacyCameraDevice.disconnectSurface(s); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); + } + } mPreviewOutputs.clear(); mCallbackOutputs.clear(); mJpegSurfaceIds.clear(); @@ -392,6 +400,10 @@ public class RequestThreadManager { mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s)); mCallbackOutputs.add(s); callbackOutputSizes.add(outSize); + + // LegacyCameraDevice is the producer of JPEG output surfaces + // so LegacyCameraDevice needs to connect to the surfaces. + LegacyCameraDevice.connectSurface(s); break; default: LegacyCameraDevice.setScalingMode(s, LegacyCameraDevice. diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index bc80fc114772..70bc2fd19648 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -401,6 +401,13 @@ public class SurfaceTextureRenderer { private void clearState() { mSurfaces.clear(); + for (EGLSurfaceHolder holder : mConversionSurfaces) { + try { + LegacyCameraDevice.disconnectSurface(holder.surface); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); + } + } mConversionSurfaces.clear(); mPBufferPixels = null; if (mSurfaceTexture != null) { @@ -631,6 +638,9 @@ public class SurfaceTextureRenderer { holder.height = surfaceSize.getHeight(); if (LegacyCameraDevice.needsConversion(s)) { mConversionSurfaces.add(holder); + // LegacyCameraDevice is the producer of surfaces if it's not handled by EGL, + // so LegacyCameraDevice needs to connect to the surfaces. + LegacyCameraDevice.connectSurface(s); } else { mSurfaces.add(holder); } diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 03a1ca60ecf2..0065cd961eb2 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -478,7 +478,6 @@ public final class DocumentsContract { /** * Capacity of a root in bytes. This column is optional, and may be * {@code null} if unknown or unbounded. - * {@hide} * <p> * Type: INTEGER (long) */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f13f2428cf8c..a40cf963751e 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1241,6 +1241,19 @@ public final class Settings { public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS"; + /** + * Activity Action: Show a dialog for remote bugreport flow. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_SHOW_REMOTE_BUGREPORT_DIALOG + = "android.settings.SHOW_REMOTE_BUGREPORT_DIALOG"; + // End of Intent actions for Settings /** diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java index 728f72309439..60c727037379 100644 --- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java +++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java @@ -75,6 +75,36 @@ public class ApkSignatureSchemeV2Verifier { public static final int SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID = 2; /** + * Returns {@code true} if the provided APK contains an APK Signature Scheme V2 + * signature. The signature will not be verified. + */ + public static boolean hasSignature(String apkFile) throws IOException { + try (RandomAccessFile apk = new RandomAccessFile(apkFile, "r")) { + long fileSize = apk.length(); + if (fileSize > Integer.MAX_VALUE) { + return false; + } + MappedByteBuffer apkContents = + apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize); + // ZipUtils and APK Signature Scheme v2 verifier expect little-endian byte order. + apkContents.order(ByteOrder.LITTLE_ENDIAN); + + final int centralDirOffset = + (int) getCentralDirOffset(apkContents, getEocdOffset(apkContents)); + // Find the APK Signing Block. + int apkSigningBlockOffset = findApkSigningBlock(apkContents, centralDirOffset); + ByteBuffer apkSigningBlock = + sliceFromTo(apkContents, apkSigningBlockOffset, centralDirOffset); + + // Find the APK Signature Scheme v2 Block inside the APK Signing Block. + findApkSignatureSchemeV2Block(apkSigningBlock); + return true; + } catch (SignatureNotFoundException e) { + } + return false; + } + + /** * Verifies APK Signature Scheme v2 signatures of the provided APK and returns the certificates * associated with each signer. * @@ -130,31 +160,8 @@ public class ApkSignatureSchemeV2Verifier { // ZipUtils and APK Signature Scheme v2 verifier expect little-endian byte order. apkContents.order(ByteOrder.LITTLE_ENDIAN); - // Find the offset of ZIP End of Central Directory (EoCD) - int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(apkContents); - if (eocdOffset == -1) { - throw new SignatureNotFoundException( - "Not an APK file: ZIP End of Central Directory record not found"); - } - if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apkContents, eocdOffset)) { - throw new SignatureNotFoundException("ZIP64 APK not supported"); - } - ByteBuffer eocd = sliceFromTo(apkContents, eocdOffset, apkContents.capacity()); - - // Look up the offset of ZIP Central Directory. - long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(eocd); - if (centralDirOffsetLong >= eocdOffset) { - throw new SignatureNotFoundException( - "ZIP Central Directory offset out of range: " + centralDirOffsetLong - + ". ZIP End of Central Directory offset: " + eocdOffset); - } - long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocd); - if (centralDirOffsetLong + centralDirSizeLong != eocdOffset) { - throw new SignatureNotFoundException( - "ZIP Central Directory is not immediately followed by End of Central" - + " Directory"); - } - int centralDirOffset = (int) centralDirOffsetLong; + final int eocdOffset = getEocdOffset(apkContents); + final int centralDirOffset = (int) getCentralDirOffset(apkContents, eocdOffset); // Find the APK Signing Block. int apkSigningBlockOffset = findApkSigningBlock(apkContents, centralDirOffset); @@ -499,6 +506,43 @@ public class ApkSignatureSchemeV2Verifier { return result; } + /** + * Finds the offset of ZIP End of Central Directory (EoCD). + * + * @throws SignatureNotFoundException If the EoCD could not be found + */ + private static int getEocdOffset(ByteBuffer apkContents) throws SignatureNotFoundException { + int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(apkContents); + if (eocdOffset == -1) { + throw new SignatureNotFoundException( + "Not an APK file: ZIP End of Central Directory record not found"); + } + return eocdOffset; + } + + private static long getCentralDirOffset(ByteBuffer apkContents, int eocdOffset) + throws SignatureNotFoundException { + if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apkContents, eocdOffset)) { + throw new SignatureNotFoundException("ZIP64 APK not supported"); + } + ByteBuffer eocd = sliceFromTo(apkContents, eocdOffset, apkContents.capacity()); + + // Look up the offset of ZIP Central Directory. + long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(eocd); + if (centralDirOffsetLong >= eocdOffset) { + throw new SignatureNotFoundException( + "ZIP Central Directory offset out of range: " + centralDirOffsetLong + + ". ZIP End of Central Directory offset: " + eocdOffset); + } + long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocd); + if (centralDirOffsetLong + centralDirSizeLong != eocdOffset) { + throw new SignatureNotFoundException( + "ZIP Central Directory is not immediately followed by End of Central" + + " Directory"); + } + return centralDirOffsetLong; + } + private static final int getChunkCount(int inputSizeBytes) { return (inputSizeBytes + CHUNK_SIZE_BYTES - 1) / CHUNK_SIZE_BYTES; } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 9543acfba51b..804830101ffb 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -167,7 +167,7 @@ interface IWindowManager in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded); void setAppVisibility(IBinder token, boolean visible); - void notifyAppStopped(IBinder token); + void notifyAppStopped(IBinder token, boolean stopped); void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); void removeAppToken(IBinder token); diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 2099b040fd0b..72a50ec1af90 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -17,21 +17,15 @@ package android.widget; import android.animation.ObjectAnimator; +import android.annotation.InterpolatorRes; import android.annotation.NonNull; import android.annotation.Nullable; -import android.graphics.PorterDuff; - -import android.util.FloatProperty; -import android.util.IntProperty; -import android.view.accessibility.AccessibilityNodeInfo; -import com.android.internal.R; - -import android.annotation.InterpolatorRes; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.drawable.Animatable; @@ -46,6 +40,7 @@ import android.graphics.drawable.shapes.Shape; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; +import android.util.FloatProperty; import android.util.MathUtils; import android.util.Pools.SynchronizedPool; import android.view.Gravity; @@ -55,6 +50,7 @@ import android.view.ViewDebug; import android.view.ViewHierarchyEncoder; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationUtils; @@ -63,6 +59,7 @@ import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.RemoteViews.RemoteView; +import com.android.internal.R; import java.util.ArrayList; @@ -606,15 +603,30 @@ public class ProgressBar extends View { if (indeterminate) { // swap between indeterminate and regular backgrounds - mCurrentDrawable = mIndeterminateDrawable; + swapCurrentDrawable(mIndeterminateDrawable); startAnimation(); } else { - mCurrentDrawable = mProgressDrawable; + swapCurrentDrawable(mProgressDrawable); stopAnimation(); } } } + private void swapCurrentDrawable(Drawable newDrawable) { + final Drawable oldDrawable = mCurrentDrawable; + mCurrentDrawable = newDrawable; + if (oldDrawable != mCurrentDrawable) { + if (oldDrawable != null) { + oldDrawable.setVisible(false, false); + } + if (mCurrentDrawable != null) { + mCurrentDrawable.setVisible( + getVisibility() == VISIBLE && getWindowVisibility() == VISIBLE, + false); + } + } + } + /** * <p>Get the drawable used to draw the progress bar in * indeterminate mode.</p> @@ -654,7 +666,7 @@ public class ProgressBar extends View { } if (mIndeterminate) { - mCurrentDrawable = d; + swapCurrentDrawable(d); postInvalidate(); } } @@ -820,7 +832,7 @@ public class ProgressBar extends View { } if (!mIndeterminate) { - mCurrentDrawable = d; + swapCurrentDrawable(d); postInvalidate(); } @@ -1555,7 +1567,7 @@ public class ProgressBar extends View { * <p>Start the indeterminate progress animation.</p> */ void startAnimation() { - if (getVisibility() != VISIBLE) { + if (getVisibility() != VISIBLE || getWindowVisibility() != VISIBLE) { return; } @@ -1653,14 +1665,30 @@ public class ProgressBar extends View { protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); + updateVisibility(); + } + + @Override + protected void onWindowVisibilityChanged(@Visibility int visibility) { + super.onWindowVisibilityChanged(visibility); + + updateVisibility(); + } + + private void updateVisibility() { + final boolean isVisible = getVisibility() == VISIBLE && getWindowVisibility() == VISIBLE; if (mIndeterminate) { // let's be nice with the UI thread - if (visibility == GONE || visibility == INVISIBLE) { - stopAnimation(); - } else { + if (isVisible) { startAnimation(); + } else { + stopAnimation(); } } + + if (mCurrentDrawable != null) { + mCurrentDrawable.setVisible(isVisible, false); + } } @Override diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 816a2c49a2d9..623b603d8280 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -7,7 +7,7 @@ LOCAL_CFLAGS += -U__APPLE__ LOCAL_CFLAGS += -Wno-unused-parameter LOCAL_CFLAGS += -Wno-non-virtual-dtor LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses -#LOCAL_CFLAGS += -DHWUI_NEW_OPS +LOCAL_CFLAGS += -DHWUI_NEW_OPS LOCAL_CPPFLAGS += -Wno-conversion-null ifeq ($(TARGET_ARCH), arm) diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index cb0abb6bfaa8..c6baf1c645bf 100644 --- a/core/jni/android_hardware_camera2_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -80,6 +80,13 @@ using namespace img_utils; return nullptr; \ } +#define BAIL_IF_EXPR_RET_NULL_SP(expr, jnienv, tagId, writer) \ + if (expr) { \ + jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ + "Invalid metadata for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \ + return nullptr; \ + } + #define ANDROID_DNGCREATOR_CTX_JNI_ID "mNativeContext" @@ -195,8 +202,8 @@ private: NativeContext::NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result) : mCharacteristics(std::make_shared<CameraMetadata>(characteristics)), mResult(std::make_shared<CameraMetadata>(result)), mThumbnailWidth(0), - mThumbnailHeight(0), mOrientation(0), mThumbnailSet(false), mGpsSet(false), - mDescriptionSet(false), mCaptureTimeSet(false) {} + mThumbnailHeight(0), mOrientation(TAG_ORIENTATION_UNKNOWN), mThumbnailSet(false), + mGpsSet(false), mDescriptionSet(false), mCaptureTimeSet(false) {} NativeContext::~NativeContext() {} @@ -1096,7 +1103,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // Set orientation - uint16_t orientation = 1; // Normal + uint16_t orientation = TAG_ORIENTATION_NORMAL; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0), env, TAG_ORIENTATION, writer); } @@ -1138,12 +1145,27 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } { - // Set blacklevel tags + // Set blacklevel tags, using dynamic black level if available camera_metadata_entry entry = - characteristics.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN); - BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_BLACKLEVEL, writer); - const uint32_t* blackLevel = reinterpret_cast<const uint32_t*>(entry.data.i32); - BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, entry.count, blackLevel, + results.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL); + uint32_t blackLevelRational[8] = {0}; + if (entry.count != 0) { + BAIL_IF_EXPR_RET_NULL_SP(entry.count != 4, env, TAG_BLACKLEVEL, writer); + for (size_t i = 0; i < entry.count; i++) { + blackLevelRational[i * 2] = static_cast<uint32_t>(entry.data.f[i] * 100); + blackLevelRational[i * 2 + 1] = 100; + } + } else { + // Fall back to static black level which is guaranteed + entry = characteristics.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN); + BAIL_IF_EXPR_RET_NULL_SP(entry.count != 4, env, TAG_BLACKLEVEL, writer); + for (size_t i = 0; i < entry.count; i++) { + blackLevelRational[i * 2] = static_cast<uint32_t>(entry.data.i32[i]); + blackLevelRational[i * 2 + 1] = 1; + } + + } + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, 4, blackLevelRational, TIFF_IFD_0), env, TAG_BLACKLEVEL, writer); uint16_t repeatDim[2] = {2, 2}; @@ -1913,8 +1935,10 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // Set bits per sample - uint16_t bits = BITS_PER_RGB_SAMPLE; - BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BITSPERSAMPLE, 1, &bits, TIFF_IFD_0), + uint16_t bits[SAMPLES_PER_RGB_PIXEL]; + for (int i = 0; i < SAMPLES_PER_RGB_PIXEL; i++) bits[i] = BITS_PER_RGB_SAMPLE; + BAIL_IF_INVALID_RET_NULL_SP( + writer->addEntry(TAG_BITSPERSAMPLE, SAMPLES_PER_RGB_PIXEL, bits, TIFF_IFD_0), env, TAG_BITSPERSAMPLE, writer); } diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index f1ea7ec7e8a2..80f9d5750d8a 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -29,6 +29,7 @@ #include <gui/Surface.h> #include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> #include <ui/GraphicBuffer.h> #include <system/window.h> #include <hardware/camera3.h> @@ -93,27 +94,17 @@ static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_yc cStep, yStride, cStride); } -static status_t configureSurface(const sp<ANativeWindow>& anw, - int32_t width, - int32_t height, - int32_t pixelFmt, - int32_t maxBufferSlack) { +static status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) { status_t err = NO_ERROR; - err = native_window_set_buffers_dimensions(anw.get(), width, height); - if (err != NO_ERROR) { - ALOGE("%s: Failed to set native window buffer dimensions, error %s (%d).", __FUNCTION__, - strerror(-err), err); - return err; - } - err = native_window_set_buffers_format(anw.get(), pixelFmt); - if (err != NO_ERROR) { - ALOGE("%s: Failed to set native window buffer format, error %s (%d).", __FUNCTION__, + err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL); + if (err != OK) { + ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } - err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); + err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__, strerror(-err), err); @@ -121,19 +112,17 @@ static status_t configureSurface(const sp<ANativeWindow>& anw, } int minUndequeuedBuffers; - err = anw.get()->query(anw.get(), - NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, - &minUndequeuedBuffers); + err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(), + NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); if (err != NO_ERROR) { ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).", __FUNCTION__, strerror(-err), err); return err; } - ALOGV("%s: Setting buffer count to %d, size to (%dx%d), fmt (0x%x)", __FUNCTION__, - maxBufferSlack + 1 + minUndequeuedBuffers, - width, height, pixelFmt); - err = native_window_set_buffer_count(anw.get(), maxBufferSlack + 1 + minUndequeuedBuffers); + ALOGV("%s: Setting buffer count to %d", __FUNCTION__, + maxBufferSlack + 1 + minUndequeuedBuffers); + err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers); if (err != NO_ERROR) { ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__, strerror(-err), err); @@ -509,6 +498,26 @@ static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobjec return usage; } +static jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz, + jobject surface) { + ALOGV("nativeDisconnectSurface"); + if (surface == nullptr) return NO_ERROR; + + sp<ANativeWindow> anw; + if ((anw = getNativeWindow(env, surface)) == NULL) { + ALOGV("Buffer queue has already been abandoned."); + return NO_ERROR; + } + + status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA); + if(err != NO_ERROR) { + jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", + "Error while disconnecting surface"); + return err; + } + return NO_ERROR; +} + static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, jobject surfaceTexture, jintArray dimens) { ALOGV("nativeDetectTextureDimens"); @@ -540,15 +549,14 @@ static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject th return NO_ERROR; } -static jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, - jint width, jint height, jint pixelFormat) { - ALOGV("nativeConfigureSurface"); - sp<ANativeWindow> anw; - if ((anw = getNativeWindow(env, surface)) == NULL) { - ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); +static jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) { + ALOGV("nativeConnectSurface"); + sp<Surface> s; + if ((s = getSurface(env, surface)) == NULL) { + ALOGE("%s: Could not retrieve surface.", __FUNCTION__); return BAD_VALUE; } - status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); + status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK); if (err != NO_ERROR) { ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); return err; @@ -740,9 +748,9 @@ static const JNINativeMethod gCameraDeviceMethods[] = { { "nativeDetectSurfaceDimens", "(Landroid/view/Surface;[I)I", (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, - { "nativeConfigureSurface", - "(Landroid/view/Surface;III)I", - (void *)LegacyCameraDevice_nativeConfigureSurface }, + { "nativeConnectSurface", + "(Landroid/view/Surface;)I", + (void *)LegacyCameraDevice_nativeConnectSurface }, { "nativeProduceFrame", "(Landroid/view/Surface;[BIII)I", (void *)LegacyCameraDevice_nativeProduceFrame }, @@ -773,6 +781,9 @@ static const JNINativeMethod gCameraDeviceMethods[] = { { "nativeSetScalingMode", "(Landroid/view/Surface;I)I", (void *)LegacyCameraDevice_nativeSetScalingMode }, + { "nativeDisconnectSurface", + "(Landroid/view/Surface;)I", + (void *)LegacyCameraDevice_nativeDisconnectSurface }, }; // Get all the required offsets in java class and register native functions diff --git a/core/res/res/layout/text_edit_suggestion_container_material.xml b/core/res/res/layout/text_edit_suggestion_container_material.xml index 15b18dd057e8..d1c65c05b7f1 100644 --- a/core/res/res/layout/text_edit_suggestion_container_material.xml +++ b/core/res/res/layout/text_edit_suggestion_container_material.xml @@ -33,7 +33,7 @@ android:id="@+id/suggestionContainer" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="8dp" + android:paddingTop="4dp" android:paddingBottom="0dp" android:divider="@null" /> <LinearLayout diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9a2a6eb8ab42..7857107106ce 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2440,6 +2440,10 @@ flag). --> <bool name="config_forceWindowDrawsStatusBarBackground">true</bool> + <!-- If set, this will force the navigation bar to always be drawn with an opaque + background. --> + <bool name="config_forceNavBarAlwaysOpaque">false</bool> + <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. --> <string translatable="false" name="config_defaultPictureInPictureBounds">"0 0 100 100"</string> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 7b113023d194..d8efd63047a4 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2917,20 +2917,18 @@ <!-- Message of notification shown when ADB is actively connected to the phone. --> <string name="adb_active_notification_message">Touch to disable USB debugging.</string> + <!-- Title of notification shown to indicate that bug report is being collected. --> + <string name="taking_remote_bugreport_notification_title">Taking bug report\u2026</string> <!-- Title of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. --> <string name="share_remote_bugreport_notification_title">Share bug report?</string> <!-- Title of notification shown to indicate that bug report is still being collected after sharing was accepted. --> <string name="sharing_remote_bugreport_notification_title">Sharing bug report\u2026</string> - <!-- Message of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. --> - <string name="share_remote_bugreport_notification_message">Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared and your device may temporarily slow down.</string> - <!-- Message of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. --> - <string name="share_finished_remote_bugreport_notification_message">Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.</string> - <!-- Message of notification shown to shown to indicate that bug report is still being collected after sharing was accepted. --> - <string name="sharing_remote_bugreport_notification_message">This may temporarily slow down your device</string> + <!-- Message of a notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. --> + <string name="share_remote_bugreport_notification_message_finished">Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.</string> <!-- Acceptance label of notification shown to ask for user consent for sharing the remote bugreport. --> - <string name="share_remote_bugreport_notification_accept">ACCEPT</string> + <string name="share_remote_bugreport_action">SHARE</string> <!-- Decline label of notification shown to ask for user consent for sharing the remote bugreport. --> - <string name="share_remote_bugreport_notification_decline">DECLINE</string> + <string name="decline_remote_bugreport_action">DECLINE</string> <!-- Used to replace %s in urls retreived from the signin server with locales. For Some --> <!-- devices we don't support all the locales we ship to and need to replace the '%s' with a --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 11f42ecf2463..15521e48d319 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1771,13 +1771,12 @@ <java-symbol type="string" name="accessibility_binding_label" /> <java-symbol type="string" name="adb_active_notification_message" /> <java-symbol type="string" name="adb_active_notification_title" /> + <java-symbol type="string" name="taking_remote_bugreport_notification_title" /> <java-symbol type="string" name="share_remote_bugreport_notification_title" /> - <java-symbol type="string" name="share_remote_bugreport_notification_message" /> - <java-symbol type="string" name="share_finished_remote_bugreport_notification_message" /> <java-symbol type="string" name="sharing_remote_bugreport_notification_title" /> - <java-symbol type="string" name="sharing_remote_bugreport_notification_message" /> - <java-symbol type="string" name="share_remote_bugreport_notification_accept" /> - <java-symbol type="string" name="share_remote_bugreport_notification_decline" /> + <java-symbol type="string" name="share_remote_bugreport_notification_message_finished" /> + <java-symbol type="string" name="share_remote_bugreport_action" /> + <java-symbol type="string" name="decline_remote_bugreport_action" /> <java-symbol type="string" name="aerr_application" /> <java-symbol type="string" name="aerr_process" /> <java-symbol type="string" name="aerr_application_repeated" /> @@ -2392,6 +2391,7 @@ <java-symbol type="string" name="config_packagedKeyboardName" /> <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" /> + <java-symbol type="bool" name="config_forceNavBarAlwaysOpaque" /> <java-symbol type="color" name="system_bar_background_semi_transparent" /> <!-- EditText suggestion popup. --> diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 54b453d044b4..70995acbb4ca 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -2,7 +2,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk -HWUI_NEW_OPS := false +HWUI_NEW_OPS := true # Enables fine-grained GLES error checking # If set to true, every GLES call is wrapped & error checked diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp index 501cbe50ee05..afe980712d81 100644 --- a/libs/hwui/ClipArea.cpp +++ b/libs/hwui/ClipArea.cpp @@ -375,15 +375,13 @@ const ClipBase* ClipArea::serializeClip(LinearAllocator& allocator) { serialization->rect.set(mClipRegion.getBounds()); break; } + // TODO: this is only done for draw time, should eventually avoid for record time + serialization->rect.snapToPixelBoundaries(); mLastSerialization = serialization; } return mLastSerialization; } -inline static const Rect& getRect(const ClipBase* scb) { - return reinterpret_cast<const ClipRect*>(scb)->rect; -} - inline static const RectangleList& getRectList(const ClipBase* scb) { return reinterpret_cast<const ClipRectList*>(scb)->rectList; } @@ -425,9 +423,10 @@ const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator, && recordedClip->mode == ClipMode::Rectangle && recordedClipTransform.rectToRect())) { // common case - result is a single rectangle - auto rectClip = allocator.create<ClipRect>(getRect(recordedClip)); + auto rectClip = allocator.create<ClipRect>(recordedClip->rect); recordedClipTransform.mapRect(rectClip->rect); rectClip->rect.doIntersect(mClipRect); + rectClip->rect.snapToPixelBoundaries(); mLastResolutionResult = rectClip; } else if (CC_UNLIKELY(mMode == ClipMode::Region || recordedClip->mode == ClipMode::Region @@ -438,11 +437,11 @@ const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator, case ClipMode::Rectangle: if (CC_LIKELY(recordedClipTransform.rectToRect())) { // simple transform, skip creating SkPath - Rect resultClip(getRect(recordedClip)); + Rect resultClip(recordedClip->rect); recordedClipTransform.mapRect(resultClip); other.setRect(resultClip.toSkIRect()); } else { - SkPath transformedRect = pathFromTransformedRectangle(getRect(recordedClip), + SkPath transformedRect = pathFromTransformedRectangle(recordedClip->rect, recordedClipTransform); other.setPath(transformedRect, createViewportRegion()); } @@ -474,6 +473,7 @@ const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator, regionClip->region.op(mClipRegion, other, SkRegion::kIntersect_Op); break; } + // Don't need to snap, since region's in int bounds regionClip->rect.set(regionClip->region.getBounds()); mLastResolutionResult = regionClip; } else { @@ -484,7 +484,7 @@ const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator, } if (recordedClip->mode == ClipMode::Rectangle) { - rectList.intersectWith(getRect(recordedClip), recordedClipTransform); + rectList.intersectWith(recordedClip->rect, recordedClipTransform); } else { const RectangleList& other = getRectList(recordedClip); for (int i = 0; i < other.getTransformedRectanglesCount(); i++) { @@ -495,6 +495,7 @@ const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator, } } rectListClip->rect = rectList.calculateBounds(); + rectListClip->rect.snapToPixelBoundaries(); mLastResolutionResult = rectListClip; } } @@ -505,7 +506,7 @@ void ClipArea::applyClip(const ClipBase* clip, const Matrix4& transform) { if (!clip) return; // nothing to do if (CC_LIKELY(clip->mode == ClipMode::Rectangle)) { - clipRectWithTransform(getRect(clip), &transform, SkRegion::kIntersect_Op); + clipRectWithTransform(clip->rect, &transform, SkRegion::kIntersect_Op); } else if (CC_LIKELY(clip->mode == ClipMode::RectangleList)) { auto&& rectList = getRectList(clip); for (int i = 0; i < rectList.getTransformedRectanglesCount(); i++) { diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp index dc2ea0784b7e..822d04f61eb5 100644 --- a/libs/hwui/tests/unit/ClipAreaTests.cpp +++ b/libs/hwui/tests/unit/ClipAreaTests.cpp @@ -27,7 +27,7 @@ namespace android { namespace uirenderer { -static Rect kViewportBounds(0, 0, 2048, 2048); +static Rect kViewportBounds(2048, 2048); static ClipArea createClipArea() { ClipArea area; @@ -140,17 +140,15 @@ TEST(ClipArea, serializeClip) { // rect list Matrix4 rotate; - rotate.loadRotate(2.0f); - area.clipRectWithTransform(Rect(200, 200), &rotate, SkRegion::kIntersect_Op); + rotate.loadRotate(5.0f); + area.clipRectWithTransform(Rect(50, 50, 150, 150), &rotate, SkRegion::kIntersect_Op); { auto serializedClip = area.serializeClip(allocator); ASSERT_NE(nullptr, serializedClip); ASSERT_EQ(ClipMode::RectangleList, serializedClip->mode); auto clipRectList = reinterpret_cast<const ClipRectList*>(serializedClip); EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount()); - EXPECT_FALSE(clipRectList->rect.isEmpty()); - EXPECT_FLOAT_EQ(199.87817f, clipRectList->rect.right) - << "Right side should be clipped by rotated rect"; + EXPECT_EQ(Rect(37, 54, 145, 163), clipRectList->rect); EXPECT_EQ(serializedClip, area.serializeClip(allocator)) << "Requery of clip on unmodified ClipArea must return same pointer."; } @@ -241,5 +239,28 @@ TEST(ClipArea, serializeIntersectedClip) { } } +TEST(ClipArea, serializeIntersectedClip_snap) { + ClipArea area(createClipArea()); + area.setClip(100.2, 100.4, 500.6, 500.8); + LinearAllocator allocator; + + { + // no recorded clip case + auto resolvedClip = area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity()); + EXPECT_EQ(Rect(100, 100, 501, 501), resolvedClip->rect); + } + { + // recorded clip case + ClipRect recordedClip(Rect(100.12, 100.74)); + Matrix4 translateScale; + translateScale.loadTranslate(100, 100, 0); + translateScale.scale(2, 3, 1); // recorded clip will have non-int coords, even after transform + auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale); + ASSERT_NE(nullptr, resolvedClip); + EXPECT_EQ(ClipMode::Rectangle, resolvedClip->mode); + EXPECT_EQ(Rect(100, 100, 300, 402), resolvedClip->rect); + } +} + } // namespace uirenderer } // namespace android diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp index c39047ca1d89..d35b1f94583d 100644 --- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp +++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp @@ -442,9 +442,7 @@ TEST(RecordingCanvas, saveLayer_rotateClipped) { // since the same clip will be computed at draw time. If such a change is made, this // check could be done at record time by querying the clip, or the clip could be altered // slightly so that it is serialized. - EXPECT_RECT_APPROX_EQ(Rect(58.57864, 58.57864, 341.42136, 341.42136), - (reinterpret_cast<const ClipRect*>(op.localClip))->rect); - + EXPECT_EQ(Rect(59, 59, 341, 341), op.localClip->rect); EXPECT_EQ(Rect(400, 400), op.unmappedBounds); expectedMatrix.loadIdentity(); EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index c7e96cf664bb..8206d237ac42 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -2147,9 +2147,10 @@ public class AudioManager { } break; case MSSG_RECORDING_CONFIG_CHANGE: - final AudioRecordingCallback cb = (AudioRecordingCallback) msg.obj; - if (cb != null) { - cb.onRecordConfigChanged(); + final RecordConfigChangeCallbackData cbData = + (RecordConfigChangeCallbackData) msg.obj; + if (cbData.mCb != null) { + cbData.mCb.onRecordConfigChanged(cbData.mConfigs); } break; default: @@ -2734,8 +2735,10 @@ public class AudioManager { public static abstract class AudioRecordingCallback { /** * Called whenever the device recording configuration has changed. + * @param configs array containing the results of + * {@link AudioManager#getActiveRecordConfigurations()}. */ - public void onRecordConfigChanged() {} + public void onRecordConfigChanged(AudioRecordConfiguration[] configs) {} } private static class AudioRecordingCallbackInfo { @@ -2747,6 +2750,17 @@ public class AudioManager { } } + private final static class RecordConfigChangeCallbackData { + final AudioRecordingCallback mCb; + final AudioRecordConfiguration[] mConfigs; + + RecordConfigChangeCallbackData(AudioRecordingCallback cb, + AudioRecordConfiguration[] configs) { + mCb = cb; + mConfigs = configs; + } + } + /** * Register a callback to be notified of audio recording changes through * {@link AudioRecordingCallback} @@ -2882,14 +2896,15 @@ public class AudioManager { private final IRecordingConfigDispatcher mRecCb = new IRecordingConfigDispatcher.Stub() { - public void dispatchRecordingConfigChange() { + public void dispatchRecordingConfigChange(AudioRecordConfiguration[] configs) { synchronized(mRecordCallbackLock) { if (mRecordCallbackList != null) { for (int i=0 ; i < mRecordCallbackList.size() ; i++) { final AudioRecordingCallbackInfo arci = mRecordCallbackList.get(i); if (arci.mHandler != null) { final Message m = arci.mHandler.obtainMessage( - MSSG_RECORDING_CONFIG_CHANGE/*what*/, arci.mCb/*obj*/); + MSSG_RECORDING_CONFIG_CHANGE/*what*/, + new RecordConfigChangeCallbackData(arci.mCb, configs)/*obj*/); arci.mHandler.sendMessage(m); } } diff --git a/media/java/android/media/AudioRecordConfiguration.java b/media/java/android/media/AudioRecordConfiguration.java index 2fc8ee82efa9..de78a5a813eb 100644 --- a/media/java/android/media/AudioRecordConfiguration.java +++ b/media/java/android/media/AudioRecordConfiguration.java @@ -16,10 +16,13 @@ package android.media; +import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Objects; @@ -53,6 +56,19 @@ public final class AudioRecordConfiguration implements Parcelable { mPatchHandle = patchHandle; } + /** @hide */ + @IntDef({ + MediaRecorder.AudioSource.DEFAULT, + MediaRecorder.AudioSource.VOICE_UPLINK, + MediaRecorder.AudioSource.VOICE_DOWNLINK, + MediaRecorder.AudioSource.VOICE_CALL, + MediaRecorder.AudioSource.CAMCORDER, + MediaRecorder.AudioSource.VOICE_RECOGNITION, + MediaRecorder.AudioSource.VOICE_COMMUNICATION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AudioSource {} + /** * Returns the audio source being used for the recording. * @return one of {@link MediaRecorder.AudioSource#MIC}, @@ -63,7 +79,7 @@ public final class AudioRecordConfiguration implements Parcelable { * {@link MediaRecorder.AudioSource#VOICE_RECOGNITION}, * {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}. */ - public int getClientAudioSource() { return mClientSource; } + public @AudioSource int getClientAudioSource() { return mClientSource; } /** * Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}. diff --git a/media/java/android/media/IRecordingConfigDispatcher.aidl b/media/java/android/media/IRecordingConfigDispatcher.aidl index a5eb8b9fa787..eaa92ca56d20 100644 --- a/media/java/android/media/IRecordingConfigDispatcher.aidl +++ b/media/java/android/media/IRecordingConfigDispatcher.aidl @@ -16,6 +16,8 @@ package android.media; +import android.media.AudioRecordConfiguration; + /** * AIDL for the RecordingActivity monitor in AudioService to signal audio recording updates. * @@ -23,6 +25,6 @@ package android.media; */ oneway interface IRecordingConfigDispatcher { - void dispatchRecordingConfigChange(); + void dispatchRecordingConfigChange(in AudioRecordConfiguration[] configs); } diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index b5ea2a0a0f03..f593685532f7 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -370,15 +370,14 @@ public abstract class MediaBrowserService extends Service { * called when the loading is complete. * </p><p> * In case the media item does not have any children, call {@link Result#sendResult} - * with an empty list which is not {@code null}. If {@code null} is sent that means - * the given {@code parentId} is invalid and {@link MediaBrowser.SubscriptionCallback#onError} - * will be called. + * with an empty list. When the given {@code parentId} is invalid, implementations must + * call {@link Result#sendResult result.sendResult} with {@code null}, which will invoke + * {@link MediaBrowser.SubscriptionCallback#onError}. * </p> * * @param parentId The id of the parent media item whose children are to be * queried. - * @param result The Result to send the list of children to. Send null if the - * id is invalid. + * @param result The Result to send the list of children to. */ public abstract void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowser.MediaItem>> result); @@ -394,15 +393,14 @@ public abstract class MediaBrowserService extends Service { * called when the loading is complete. * </p><p> * In case the media item does not have any children, call {@link Result#sendResult} - * with an empty list which is not {@code null}. If {@code null} is sent that means - * the given {@code parentId} is invalid and {@link MediaBrowser.SubscriptionCallback#onError} - * will be called. + * with an empty list. When the given {@code parentId} is invalid, implementations must + * call {@link Result#sendResult result.sendResult} with {@code null}, which will invoke + * {@link MediaBrowser.SubscriptionCallback#onError}. * </p> * * @param parentId The id of the parent media item whose children are to be * queried. - * @param result The Result to send the list of children to. Send null if the - * id is invalid. + * @param result The Result to send the list of children to. * @param options A bundle of service-specific arguments sent from the media * browse. The information returned through the result should be * affected by the contents of this bundle. @@ -424,13 +422,18 @@ public abstract class MediaBrowserService extends Service { * result.detach} may be called before returning from this function, and * then {@link Result#sendResult result.sendResult} called when the item has * been loaded. - * <p> - * The default implementation sends a null result. + * </p><p> + * When the given {@code itemId} is invalid, implementations must call + * {@link Result#sendResult result.sendResult} with {@code null}, which will + * invoke {@link MediaBrowser.ItemCallback#onError}. + * </p><p> + * The default implementation calls {@link Result#sendResult result.sendResult} + * with {@code null}. + * </p> * * @param itemId The id for the specific * {@link android.media.browse.MediaBrowser.MediaItem}. - * @param result The Result to send the item to. Send null if the id is - * invalid. + * @param result The Result to send the item to. */ public void onLoadItem(String itemId, Result<MediaBrowser.MediaItem> result) { result.sendResult(null); diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 2004a3aef2b8..d6994b349b27 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -1302,7 +1302,10 @@ static void android_media_MediaCodec_queueSecureInputBuffer( jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID); CryptoPlugin::Pattern pattern; - if (patternObj != NULL) { + if (patternObj == NULL) { + pattern.mEncryptBlocks = 0; + pattern.mSkipBlocks = 0; + } else { pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID); pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID); } diff --git a/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesActivityPerfTest.java b/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesActivityPerfTest.java index 05fd2f7b19cd..bf056f12fba5 100644 --- a/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesActivityPerfTest.java +++ b/packages/DocumentsUI/perf-tests/src/com/android/documentsui/FilesActivityPerfTest.java @@ -121,7 +121,7 @@ public class FilesActivityPerfTest extends ActivityTest<FilesActivity> { activity.removeEventListener(listener); } - assertEquals(i, measurements.size()); + assertEquals(i + 1, measurements.size()); // Go back to the empty root. bots.roots.openRoot(STRESS_ROOT_0_ID); diff --git a/packages/DocumentsUI/res/layout/drawer_layout.xml b/packages/DocumentsUI/res/layout/drawer_layout.xml index 065102b18075..09f4401b84c3 100644 --- a/packages/DocumentsUI/res/layout/drawer_layout.xml +++ b/packages/DocumentsUI/res/layout/drawer_layout.xml @@ -46,6 +46,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" + android:popupTheme="?actionBarPopupTheme" android:overlapAnchor="true" /> </com.android.documentsui.DocumentsToolbar> diff --git a/packages/DocumentsUI/res/layout/fixed_layout.xml b/packages/DocumentsUI/res/layout/fixed_layout.xml index 84a928dc3d9b..9f7296b2b5e7 100644 --- a/packages/DocumentsUI/res/layout/fixed_layout.xml +++ b/packages/DocumentsUI/res/layout/fixed_layout.xml @@ -44,6 +44,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" + android:popupTheme="?actionBarPopupTheme" android:overlapAnchor="true" /> </com.android.documentsui.DocumentsToolbar> diff --git a/packages/DocumentsUI/res/layout/item_subdir.xml b/packages/DocumentsUI/res/layout/item_subdir.xml index b8251d1eb865..ffe4afee7530 100644 --- a/packages/DocumentsUI/res/layout/item_subdir.xml +++ b/packages/DocumentsUI/res/layout/item_subdir.xml @@ -24,16 +24,6 @@ android:orientation="horizontal" android:baselineAligned="false"> - <ImageView - android:id="@+id/subdir" - android:layout_width="24dp" - android:layout_height="24dp" - android:paddingEnd="8dp" - android:scaleType="centerInside" - android:visibility="gone" - android:src="@drawable/ic_subdirectory_arrow" - android:contentDescription="@null" /> - <TextView android:id="@android:id/title" android:layout_width="0dp" diff --git a/packages/DocumentsUI/res/layout/single_pane_layout.xml b/packages/DocumentsUI/res/layout/single_pane_layout.xml index 235d22d0737b..8bf023f118f5 100644 --- a/packages/DocumentsUI/res/layout/single_pane_layout.xml +++ b/packages/DocumentsUI/res/layout/single_pane_layout.xml @@ -43,6 +43,7 @@ android:id="@+id/stack" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:popupTheme="?actionBarPopupTheme" android:layout_marginStart="4dp" android:overlapAnchor="true" /> diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java index 4cba1354d853..c5202042de69 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java +++ b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java @@ -220,17 +220,14 @@ class NavigationView { .inflate(R.layout.item_subdir, parent, false); } - final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir); final TextView title = (TextView) convertView.findViewById(android.R.id.title); final DocumentInfo doc = getItem(position); if (position == 0) { final RootInfo root = mEnv.getCurrentRoot(); title.setText(root.title); - subdir.setVisibility(View.GONE); } else { title.setText(doc.displayName); - subdir.setVisibility(View.VISIBLE); } return convertView; diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java index 8b619b666aaa..0831dbfc14d2 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java @@ -52,13 +52,14 @@ final class ListDocumentHolder extends DocumentHolder { super(context, parent, R.layout.item_doc_list); mTitle = (TextView) itemView.findViewById(android.R.id.title); - mDetails = (LinearLayout) itemView.findViewById(R.id.line2); mDate = (TextView) itemView.findViewById(R.id.date); mSize = (TextView) itemView.findViewById(R.id.size); mSummary = (TextView) itemView.findViewById(android.R.id.summary); mIconMime = (ImageView) itemView.findViewById(R.id.icon_mime); mIconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb); mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check); + // Warning: mDetails view doesn't exists in layout-sw720dp-land layout + mDetails = (LinearLayout) itemView.findViewById(R.id.line2); mIconHelper = iconHelper; } @@ -110,11 +111,11 @@ final class ListDocumentHolder extends DocumentHolder { mTitle.setVisibility(View.VISIBLE); - // Note, we don't show any details for any directory...ever. + boolean hasDetails = false; if (isDirectory) { - mDetails.setVisibility(View.GONE); + // Note, we don't show any details for any directory...ever. + hasDetails = false; } else { - boolean hasDetails = false; if (docSummary != null) { hasDetails = true; mSummary.setText(docSummary); @@ -136,8 +137,11 @@ final class ListDocumentHolder extends DocumentHolder { mSize.setText(Formatter.formatFileSize(mContext, docSize)); } else { mSize.setVisibility(View.GONE); - mDetails.setVisibility(View.GONE); } + } + + // mDetails view doesn't exists in layout-sw720dp-land layout + if (mDetails != null) { mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE); } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java index 409f6a700ff3..b1d42e7eb3ba 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -519,6 +519,9 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe @Override public void showPromptReason(int reason) { if (mCurrentSecuritySelection != SecurityMode.None) { + if (reason != PROMPT_REASON_NONE) { + Log.i(TAG, "Strong auth required, reason: " + reason); + } getSecurityView(mCurrentSecuritySelection).showPromptReason(reason); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java index 2dfdfda7eaa3..418b138c3b0a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java @@ -41,7 +41,7 @@ import java.util.Map; public class TileUtils { private static final boolean DEBUG = false; - private static final boolean DEBUG_TIMING = true; + private static final boolean DEBUG_TIMING = false; private static final String LOG_TAG = "TileUtils"; diff --git a/packages/SystemUI/res/color/notification_guts_buttons.xml b/packages/SystemUI/res/color/notification_guts_buttons.xml new file mode 100644 index 000000000000..f7a4ee9cd943 --- /dev/null +++ b/packages/SystemUI/res/color/notification_guts_buttons.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_checked="true" + android:color="@*android:color/material_deep_teal_500" /> + <item android:color="@android:color/black" + android:alpha=".87" /> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml index 4b0c834d8415..1ab6bf9f22ce 100644 --- a/packages/SystemUI/res/layout/notification_guts.xml +++ b/packages/SystemUI/res/layout/notification_guts.xml @@ -63,29 +63,32 @@ android:id="@+id/importance_buttons" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="8dp" - android:paddingBottom="8dip" + android:paddingTop="4dp" + android:paddingBottom="16dip" android:paddingEnd="8dp" > <RadioButton android:id="@+id/silent_importance" android:layout_width="wrap_content" android:layout_height="48dp" + android:paddingStart="32dp" android:text="@string/show_silently" - style="@style/TextAppearance.NotificationGuts.Primary" - android:buttonTint="#858383" /> + style="@style/TextAppearance.NotificationGuts.Radio" + android:buttonTint="@color/notification_guts_buttons" /> <RadioButton android:id="@+id/block_importance" android:layout_width="wrap_content" android:layout_height="48dp" + android:paddingStart="32dp" android:text="@string/block" - style="@style/TextAppearance.NotificationGuts.Primary" - android:buttonTint="#858383" /> + style="@style/TextAppearance.NotificationGuts.Radio" + android:buttonTint="@color/notification_guts_buttons" /> <RadioButton android:id="@+id/reset_importance" android:layout_width="wrap_content" android:layout_height="48dp" - style="@style/TextAppearance.NotificationGuts.Primary" - android:buttonTint="#858383" /> + android:paddingStart="32dp" + style="@style/TextAppearance.NotificationGuts.Radio" + android:buttonTint="@color/notification_guts_buttons" /> </RadioGroup> <!-- Importance slider --> <LinearLayout diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 11df6817d7af..89890d6d320d 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -323,6 +323,10 @@ <item name="android:textSize">16sp</item> </style> + <style name="TextAppearance.NotificationGuts.Radio"> + <item name="android:alpha">.87</item> + </style> + <style name="TextAppearance.NotificationGuts.Button"> <item name="android:textSize">14sp</item> <item name="android:textAllCaps">true</item> diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 8ccf60d38650..24b45cc1030b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -167,6 +167,11 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { } }; + public int getColumnCount() { + if (mPages.size() == 0) return 0; + return mPages.get(0).mColumns; + } + public static class TilePage extends TileLayout { private int mMaxRows = 3; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index c643d6708adb..6137349e179f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -16,6 +16,7 @@ package com.android.systemui.qs; import android.util.Log; import android.view.View; +import android.view.View.OnAttachStateChangeListener; import android.view.View.OnLayoutChangeListener; import android.view.animation.PathInterpolator; import android.widget.TextView; @@ -25,14 +26,20 @@ import com.android.systemui.qs.QSTile.Host.Callback; import com.android.systemui.qs.TouchAnimator.Builder; import com.android.systemui.qs.TouchAnimator.Listener; import com.android.systemui.statusbar.phone.QSTileHost; +import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerService.Tunable; import java.util.ArrayList; import java.util.Collection; -public class QSAnimator implements Callback, PageListener, Listener, OnLayoutChangeListener { +public class QSAnimator implements Callback, PageListener, Listener, OnLayoutChangeListener, + OnAttachStateChangeListener, Tunable { private static final String TAG = "QSAnimator"; + private static final String ALLOW_FANCY_ANIMATION = "sysui_qs_fancy_anim"; + private static final String MOVE_FULL_ROWS = "sysui_qs_move_whole_rows"; + public static final PathInterpolator TRANSLATION_Y_INTERPOLATOR = new PathInterpolator(.1f, .3f, 1, 1); @@ -44,34 +51,77 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private final QSPanel mQsPanel; private final QSContainer mQsContainer; + private PagedTileLayout mPagedLayout; + private boolean mOnFirstPage = true; private TouchAnimator mFirstPageAnimator; private TouchAnimator mFirstPageDelayedAnimator; private TouchAnimator mTranslationYAnimator; private TouchAnimator mNonfirstPageAnimator; + private boolean mOnKeyguard; + + private boolean mAllowFancy; + private boolean mFullRows; + private int mNumQuickTiles; + public QSAnimator(QSContainer container, QuickQSPanel quickPanel, QSPanel panel) { mQsContainer = container; mQuickQsPanel = quickPanel; mQsPanel = panel; + mQsPanel.addOnAttachStateChangeListener(this); container.addOnLayoutChangeListener(this); QSTileLayout tileLayout = mQsPanel.getTileLayout(); if (tileLayout instanceof PagedTileLayout) { - ((PagedTileLayout) tileLayout).setPageListener(this); + mPagedLayout = ((PagedTileLayout) tileLayout); + mPagedLayout.setPageListener(this); } else { Log.w(TAG, "QS Not using page layout"); } } + public void setOnKeyguard(boolean onKeyguard) { + mOnKeyguard = onKeyguard; + if (mOnKeyguard) { + clearAnimationState(); + } + } + public void setHost(QSTileHost qsh) { qsh.addCallback(this); } @Override + public void onViewAttachedToWindow(View v) { + TunerService.get(mQsContainer.getContext()).addTunable(this, ALLOW_FANCY_ANIMATION, + MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES); + } + + @Override + public void onViewDetachedFromWindow(View v) { + TunerService.get(mQsContainer.getContext()).removeTunable(this); + } + + @Override + public void onTuningChanged(String key, String newValue) { + if (ALLOW_FANCY_ANIMATION.equals(key)) { + mAllowFancy = newValue == null || Integer.parseInt(newValue) != 0; + if (!mAllowFancy) { + clearAnimationState(); + } + } else if (MOVE_FULL_ROWS.equals(key)) { + mFullRows = newValue != null && Integer.parseInt(newValue) != 0; + } else if (QuickQSPanel.NUM_QUICK_TILES.equals(key)) { + mNumQuickTiles = QuickQSPanel.getNumQuickTiles(mQsContainer.getContext()); + clearAnimationState(); + } + updateAnimators(); + } + + @Override public void onPageChanged(boolean isFirst) { if (mOnFirstPage == isFirst) return; if (!isFirst) { - setPosition(1); clearAnimationState(); } mOnFirstPage = isFirst; @@ -85,6 +135,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha int count = 0; int[] loc1 = new int[2]; int[] loc2 = new int[2]; + int lastYDiff = 0; firstPageDelayedBuilder.setStartDelay(EXPANDED_TILE_DELAY); firstPageBuilder.setListener(this); translationYBuilder.setInterpolator(TRANSLATION_Y_INTERPOLATOR); @@ -92,18 +143,20 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha firstPageDelayedBuilder.addFloat(mQsPanel.getTileLayout(), "alpha", 0, 1); mAllViews.clear(); mTopFiveQs.clear(); + mAllViews.add((View) mQsPanel.getTileLayout()); for (QSTile<?> tile : tiles) { QSTileBaseView tileView = mQsPanel.getTileView(tile); final TextView label = ((QSTileView) tileView).getLabel(); - if (count++ < 5) { + final View tileIcon = tileView.getIcon(); + if (count < mNumQuickTiles && mAllowFancy) { // Quick tiles. QSTileBaseView quickTileView = mQuickQsPanel.getTileView(tile); - final View tileIcon = tileView.getIcon(); getRelativePosition(loc1, quickTileView.getIcon(), mQsContainer); getRelativePosition(loc2, tileIcon, mQsContainer); final int xDiff = loc2[0] - loc1[0]; final int yDiff = loc2[1] - loc1[1]; + lastYDiff = yDiff; // Move the quick tile right from its location to the new one. firstPageBuilder.addFloat(quickTileView, "translationX", 0, xDiff); translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); @@ -119,20 +172,38 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mTopFiveQs.add(tileIcon); mAllViews.add(tileIcon); + mAllViews.add(label); mAllViews.add(quickTileView); + } else if (mFullRows && isIconInAnimatedRow(count)) { + firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0); + translationYBuilder.addFloat(label, "translationY", -lastYDiff, 0); + translationYBuilder.addFloat(tileIcon, "translationY", -lastYDiff, 0); + mAllViews.add(tileIcon); + mAllViews.add(label); } mAllViews.add(tileView); mAllViews.add(label); + count++; + } + if (mAllowFancy) { + mFirstPageAnimator = firstPageBuilder.build(); + mFirstPageDelayedAnimator = firstPageDelayedBuilder.build(); + mTranslationYAnimator = translationYBuilder.build(); } - mFirstPageAnimator = firstPageBuilder.build(); - mFirstPageDelayedAnimator = firstPageDelayedBuilder.build(); - mTranslationYAnimator = translationYBuilder.build(); mNonfirstPageAnimator = new TouchAnimator.Builder() .addFloat(mQuickQsPanel, "alpha", 1, 0) .setEndDelay(.5f) .build(); } + private boolean isIconInAnimatedRow(int count) { + if (mPagedLayout == null) { + return false; + } + final int columnCount = mPagedLayout.getColumnCount(); + return count < ((mNumQuickTiles + columnCount - 1) / columnCount) * columnCount; + } + private void getRelativePosition(int[] loc1, View view, View parent) { loc1[0] = 0 + view.getWidth() / 2; loc1[1] = 0; @@ -148,7 +219,10 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha public void setPosition(float position) { if (mFirstPageAnimator == null) return; - if (mOnFirstPage) { + if (mOnKeyguard) { + return; + } + if (mOnFirstPage && mAllowFancy) { mQuickQsPanel.setAlpha(1); mFirstPageAnimator.setPosition(position); mFirstPageDelayedAnimator.setPosition(position); @@ -186,12 +260,17 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private void clearAnimationState() { final int N = mAllViews.size(); mQuickQsPanel.setAlpha(0); + mQuickQsPanel.setVisibility(View.VISIBLE); for (int i = 0; i < N; i++) { View v = mAllViews.get(i); v.setAlpha(1); v.setTranslationX(1); v.setTranslationY(1); } + final int N2 = mTopFiveQs.size(); + for (int i = 0; i < N2; i++) { + mTopFiveQs.get(i).setVisibility(View.VISIBLE); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java index c59da8d8baf7..c0c1e4d24359 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java @@ -156,6 +156,7 @@ public class QSContainer extends FrameLayout { public void setKeyguardShowing(boolean keyguardShowing) { if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing); mKeyguardShowing = keyguardShowing; + mQSAnimator.setOnKeyguard(keyguardShowing); updateQsState(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index 8b826eea4285..f8a57d08e5b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -26,6 +26,8 @@ import android.widget.Space; import com.android.systemui.R; import com.android.systemui.qs.QSTile.SignalState; import com.android.systemui.qs.QSTile.State; +import com.android.systemui.tuner.TunerService; +import com.android.systemui.tuner.TunerService.Tunable; import java.util.ArrayList; import java.util.Collection; @@ -35,6 +37,8 @@ import java.util.Collection; */ public class QuickQSPanel extends QSPanel { + public static final String NUM_QUICK_TILES = "sysui_qqs_count"; + private int mMaxTiles; private QSPanel mFullPanel; private View mHeader; @@ -52,6 +56,18 @@ public class QuickQSPanel extends QSPanel { } @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + TunerService.get(mContext).addTunable(mNumTiles, NUM_QUICK_TILES); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + TunerService.get(mContext).removeTunable(mNumTiles); + } + + @Override protected void createCustomizePanel() { // No customizing from the header. } @@ -86,6 +102,7 @@ public class QuickQSPanel extends QSPanel { public void setMaxTiles(int maxTiles) { mMaxTiles = maxTiles; + setTiles(mHost.getTiles()); } @Override @@ -114,6 +131,17 @@ public class QuickQSPanel extends QSPanel { super.setTiles(quickTiles); } + private final Tunable mNumTiles = new Tunable() { + @Override + public void onTuningChanged(String key, String newValue) { + setMaxTiles(getNumQuickTiles(mContext)); + } + }; + + public static int getNumQuickTiles(Context context) { + return TunerService.get(context).getValue(NUM_QUICK_TILES, 5); + } + private static class HeaderTileLayout extends LinearLayout implements QSTileLayout { private final Space mEndSpacer; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java index b60fca8c1923..17c3eeb1a429 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java @@ -672,8 +672,9 @@ public class TaskStackLayoutAlgorithm { boolean isFrontMostTaskInGroup = task.group == null || task.group.isFrontMostTask(task); if (isFrontMostTaskInGroup) { - getStackTransform(taskProgress, mInitialScrollP, mFocusState, tmpTransform, null, - false /* ignoreSingleTaskCase */, false /* forceUpdate */); + getStackTransform(taskProgress, taskProgress, mInitialScrollP, mFocusState, + tmpTransform, null, false /* ignoreSingleTaskCase */, + false /* forceUpdate */); float screenY = tmpTransform.rect.top; boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight; if (hasVisibleThumbnail) { @@ -725,15 +726,16 @@ public class TaskStackLayoutAlgorithm { return transformOut; } else { // Return early if we have an invalid index - if (task == null || mTaskIndexMap.get(task.key.id, -1) == -1) { + int nonOverrideTaskProgress = mTaskIndexMap.get(task.key.id, -1); + if (task == null || nonOverrideTaskProgress == -1) { transformOut.reset(); return transformOut; } float taskProgress = ignoreTaskOverrides - ? mTaskIndexMap.get(task.key.id, 0) + ? nonOverrideTaskProgress : getStackScrollForTask(task); - getStackTransform(taskProgress, stackScroll, focusState, transformOut, - frontTransform, false /* ignoreSingleTaskCase */, forceUpdate); + getStackTransform(taskProgress, nonOverrideTaskProgress, stackScroll, focusState, + transformOut, frontTransform, false /* ignoreSingleTaskCase */, forceUpdate); return transformOut; } } @@ -758,9 +760,9 @@ public class TaskStackLayoutAlgorithm { * internally to ensure that we can calculate the transform for any * position in the stack. */ - public void getStackTransform(float taskProgress, float stackScroll, int focusState, - TaskViewTransform transformOut, TaskViewTransform frontTransform, - boolean ignoreSingleTaskCase, boolean forceUpdate) { + public void getStackTransform(float taskProgress, float nonOverrideTaskProgress, + float stackScroll, int focusState, TaskViewTransform transformOut, + TaskViewTransform frontTransform, boolean ignoreSingleTaskCase, boolean forceUpdate) { SystemServicesProxy ssp = Recents.getSystemServices(); // Compute the focused and unfocused offset @@ -769,6 +771,8 @@ public class TaskStackLayoutAlgorithm { mFocusedRange.offset(boundedStackScroll); float boundedScrollUnfocusedRangeX = mUnfocusedRange.getNormalizedX(taskProgress); float boundedScrollFocusedRangeX = mFocusedRange.getNormalizedX(taskProgress); + float boundedScrollUnfocusedNonOverrideRangeX = + mUnfocusedRange.getNormalizedX(nonOverrideTaskProgress); mUnfocusedRange.offset(stackScroll); mFocusedRange.offset(stackScroll); boolean unfocusedVisible = mUnfocusedRange.isInRange(taskProgress); @@ -812,7 +816,7 @@ public class TaskStackLayoutAlgorithm { y = (mStackRect.top - mTaskRect.top) + (int) Utilities.mapRange(focusState, unfocusedY, focusedY); - z = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedRangeX), + z = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedNonOverrideRangeX), mMinTranslationZ, mMaxTranslationZ); dimAlpha = Utilities.mapRange(focusState, unfocusedDim, focusedDim); viewOutlineAlpha = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedRangeX), @@ -952,9 +956,9 @@ public class TaskStackLayoutAlgorithm { mFocusedRange.relativeMin); float max = Utilities.mapRange(mFocusState, mUnfocusedRange.relativeMax, mFocusedRange.relativeMax); - getStackTransform(min, 0f, mFocusState, mBackOfStackTransform, null, + getStackTransform(min, min, 0f, mFocusState, mBackOfStackTransform, null, true /* ignoreSingleTaskCase */, true /* forceUpdate */); - getStackTransform(max, 0f, mFocusState, mFrontOfStackTransform, null, + getStackTransform(max, max, 0f, mFocusState, mFrontOfStackTransform, null, true /* ignoreSingleTaskCase */, true /* forceUpdate */); mBackOfStackTransform.visible = true; mFrontOfStackTransform.visible = true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 469a1fc58be1..143f1601e21a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1891,7 +1891,7 @@ public abstract class BaseStatusBar extends SystemUI implements } } - protected abstract boolean isPanelFullyCollapsed(); + public abstract boolean isPanelFullyCollapsed(); /** * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index ef16388502f5..073a8484dc30 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -3554,7 +3554,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - protected boolean isPanelFullyCollapsed() { + public boolean isPanelFullyCollapsed() { return mNotificationPanel.isFullyCollapsed(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index 256cc6b6ae3f..326ca2b121a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -296,7 +296,6 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements mHost = host; host.setHeaderView(this); mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this); - mHeaderQsPanel.setMaxTiles(5); mHeaderQsPanel.setHost(host); setUserInfoController(host.getUserInfoController()); setBatteryController(host.getBatteryController()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index 0ed6ef899d1f..2524e1a868cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -125,7 +125,7 @@ public class TvStatusBar extends BaseStatusBar { } @Override - protected boolean isPanelFullyCollapsed() { + public boolean isPanelFullyCollapsed() { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java index fb425abfca05..285dfd1f9318 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java @@ -50,7 +50,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { private TextView mPlayPauseDescriptionTextView; private View mCloseButtonView; private View mCloseDescriptionView; - private boolean mMovePipToFullscreen; + private boolean mPipMovedToFullscreen; private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() { @Override @@ -70,7 +70,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override public void onClick(View v) { mPipManager.movePipToFullscreen(); - mMovePipToFullscreen = true; + mPipMovedToFullscreen = true; finish(); } }); @@ -169,7 +169,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { } private void restorePipAndFinish() { - if (!mMovePipToFullscreen) { + if (!mPipMovedToFullscreen) { mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY); } finish(); @@ -225,7 +225,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override public void finish() { super.finish(); - if (mPipManager.isRecentsShown() && !mMovePipToFullscreen) { + if (mPipManager.isRecentsShown() && !mPipMovedToFullscreen) { SystemUI[] services = ((SystemUIApplication) getApplication()).getServices(); for (int i = services.length - 1; i >= 0; i--) { if (services[i] instanceof Recents) { diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 8171b49480e9..f3140d28ad3a 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -1798,38 +1798,56 @@ message MetricsEvent { // ACTION: User tapped notification action to cancel a bug report // CATEGORY: NOTIFICATION + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_CANCEL = 296; // ACTION: User tapped notification action to launch bug report details screen // CATEGORY: NOTIFICATION + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_DETAILS = 297; // ACTION: User tapped notification action to take adition screenshot on bug report // CATEGORY: NOTIFICATION + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT = 298; // ACTION: User tapped notification to share bug report // CATEGORY: NOTIFICATION + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE = 299; // ACTION: User changed bug report name using the details screen // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_NAME_CHANGED = 300; // ACTION: User changed bug report title using the details screen // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_TITLE_CHANGED = 301; // ACTION: User changed bug report description using the details screen // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_DESCRIPTION_CHANGED = 302; // ACTION: User tapped Save in the bug report details screen. // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_SAVED = 303; // ACTION: User tapped Cancel in the bug report details screen. // CATEGORY: GLOBAL_SYSTEM_UI + // OS: N + // GMS: 7.8.99 ACTION_BUGREPORT_DETAILS_CANCELED = 304; // Tuner: Open/close calibrate dialog. diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index f1a9c44ffe6c..cd4d107d5a98 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -3495,9 +3495,8 @@ public class BackupManagerService { // The agent was running with a stub Application object, so shut it down. // !!! We hardcode the confirmation UI's package name here rather than use a // manifest flag! TODO something less direct. - if (app.uid != Process.SYSTEM_UID - && !app.packageName.equals("com.android.backupconfirm") - && app.uid != Process.PHONE_UID) { + if (app.uid >= Process.FIRST_APPLICATION_UID + && !app.packageName.equals("com.android.backupconfirm")) { if (MORE_DEBUG) Slog.d(TAG, "Killing agent host process"); mActivityManager.killApplicationProcess(app.processName, app.uid); } else { @@ -6881,7 +6880,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // The agent was running with a stub Application object, so shut it down. // !!! We hardcode the confirmation UI's package name here rather than use a // manifest flag! TODO something less direct. - if (app.uid != Process.SYSTEM_UID + if (app.uid >= Process.FIRST_APPLICATION_UID && !app.packageName.equals("com.android.backupconfirm")) { if (DEBUG) Slog.d(TAG, "Killing host process"); mActivityManager.killApplicationProcess(app.processName, app.uid); @@ -8625,13 +8624,15 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // it is explicitly not killed following that operation. // // We execute this kill when these conditions hold: - // 1. the app did not request its own restore (mTargetPackage == null), and either - // 2a. the app is a full-data target (TYPE_FULL_STREAM) or + // 1. it's not a system-uid process, + // 2. the app did not request its own restore (mTargetPackage == null), and either + // 3a. the app is a full-data target (TYPE_FULL_STREAM) or // b. the app does not state android:killAfterRestore="false" in its manifest final int appFlags = mCurrentPackage.applicationInfo.flags; final boolean killAfterRestore = - (mRestoreDescription.getDataType() == RestoreDescription.TYPE_FULL_STREAM) - || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0); + (mCurrentPackage.applicationInfo.uid >= Process.FIRST_APPLICATION_UID) + && ((mRestoreDescription.getDataType() == RestoreDescription.TYPE_FULL_STREAM) + || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0)); if (mTargetPackage == null && killAfterRestore) { if (DEBUG) Slog.d(TAG, "Restore complete, killing host process of " diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 079b2f28ce47..86040c2842ed 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -164,7 +164,7 @@ public class ConnectivityService extends IConnectivityManager.Stub implements PendingIntent.OnFinished { private static final String TAG = "ConnectivityService"; - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean VDBG = false; private static final boolean LOGD_RULES = false; @@ -455,7 +455,7 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private class LegacyTypeTracker { - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean VDBG = false; private static final String TAG = "CSLegacyTypeTracker"; diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 63c9822d82c8..3b6c62b5f111 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -1960,14 +1960,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub throw new IllegalArgumentException("Unknown id: " + id); } - if (mCurClient != null && mCurAttribute != null) { - // We have already made sure that the package name belongs to the application's UID. - // No further UID check is required. - if (SystemConfig.getInstance().getFixedImeApps().contains(mCurAttribute.packageName)) { - return; - } - } - // See if we need to notify a subtype change within the same IME. if (id.equals(mCurMethodId)) { final int subtypeCount = info.getSubtypeCount(); diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index f4c62259e194..11aef178a26f 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -58,7 +58,7 @@ public class NsdService extends INsdManager.Stub { private static final String TAG = "NsdService"; private static final String MDNS_TAG = "mDnsConnector"; - private static final boolean DBG = true; + private static final boolean DBG = false; private Context mContext; private ContentResolver mContentResolver; diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java index 1c1784ec3668..73d8bddc5e60 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -105,9 +105,6 @@ public class SystemConfig { // background while in data-usage save mode, as read from the configuration files. final ArraySet<String> mAllowInDataUsageSave = new ArraySet<>(); - // These are the app package names that should not allow IME switching. - final ArraySet<String> mFixedImeApps = new ArraySet<>(); - // These are the package names of apps which should be in the 'always' // URL-handling state upon factory reset. final ArraySet<String> mLinkedApps = new ArraySet<>(); @@ -159,10 +156,6 @@ public class SystemConfig { return mAllowInDataUsageSave; } - public ArraySet<String> getFixedImeApps() { - return mFixedImeApps; - } - public ArraySet<String> getLinkedApps() { return mLinkedApps; } @@ -411,17 +404,6 @@ public class SystemConfig { XmlUtils.skipCurrentTag(parser); continue; - } else if ("fixed-ime-app".equals(name) && allowAll) { - String pkgname = parser.getAttributeValue(null, "package"); - if (pkgname == null) { - Slog.w(TAG, "<fixed-ime-app> without package in " + permFile + " at " - + parser.getPositionDescription()); - } else { - mFixedImeApps.add(pkgname); - } - XmlUtils.skipCurrentTag(parser); - continue; - } else if ("app-link".equals(name) && allowAppConfigs) { String pkgname = parser.getAttributeValue(null, "package"); if (pkgname == null) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index dee3d02c8d23..037ec59fc3db 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -101,6 +101,8 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.ProfilerInfo; import android.app.admin.DevicePolicyManager; +import android.app.admin.DevicePolicyManagerInternal; +import android.app.admin.IDevicePolicyManager; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.IBackupManager; @@ -5261,9 +5263,13 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId) { enforceNotIsolatedCaller("clearApplicationUserData"); - if (packageName != null && packageName.equals(mDeviceOwnerName)) { - throw new SecurityException("Clearing DeviceOwner data is forbidden."); + + final DevicePolicyManagerInternal dpmi = LocalServices + .getService(DevicePolicyManagerInternal.class); + if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { + throw new SecurityException("Cannot clear data for a device owner or a profile owner"); } + int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); userId = mUserController.handleIncomingUser(pid, uid, userId, false, @@ -6287,9 +6293,10 @@ public final class ActivityManagerService extends ActivityManagerNative // If the app is being launched for restore or full backup, set it up specially boolean isRestrictedBackupMode = false; if (mBackupTarget != null && mBackupAppName.equals(processName)) { - isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) - || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) - || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); + isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID + && ((mBackupTarget.backupMode == BackupRecord.RESTORE) + || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) + || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL)); } notifyPackageUse(app.instrumentationInfo != null diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 74c836390a0b..d1e1d27af1f6 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1115,7 +1115,7 @@ final class ActivityStack { r.stopped = true; r.state = ActivityState.STOPPED; - mWindowManager.notifyAppStopped(r.appToken); + mWindowManager.notifyAppStopped(r.appToken, true); if (getVisibleBehindActivity() == r) { mStackSupervisor.requestVisibleBehindLocked(r, false); @@ -2247,6 +2247,10 @@ final class ActivityStack { next.app.thread.scheduleNewIntent(next.newIntents, next.appToken); } + // Well the app will no longer be stopped. + // Clear app token stopped state in window manager if needed. + mWindowManager.notifyAppStopped(next.appToken, false); + EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.task.taskId, next.shortComponentName); diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java index 86cdbcc43edf..ddfab4d6dd84 100644 --- a/services/core/java/com/android/server/am/AppErrorDialog.java +++ b/services/core/java/com/android/server/am/AppErrorDialog.java @@ -25,6 +25,7 @@ import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.text.BidiFormatter; import android.util.Slog; import android.view.LayoutInflater; import android.view.View; @@ -68,18 +69,21 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen mProc = data.proc; mResult = data.result; mRepeating = data.repeating; + BidiFormatter bidi = BidiFormatter.getInstance(); + if ((mProc.pkgList.size() == 1) && (mName = context.getPackageManager().getApplicationLabel(mProc.info)) != null) { setTitle(res.getString( mRepeating ? com.android.internal.R.string.aerr_application_repeated : com.android.internal.R.string.aerr_application, - mName.toString(), mProc.info.processName)); + bidi.unicodeWrap(mName.toString()), + bidi.unicodeWrap(mProc.info.processName))); } else { mName = mProc.processName; setTitle(res.getString( mRepeating ? com.android.internal.R.string.aerr_process_repeated : com.android.internal.R.string.aerr_process, - mName.toString())); + bidi.unicodeWrap(mName.toString()))); } setCancelable(false); diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java index 6d1d9f38c055..c6befd7fbb7a 100644 --- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java +++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java @@ -27,6 +27,7 @@ import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.text.BidiFormatter; import android.util.Slog; import android.view.LayoutInflater; import android.view.View; @@ -84,9 +85,11 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli } } + BidiFormatter bidi = BidiFormatter.getInstance(); + setTitle(name2 != null - ? res.getString(resid, name1.toString(), name2.toString()) - : res.getString(resid, name1.toString())); + ? res.getString(resid, bidi.unicodeWrap(name1.toString()), bidi.unicodeWrap(name2.toString())) + : res.getString(resid, bidi.unicodeWrap(name1.toString()))); if (aboveSystem) { getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java index 7e76ac46a545..86dcd0f1f0f2 100644 --- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java +++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java @@ -54,12 +54,15 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin if (MediaRecorder.isSystemOnlyAudioSource(source)) { return; } - if (updateSnapshot(event, session, source, recordingInfo)) { - final Iterator<RecMonitorClient> clientIterator = mClients.iterator(); + final AudioRecordConfiguration[] configs = + updateSnapshot(event, session, source, recordingInfo); + if (configs != null){ synchronized(mClients) { + final Iterator<RecMonitorClient> clientIterator = mClients.iterator(); while (clientIterator.hasNext()) { try { - clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange(); + clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange( + configs); } catch (RemoteException e) { Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e); } @@ -115,14 +118,19 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin * @param recordingFormat see * {@link AudioSystem.AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} * for the definition of the contents of the array - * @return true if the list of active recording sessions has been modified, false otherwise. + * @return null if the list of active recording sessions has not been modified, an array + * with the current active configurations otherwise. */ - private boolean updateSnapshot(int event, int session, int source, int[] recordingInfo) { + private AudioRecordConfiguration[] updateSnapshot(int event, int session, int source, + int[] recordingInfo) { + final boolean configChanged; + final AudioRecordConfiguration[] configs; synchronized(mRecordConfigs) { switch (event) { case AudioManager.RECORD_CONFIG_EVENT_STOP: // return failure if an unknown recording session stopped - return (mRecordConfigs.remove(new Integer(session)) != null); + configChanged = (mRecordConfigs.remove(new Integer(session)) != null); + break; case AudioManager.RECORD_CONFIG_EVENT_START: final AudioFormat clientFormat = new AudioFormat.Builder() .setEncoding(recordingInfo[0]) @@ -143,25 +151,32 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin new AudioRecordConfiguration(session, source, clientFormat, deviceFormat, patchHandle); if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) { - return false; + configChanged = false; } else { // config exists but has been modified mRecordConfigs.remove(sessionKey); mRecordConfigs.put(sessionKey, updatedConfig); - return true; + configChanged = true; } } else { mRecordConfigs.put(sessionKey, new AudioRecordConfiguration(session, source, clientFormat, deviceFormat, patchHandle)); - return true; + configChanged = true; } + break; default: Log.e(TAG, String.format("Unknown event %d for session %d, source %d", event, session, source)); - return false; + configChanged = false; + } + if (configChanged) { + configs = mRecordConfigs.values().toArray(new AudioRecordConfiguration[0]); + } else { + configs = null; } } + return configs; } /** diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 90c9ddffd6bd..9e1f6b85ce39 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -60,7 +60,7 @@ import static android.net.NetworkAgent.EVENT_PACKET_KEEPALIVE; public class KeepaliveTracker { private static final String TAG = "KeepaliveTracker"; - private static final boolean DBG = true; + private static final boolean DBG = false; public static final String PERMISSION = android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD; diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index fb8b110fbcab..73da427c47c4 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -76,7 +76,7 @@ import java.util.Random; * {@hide} */ public class NetworkMonitor extends StateMachine { - private static final boolean DBG = true; + private static final boolean DBG = false; private static final String TAG = "NetworkMonitor"; private static final String DEFAULT_SERVER = "connectivitycheck.gstatic.com"; private static final int SOCKET_TIMEOUT_MS = 10000; diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index debda1483d9a..22cefd14d45f 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -54,7 +54,7 @@ import java.util.Set; */ public class PermissionMonitor { private static final String TAG = "PermissionMonitor"; - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean SYSTEM = true; private static final boolean NETWORK = false; diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 760b21819420..4eecc8186c1e 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -90,7 +90,7 @@ public class Tethering extends BaseNetworkObserver { private Context mContext; private final static String TAG = "Tethering"; - private final static boolean DBG = true; + private final static boolean DBG = false; private final static boolean VDBG = false; // TODO - remove both of these - should be part of interface inspection/selection stuff diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java index 9f1435acd4c7..2807ec822ba8 100644 --- a/services/core/java/com/android/server/net/IpConfigStore.java +++ b/services/core/java/com/android/server/net/IpConfigStore.java @@ -40,7 +40,7 @@ import java.net.Inet4Address; public class IpConfigStore { private static final String TAG = "IpConfigStore"; - private static final boolean DBG = true; + private static final boolean DBG = false; protected final DelayedDiskWrite mWriter; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 290034522c5d..3acd2cad44af 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1619,7 +1619,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); if (oldPolicy != policy) { - setUidPolicyUncheckedLocked(uid, policy, true); + setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); } } finally { Binder.restoreCallingIdentity(token); @@ -1639,7 +1639,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); policy |= oldPolicy; if (oldPolicy != policy) { - setUidPolicyUncheckedLocked(uid, policy, true); + setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); } } } @@ -1656,11 +1656,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); policy = oldPolicy & ~policy; if (oldPolicy != policy) { - setUidPolicyUncheckedLocked(uid, policy, true); + setUidPolicyUncheckedLocked(uid, oldPolicy, policy, true); } } } + private void setUidPolicyUncheckedLocked(int uid, int oldPolicy, int policy, boolean persist) { + setUidPolicyUncheckedLocked(uid, policy, persist); + + // Checks if app was added or removed to the blacklist. + if ((oldPolicy == POLICY_NONE && policy == POLICY_REJECT_METERED_BACKGROUND) + || (oldPolicy == POLICY_REJECT_METERED_BACKGROUND && policy == POLICY_NONE)) { + mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 0) + .sendToTarget(); + } + } + private void setUidPolicyUncheckedLocked(int uid, int policy, boolean persist) { mUidPolicy.put(uid, policy); @@ -1988,7 +1999,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public int getRestrictBackgroundByCaller() { mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); final int uid = Binder.getCallingUid(); + synchronized (mRulesLock) { + // Must clear identity because getUidPolicy() is restricted to system. + final long token = Binder.clearCallingIdentity(); + final int policy; + try { + policy = getUidPolicy(uid); + } finally { + Binder.restoreCallingIdentity(token); + } + if (policy == POLICY_REJECT_METERED_BACKGROUND) { + // App is blacklisted. + return RESTRICT_BACKGROUND_STATUS_ENABLED; + } if (!mRestrictBackground) { return RESTRICT_BACKGROUND_STATUS_DISABLED; } @@ -2519,7 +2543,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final List<UserInfo> users = mUserManager.getUsers(); for (int i = 0; i < users.size(); i++) { final UserInfo user = users.get(i); - for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; i--) { + for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) { int appId = mPowerSaveTempWhitelistAppIds.keyAt(j); int uid = UserHandle.getUid(user.id, appId); updateRuleForAppIdleLocked(uid); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5562e76c024e..b2ee0b2324a1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -103,6 +103,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.IActivityManager; +import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.IDevicePolicyManager; import android.app.backup.IBackupManager; import android.content.BroadcastReceiver; @@ -15110,8 +15111,15 @@ public class PackageManagerService extends IPackageManager.Stub { final IPackageDataObserver observer, final int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CLEAR_APP_USER_DATA, null); + enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, false /* checkShell */, "clear application data"); + + final DevicePolicyManagerInternal dpmi = LocalServices + .getService(DevicePolicyManagerInternal.class); + if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { + throw new SecurityException("Cannot clear data for a device owner or a profile owner"); + } // Queue up an async operation since the package deletion may take a little while. mHandler.post(new Runnable() { public void run() { @@ -15123,8 +15131,8 @@ public class PackageManagerService extends IPackageManager.Stub { clearExternalStorageDataSync(packageName, userId, true); if (succeeded) { // invoke DeviceStorageMonitor's update method to clear any notifications - DeviceStorageMonitorInternal - dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); + DeviceStorageMonitorInternal dsm = LocalServices + .getService(DeviceStorageMonitorInternal.class); if (dsm != null) { dsm.checkMemory(); } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 310ad5353e32..bf5a8f6b7783 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2604,7 +2604,6 @@ final class Settings { if (pkg.volumeUuid != null) { serializer.attribute(null, "volumeUuid", pkg.volumeUuid); } - if (pkg.parentPackageName != null) { serializer.attribute(null, "parentPackageName", pkg.parentPackageName); } @@ -4171,9 +4170,19 @@ final class Settings { }; static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] { - ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED", - ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK", + ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN", ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE", + ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK", + ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED", + ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS", + ApplicationInfo.PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED, "FORCE_DEVICE_ENCRYPTED", + ApplicationInfo.PRIVATE_FLAG_ENCRYPTION_AWARE, "ENCRYPTION_AWARE", + ApplicationInfo.PRIVATE_FLAG_AUTOPLAY, "AUTOPLAY", + ApplicationInfo.PRIVATE_FLAG_PARTIALLY_ENCRYPTION_AWARE, "PARTIALLY_ENCRYPTION_AWARE", + ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL", + ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER", + ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES, "RESIZEABLE_ACTIVITIES", + ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND", }; void dumpVersionLPr(IndentingPrintWriter pw) { @@ -4316,6 +4325,10 @@ final class Settings { } pw.print(prefix); pw.print(" versionName="); pw.println(ps.pkg.mVersionName); pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, ps.pkg); pw.println(); + final int apkSigningVersion = PackageParser.getApkSigningVersion(ps.pkg); + if (apkSigningVersion != PackageParser.APK_SIGNING_UNKNOWN) { + pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion); + } pw.print(prefix); pw.print(" applicationInfo="); pw.println(ps.pkg.applicationInfo.toString()); pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 6320413a452a..252dda7984c6 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -535,6 +535,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mForceStatusBar; boolean mForceStatusBarFromKeyguard; private boolean mForceStatusBarTransparent; + boolean mForceNavBarOpaque; boolean mHideLockScreen; boolean mForcingShowNavBar; int mForcingShowNavBarLayer; @@ -1715,6 +1716,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { mShortPressWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE; } + + mForceNavBarOpaque = res.getBoolean( + com.android.internal.R.bool.config_forceNavBarAlwaysOpaque); } @Override @@ -7080,6 +7084,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { | View.SYSTEM_UI_TRANSPARENT); } + if (mForceNavBarOpaque) { + vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); + } + if (mForceWindowDrawsStatusBarBackground) { vis |= View.STATUS_BAR_TRANSPARENT; vis &= ~View.STATUS_BAR_TRANSLUCENT; diff --git a/services/core/java/com/android/server/policy/ShortcutManager.java b/services/core/java/com/android/server/policy/ShortcutManager.java index 928444275854..57ae52306cce 100644 --- a/services/core/java/com/android/server/policy/ShortcutManager.java +++ b/services/core/java/com/android/server/policy/ShortcutManager.java @@ -138,14 +138,16 @@ class ShortcutManager { ComponentName componentName = new ComponentName(packageName, className); try { info = packageManager.getActivityInfo(componentName, - PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE); + PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE + | PackageManager.MATCH_UNINSTALLED_PACKAGES); } catch (PackageManager.NameNotFoundException e) { String[] packages = packageManager.canonicalToCurrentPackageNames( new String[] { packageName }); componentName = new ComponentName(packages[0], className); try { info = packageManager.getActivityInfo(componentName, - PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE); + PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE + | PackageManager.MATCH_UNINSTALLED_PACKAGES); } catch (PackageManager.NameNotFoundException e1) { Log.w(TAG, "Unable to add bookmark: " + packageName + "/" + className, e); diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index ecfbc0a30256..2731f42991a5 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -354,6 +354,11 @@ class AppWindowToken extends WindowToken { continue; } + if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win + + " destroySurfaces: mAppStopped=" + mAppStopped + + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed + + " win.mRemoveOnExit=" + win.mRemoveOnExit); + win.destroyOrSaveSurface(); if (win.mRemoveOnExit) { win.mAnimatingExit = false; @@ -372,15 +377,19 @@ class AppWindowToken extends WindowToken { } } - // The application has stopped, so destroy any surfaces which were keeping alive - // in case they were still being used. - void notifyAppStopped() { - if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this); - mAppStopped = true; - destroySurfaces(); + /** + * If the application has stopped it is okay to destroy any surfaces which were keeping alive + * in case they were still being used. + */ + void notifyAppStopped(boolean stopped) { + if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: stopped=" + stopped + " " + this); + mAppStopped = stopped; - // Remove any starting window that was added for this app if they are still around. - mTask.mService.scheduleRemoveStartingWindowLocked(this); + if (stopped) { + destroySurfaces(); + // Remove any starting window that was added for this app if they are still around. + mTask.mService.scheduleRemoveStartingWindowLocked(this); + } } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 7c2a8e338557..b64aaa89475a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4197,7 +4197,7 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void notifyAppStopped(IBinder token) { + public void notifyAppStopped(IBinder token, boolean stopped) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "notifyAppStopped()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); @@ -4210,7 +4210,7 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token); return; } - wtoken.notifyAppStopped(); + wtoken.notifyAppStopped(stopped); } } @@ -4247,6 +4247,8 @@ public class WindowManagerService extends IWindowManager.Stub wtoken.appDied = false; wtoken.removeAllWindows(); } else if (visible) { + if (DEBUG_ADD_REMOVE) Slog.v( + TAG_WM, "No longer Stopped: " + wtoken); wtoken.mAppStopped = false; wtoken.setWindowsExiting(false); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 14901099c116..d8aa5d7e823a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -31,8 +31,8 @@ import com.google.android.collect.Sets; import android.Manifest.permission; import android.accessibilityservice.AccessibilityServiceInfo; import android.accounts.AccountManager; +import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerNative; @@ -151,6 +151,8 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -280,6 +282,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final int PROFILE_KEYGUARD_FEATURES = PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER | PROFILE_KEYGUARD_FEATURES_PROFILE_ONLY; + private static final int CODE_OK = 0; + private static final int CODE_HAS_DEVICE_OWNER = 1; + private static final int CODE_USER_HAS_PROFILE_OWNER = 2; + private static final int CODE_USER_NOT_RUNNING = 3; + private static final int CODE_USER_SETUP_COMPLETED = 4; + private static final int CODE_NONSYSTEM_USER_EXISTS = 5; + private static final int CODE_ACCOUNTS_NOT_EMPTY = 6; + private static final int CODE_NOT_SYSTEM_USER = 7; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ CODE_OK, CODE_HAS_DEVICE_OWNER, CODE_USER_HAS_PROFILE_OWNER, CODE_USER_NOT_RUNNING, + CODE_USER_SETUP_COMPLETED, CODE_NOT_SYSTEM_USER }) + private @interface DeviceOwnerPreConditionCode {} + private static final int DEVICE_ADMIN_DEACTIVATE_TIMEOUT = 10000; final Context mContext; @@ -308,7 +324,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * Whether or not device admin feature is supported. If it isn't return defaults for all * public methods. */ - private boolean mHasFeature; + boolean mHasFeature; private final SecurityLogMonitor mSecurityLogMonitor; @@ -328,7 +344,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void onReceive(Context context, Intent intent) { - if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_DISPATCH.equals(intent.getAction()) + if (DevicePolicyManager.ACTION_REMOTE_BUGREPORT_DISPATCH.equals(intent.getAction()) && mRemoteBugreportServiceIsActive.get()) { onBugreportFinished(intent); } @@ -342,10 +358,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { String action = intent.getAction(); mInjector.getNotificationManager().cancel(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID); - if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED.equals(action)) { + if (DevicePolicyManager.ACTION_BUGREPORT_SHARING_ACCEPTED.equals(action)) { onBugreportSharingAccepted(); - } else if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED - .equals(action)) { + } else if (DevicePolicyManager.ACTION_BUGREPORT_SHARING_DECLINED.equals(action)) { onBugreportSharingDeclined(); } mContext.unregisterReceiver(mRemoteBugreportConsentReceiver); @@ -437,15 +452,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { && userHandle == mOwners.getDeviceOwnerUserId() && getDeviceOwnerRemoteBugreportUri() != null) { IntentFilter filterConsent = new IntentFilter(); - filterConsent.addAction( - RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED); - filterConsent.addAction( - RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED); + filterConsent.addAction(DevicePolicyManager.ACTION_BUGREPORT_SHARING_DECLINED); + filterConsent.addAction(DevicePolicyManager.ACTION_BUGREPORT_SHARING_ACCEPTED); mContext.registerReceiver(mRemoteBugreportConsentReceiver, filterConsent); - mInjector.getNotificationManager().notify(LOG_TAG, + mInjector.getNotificationManager().notifyAsUser(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, RemoteBugreportUtils.buildNotification(mContext, - RemoteBugreportUtils.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED)); + DevicePolicyManager.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED), + UserHandle.ALL); } if (Intent.ACTION_BOOT_COMPLETED.equals(action) || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) { @@ -5068,9 +5082,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mRemoteBugreportServiceIsActive.set(true); mRemoteBugreportSharingAccepted.set(false); registerRemoteBugreportReceivers(); - mInjector.getNotificationManager().notify(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, + mInjector.getNotificationManager().notifyAsUser(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, RemoteBugreportUtils.buildNotification(mContext, - RemoteBugreportUtils.NOTIFICATION_BUGREPORT_STARTED)); + DevicePolicyManager.NOTIFICATION_BUGREPORT_STARTED), UserHandle.ALL); mHandler.postDelayed(mRemoteBugreportTimeoutRunnable, RemoteBugreportUtils.REMOTE_BUGREPORT_TIMEOUT_MILLIS); return true; @@ -5104,7 +5118,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void registerRemoteBugreportReceivers() { try { IntentFilter filterFinished = new IntentFilter( - RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_DISPATCH, + DevicePolicyManager.ACTION_REMOTE_BUGREPORT_DISPATCH, RemoteBugreportUtils.BUGREPORT_MIMETYPE); mContext.registerReceiver(mRemoteBugreportFinishedReceiver, filterFinished); } catch (IntentFilter.MalformedMimeTypeException e) { @@ -5112,8 +5126,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Slog.w(LOG_TAG, "Failed to set type " + RemoteBugreportUtils.BUGREPORT_MIMETYPE, e); } IntentFilter filterConsent = new IntentFilter(); - filterConsent.addAction(RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED); - filterConsent.addAction(RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED); + filterConsent.addAction(DevicePolicyManager.ACTION_BUGREPORT_SHARING_DECLINED); + filterConsent.addAction(DevicePolicyManager.ACTION_BUGREPORT_SHARING_ACCEPTED); mContext.registerReceiver(mRemoteBugreportConsentReceiver, filterConsent); } @@ -5126,16 +5140,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { bugreportUriString = bugreportUri.toString(); } String bugreportHash = intent.getStringExtra( - RemoteBugreportUtils.EXTRA_REMOTE_BUGREPORT_HASH); + DevicePolicyManager.EXTRA_REMOTE_BUGREPORT_HASH); if (mRemoteBugreportSharingAccepted.get()) { shareBugreportWithDeviceOwnerIfExists(bugreportUriString, bugreportHash); mInjector.getNotificationManager().cancel(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID); } else { setDeviceOwnerRemoteBugreportUriAndHash(bugreportUriString, bugreportHash); - mInjector.getNotificationManager().notify(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, + mInjector.getNotificationManager().notifyAsUser(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, RemoteBugreportUtils.buildNotification(mContext, - RemoteBugreportUtils.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED)); + DevicePolicyManager.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED), + UserHandle.ALL); } mContext.unregisterReceiver(mRemoteBugreportFinishedReceiver); } @@ -5166,9 +5181,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (bugreportUriString != null) { shareBugreportWithDeviceOwnerIfExists(bugreportUriString, bugreportHash); } else if (mRemoteBugreportServiceIsActive.get()) { - mInjector.getNotificationManager().notify(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, + mInjector.getNotificationManager().notifyAsUser(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID, RemoteBugreportUtils.buildNotification(mContext, - RemoteBugreportUtils.NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED)); + DevicePolicyManager.NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED), + UserHandle.ALL); } } @@ -5934,52 +5950,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { /** * The Device owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS * permission. - * The device owner can only be set before the setup phase of the primary user has completed, - * except for adb if no accounts or additional users are present on the device. */ private void enforceCanSetDeviceOwnerLocked(int userId) { - if (mOwners.hasDeviceOwner()) { - throw new IllegalStateException("Trying to set the device owner, but device owner " - + "is already set."); - } - if (mOwners.hasProfileOwner(userId)) { - throw new IllegalStateException("Trying to set the device owner, but the user already " - + "has a profile owner."); - } - if (!mUserManager.isUserRunning(new UserHandle(userId))) { - throw new IllegalStateException("User not running: " + userId); - } - int callingUid = mInjector.binderGetCallingUid(); - if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { - if (!hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { - return; - } - // STOPSHIP Do proper check in split user mode - if (!mInjector.userManagerIsSplitSystemUser()) { - if (mUserManager.getUserCount() > 1) { - throw new IllegalStateException( - "Not allowed to set the device owner because there " - + "are already several users on the device"); - } - if (AccountManager.get(mContext).getAccounts().length > 0) { - throw new IllegalStateException( - "Not allowed to set the device owner because there " - + "are already some accounts on the device"); - } - } - return; + boolean isAdb = callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; + if (!isAdb) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); } - // STOPSHIP check the caller UID with userId - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); - // STOPSHIP Do proper check in split user mode - if (!mInjector.userManagerIsSplitSystemUser()) { - if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { - throw new IllegalStateException("Cannot set the device owner if the device is " - + "already set-up"); - } + final int code = checkSetDeviceOwnerPreCondition(userId, isAdb); + switch (code) { + case CODE_OK: + return; + case CODE_HAS_DEVICE_OWNER: + throw new IllegalStateException( + "Trying to set the device owner, but device owner is already set."); + case CODE_USER_HAS_PROFILE_OWNER: + throw new IllegalStateException("Trying to set the device owner, but the user " + + "already has a profile owner."); + case CODE_USER_NOT_RUNNING: + throw new IllegalStateException("User not running: " + userId); + case CODE_NOT_SYSTEM_USER: + throw new IllegalStateException("User is not system user"); + case CODE_USER_SETUP_COMPLETED: + throw new IllegalStateException( + "Cannot set the device owner if the device is already set-up"); + case CODE_NONSYSTEM_USER_EXISTS: + throw new IllegalStateException("Not allowed to set the device owner because there " + + "are already several users on the device"); + case CODE_ACCOUNTS_NOT_EMPTY: + throw new IllegalStateException("Not allowed to set the device owner because there " + + "are already some accounts on the device"); + default: + throw new IllegalStateException("Unknown @DeviceOwnerPreConditionCode " + code); } } @@ -7810,6 +7814,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { listener.onCrossProfileWidgetProvidersChanged(userId, packages); } } + + @Override + public boolean hasDeviceOwnerOrProfileOwner(String packageName, int userId) { + if (!mHasFeature || packageName == null) { + return false; + } + if (userId < 0) { + throw new UnsupportedOperationException("userId should be >= 0"); + } + synchronized (DevicePolicyManagerService.this) { + if (packageName.equals(mOwners.getProfileOwnerPackage(userId))) { + return true; + } + if (userId == mOwners.getDeviceOwnerUserId() + && packageName.equals(mOwners.getDeviceOwnerPackageName())) { + return true; + } + } + return false; + } } /** @@ -8036,6 +8060,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isProvisioningAllowed(String action) { + if (!mHasFeature) { + return false; + } + final int callingUserId = mInjector.userHandleGetCallingUserId(); if (DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE.equals(action)) { if (!hasFeatureManagedUsers()) { @@ -8100,23 +8128,55 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throw new IllegalArgumentException("Unknown provisioning action " + action); } - private boolean isDeviceOwnerProvisioningAllowed(int callingUserId) { - synchronized (this) { - if (mOwners.hasDeviceOwner()) { - return false; - } + /* + * The device owner can only be set before the setup phase of the primary user has completed, + * except for adb command if no accounts or additional users are present on the device. + */ + private synchronized @DeviceOwnerPreConditionCode int checkSetDeviceOwnerPreCondition( + int deviceOwnerUserId, boolean isAdb) { + if (mOwners.hasDeviceOwner()) { + return CODE_HAS_DEVICE_OWNER; } - if (getProfileOwner(callingUserId) != null) { - return false; + if (mOwners.hasProfileOwner(deviceOwnerUserId)) { + return CODE_USER_HAS_PROFILE_OWNER; } - if (mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) != 0) { - return false; + if (!mUserManager.isUserRunning(new UserHandle(deviceOwnerUserId))) { + return CODE_USER_NOT_RUNNING; } - if (callingUserId != UserHandle.USER_SYSTEM) { - // Device owner provisioning can only be initiated from system user. - return false; + if (isAdb) { + // if shell command runs after user setup completed check device status. Otherwise, OK. + if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { + if (!mInjector.userManagerIsSplitSystemUser()) { + if (mUserManager.getUserCount() > 1) { + return CODE_NONSYSTEM_USER_EXISTS; + } + if (AccountManager.get(mContext).getAccounts().length > 0) { + return CODE_ACCOUNTS_NOT_EMPTY; + } + } else { + // STOPSHIP Do proper check in split user mode + } + } + return CODE_OK; + } else { + if (!mInjector.userManagerIsSplitSystemUser()) { + // In non-split user mode, DO has to be user 0 + if (deviceOwnerUserId != UserHandle.USER_SYSTEM) { + return CODE_NOT_SYSTEM_USER; + } + // In non-split user mode, only provision DO before setup wizard completes + if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) { + return CODE_USER_SETUP_COMPLETED; + } + } else { + // STOPSHIP Do proper check in split user mode + } + return CODE_OK; } - return true; + } + + private boolean isDeviceOwnerProvisioningAllowed(int deviceOwnerUserId) { + return CODE_OK == checkSetDeviceOwnerPreCondition(deviceOwnerUserId, /* isAdb */ false); } private boolean hasFeatureManagedUsers() { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java index 117ba15cf65a..6d42dc9e4e5a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java @@ -19,8 +19,12 @@ package com.android.server.devicepolicy; import android.annotation.IntDef; import android.app.Notification; import android.app.PendingIntent; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.os.UserHandle; +import android.provider.Settings; import android.text.format.DateUtils; import com.android.internal.R; @@ -37,79 +41,62 @@ class RemoteBugreportUtils { @Retention(RetentionPolicy.SOURCE) @IntDef({ - NOTIFICATION_BUGREPORT_STARTED, - NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED, - NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED + DevicePolicyManager.NOTIFICATION_BUGREPORT_STARTED, + DevicePolicyManager.NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED, + DevicePolicyManager.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED }) @interface RemoteBugreportNotificationType {} - static final int NOTIFICATION_BUGREPORT_STARTED = 1; - static final int NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED = 2; - static final int NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED = 3; static final long REMOTE_BUGREPORT_TIMEOUT_MILLIS = 10 * DateUtils.MINUTE_IN_MILLIS; static final String CTL_STOP = "ctl.stop"; static final String REMOTE_BUGREPORT_SERVICE = "bugreportremote"; - static final String ACTION_REMOTE_BUGREPORT_DISPATCH = - "android.intent.action.REMOTE_BUGREPORT_DISPATCH"; - static final String ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED = - "com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED"; - static final String ACTION_REMOTE_BUGREPORT_SHARING_DECLINED = - "com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED"; - static final String EXTRA_REMOTE_BUGREPORT_HASH = "android.intent.extra.REMOTE_BUGREPORT_HASH"; - static final String BUGREPORT_MIMETYPE = "application/vnd.android.bugreport"; static Notification buildNotification(Context context, @RemoteBugreportNotificationType int type) { + Intent dialogIntent = new Intent(Settings.ACTION_SHOW_REMOTE_BUGREPORT_DIALOG); + dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + dialogIntent.putExtra(DevicePolicyManager.EXTRA_BUGREPORT_NOTIFICATION_TYPE, type); + PendingIntent pendingDialogIntent = PendingIntent.getActivityAsUser(context, type, + dialogIntent, 0, null, UserHandle.CURRENT); + Notification.Builder builder = new Notification.Builder(context) .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) .setOngoing(true) .setLocalOnly(true) + .setPriority(Notification.PRIORITY_HIGH) + .setContentIntent(pendingDialogIntent) .setColor(context.getColor( com.android.internal.R.color.system_notification_accent_color)); - if (type == NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED) { + if (type == DevicePolicyManager.NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED) { builder.setContentTitle(context.getString( - R.string.sharing_remote_bugreport_notification_title)) - .setContentText(context.getString( - R.string.sharing_remote_bugreport_notification_message)) - .setPriority(Notification.PRIORITY_HIGH) - .setProgress(0, 0, true) - .setStyle(new Notification.BigTextStyle().bigText(context.getString( - R.string.sharing_remote_bugreport_notification_message))); - } else { + R.string.sharing_remote_bugreport_notification_title)) + .setProgress(0, 0, true); + } else if (type == DevicePolicyManager.NOTIFICATION_BUGREPORT_STARTED) { + builder.setContentTitle(context.getString( + R.string.taking_remote_bugreport_notification_title)) + .setProgress(0, 0, true); + } else if (type == DevicePolicyManager.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED) { PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(context, NOTIFICATION_ID, - new Intent(ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED), + new Intent(DevicePolicyManager.ACTION_BUGREPORT_SHARING_ACCEPTED), PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent pendingIntentDecline = PendingIntent.getBroadcast(context, - NOTIFICATION_ID, new Intent(ACTION_REMOTE_BUGREPORT_SHARING_DECLINED), + NOTIFICATION_ID, new Intent( + DevicePolicyManager.ACTION_BUGREPORT_SHARING_DECLINED), PendingIntent.FLAG_CANCEL_CURRENT); builder.addAction(new Notification.Action.Builder(null /* icon */, context.getString( - R.string.share_remote_bugreport_notification_decline), - pendingIntentDecline).build()) + R.string.decline_remote_bugreport_action), pendingIntentDecline).build()) .addAction(new Notification.Action.Builder(null /* icon */, context.getString( - R.string.share_remote_bugreport_notification_accept), - pendingIntentAccept).build()) + R.string.share_remote_bugreport_action), pendingIntentAccept).build()) .setContentTitle(context.getString( - R.string.share_remote_bugreport_notification_title)); - - if (type == NOTIFICATION_BUGREPORT_STARTED) { - builder.setContentText(context.getString( - R.string.share_remote_bugreport_notification_message)) - .setStyle(new Notification.BigTextStyle().bigText(context.getString( - R.string.share_remote_bugreport_notification_message))) - .setProgress(0, 0, true) - .setPriority(Notification.PRIORITY_MAX) - .setVibrate(new long[0]); - } else if (type == NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED) { - builder.setContentText(context.getString( - R.string.share_finished_remote_bugreport_notification_message)) - .setStyle(new Notification.BigTextStyle().bigText(context.getString( - R.string.share_finished_remote_bugreport_notification_message))) - .setPriority(Notification.PRIORITY_HIGH); - } + R.string.share_remote_bugreport_notification_title)) + .setContentText(context.getString( + R.string.share_remote_bugreport_notification_message_finished)) + .setStyle(new Notification.BigTextStyle().bigText(context.getString( + R.string.share_remote_bugreport_notification_message_finished))); } return builder.build(); diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java index 4f99bffe245b..e2562cd5d40b 100644 --- a/services/net/java/android/net/dhcp/DhcpClient.java +++ b/services/net/java/android/net/dhcp/DhcpClient.java @@ -84,10 +84,10 @@ import static android.net.dhcp.DhcpPacket.*; public class DhcpClient extends StateMachine { private static final String TAG = "DhcpClient"; - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean STATE_DBG = false; private static final boolean MSG_DBG = false; - private static final boolean PACKET_DBG = true; + private static final boolean PACKET_DBG = false; // Timers and timeouts. private static final int SECONDS = 1000; @@ -342,14 +342,14 @@ public class DhcpClient extends StateMachine { @Override public void run() { - maybeLog("Receive thread started"); + if (DBG) Log.d(TAG, "Receive thread started"); while (!stopped) { int length = 0; // Or compiler can't tell it's initialized if a parse error occurs. try { length = Os.read(mPacketSock, mPacket, 0, mPacket.length); DhcpPacket packet = null; packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2); - maybeLog("Received packet: " + packet); + if (DBG) Log.d(TAG, "Received packet: " + packet); sendMessage(CMD_RECEIVED_PACKET, packet); } catch (IOException|ErrnoException e) { if (!stopped) { @@ -362,7 +362,7 @@ public class DhcpClient extends StateMachine { } } } - maybeLog("Receive thread stopped"); + if (DBG) Log.d(TAG, "Receive thread stopped"); } } @@ -373,12 +373,12 @@ public class DhcpClient extends StateMachine { private boolean transmitPacket(ByteBuffer buf, String description, Inet4Address to) { try { if (to.equals(INADDR_BROADCAST)) { - maybeLog("Broadcasting " + description); + if (DBG) Log.d(TAG, "Broadcasting " + description); Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr); } else { // It's safe to call getpeername here, because we only send unicast packets if we // have an IP address, and we connect the UDP socket in DhcpHaveAddressState#enter. - maybeLog("Unicasting " + description + " to " + Os.getpeername(mUdpSock)); + if (DBG) Log.d(TAG, "Unicasting " + description + " to " + Os.getpeername(mUdpSock)); Os.write(mUdpSock, buf); } } catch(ErrnoException|IOException e) { @@ -454,10 +454,6 @@ public class DhcpClient extends StateMachine { mController.sendMessage(CMD_ON_QUIT); } - private void maybeLog(String msg) { - if (DBG) Log.d(TAG, msg); - } - abstract class LoggingState extends State { public void enter() { if (STATE_DBG) Log.d(TAG, "Entering state " + getName()); @@ -592,7 +588,7 @@ public class DhcpClient extends StateMachine { transitionTo(mStoppedState); return HANDLED; case CMD_ONESHOT_TIMEOUT: - maybeLog("Timed out"); + if (DBG) Log.d(TAG, "Timed out"); notifyFailure(); return HANDLED; default: @@ -790,7 +786,7 @@ public class DhcpClient extends StateMachine { @Override public void exit() { - maybeLog("Clearing IP address"); + if (DBG) Log.d(TAG, "Clearing IP address"); setIpAddress(new LinkAddress("0.0.0.0/0")); } } diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java index afae9563cb19..c7c50153f855 100644 --- a/services/net/java/android/net/ip/IpManager.java +++ b/services/net/java/android/net/ip/IpManager.java @@ -63,7 +63,7 @@ import java.util.Objects; * @hide */ public class IpManager extends StateMachine { - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean VDBG = false; // For message logging. diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java index 88155f715f49..5b4fd503e0bb 100644 --- a/services/net/java/android/net/ip/IpReachabilityMonitor.java +++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java @@ -132,7 +132,7 @@ import java.util.Set; */ public class IpReachabilityMonitor { private static final String TAG = "IpReachabilityMonitor"; - private static final boolean DBG = true; + private static final boolean DBG = false; private static final boolean VDBG = false; public interface Callback { diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 212b37cebead..8c47087f4305 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -969,6 +969,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); + // Make sure the admin packge is installed to each user. setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID); @@ -1008,6 +1010,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { * finds the right component from a package name upon migration. */ public void testDeviceOwnerMigration() throws Exception { + when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); checkDeviceOwnerWithMultipleDeviceAdmins(); // Overwrite the device owner setting and clears the clas name. diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 6ab0b998bd6c..837b4a4963ad 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -75,7 +75,7 @@ import java.util.List; */ public class VoiceInteractionManagerService extends SystemService { static final String TAG = "VoiceInteractionManagerService"; - static final boolean DEBUG = true; + static final boolean DEBUG = false; final Context mContext; final ContentResolver mResolver; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 1278c07897f5..cd1c5e9ac229 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -637,7 +637,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false); sDefaults.putBoolean(KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL, true); sDefaults.putBoolean(KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL, true); - sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, true); + sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false); sDefaults.putBoolean(KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL, true); sDefaults.putBoolean(KEY_USE_HFA_FOR_PROVISIONING_BOOL, false); sDefaults.putBoolean(KEY_USE_OTASP_FOR_PROVISIONING_BOOL, false); diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index ad007c648617..39a9295ed8b6 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -36,7 +36,7 @@ import android.telephony.Rlog; public class ServiceState implements Parcelable { static final String LOG_TAG = "PHONE"; - static final boolean DBG = true; + static final boolean DBG = false; static final boolean VDBG = false; // STOPSHIP if true /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e90be91e3248..b482811a18f2 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -4403,7 +4403,6 @@ public class TelephonyManager { Log.e(TAG, "Error calling ITelephony#getDataEnabled", e); } catch (NullPointerException e) { } - Log.d(TAG, "getDataEnabled: retVal=" + retVal); return retVal; } diff --git a/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java index c8a8d6cae969..6463e1f76b6a 100644 --- a/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java +++ b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java @@ -47,7 +47,7 @@ public class LocalRenderer extends Renderer implements OnPreparedListener, OnBufferingUpdateListener, OnCompletionListener, OnErrorListener, OnAudioFocusChangeListener { private static final String TAG = "MediaPlayerManager"; - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; private static long sDebugInstanceId = 0; private static final String[] SUPPORTED_FEATURES = { diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java index 4770c056814c..3ca96d2e7a06 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java @@ -40,7 +40,7 @@ import android.widget.Toast; public class TestSoundTriggerActivity extends Activity { private static final String TAG = "TestSoundTriggerActivity"; - private static final boolean DBG = true; + private static final boolean DBG = false; private SoundTriggerUtil mSoundTriggerUtil; private Random mRandom; diff --git a/tests/SoundTriggerTests/Android.mk b/tests/SoundTriggerTests/Android.mk index 407a9d70d93f..ac562b911cbe 100644 --- a/tests/SoundTriggerTests/Android.mk +++ b/tests/SoundTriggerTests/Android.mk @@ -18,7 +18,14 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-subdir-java-files) +ifeq ($(SOUND_TRIGGER_USE_STUB_MODULE), 1) + LOCAL_SRC_FILES := $(call all-subdir-java-files) + LOCAL_PRIVILEGED_MODULE := true + LOCAL_CERTIFICATE := platform + TARGET_OUT_DATA_APPS_PRIVILEGED := $(TARGET_OUT_DATA)/priv-app +else + LOCAL_SRC_FILES := src/android/hardware/soundtrigger/SoundTriggerTest.java +endif LOCAL_JAVA_LIBRARIES := android.test.runner diff --git a/tests/SoundTriggerTests/AndroidManifest.xml b/tests/SoundTriggerTests/AndroidManifest.xml index 5e5a108d263e..e8b9dd32d62f 100644 --- a/tests/SoundTriggerTests/AndroidManifest.xml +++ b/tests/SoundTriggerTests/AndroidManifest.xml @@ -14,7 +14,10 @@ limitations under the License. --> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.hardware.soundtrigger"> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.hardware.soundtrigger"> + <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" /> + <application> <uses-library android:name="android.test.runner" /> </application> diff --git a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java new file mode 100644 index 000000000000..7acb472339e0 --- /dev/null +++ b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 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 android.hardware.soundtrigger; + +import java.util.Random; +import java.util.UUID; + +import android.content.Context; +import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel; +import android.media.soundtrigger.SoundTriggerManager; +import android.os.ParcelUuid; +import android.os.ServiceManager; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.internal.app.ISoundTriggerService; + +import java.util.Arrays; +import java.util.Random; +import java.util.UUID; + +public class GenericSoundModelTest extends AndroidTestCase { + private Random mRandom = new Random(); + + @SmallTest + public void testUpdateGenericSoundModel() throws Exception { + Context context = getContext(); + ISoundTriggerService mSoundTriggerService = ISoundTriggerService.Stub.asInterface( + ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE)); + SoundTriggerManager mSoundTriggerManager = (SoundTriggerManager) context.getSystemService( + Context.SOUND_TRIGGER_SERVICE); + + byte[] data = new byte[1024]; + mRandom.nextBytes(data); + UUID modelUuid = UUID.randomUUID(); + UUID mVendorUuid = UUID.randomUUID(); + GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data); + + mSoundTriggerService.updateSoundModel(model); + GenericSoundModel returnedModel = + mSoundTriggerService.getSoundModel(new ParcelUuid(modelUuid)); + + assertEquals(model, returnedModel); + + // Cleanup sound model + mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelUuid)); + } + + + @SmallTest + public void testDeleteGenericSoundModel() throws Exception { + Context context = getContext(); + ISoundTriggerService mSoundTriggerService = ISoundTriggerService.Stub.asInterface( + ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE)); + SoundTriggerManager mSoundTriggerManager = (SoundTriggerManager) context.getSystemService( + Context.SOUND_TRIGGER_SERVICE); + + byte[] data = new byte[1024]; + mRandom.nextBytes(data); + UUID modelUuid = UUID.randomUUID(); + UUID mVendorUuid = UUID.randomUUID(); + GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data); + + mSoundTriggerService.updateSoundModel(model); + mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelUuid)); + + GenericSoundModel returnedModel = + mSoundTriggerService.getSoundModel(new ParcelUuid(modelUuid)); + assertEquals(null, returnedModel); + } +} diff --git a/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java index 2494db7ee623..54c944f9588e 100644 --- a/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java +++ b/tests/VoiceEnrollment/src/com/android/test/voiceenrollment/TestEnrollmentActivity.java @@ -31,7 +31,7 @@ import android.widget.Toast; public class TestEnrollmentActivity extends Activity { private static final String TAG = "TestEnrollmentActivity"; - private static final boolean DBG = true; + private static final boolean DBG = false; /** Keyphrase related constants, must match those defined in enrollment_application.xml */ private static final int KEYPHRASE_ID = 101; diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index d2103c811d3e..97195e4b32da 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -349,7 +349,7 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public void notifyAppStopped(IBinder token) throws RemoteException { + public void notifyAppStopped(IBinder token, boolean stopped) throws RemoteException { // TODO Auto-generated method stub } diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 69e179ddfaf5..97dd98573862 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -192,6 +192,11 @@ public class WifiScanner { * for a given period */ public int stepCount; + /** + * Flag to indicate if the scan settings are targeted for PNO scan. + * {@hide} + */ + public boolean isPnoScan; /** Implement the Parcelable interface {@hide} */ public int describeContents() { @@ -207,6 +212,7 @@ public class WifiScanner { dest.writeInt(maxScansToCache); dest.writeInt(maxPeriodInMs); dest.writeInt(stepCount); + dest.writeInt(isPnoScan ? 1 : 0); if (channels != null) { dest.writeInt(channels.length); @@ -234,6 +240,7 @@ public class WifiScanner { settings.maxScansToCache = in.readInt(); settings.maxPeriodInMs = in.readInt(); settings.stepCount = in.readInt(); + settings.isPnoScan = in.readInt() == 1; int num_channels = in.readInt(); settings.channels = new ChannelSpec[num_channels]; for (int i = 0; i < num_channels; i++) { @@ -436,6 +443,158 @@ public class WifiScanner { }; } + /** {@hide} */ + public static final String PNO_PARAMS_PNO_SETTINGS_KEY = "PnoSettings"; + /** {@hide} */ + public static final String PNO_PARAMS_SCAN_SETTINGS_KEY = "ScanSettings"; + /** + * PNO scan configuration parameters to be sent to {@link #startPnoScan}. + * Note: This structure needs to be in sync with |wifi_epno_params| struct in gscan HAL API. + * {@hide} + */ + public static class PnoSettings implements Parcelable { + /** + * Pno network to be added to the PNO scan filtering. + * {@hide} + */ + public static class PnoNetwork { + /* + * Pno flags bitmask to be set in {@link #PnoNetwork.flags} + */ + /** Whether directed scan needs to be performed (for hidden SSIDs) */ + public static final byte FLAG_DIRECTED_SCAN = (1 << 0); + /** Whether PNO event shall be triggered if the network is found on A band */ + public static final byte FLAG_A_BAND = (1 << 1); + /** Whether PNO event shall be triggered if the network is found on G band */ + public static final byte FLAG_G_BAND = (1 << 2); + /** + * Whether strict matching is required + * If required then the firmware must store the network's SSID and not just a hash + */ + public static final byte FLAG_STRICT_MATCH = (1 << 3); + /** + * If this SSID should be considered the same network as the currently connected + * one for scoring. + */ + public static final byte FLAG_SAME_NETWORK = (1 << 4); + + /* + * Code for matching the beacon AUTH IE - additional codes. Bitmask to be set in + * {@link #PnoNetwork.authBitField} + */ + /** Open Network */ + public static final byte AUTH_CODE_OPEN = (1 << 0); + /** WPA_PSK or WPA2PSK */ + public static final byte AUTH_CODE_PSK = (1 << 1); + /** any EAPOL */ + public static final byte AUTH_CODE_EAPOL = (1 << 2); + + /** SSID of the network */ + public String ssid; + /** Network ID in wpa_supplicant */ + public int networkId; + /** Assigned priority for the network */ + public int priority; + /** Bitmask of the FLAG_XXX */ + public byte flags; + /** Bitmask of the ATUH_XXX */ + public byte authBitField; + + /** + * default constructor for PnoNetwork + */ + public PnoNetwork(String ssid) { + this.ssid = ssid; + flags = 0; + authBitField = 0; + } + } + + /** Connected vs Disconnected PNO flag {@hide} */ + public boolean isConnected; + /** Minimum 5GHz RSSI for a BSSID to be considered */ + public int min5GHzRssi; + /** Minimum 2.4GHz RSSI for a BSSID to be considered */ + public int min24GHzRssi; + /** Maximum score that a network can have before bonuses */ + public int initialScoreMax; + /** + * Only report when there is a network's score this much higher + * than the current connection. + */ + public int currentConnectionBonus; + /** score bonus for all networks with the same network flag */ + public int sameNetworkBonus; + /** score bonus for networks that are not open */ + public int secureBonus; + /** 5GHz RSSI score bonus (applied to all 5GHz networks) */ + public int band5GHzBonus; + /** Pno Network filter list */ + public PnoNetwork[] networkList; + + /** Implement the Parcelable interface {@hide} */ + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface {@hide} */ + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(isConnected ? 1 : 0); + dest.writeInt(min5GHzRssi); + dest.writeInt(min24GHzRssi); + dest.writeInt(initialScoreMax); + dest.writeInt(currentConnectionBonus); + dest.writeInt(sameNetworkBonus); + dest.writeInt(secureBonus); + dest.writeInt(band5GHzBonus); + if (networkList != null) { + dest.writeInt(networkList.length); + for (int i = 0; i < networkList.length; i++) { + dest.writeString(networkList[i].ssid); + dest.writeInt(networkList[i].networkId); + dest.writeInt(networkList[i].priority); + dest.writeByte(networkList[i].flags); + dest.writeByte(networkList[i].authBitField); + } + } else { + dest.writeInt(0); + } + } + + /** Implement the Parcelable interface {@hide} */ + public static final Creator<PnoSettings> CREATOR = + new Creator<PnoSettings>() { + public PnoSettings createFromParcel(Parcel in) { + PnoSettings settings = new PnoSettings(); + settings.isConnected = in.readInt() == 1; + settings.min5GHzRssi = in.readInt(); + settings.min24GHzRssi = in.readInt(); + settings.initialScoreMax = in.readInt(); + settings.currentConnectionBonus = in.readInt(); + settings.sameNetworkBonus = in.readInt(); + settings.secureBonus = in.readInt(); + settings.band5GHzBonus = in.readInt(); + int numNetworks = in.readInt(); + settings.networkList = new PnoNetwork[numNetworks]; + for (int i = 0; i < numNetworks; i++) { + String ssid = in.readString(); + PnoNetwork network = new PnoNetwork(ssid); + network.networkId = in.readInt(); + network.priority = in.readInt(); + network.flags = in.readByte(); + network.authBitField = in.readByte(); + settings.networkList[i] = network; + } + return settings; + } + + public PnoSettings[] newArray(int size) { + return new PnoSettings[size]; + } + }; + + } + /** * interface to get scan events on; specify this on {@link #startBackgroundScan} or * {@link #startScan} @@ -456,6 +615,18 @@ public class WifiScanner { public void onFullResult(ScanResult fullScanResult); } + /** + * interface to get PNO scan events on; specify this on {@link #startDisconnectedPnoScan} and + * {@link #startConnectedPnoScan}. + * {@hide} + */ + public interface PnoScanListener extends ScanListener { + /** + * Invoked when one of the PNO networks are found in scan results. + */ + void onPnoNetworkFound(ScanResult[] results); + } + /** start wifi scan in background * @param settings specifies various parameters for the scan; for more information look at * {@link ScanSettings} @@ -521,6 +692,75 @@ public class WifiScanner { sAsyncChannel.sendMessage(CMD_STOP_SINGLE_SCAN, 0, key); } + private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) { + // Bundle up both the settings and send it across. + Bundle pnoParams = new Bundle(); + if (pnoParams == null) return; + // Set the PNO scan flag. + scanSettings.isPnoScan = true; + pnoParams.putParcelable(PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings); + pnoParams.putParcelable(PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings); + sAsyncChannel.sendMessage(CMD_START_PNO_SCAN, 0, key, pnoParams); + } + /** + * Start wifi connected PNO scan + * @param scanSettings specifies various parameters for the scan; for more information look at + * {@link ScanSettings} + * @param pnoSettings specifies various parameters for PNO; for more information look at + * {@link PnoSettings} + * @param listener specifies the object to report events to. This object is also treated as a + * key for this scan, and must also be specified to cancel the scan. Multiple + * scans should also not share this object. + * {@hide} + */ + public void startConnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, + PnoScanListener listener) { + Preconditions.checkNotNull(listener, "listener cannot be null"); + Preconditions.checkNotNull(pnoSettings, "pnoSettings cannot be null"); + int key = addListener(listener); + if (key == INVALID_KEY) return; + validateChannel(); + pnoSettings.isConnected = true; + startPnoScan(scanSettings, pnoSettings, key); + } + /** + * Start wifi disconnected PNO scan + * @param scanSettings specifies various parameters for the scan; for more information look at + * {@link ScanSettings} + * @param pnoSettings specifies various parameters for PNO; for more information look at + * {@link PnoSettings} + * @param listener specifies the object to report events to. This object is also treated as a + * key for this scan, and must also be specified to cancel the scan. Multiple + * scans should also not share this object. + * {@hide} + */ + public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, + PnoScanListener listener) { + Preconditions.checkNotNull(listener, "listener cannot be null"); + Preconditions.checkNotNull(pnoSettings, "pnoSettings cannot be null"); + int key = addListener(listener); + if (key == INVALID_KEY) return; + validateChannel(); + pnoSettings.isConnected = false; + startPnoScan(scanSettings, pnoSettings, key); + } + /** + * Stop an ongoing wifi PNO scan + * @param pnoSettings specifies various parameters for PNO; for more information look at + * {@link PnoSettings} + * @param listener specifies which scan to cancel; must be same object as passed in {@link + * #startPnoScan} + * TODO(rpius): Check if we can remove pnoSettings param in stop. + * {@hide} + */ + public void stopPnoScan(PnoSettings pnoSettings, ScanListener listener) { + Preconditions.checkNotNull(listener, "listener cannot be null"); + int key = removeListener(listener); + if (key == INVALID_KEY) return; + validateChannel(); + sAsyncChannel.sendMessage(CMD_STOP_PNO_SCAN, 0, key, pnoSettings); + } + /** specifies information about an access point of interest */ public static class BssidInfo { /** bssid of the access point; in XX:XX:XX:XX:XX:XX format */ @@ -824,6 +1064,12 @@ public class WifiScanner { public static final int CMD_STOP_SINGLE_SCAN = BASE + 22; /** @hide */ public static final int CMD_SINGLE_SCAN_COMPLETED = BASE + 23; + /** @hide */ + public static final int CMD_START_PNO_SCAN = BASE + 24; + /** @hide */ + public static final int CMD_STOP_PNO_SCAN = BASE + 25; + /** @hide */ + public static final int CMD_PNO_NETWORK_FOUND = BASE + 26; private Context mContext; private IWifiScanner mService; @@ -1110,6 +1356,10 @@ public class WifiScanner { if (DBG) Log.d(TAG, "removing listener for single scan"); removeListener(msg.arg2); break; + case CMD_PNO_NETWORK_FOUND: + ((PnoScanListener) listener).onPnoNetworkFound( + ((ParcelableScanResults) msg.obj).getResults()); + return; default: if (DBG) Log.d(TAG, "Ignoring message " + msg.what); return; |