summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt18
-rw-r--r--core/java/android/hardware/display/DeviceProductInfo.java99
-rw-r--r--core/java/android/view/Display.java13
-rw-r--r--core/jni/android_view_SurfaceControl.cpp23
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp31
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.h17
-rw-r--r--media/java/android/media/AudioManager.java71
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl4
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values/dimens.xml13
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java18
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java18
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java86
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java10
-rw-r--r--services/core/java/com/android/server/audio/SoundEffectsHelper.java30
32 files changed, 430 insertions, 228 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 71aeff59402f..4382b3207e1e 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -18537,6 +18537,23 @@ package android.hardware.camera2.params {
package android.hardware.display {
+ public final class DeviceProductInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getConnectionToSinkType();
+ method public int getManufactureWeek();
+ method public int getManufactureYear();
+ method @NonNull public String getManufacturerPnpId();
+ method public int getModelYear();
+ method @Nullable public String getName();
+ method @NonNull public String getProductId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CONNECTION_TO_SINK_BUILT_IN = 1; // 0x1
+ field public static final int CONNECTION_TO_SINK_DIRECT = 2; // 0x2
+ field public static final int CONNECTION_TO_SINK_TRANSITIVE = 3; // 0x3
+ field public static final int CONNECTION_TO_SINK_UNKNOWN = 0; // 0x0
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.DeviceProductInfo> CREATOR;
+ }
+
public final class DisplayManager {
method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface, int);
method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface, int, @Nullable android.hardware.display.VirtualDisplay.Callback, @Nullable android.os.Handler);
@@ -46613,6 +46630,7 @@ package android.view {
method public long getAppVsyncOffsetNanos();
method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method @Nullable public android.view.DisplayCutout getCutout();
+ method @Nullable public android.hardware.display.DeviceProductInfo getDeviceProductInfo();
method public int getDisplayId();
method public int getFlags();
method public android.view.Display.HdrCapabilities getHdrCapabilities();
diff --git a/core/java/android/hardware/display/DeviceProductInfo.java b/core/java/android/hardware/display/DeviceProductInfo.java
index 41126b70c89f..9457d8f1aac4 100644
--- a/core/java/android/hardware/display/DeviceProductInfo.java
+++ b/core/java/android/hardware/display/DeviceProductInfo.java
@@ -16,40 +16,69 @@
package android.hardware.display;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.Arrays;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Product-specific information about the display or the directly connected device on the
* display chain. For example, if the display is transitively connected, this field may contain
* product information about the intermediate device.
- * @hide
*/
public final class DeviceProductInfo implements Parcelable {
+ /** @hide */
+ @IntDef(prefix = {"CONNECTION_TO_SINK_"}, value = {
+ CONNECTION_TO_SINK_UNKNOWN,
+ CONNECTION_TO_SINK_BUILT_IN,
+ CONNECTION_TO_SINK_DIRECT,
+ CONNECTION_TO_SINK_TRANSITIVE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ConnectionToSinkType { }
+
+ /** The device connection to the display sink is unknown. */
+ public static final int CONNECTION_TO_SINK_UNKNOWN =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_UNKNOWN;
+
+ /** The display sink is built-in to the device */
+ public static final int CONNECTION_TO_SINK_BUILT_IN =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_BUILT_IN;
+
+ /** The device is directly connected to the display sink. */
+ public static final int CONNECTION_TO_SINK_DIRECT =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_DIRECT;
+
+ /** The device is transitively connected to the display sink. */
+ public static final int CONNECTION_TO_SINK_TRANSITIVE =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_TRANSITIVE;
+
private final String mName;
private final String mManufacturerPnpId;
private final String mProductId;
private final Integer mModelYear;
private final ManufactureDate mManufactureDate;
- private final int[] mRelativeAddress;
+ private final @ConnectionToSinkType int mConnectionToSinkType;
+ /** @hide */
public DeviceProductInfo(
String name,
String manufacturerPnpId,
String productId,
Integer modelYear,
ManufactureDate manufactureDate,
- int[] relativeAddress) {
+ int connectionToSinkType) {
this.mName = name;
this.mManufacturerPnpId = manufacturerPnpId;
this.mProductId = productId;
this.mModelYear = modelYear;
this.mManufactureDate = manufactureDate;
- this.mRelativeAddress = relativeAddress;
+ this.mConnectionToSinkType = connectionToSinkType;
}
private DeviceProductInfo(Parcel in) {
@@ -58,12 +87,13 @@ public final class DeviceProductInfo implements Parcelable {
mProductId = (String) in.readValue(null);
mModelYear = (Integer) in.readValue(null);
mManufactureDate = (ManufactureDate) in.readValue(null);
- mRelativeAddress = in.createIntArray();
+ mConnectionToSinkType = in.readInt();
}
/**
* @return Display name.
*/
+ @Nullable
public String getName() {
return mName;
}
@@ -71,6 +101,7 @@ public final class DeviceProductInfo implements Parcelable {
/**
* @return Manufacturer Plug and Play ID.
*/
+ @NonNull
public String getManufacturerPnpId() {
return mManufacturerPnpId;
}
@@ -78,32 +109,58 @@ public final class DeviceProductInfo implements Parcelable {
/**
* @return Manufacturer product ID.
*/
+ @NonNull
public String getProductId() {
return mProductId;
}
/**
- * @return Model year of the device. Typically exactly one of model year or
- * manufacture date will be present.
+ * @return Model year of the device. Return -1 if not available. Typically,
+ * one of model year or manufacture year is available.
*/
- public Integer getModelYear() {
- return mModelYear;
+ public int getModelYear() {
+ return mModelYear != null ? mModelYear : -1;
+ }
+
+ /**
+ * @return The year of manufacture, or -1 it is not available. Typically,
+ * one of model year or manufacture year is available.
+ */
+ public int getManufactureYear() {
+ if (mManufactureDate == null) {
+ return -1;
+ }
+ return mManufactureDate.mYear != null ? mManufactureDate.mYear : -1;
+ }
+
+ /**
+ * @return The week of manufacture, or -1 it is not available. Typically,
+ * not present if model year is available.
+ */
+ public int getManufactureWeek() {
+ if (mManufactureDate == null) {
+ return -1;
+ }
+ return mManufactureDate.mWeek != null ? mManufactureDate.mWeek : -1;
}
/**
* @return Manufacture date. Typically exactly one of model year or manufacture
* date will be present.
+ *
+ * @hide
*/
public ManufactureDate getManufactureDate() {
return mManufactureDate;
}
/**
- * @return Relative address in the display network. For example, for HDMI connected devices this
- * can be its physical address. Each component of the address is in the range [0, 255].
+ * @return How the current device is connected to the display sink. For example, the display
+ * can be connected immediately to the device or there can be a receiver in between.
*/
- public int[] getRelativeAddress() {
- return mRelativeAddress;
+ @ConnectionToSinkType
+ public int getConnectionToSinkType() {
+ return mConnectionToSinkType;
}
@Override
@@ -119,8 +176,8 @@ public final class DeviceProductInfo implements Parcelable {
+ mModelYear
+ ", manufactureDate="
+ mManufactureDate
- + ", relativeAddress="
- + Arrays.toString(mRelativeAddress)
+ + ", connectionToSinkType="
+ + mConnectionToSinkType
+ '}';
}
@@ -134,16 +191,16 @@ public final class DeviceProductInfo implements Parcelable {
&& Objects.equals(mProductId, that.mProductId)
&& Objects.equals(mModelYear, that.mModelYear)
&& Objects.equals(mManufactureDate, that.mManufactureDate)
- && Arrays.equals(mRelativeAddress, that.mRelativeAddress);
+ && mConnectionToSinkType == that.mConnectionToSinkType;
}
@Override
public int hashCode() {
return Objects.hash(mName, mManufacturerPnpId, mProductId, mModelYear, mManufactureDate,
- Arrays.hashCode(mRelativeAddress));
+ mConnectionToSinkType);
}
- public static final Creator<DeviceProductInfo> CREATOR =
+ @NonNull public static final Creator<DeviceProductInfo> CREATOR =
new Creator<DeviceProductInfo>() {
@Override
public DeviceProductInfo createFromParcel(Parcel in) {
@@ -162,13 +219,13 @@ public final class DeviceProductInfo implements Parcelable {
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mName);
dest.writeString(mManufacturerPnpId);
dest.writeValue(mProductId);
dest.writeValue(mModelYear);
dest.writeValue(mManufactureDate);
- dest.writeIntArray(mRelativeAddress);
+ dest.writeInt(mConnectionToSinkType);
}
/**
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0ba1dfee16f3..8117c963b959 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -34,6 +34,7 @@ import android.graphics.ColorSpace;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.display.DeviceProductInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Build;
@@ -1181,6 +1182,18 @@ public final class Display {
}
/**
+ * Returns the product-specific information about the display or the directly connected
+ * device on the display chain.
+ * For example, if the display is transitively connected, this field may contain product
+ * information about the intermediate device.
+ * Returns {@code null} if product information is not available.
+ */
+ @Nullable
+ public DeviceProductInfo getDeviceProductInfo() {
+ return mDisplayInfo.deviceProductInfo;
+ }
+
+ /**
* Gets display metrics that describe the size and density of this display.
* The size returned by this method does not necessarily represent the
* actual raw size (native resolution) of the display.
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 7a3366acce27..961d4cb23679 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -27,6 +27,7 @@
#include <android-base/chrono_utils.h>
#include <android/graphics/region.h>
#include <android/gui/BnScreenCaptureListener.h>
+#include <android/hardware/display/IDeviceProductInfoConstants.h>
#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
@@ -999,16 +1000,24 @@ static jobject convertDeviceProductInfoToJavaObject(
} else {
LOG_FATAL("Unknown alternative for variant DeviceProductInfo::ManufactureOrModelDate");
}
- auto relativeAddress = env->NewIntArray(info->relativeAddress.size());
- auto relativeAddressData = env->GetIntArrayElements(relativeAddress, nullptr);
- for (int i = 0; i < info->relativeAddress.size(); i++) {
- relativeAddressData[i] = info->relativeAddress[i];
+ jint connectionToSinkType;
+ // Relative address maps to HDMI physical address. All addresses are 4 digits long allowing
+ // for a 5–device-deep hierarchy. For more information, refer:
+ // Section 8.7 - Physical Address of HDMI Specification Version 1.3a
+ using android::hardware::display::IDeviceProductInfoConstants;
+ if (info->relativeAddress.size() != 4) {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_UNKNOWN;
+ } else if (info->relativeAddress[0] == 0) {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_BUILT_IN;
+ } else if (info->relativeAddress[1] == 0) {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_DIRECT;
+ } else {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_TRANSITIVE;
}
- env->ReleaseIntArrayElements(relativeAddress, relativeAddressData, 0);
return env->NewObject(gDeviceProductInfoClassInfo.clazz, gDeviceProductInfoClassInfo.ctor, name,
manufacturerPnpId, productId, modelYear, manufactureDate,
- relativeAddress);
+ connectionToSinkType);
}
static jobject nativeGetDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) {
@@ -1948,7 +1957,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
"Ljava/lang/String;"
"Ljava/lang/Integer;"
"Landroid/hardware/display/DeviceProductInfo$ManufactureDate;"
- "[I)V");
+ "I)V");
jclass deviceProductInfoManufactureDateClazz =
FindClassOrDie(env, "android/hardware/display/DeviceProductInfo$ManufactureDate");
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index b2884023a83d..04e3a1cb887e 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -194,25 +194,6 @@ SkiaCanvas::PaintCoW&& SkiaRecordingCanvas::filterBitmap(PaintCoW&& paint) {
return filterPaint(std::move(paint));
}
-static BlurDrawLooper* get_looper(const Paint* paint) {
- return paint ? paint->getLooper() : nullptr;
-}
-
-template <typename Proc>
-void applyLooper(BlurDrawLooper* looper, const SkPaint* paint, Proc proc) {
- if (looper) {
- SkPaint p;
- if (paint) {
- p = *paint;
- }
- looper->apply(p, [&](SkPoint offset, const SkPaint& modifiedPaint) {
- proc(offset.fX, offset.fY, &modifiedPaint);
- });
- } else {
- proc(0, 0, paint);
- }
-}
-
static SkFilterMode Paint_to_filter(const SkPaint* paint) {
return paint && paint->getFilterQuality() != kNone_SkFilterQuality ? SkFilterMode::kLinear
: SkFilterMode::kNearest;
@@ -226,8 +207,7 @@ static SkSamplingOptions Paint_to_sampling(const SkPaint* paint) {
void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) {
sk_sp<SkImage> image = bitmap.makeImage();
- applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
- const SkPaint* p) {
+ applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) {
mRecorder.drawImage(image, left + x, top + y, Paint_to_sampling(p), p, bitmap.palette());
});
@@ -245,8 +225,7 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, con
sk_sp<SkImage> image = bitmap.makeImage();
- applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
- const SkPaint* p) {
+ applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) {
mRecorder.drawImage(image, x, y, Paint_to_sampling(p), p, bitmap.palette());
});
@@ -263,8 +242,7 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop
sk_sp<SkImage> image = bitmap.makeImage();
- applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
- const SkPaint* p) {
+ applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) {
mRecorder.drawImageRect(image, srcRect, dstRect.makeOffset(x, y), Paint_to_sampling(p),
p, SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
});
@@ -303,8 +281,7 @@ void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& ch
// HWUI always draws 9-patches with linear filtering, regardless of the Paint.
const SkFilterMode filter = SkFilterMode::kLinear;
- applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
- const SkPaint* p) {
+ applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) {
mRecorder.drawImageLattice(image, lattice, dst.makeOffset(x, y), filter, p,
bitmap.palette());
});
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 8d7a21a732dd..1e404b845084 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -87,6 +87,23 @@ private:
std::unique_ptr<SkiaDisplayList> mDisplayList;
StartReorderBarrierDrawable* mCurrentBarrier;
+ template <typename Proc>
+ void applyLooper(const Paint* paint, Proc proc) {
+ SkPaint skp;
+ BlurDrawLooper* looper = nullptr;
+ if (paint) {
+ skp = *filterBitmap(paint);
+ looper = paint->getLooper();
+ }
+ if (looper) {
+ looper->apply(skp, [&](SkPoint offset, const SkPaint& modifiedPaint) {
+ proc(offset.fX, offset.fY, &modifiedPaint);
+ });
+ } else {
+ proc(0, 0, &skp);
+ }
+ }
+
/**
* A new SkiaDisplayList is created or recycled if available.
*
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d896c1fc82b5..f87f90d8e0a2 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3123,52 +3123,57 @@ public class AudioManager {
/**
* @hide Home sound
- * Played by the framework when the home app becomes active if config_enableHomeSound is set to
- * true. This is currently only used on TV devices.
+ * <p>
+ * To be played by the framework when the home app becomes active if config_enableHomeSound is
+ * set to true. This is currently only used on TV devices.
* Note that this sound is only available if a sound file is specified in audio_assets.xml.
* @see #playSoundEffect(int)
*/
public static final int FX_HOME = 11;
/**
- * @hide Fast scroll sound 1
- * To be by the framework when a fast-scrolling is performed and
- * {@link #areFastScrollSoundEffectsEnabled()} is true.
+ * @hide Navigation repeat sound 1
+ * <p>
+ * To be played by the framework when a focus navigation is repeatedly triggered
+ * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
* This is currently only used on TV devices.
* Note that this sound is only available if a sound file is specified in audio_assets.xml
* @see #playSoundEffect(int)
*/
- public static final int FX_FAST_SCROLL_1 = 12;
+ public static final int FX_FOCUS_NAVIGATION_REPEAT_1 = 12;
/**
- * @hide Fast scroll sound 2
- * To be by the framework when a fast-scrolling is performed and
- * {@link #areFastScrollSoundEffectsEnabled()} is true.
+ * @hide Navigation repeat sound 2
+ * <p>
+ * To be played by the framework when a focus navigation is repeatedly triggered
+ * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
* This is currently only used on TV devices.
* Note that this sound is only available if a sound file is specified in audio_assets.xml
* @see #playSoundEffect(int)
*/
- public static final int FX_FAST_SCROLL_2 = 13;
+ public static final int FX_FOCUS_NAVIGATION_REPEAT_2 = 13;
/**
- * @hide Fast scroll sound 3
- * To be by the framework when a fast-scrolling is performed and
- * {@link #areFastScrollSoundEffectsEnabled()} is true.
+ * @hide Navigation repeat sound 3
+ * <p>
+ * To be played by the framework when a focus navigation is repeatedly triggered
+ * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
* This is currently only used on TV devices.
* Note that this sound is only available if a sound file is specified in audio_assets.xml
* @see #playSoundEffect(int)
*/
- public static final int FX_FAST_SCROLL_3 = 14;
+ public static final int FX_FOCUS_NAVIGATION_REPEAT_3 = 14;
/**
- * @hide Fast scroll sound 4
- * To be by the framework when a fast-scrolling is performed and
- * {@link #areFastScrollSoundEffectsEnabled()} is true.
+ * @hide Navigation repeat sound 4
+ * <p>
+ * To be played by the framework when a focus navigation is repeatedly triggered
+ * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
* This is currently only used on TV devices.
* Note that this sound is only available if a sound file is specified in audio_assets.xml
* @see #playSoundEffect(int)
*/
- public static final int FX_FAST_SCROLL_4 = 15;
+ public static final int FX_FOCUS_NAVIGATION_REPEAT_4 = 15;
/**
* @hide Number of sound effects
@@ -3177,27 +3182,27 @@ public class AudioManager {
public static final int NUM_SOUND_EFFECTS = 16;
/**
- * @hide Number of fast scroll sound effects
+ * @hide Number of FX_FOCUS_NAVIGATION_REPEAT_* sound effects
*/
- public static final int NUM_FAST_SCROLL_SOUND_EFFECTS = 4;
+ public static final int NUM_NAVIGATION_REPEAT_SOUND_EFFECTS = 4;
/**
* @hide
- * @param n a value in [0, {@link #NUM_FAST_SCROLL_SOUND_EFFECTS}[
- * @return The id of a fast scroll sound effect or -1 if out of bounds
+ * @param n a value in [0, {@link #NUM_NAVIGATION_REPEAT_SOUND_EFFECTS}[
+ * @return The id of a navigation repeat sound effect or -1 if out of bounds
*/
- public static int getNthFastScrollSoundEffectId(int n) {
+ public static int getNthNavigationRepeatSoundEffect(int n) {
switch (n) {
case 0:
- return FX_FAST_SCROLL_1;
+ return FX_FOCUS_NAVIGATION_REPEAT_1;
case 1:
- return FX_FAST_SCROLL_2;
+ return FX_FOCUS_NAVIGATION_REPEAT_2;
case 2:
- return FX_FAST_SCROLL_3;
+ return FX_FOCUS_NAVIGATION_REPEAT_3;
case 3:
- return FX_FAST_SCROLL_4;
+ return FX_FOCUS_NAVIGATION_REPEAT_4;
default:
- Log.w(TAG, "Invalid fast-scroll sound effect id: " + n);
+ Log.w(TAG, "Invalid navigation repeat sound effect id: " + n);
return -1;
}
}
@@ -3205,9 +3210,9 @@ public class AudioManager {
/**
* @hide
*/
- public void setFastScrollSoundEffectsEnabled(boolean enabled) {
+ public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
try {
- getService().setFastScrollSoundEffectsEnabled(enabled);
+ getService().setNavigationRepeatSoundEffectsEnabled(enabled);
} catch (RemoteException e) {
}
@@ -3215,11 +3220,11 @@ public class AudioManager {
/**
* @hide
- * @return true if the fast scroll sound effects are enabled
+ * @return true if the navigation repeat sound effects are enabled
*/
- public boolean areFastScrollSoundEffectsEnabled() {
+ public boolean areNavigationRepeatSoundEffectsEnabled() {
try {
- return getService().areFastScrollSoundEffectsEnabled();
+ return getService().areNavigationRepeatSoundEffectsEnabled();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 71ee57e3d471..0073b5cc93b9 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -351,9 +351,9 @@ interface IAudioService {
oneway void unregisterCommunicationDeviceDispatcher(
ICommunicationDeviceDispatcher dispatcher);
- boolean areFastScrollSoundEffectsEnabled();
+ boolean areNavigationRepeatSoundEffectsEnabled();
- oneway void setFastScrollSoundEffectsEnabled(boolean enabled);
+ oneway void setNavigationRepeatSoundEffectsEnabled(boolean enabled);
boolean isHomeSoundEffectEnabled();
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index f3ec39d2b1fb..b6a41c20a607 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -64,7 +64,7 @@
android:id="@+id/new_lockscreen_clock_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
+ android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="gone">
<com.android.keyguard.AnimatableClockView
@@ -73,7 +73,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
- android:textSize="100dp"
+ android:textSize="60dp"
android:fontFamily="@font/clock"
android:typeface="monospace"
android:elegantTextHeight="false"
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 2a5784a1e6e9..115a156b65e7 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -47,26 +47,25 @@
<dimen name="eca_overlap">-10dip</dimen>
<!-- Slice header -->
- <dimen name="widget_title_font_size">24dp</dimen>
- <dimen name="header_subtitle_padding">12dp</dimen>
+ <dimen name="widget_title_font_size">20dp</dimen>
+ <dimen name="widget_title_line_height">24dp</dimen>
<dimen name="header_icon_size">16dp</dimen>
<!-- Slice subtitle -->
- <dimen name="widget_label_font_size">18dp</dimen>
+ <dimen name="widget_label_font_size">16dp</dimen>
+ <dimen name="widget_label_line_height">20dp</dimen>
<!-- Clock without header -->
<dimen name="widget_big_font_size">54dp</dimen>
<dimen name="bottom_text_spacing_digital">0dp</dimen>
<dimen name="title_clock_padding">4dp</dimen>
<!-- Clock with header -->
<dimen name="widget_small_font_size">@dimen/widget_title_font_size</dimen>
- <dimen name="widget_vertical_padding">17dp</dimen>
+ <dimen name="widget_vertical_padding">5dp</dimen>
<dimen name="widget_vertical_padding_with_header">25dp</dimen>
<dimen name="widget_vertical_padding_clock">12dp</dimen>
<!-- Subtitle paddings -->
<dimen name="widget_horizontal_padding">8dp</dimen>
- <dimen name="widget_icon_size">20dp</dimen>
+ <dimen name="widget_icon_size">18dp</dimen>
<dimen name="widget_icon_padding">8dp</dimen>
- <dimen name="subtitle_clock_padding">0dp</dimen>
- <dimen name="header_row_font_size">14dp</dimen>
<!-- Notification shelf padding when dark -->
<dimen name="widget_bottom_separator_padding">-6dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 2391803957e5..8f42cbe31646 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -120,6 +120,7 @@
<style name="TextAppearance.Keyguard">
<item name="android:textSize">@dimen/widget_title_font_size</item>
+ <item name="android:lineHeight">@dimen/widget_title_line_height</item>
<item name="android:gravity">center</item>
<item name="android:ellipsize">end</item>
<item name="android:maxLines">2</item>
@@ -133,6 +134,7 @@
<item name="android:layout_height">wrap_content</item>
<item name="android:lines">1</item>
<item name="android:textSize">@dimen/widget_label_font_size</item>
+ <item name="android:lineHeight">@dimen/widget_label_line_height</item>
</style>
<style name="TextAppearance.Keyguard.BottomArea">
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index 0a117c17a354..1569fff63453 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -21,9 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
-import android.graphics.Paint;
import android.icu.text.NumberFormat;
-import android.util.MathUtils;
import com.android.settingslib.Utils;
import com.android.systemui.R;
@@ -94,11 +92,6 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
mStatusBarStateController.removeCallback(mStatusBarStateListener);
}
- float getClockTextTopPadding() {
- Paint.FontMetrics fm = mView.getPaint().getFontMetrics();
- return MathUtils.abs(fm.ascent - fm.top);
- }
-
/**
* Updates the time for the view.
*/
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 6eb54c25a440..93ed0eaa3fba 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -179,20 +179,15 @@ public class KeyguardClockSwitch extends RelativeLayout {
setPaddingRelative(startEndPadding, 0, startEndPadding, 0);
mSmallClockFrame.setVisibility(GONE);
mNewLockscreenClockFrame.setVisibility(VISIBLE);
-
- statusAreaLP.removeRule(RelativeLayout.BELOW);
+ statusAreaLP.addRule(RelativeLayout.BELOW, R.id.new_lockscreen_clock_view);
statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);
- statusAreaLP.addRule(RelativeLayout.START_OF, R.id.new_lockscreen_clock_view);
- statusAreaLP.width = 0;
} else {
setPaddingRelative(0, 0, 0, 0);
mSmallClockFrame.setVisibility(VISIBLE);
mNewLockscreenClockFrame.setVisibility(GONE);
statusAreaLP.removeRule(RelativeLayout.ALIGN_PARENT_START);
- statusAreaLP.removeRule(RelativeLayout.START_OF);
statusAreaLP.addRule(RelativeLayout.BELOW, R.id.clock_view);
- statusAreaLP.width = ViewGroup.LayoutParams.MATCH_PARENT;
}
requestLayout();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index e375877ed6cf..0675200f81e2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -20,6 +20,7 @@ import android.app.WallpaperManager;
import android.content.ContentResolver;
import android.content.res.Resources;
import android.provider.Settings;
+import android.text.TextUtils;
import android.text.format.DateFormat;
import android.view.View;
import android.view.ViewGroup;
@@ -212,10 +213,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
* keep the clock centered.
*/
void updatePosition(int x, float scale, AnimationProperties props, boolean animate) {
- x = Math.abs(x);
+ x = getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -x : x;
if (mNewLockScreenClockFrame != null) {
PropertyAnimator.setProperty(mNewLockScreenClockFrame, AnimatableProperty.TRANSLATION_X,
- -x, props, animate);
+ x, props, animate);
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_X,
scale, props, animate);
PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_Y,
@@ -277,15 +278,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
refreshFormat(mTimeFormat);
}
- float getClockTextTopPadding() {
- if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1
- && mNewLockScreenClockViewController != null) {
- return mNewLockScreenClockViewController.getClockTextTopPadding();
- }
-
- return mView.getClockTextTopPadding();
- }
-
private void updateAodIcons() {
NotificationIconContainer nic = (NotificationIconContainer)
mView.findViewById(
@@ -337,4 +329,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
sCacheKey = key;
}
}
+
+ private int getCurrentLayoutDirection() {
+ return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault());
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index fb97a30f93fb..2373d75cd4ea 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -85,10 +85,6 @@ public class KeyguardSliceView extends LinearLayout {
*/
private Runnable mContentChangeListener;
private boolean mHasHeader;
- private final int mRowWithHeaderPadding;
- private final int mRowPadding;
- private float mRowTextSize;
- private float mRowWithHeaderTextSize;
private View.OnClickListener mOnClickListener;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
@@ -97,9 +93,6 @@ public class KeyguardSliceView extends LinearLayout {
super(context, attrs);
Resources resources = context.getResources();
- mRowPadding = resources.getDimensionPixelSize(R.dimen.subtitle_clock_padding);
- mRowWithHeaderPadding = resources.getDimensionPixelSize(R.dimen.header_subtitle_padding);
-
mLayoutTransition = new LayoutTransition();
mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION / 2);
mLayoutTransition.setDuration(LayoutTransition.APPEARING, DEFAULT_ANIM_DURATION);
@@ -120,10 +113,6 @@ public class KeyguardSliceView extends LinearLayout {
mTextColor = Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor);
mIconSize = (int) mContext.getResources().getDimension(R.dimen.widget_icon_size);
mIconSizeWithHeader = (int) mContext.getResources().getDimension(R.dimen.header_icon_size);
- mRowTextSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.widget_label_font_size);
- mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.header_row_font_size);
mTitle.setBreakStrategy(LineBreaker.BREAK_STRATEGY_BALANCED);
}
@@ -204,7 +193,6 @@ public class KeyguardSliceView extends LinearLayout {
LinearLayout.LayoutParams layoutParams = (LayoutParams) mRow.getLayoutParams();
layoutParams.gravity = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL
? Gravity.START : Gravity.CENTER;
- layoutParams.topMargin = mHasHeader ? mRowWithHeaderPadding : mRowPadding;
mRow.setLayoutParams(layoutParams);
for (int i = startIndex; i < subItemsCount; i++) {
@@ -230,8 +218,6 @@ public class KeyguardSliceView extends LinearLayout {
final SliceItem titleItem = rc.getTitleItem();
button.setText(titleItem == null ? null : titleItem.getText());
button.setContentDescription(rc.getContentDescription());
- button.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- mHasHeader ? mRowWithHeaderTextSize : mRowTextSize);
Drawable iconDrawable = null;
SliceItem icon = SliceQuery.find(item.getSlice(),
@@ -313,10 +299,6 @@ public class KeyguardSliceView extends LinearLayout {
void onDensityOrFontScaleChanged() {
mIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.widget_icon_size);
mIconSizeWithHeader = (int) mContext.getResources().getDimension(R.dimen.header_icon_size);
- mRowTextSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.widget_label_font_size);
- mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.header_row_font_size);
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 6fb6760be653..934e768f9ba8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -266,15 +266,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardClockSwitchController.updateLockScreenMode(mode);
mKeyguardSliceViewController.updateLockScreenMode(mode);
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
- // align the top of keyguard_status_area with the top of the clock text instead
- // of the top of the view
- mKeyguardSliceViewController.updateTopMargin(
- mKeyguardClockSwitchController.getClockTextTopPadding());
mView.setCanShowOwnerInfo(false);
mView.setCanShowLogout(false);
} else {
- // reset margin
- mKeyguardSliceViewController.updateTopMargin(0);
mView.setCanShowOwnerInfo(true);
mView.setCanShowLogout(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
index 3ea8140427cb..3bf75d105b9f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
@@ -19,8 +19,10 @@ package com.android.systemui.biometrics;
import android.content.Context;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
+import android.view.View;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.systemui.R;
@@ -33,6 +35,7 @@ public abstract class UdfpsAnimation extends Drawable {
@NonNull protected final Context mContext;
@NonNull protected final Drawable mFingerprintDrawable;
+ @Nullable private View mView;
public UdfpsAnimation(@NonNull Context context) {
mContext = context;
@@ -53,6 +56,10 @@ public abstract class UdfpsAnimation extends Drawable {
mFingerprintDrawable.setAlpha(alpha);
}
+ public void setAnimationView(UdfpsAnimationView view) {
+ mView = view;
+ }
+
/**
* @return The amount of padding that's needed on each side of the sensor, in pixels.
*/
@@ -66,4 +73,10 @@ public abstract class UdfpsAnimation extends Drawable {
public int getPaddingY() {
return 0;
}
+
+ protected void postInvalidateView() {
+ if (mView != null) {
+ mView.postInvalidate();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
index 501de9df575b..8664e44c9ad2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
@@ -23,7 +23,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.util.MathUtils;
-import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -42,7 +41,6 @@ public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiv
private static final String TAG = "UdfpsAnimationKeyguard";
- @NonNull private final View mParent;
@NonNull private final Context mContext;
private final int mMaxBurnInOffsetX;
private final int mMaxBurnInOffsetY;
@@ -52,10 +50,9 @@ public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiv
private float mBurnInOffsetX;
private float mBurnInOffsetY;
- UdfpsAnimationKeyguard(@NonNull View parent, @NonNull Context context,
+ UdfpsAnimationKeyguard(@NonNull Context context,
@NonNull StatusBarStateController statusBarStateController) {
super(context);
- mParent = parent;
mContext = context;
mMaxBurnInOffsetX = context.getResources()
@@ -73,10 +70,10 @@ public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiv
mInterpolatedDarkAmount);
mBurnInOffsetY = MathUtils.lerp(0f,
getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
- - 0.5f * mMaxBurnInOffsetY,
+ - mMaxBurnInOffsetY,
mInterpolatedDarkAmount);
updateColor();
- mParent.postInvalidate();
+ postInvalidateView();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
index 41ea4d66f575..44122cba8716 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
@@ -74,7 +74,14 @@ public class UdfpsAnimationView extends View implements DozeReceiver,
}
void setAnimation(@Nullable UdfpsAnimation animation) {
+ if (mUdfpsAnimation != null) {
+ mUdfpsAnimation.setAnimationView(null);
+ }
+
mUdfpsAnimation = animation;
+ if (mUdfpsAnimation != null) {
+ mUdfpsAnimation.setAnimationView(this);
+ }
}
void onSensorRectUpdated(@NonNull RectF sensorRect) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index e7b08e72877d..6451ad9fd5d2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -44,7 +44,6 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -324,7 +323,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
case IUdfpsOverlayController.REASON_ENROLL_ENROLLING:
return new UdfpsAnimationEnroll(mContext);
case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD:
- return new UdfpsAnimationKeyguard(mView, mContext, mStatusBarStateController);
+ return new UdfpsAnimationKeyguard(mContext, mStatusBarStateController);
case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER:
return new UdfpsAnimationFpmOther(mContext);
default:
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 00cb28b8b8fb..6ffecdba883b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -113,6 +113,7 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
void setExtras(@Nullable UdfpsAnimation animation, @Nullable UdfpsEnrollHelper enrollHelper) {
mAnimationView.setAnimation(animation);
+
mEnrollHelper = enrollHelper;
if (enrollHelper != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 8ab135ced97e..4418696bfc9b 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -32,6 +32,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.dagger.DozeScope;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.AlarmTimeout;
@@ -41,12 +42,15 @@ import java.util.Calendar;
import javax.inject.Inject;
+import dagger.Lazy;
+
/**
* The policy controlling doze.
*/
@DozeScope
public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
-
+ // if enabled, calls dozeTimeTick() whenever the time changes:
+ private static final boolean BURN_IN_TESTING_ENABLED = false;
private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
private final Context mContext;
private final DozeHost mHost;
@@ -57,16 +61,28 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
private final boolean mCanAnimateTransition;
private final DozeParameters mDozeParameters;
private final DozeLog mDozeLog;
+ private final Lazy<StatusBarStateController> mStatusBarStateController;
private boolean mKeyguardShowing;
private final KeyguardUpdateMonitorCallback mKeyguardVisibilityCallback =
new KeyguardUpdateMonitorCallback() {
-
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
mKeyguardShowing = showing;
updateAnimateScreenOff();
}
+
+ @Override
+ public void onTimeChanged() {
+ if (BURN_IN_TESTING_ENABLED && mStatusBarStateController != null
+ && mStatusBarStateController.get().isDozing()) {
+ // update whenever the time changes for manual burn in testing
+ mHost.dozeTimeTick();
+
+ // Keep wakelock until a frame has been pushed.
+ mHandler.post(mWakeLock.wrap(() -> {}));
+ }
+ }
};
private long mLastTimeTickElapsed = 0;
@@ -75,7 +91,8 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
public DozeUi(Context context, AlarmManager alarmManager,
WakeLock wakeLock, DozeHost host, @Main Handler handler,
DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor,
- DozeLog dozeLog, TunerService tunerService) {
+ DozeLog dozeLog, TunerService tunerService,
+ Lazy<StatusBarStateController> statusBarStateController) {
mContext = context;
mWakeLock = wakeLock;
mHost = host;
@@ -85,8 +102,8 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
mDozeLog = dozeLog;
-
tunerService.addTunable(this, Settings.Secure.DOZE_ALWAYS_ON);
+ mStatusBarStateController = statusBarStateController;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 2c7c5cc91120..76925a7eceee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -21,6 +21,7 @@ import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+import static com.android.systemui.util.Utils.shouldUseSplitNotificationShade;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -83,6 +84,7 @@ import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
@@ -453,6 +455,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private NotificationEntry mTopHeadsUpEntry;
private long mNumHeadsUp;
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
+ private final FeatureFlags mFeatureFlags;
private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
new ExpandableView.OnHeightChangedListener() {
@@ -492,8 +495,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
GroupMembershipManager groupMembershipManager,
GroupExpansionManager groupExpansionManager,
SysuiStatusBarStateController statusbarStateController,
- AmbientState ambientState
- ) {
+ AmbientState ambientState,
+ FeatureFlags featureFlags) {
super(context, attrs, 0, 0);
Resources res = getResources();
mSectionsManager = notificationSectionsManager;
@@ -530,6 +533,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mGroupMembershipManager = groupMembershipManager;
mGroupExpansionManager = groupExpansionManager;
mStatusbarStateController = statusbarStateController;
+ mFeatureFlags = featureFlags;
}
void initializeForegroundServiceSection(ForegroundServiceDungeonView fgsSectionView) {
@@ -1156,8 +1160,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
if (stackStartPosition <= stackEndPosition) {
stackHeight = stackEndPosition;
} else {
- stackHeight = (int) NotificationUtils.interpolate(stackStartPosition,
- stackEndPosition, mQsExpansionFraction);
+ if (shouldUseSplitNotificationShade(mFeatureFlags, getResources())) {
+ // This prevents notifications from being collapsed when QS is expanded.
+ stackHeight = (int) height;
+ } else {
+ stackHeight = (int) NotificationUtils.interpolate(stackStartPosition,
+ stackEndPosition, mQsExpansionFraction);
+ }
}
} else {
stackHeight = (int) height;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 8cdaa63994e4..f4830fbb0028 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -134,7 +134,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mStackScrollerController = stackScrollerController;
mNotificationPanelViewController = notificationPanelViewController;
notificationPanelViewController.addTrackingHeadsUpListener(mSetTrackingHeadsUp);
- notificationPanelViewController.addVerticalTranslationListener(mUpdatePanelTranslation);
+ notificationPanelViewController.setVerticalTranslationListener(mUpdatePanelTranslation);
notificationPanelViewController.setHeadsUpAppearanceController(this);
mStackScrollerController.addOnExpandedHeightChangedListener(mSetExpandedHeight);
mStackScrollerController.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
@@ -171,7 +171,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mHeadsUpStatusBarView.setOnDrawingRectChangedListener(null);
mWakeUpCoordinator.removeListener(this);
mNotificationPanelViewController.removeTrackingHeadsUpListener(mSetTrackingHeadsUp);
- mNotificationPanelViewController.removeVerticalTranslationListener(mUpdatePanelTranslation);
+ mNotificationPanelViewController.setVerticalTranslationListener(null);
mNotificationPanelViewController.setHeadsUpAppearanceController(null);
mStackScrollerController.removeOnExpandedHeightChangedListener(mSetExpandedHeight);
mStackScrollerController.removeOnLayoutChangeListener(mStackScrollLayoutChangeListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index a6daed5a0850..2ce403764c7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -344,8 +344,11 @@ public class KeyguardClockPositionAlgorithm {
}
private float burnInPreventionOffsetX() {
- return getBurnInOffset(mBurnInPreventionOffsetX * 2, true /* xAxis */)
- - mBurnInPreventionOffsetX;
+ if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
+ return getBurnInOffset(mBurnInPreventionOffsetX * 2, true /* xAxis */)
+ - mBurnInPreventionOffsetX;
+ }
+ return getBurnInOffset(mBurnInPreventionOffsetX, true /* xAxis */);
}
public static class Result {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 0b3fd161d865..f4ffb207e665 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -196,7 +196,8 @@ public class NotificationPanelViewController extends PanelViewController {
new MyOnHeadsUpChangedListener();
private final HeightListener mHeightListener = new HeightListener();
private final ConfigurationListener mConfigurationListener = new ConfigurationListener();
- private final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener();
+ @VisibleForTesting final StatusBarStateListener mStatusBarStateListener =
+ new StatusBarStateListener();
private final ExpansionCallback mExpansionCallback = new ExpansionCallback();
private final BiometricUnlockController mBiometricUnlockController;
private final NotificationPanelView mView;
@@ -473,7 +474,7 @@ public class NotificationPanelViewController extends PanelViewController {
private ArrayList<Consumer<ExpandableNotificationRow>>
mTrackingHeadsUpListeners =
new ArrayList<>();
- private ArrayList<Runnable> mVerticalTranslationListener = new ArrayList<>();
+ private Runnable mVerticalTranslationListener;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private int mPanelAlpha;
@@ -1852,7 +1853,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
- private void setQsExpanded(boolean expanded) {
+ @VisibleForTesting void setQsExpanded(boolean expanded) {
boolean changed = mQsExpanded != expanded;
if (changed) {
mQsExpanded = expanded;
@@ -1955,8 +1956,10 @@ public class NotificationPanelViewController extends PanelViewController {
private void updateQsState() {
mNotificationStackScrollLayoutController.setQsExpanded(mQsExpanded);
mNotificationStackScrollLayoutController.setScrollingEnabled(
- mBarState != KEYGUARD && (!mQsExpanded
- || mQsExpansionFromOverscroll));
+ mBarState != KEYGUARD
+ && (!mQsExpanded
+ || mQsExpansionFromOverscroll
+ || Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)));
if (mKeyguardUserSwitcherController != null && mQsExpanded
&& !mStackScrollerOverscrolling) {
@@ -2236,13 +2239,16 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
protected boolean canCollapsePanelOnTouch() {
- if (!isInSettings()) {
- return mBarState == KEYGUARD
- || mIsPanelCollapseOnQQS
- || mNotificationStackScrollLayoutController.isScrolledToBottom();
- } else {
+ if (!isInSettings() && mBarState == KEYGUARD) {
return true;
}
+
+ if (mNotificationStackScrollLayoutController.isScrolledToBottom()) {
+ return true;
+ }
+
+ return !Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)
+ && (isInSettings() || mIsPanelCollapseOnQQS);
}
@Override
@@ -2920,7 +2926,8 @@ public class NotificationPanelViewController extends PanelViewController {
* @param x the x-coordinate the touch event
*/
protected void updateHorizontalPanelPosition(float x) {
- if (mNotificationStackScrollLayoutController.getWidth() * 1.75f > mView.getWidth()) {
+ if (mNotificationStackScrollLayoutController.getWidth() * 1.75f > mView.getWidth()
+ || Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)) {
resetHorizontalPanelPosition();
return;
}
@@ -2948,9 +2955,8 @@ public class NotificationPanelViewController extends PanelViewController {
protected void setHorizontalPanelTranslation(float translation) {
mNotificationStackScrollLayoutController.setTranslationX(translation);
mQsFrame.setTranslationX(translation);
- int size = mVerticalTranslationListener.size();
- for (int i = 0; i < size; i++) {
- mVerticalTranslationListener.get(i).run();
+ if (mVerticalTranslationListener != null) {
+ mVerticalTranslationListener.run();
}
}
@@ -3243,12 +3249,8 @@ public class NotificationPanelViewController extends PanelViewController {
mTrackingHeadsUpListeners.remove(listener);
}
- public void addVerticalTranslationListener(Runnable verticalTranslationListener) {
- mVerticalTranslationListener.add(verticalTranslationListener);
- }
-
- public void removeVerticalTranslationListener(Runnable verticalTranslationListener) {
- mVerticalTranslationListener.remove(verticalTranslationListener);
+ public void setVerticalTranslationListener(Runnable verticalTranslationListener) {
+ mVerticalTranslationListener = verticalTranslationListener;
}
public void setHeadsUpAppearanceController(
@@ -3615,6 +3617,10 @@ public class NotificationPanelViewController extends PanelViewController {
NotificationStackScrollLayout.OnOverscrollTopChangedListener {
@Override
public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
+ // When in split shade, overscroll shouldn't carry through to QS
+ if (Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources)) {
+ return;
+ }
cancelQsAnimation();
if (!mQsExpansionEnabled) {
amount = 0f;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index d60772730dff..afe5c0b2edbd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -41,6 +41,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -74,6 +75,8 @@ public class DozeUiTest extends SysuiTestCase {
private Handler mHandler;
private HandlerThread mHandlerThread;
private DozeUi mDozeUi;
+ @Mock
+ private StatusBarStateController mStatusBarStateController;
@Before
public void setUp() throws Exception {
@@ -85,7 +88,8 @@ public class DozeUiTest extends SysuiTestCase {
mHandler = mHandlerThread.getThreadHandler();
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
- mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService);
+ mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService,
+ () -> mStatusBarStateController);
mDozeUi.setDozeMachine(mMachine);
}
@@ -141,7 +145,8 @@ public class DozeUiTest extends SysuiTestCase {
reset(mHost);
when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
- mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService);
+ mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService,
+ () -> mStatusBarStateController);
mDozeUi.setDozeMachine(mMachine);
// Never animate if display doesn't support it.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 461f64eda6e5..84fb3689b0b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -21,6 +21,8 @@ import static android.provider.Settings.Secure.NOTIFICATION_HISTORY_ENABLED;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
+import static com.google.common.truth.Truth.assertWithMessage;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -49,6 +51,7 @@ import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
@@ -101,6 +104,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Mock private SysuiStatusBarStateController mStatusBarStateController;
@Mock private NotificationSwipeHelper mNotificationSwipeHelper;
@Mock private NotificationStackScrollLayoutController mStackScrollLayoutController;
+ @Mock private FeatureFlags mFeatureFlags;
@Before
@UiThreadTest
@@ -139,8 +143,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mGroupMembershipManger,
mGroupExpansionManager,
mStatusBarStateController,
- mAmbientState
- );
+ mAmbientState,
+ mFeatureFlags);
mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider,
mNotificationSwipeHelper);
mStackScroller = spy(mStackScrollerInternal);
@@ -205,8 +209,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
@UiThreadTest
public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() {
- final float expectedHeight[] = {0f};
- final float expectedAppear[] = {0f};
+ final float[] expectedHeight = {0f};
+ final float[] expectedAppear = {0f};
mStackScroller.addOnExpandedHeightChangedListener((height, appear) -> {
Assert.assertEquals(expectedHeight[0], height, 0);
@@ -222,6 +226,29 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
+ @UiThreadTest
+ public void testSetExpandedHeight_withSplitShade_doesntInterpolateStackHeight() {
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ final int[] expectedStackHeight = {0};
+
+ mStackScroller.addOnExpandedHeightChangedListener((expandedHeight, appear) -> {
+ assertWithMessage("Given shade enabled: %s",
+ mFeatureFlags.isTwoColumnNotificationShadeEnabled())
+ .that(mStackScroller.getHeight())
+ .isEqualTo(expectedStackHeight[0]);
+ });
+
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(false);
+ expectedStackHeight[0] = 0;
+ mStackScroller.setExpandedHeight(100f);
+
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ expectedStackHeight[0] = 100;
+ mStackScroller.setExpandedHeight(100f);
+ }
+
+
+ @Test
public void manageNotifications_visible() {
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 8dea84c4d0b6..6e0cbd9ecfa3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@@ -197,9 +198,9 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
mHeadsUpAppearanceController.destroy();
verify(mHeadsUpManager).removeListener(any());
verify(mDarkIconDispatcher).removeDarkReceiver((DarkIconDispatcher.DarkReceiver) any());
- verify(mPanelView).removeVerticalTranslationListener(any());
+ verify(mPanelView).setVerticalTranslationListener(isNull());
verify(mPanelView).removeTrackingHeadsUpListener(any());
- verify(mPanelView).setHeadsUpAppearanceController(any());
+ verify(mPanelView).setHeadsUpAppearanceController(isNull());
verify(mStackScrollerController).removeOnExpandedHeightChangedListener(any());
verify(mStackScrollerController).removeOnLayoutChangeListener(any());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index e788a1c0954b..8cb898443fd2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -18,13 +18,15 @@ package com.android.systemui.statusbar.phone;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -45,6 +47,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -53,6 +56,7 @@ import androidx.constraintlayout.widget.ConstraintSet;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitch;
@@ -100,7 +104,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
@@ -116,8 +119,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private StatusBar mStatusBar;
@Mock
- private SysuiStatusBarStateController mStatusBarStateController;
- @Mock
private NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock
private KeyguardBottomAreaView mKeyguardBottomArea;
@@ -227,7 +228,10 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private AmbientState mAmbientState;
@Mock
private UserManager mUserManager;
+ @Mock
+ private UiEventLogger mUiEventLogger;
+ private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -235,6 +239,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger);
+
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
when(mView.getResources()).thenReturn(mResources);
@@ -258,6 +264,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
when(mKeyguardBottomArea.getLeftView()).thenReturn(mock(KeyguardAffordanceView.class));
when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class));
+ when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
when(mView.findViewById(R.id.big_clock_container)).thenReturn(mBigClockContainer);
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mView.findViewById(R.id.keyguard_status_view))
@@ -336,17 +343,19 @@ public class NotificationPanelViewTest extends SysuiTestCase {
ArgumentCaptor.forClass(View.AccessibilityDelegate.class);
verify(mView).setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture());
mAccessibiltyDelegate = accessibilityDelegateArgumentCaptor.getValue();
+ mNotificationPanelViewController.mStatusBarStateController
+ .addCallback(mNotificationPanelViewController.mStatusBarStateListener);
+ mNotificationPanelViewController
+ .setHeadsUpAppearanceController(mock(HeadsUpAppearanceController.class));
}
@Test
public void testSetDozing_notifiesNsslAndStateController() {
- mNotificationPanelViewController.setDozing(true /* dozing */, true /* animate */,
+ mNotificationPanelViewController.setDozing(true /* dozing */, false /* animate */,
null /* touch */);
- InOrder inOrder = inOrder(
- mNotificationStackScrollLayoutController, mStatusBarStateController);
- inOrder.verify(mNotificationStackScrollLayoutController)
- .setDozing(eq(true), eq(true), eq(null));
- inOrder.verify(mStatusBarStateController).setDozeAmount(eq(1f), eq(true));
+ verify(mNotificationStackScrollLayoutController)
+ .setDozing(eq(true), eq(false), eq(null));
+ assertThat(mStatusBarStateController.getDozeAmount()).isEqualTo(1f);
}
@Test
@@ -442,9 +451,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Test
public void testAllChildrenOfNotificationContainer_haveIds() {
- when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(true);
- when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
-
+ enableDualPaneShade();
mNotificationContainerParent.addView(newViewWithId(1));
mNotificationContainerParent.addView(newViewWithId(View.NO_ID));
@@ -473,8 +480,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Test
public void testSplitShadeLayout_isAlignedToGuideline() {
- when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(true);
- when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ enableDualPaneShade();
mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame));
mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller));
@@ -489,6 +495,39 @@ public class NotificationPanelViewTest extends SysuiTestCase {
assertThat(stackScrollerLayout.startToStart).isEqualTo(R.id.qs_edge_guideline);
}
+ @Test
+ public void testCanCollapsePanelOnTouch_trueForKeyGuard() {
+ mStatusBarStateController.setState(KEYGUARD);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
+ }
+
+ @Test
+ public void testCanCollapsePanelOnTouch_trueWhenScrolledToBottom() {
+ mStatusBarStateController.setState(SHADE);
+ when(mNotificationStackScrollLayoutController.isScrolledToBottom()).thenReturn(true);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
+ }
+
+ @Test
+ public void testCanCollapsePanelOnTouch_trueWhenInSettings() {
+ mStatusBarStateController.setState(SHADE);
+ mNotificationPanelViewController.setQsExpanded(true);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
+ }
+
+ @Test
+ public void testCanCollapsePanelOnTouch_falseInDualPaneShade() {
+ mStatusBarStateController.setState(SHADE);
+ when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(true);
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ mNotificationPanelViewController.setQsExpanded(true);
+
+ assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isFalse();
+ }
+
private View newViewWithId(int id) {
View view = new View(mContext);
view.setId(id);
@@ -499,6 +538,23 @@ public class NotificationPanelViewTest extends SysuiTestCase {
return view;
}
+ @Test
+ public void testOnDragDownEvent_horizontalTranslationIsZeroForDualPaneShade() {
+ when(mNotificationStackScrollLayoutController.getWidth()).thenReturn(350f);
+ when(mView.getWidth()).thenReturn(800);
+ enableDualPaneShade();
+
+ onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN,
+ 200f /* x position */, 0f, 0));
+
+ verify(mQsFrame).setTranslationX(0);
+ }
+
+ private void enableDualPaneShade() {
+ when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(true);
+ when(mFeatureFlags.isTwoColumnNotificationShadeEnabled()).thenReturn(true);
+ }
+
private void onTouchEvent(MotionEvent ev) {
mTouchHandler.onTouch(mView, ev);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 29ee8b6c675d..5f3405379715 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -726,7 +726,7 @@ public class AudioService extends IAudioService.Stub
// caches the value returned by AudioSystem.isMicrophoneMuted()
private boolean mMicMuteFromSystemCached;
- private boolean mFastScrollSoundEffectsEnabled;
+ private boolean mNavigationRepeatSoundEffectsEnabled;
private boolean mHomeSoundEffectEnabled;
@GuardedBy("mSettingsLock")
@@ -2325,15 +2325,15 @@ public class AudioService extends IAudioService.Stub
VOL_ADJUST_NORMAL);
}
- public void setFastScrollSoundEffectsEnabled(boolean enabled) {
- mFastScrollSoundEffectsEnabled = enabled;
+ public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
+ mNavigationRepeatSoundEffectsEnabled = enabled;
}
/**
* @return true if the fast scroll sound effects are enabled
*/
- public boolean areFastScrollSoundEffectsEnabled() {
- return mFastScrollSoundEffectsEnabled;
+ public boolean areNavigationRepeatSoundEffectsEnabled() {
+ return mNavigationRepeatSoundEffectsEnabled;
}
public void setHomeSoundEffectEnabled(boolean enabled) {
diff --git a/services/core/java/com/android/server/audio/SoundEffectsHelper.java b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
index c14bb3ee5df1..7031e02af05a 100644
--- a/services/core/java/com/android/server/audio/SoundEffectsHelper.java
+++ b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
@@ -52,6 +52,7 @@ import java.util.Map;
* used by AudioService. As its methods are called on the message handler thread
* of AudioService, the actual work is offloaded to a dedicated thread.
* This helps keeping AudioService responsive.
+ *
* @hide
*/
class SoundEffectsHelper {
@@ -89,15 +90,18 @@ class SoundEffectsHelper {
final String mFileName;
int mSampleId;
boolean mLoaded; // for effects in SoundPool
+
Resource(String fileName) {
mFileName = fileName;
mSampleId = EFFECT_NOT_IN_SOUND_POOL;
}
+
void unload() {
mSampleId = EFFECT_NOT_IN_SOUND_POOL;
mLoaded = false;
}
}
+
// All the fields below are accessed by the worker thread exclusively
private final List<Resource> mResources = new ArrayList<Resource>();
private final int[] mEffects = new int[AudioManager.NUM_SOUND_EFFECTS]; // indexes in mResources
@@ -116,9 +120,9 @@ class SoundEffectsHelper {
}
/**
- * Unloads samples from the sound pool.
- * This method can be called to free some memory when
- * sound effects are disabled.
+ * Unloads samples from the sound pool.
+ * This method can be called to free some memory when
+ * sound effects are disabled.
*/
/*package*/ void unloadSoundEffects() {
sendMsg(MSG_UNLOAD_EFFECTS, 0, 0, null, 0);
@@ -385,12 +389,12 @@ class SoundEffectsHelper {
}
}
- boolean fastScrollSoundEffectsParsed = allFastScrollSoundsParsed(parserCounter);
+ boolean navigationRepeatFxParsed = allNavigationRepeatSoundsParsed(parserCounter);
boolean homeSoundParsed = parserCounter.getOrDefault(AudioManager.FX_HOME, 0) > 0;
- if (fastScrollSoundEffectsParsed || homeSoundParsed) {
+ if (navigationRepeatFxParsed || homeSoundParsed) {
AudioManager audioManager = mContext.getSystemService(AudioManager.class);
- if (audioManager != null && fastScrollSoundEffectsParsed) {
- audioManager.setFastScrollSoundEffectsEnabled(true);
+ if (audioManager != null && navigationRepeatFxParsed) {
+ audioManager.setNavigationRepeatSoundEffectsEnabled(true);
}
if (audioManager != null && homeSoundParsed) {
audioManager.setHomeSoundEffectEnabled(true);
@@ -410,13 +414,13 @@ class SoundEffectsHelper {
}
}
- private boolean allFastScrollSoundsParsed(Map<Integer, Integer> parserCounter) {
+ private boolean allNavigationRepeatSoundsParsed(Map<Integer, Integer> parserCounter) {
int numFastScrollSoundEffectsParsed =
- parserCounter.getOrDefault(AudioManager.FX_FAST_SCROLL_1, 0)
- + parserCounter.getOrDefault(AudioManager.FX_FAST_SCROLL_2, 0)
- + parserCounter.getOrDefault(AudioManager.FX_FAST_SCROLL_3, 0)
- + parserCounter.getOrDefault(AudioManager.FX_FAST_SCROLL_4, 0);
- return numFastScrollSoundEffectsParsed == AudioManager.NUM_FAST_SCROLL_SOUND_EFFECTS;
+ parserCounter.getOrDefault(AudioManager.FX_FOCUS_NAVIGATION_REPEAT_1, 0)
+ + parserCounter.getOrDefault(AudioManager.FX_FOCUS_NAVIGATION_REPEAT_2, 0)
+ + parserCounter.getOrDefault(AudioManager.FX_FOCUS_NAVIGATION_REPEAT_3, 0)
+ + parserCounter.getOrDefault(AudioManager.FX_FOCUS_NAVIGATION_REPEAT_4, 0);
+ return numFastScrollSoundEffectsParsed == AudioManager.NUM_NAVIGATION_REPEAT_SOUND_EFFECTS;
}
private int findOrAddResourceByFileName(String fileName) {