summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/service/wallpaper/IWallpaperEngine.aidl1
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java63
-rw-r--r--data/sounds/effects/ChargingStarted.oggbin33370 -> 33162 bytes
-rw-r--r--data/sounds/effects/ogg/ChargingStarted.oggbin33370 -> 33162 bytes
-rw-r--r--data/sounds/effects/ogg/ChargingStarted_48k.oggbin33370 -> 33162 bytes
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java5
-rw-r--r--packages/SystemUI/res/values/config.xml8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java46
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/Prefs.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/PrimaryProxSensor.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java283
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/SecondaryProxSensor.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java118
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java278
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java81
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java276
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorSingleTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorTest.java)148
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java246
-rw-r--r--packages/overlays/Android.mk2
-rw-r--r--packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml1
-rw-r--r--packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml27
-rw-r--r--packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml1
-rw-r--r--packages/overlays/IconShapeTaperedRectOverlay/Android.mk (renamed from packages/overlays/IconShapeHexagonOverlay/Android.mk)4
-rw-r--r--packages/overlays/IconShapeTaperedRectOverlay/AndroidManifest.xml28
-rw-r--r--packages/overlays/IconShapeTaperedRectOverlay/res/values/config.xml (renamed from packages/overlays/IconShapeHexagonOverlay/res/values/config.xml)2
-rw-r--r--packages/overlays/IconShapeTaperedRectOverlay/res/values/strings.xml (renamed from packages/overlays/IconShapeHexagonOverlay/res/values/strings.xml)4
-rw-r--r--packages/overlays/IconShapeVesselOverlay/Android.mk (renamed from packages/overlays/IconShapeFlowerOverlay/Android.mk)4
-rw-r--r--packages/overlays/IconShapeVesselOverlay/AndroidManifest.xml (renamed from packages/overlays/IconShapeFlowerOverlay/AndroidManifest.xml)5
-rw-r--r--packages/overlays/IconShapeVesselOverlay/res/values/config.xml (renamed from packages/overlays/IconShapeFlowerOverlay/res/values/config.xml)2
-rw-r--r--packages/overlays/IconShapeVesselOverlay/res/values/strings.xml (renamed from packages/overlays/IconShapeFlowerOverlay/res/values/strings.xml)4
50 files changed, 1593 insertions, 309 deletions
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index 84b6869bf620..90392e65794a 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -38,4 +38,5 @@ oneway interface IWallpaperEngine {
@UnsupportedAppUsage
void destroy();
void setZoomOut(float scale);
+ void scalePreview(in Rect positionInWindow);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index f944dd78dc3d..1fd192c656b9 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,6 +16,11 @@
package android.service.wallpaper;
+import static android.graphics.Matrix.MSCALE_X;
+import static android.graphics.Matrix.MSCALE_Y;
+import static android.graphics.Matrix.MSKEW_X;
+import static android.graphics.Matrix.MSKEW_Y;
+
import android.annotation.FloatRange;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
@@ -31,6 +36,7 @@ import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -123,7 +129,8 @@ public abstract class WallpaperService extends Service {
private static final int MSG_WINDOW_MOVED = 10035;
private static final int MSG_TOUCH_EVENT = 10040;
private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
- private static final int MSG_SCALE = 10100;
+ private static final int MSG_ZOOM = 10100;
+ private static final int MSG_SCALE_PREVIEW = 10110;
private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
@@ -178,6 +185,7 @@ public abstract class WallpaperService extends Service {
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
int mCurWindowFlags = mWindowFlags;
int mCurWindowPrivateFlags = mWindowPrivateFlags;
+ Rect mPreviewSurfacePosition;
final Rect mVisibleInsets = new Rect();
final Rect mWinFrame = new Rect();
final Rect mContentInsets = new Rect();
@@ -194,6 +202,8 @@ public abstract class WallpaperService extends Service {
final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0];
final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
private final Point mSurfaceSize = new Point();
+ private final Matrix mTmpMatrix = new Matrix();
+ private final float[] mTmpValues = new float[9];
final WindowManager.LayoutParams mLayout
= new WindowManager.LayoutParams();
@@ -366,7 +376,7 @@ public abstract class WallpaperService extends Service {
Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
mCaller.sendMessage(msg);
}
- Message msg = mCaller.obtainMessageI(MSG_SCALE, Float.floatToIntBits(zoom));
+ Message msg = mCaller.obtainMessageI(MSG_ZOOM, Float.floatToIntBits(zoom));
mCaller.sendMessage(msg);
}
}
@@ -747,6 +757,8 @@ public abstract class WallpaperService extends Service {
out.println(mMergedConfiguration.getMergedConfiguration());
out.print(prefix); out.print("mLayout="); out.println(mLayout);
out.print(prefix); out.print("mZoom="); out.println(mZoom);
+ out.print(prefix); out.print("mPreviewSurfacePosition=");
+ out.println(mPreviewSurfacePosition);
synchronized (mLock) {
out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
out.print(" mPendingXOffset="); out.println(mPendingXOffset);
@@ -908,7 +920,6 @@ public abstract class WallpaperService extends Service {
mInsetsState, mTempControls, mSurfaceSize, mTmpSurfaceControl);
if (mSurfaceControl.isValid()) {
mSurfaceHolder.mSurface.copyFrom(mSurfaceControl);
- mSurfaceControl.release();
}
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
@@ -1063,6 +1074,7 @@ public abstract class WallpaperService extends Service {
if (redrawNeeded) {
mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
}
+ reposition();
mIWallpaperEngine.reportShown();
}
} catch (RemoteException ex) {
@@ -1073,6 +1085,39 @@ public abstract class WallpaperService extends Service {
}
}
+ private void scalePreview(Rect position) {
+ if (isPreview() && mPreviewSurfacePosition == null && position != null
+ || mPreviewSurfacePosition != null
+ && !mPreviewSurfacePosition.equals(position)) {
+ mPreviewSurfacePosition = position;
+ if (mSurfaceControl.isValid()) {
+ reposition();
+ } else {
+ updateSurface(false, false, false);
+ }
+ }
+ }
+
+ private void reposition() {
+ if (mPreviewSurfacePosition == null) {
+ return;
+ }
+ if (DEBUG) {
+ Log.i(TAG, "reposition: rect: " + mPreviewSurfacePosition);
+ }
+
+ mTmpMatrix.setTranslate(mPreviewSurfacePosition.left, mPreviewSurfacePosition.top);
+ mTmpMatrix.postScale(((float) mPreviewSurfacePosition.width()) / mCurWidth,
+ ((float) mPreviewSurfacePosition.height()) / mCurHeight);
+ mTmpMatrix.getValues(mTmpValues);
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ t.setPosition(mSurfaceControl, mPreviewSurfacePosition.left,
+ mPreviewSurfacePosition.top);
+ t.setMatrix(mSurfaceControl, mTmpValues[MSCALE_X], mTmpValues[MSKEW_Y],
+ mTmpValues[MSKEW_X], mTmpValues[MSCALE_Y]);
+ t.apply();
+ }
+
void attach(IWallpaperEngineWrapper wrapper) {
if (DEBUG) Log.v(TAG, "attach: " + this + " wrapper=" + wrapper);
if (mDestroyed) {
@@ -1414,7 +1459,7 @@ public abstract class WallpaperService extends Service {
}
public void setZoomOut(float scale) {
- Message msg = mCaller.obtainMessageI(MSG_SCALE, Float.floatToIntBits(scale));
+ Message msg = mCaller.obtainMessageI(MSG_ZOOM, Float.floatToIntBits(scale));
mCaller.sendMessage(msg);
}
@@ -1444,6 +1489,11 @@ public abstract class WallpaperService extends Service {
mDetached.set(true);
}
+ public void scalePreview(Rect position) {
+ Message msg = mCaller.obtainMessageO(MSG_SCALE_PREVIEW, position);
+ mCaller.sendMessage(msg);
+ }
+
private void doDetachEngine() {
mActiveEngines.remove(mEngine);
mEngine.detach();
@@ -1490,9 +1540,12 @@ public abstract class WallpaperService extends Service {
case MSG_UPDATE_SURFACE:
mEngine.updateSurface(true, false, false);
break;
- case MSG_SCALE:
+ case MSG_ZOOM:
mEngine.setZoom(Float.intBitsToFloat(message.arg1));
break;
+ case MSG_SCALE_PREVIEW:
+ mEngine.scalePreview((Rect) message.obj);
+ break;
case MSG_VISIBILITY_CHANGED:
if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
+ ": " + message.arg1);
diff --git a/data/sounds/effects/ChargingStarted.ogg b/data/sounds/effects/ChargingStarted.ogg
index f09e273ea5ac..9526b08d9b3c 100644
--- a/data/sounds/effects/ChargingStarted.ogg
+++ b/data/sounds/effects/ChargingStarted.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/ChargingStarted.ogg b/data/sounds/effects/ogg/ChargingStarted.ogg
index f09e273ea5ac..9526b08d9b3c 100644
--- a/data/sounds/effects/ogg/ChargingStarted.ogg
+++ b/data/sounds/effects/ogg/ChargingStarted.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/ChargingStarted_48k.ogg b/data/sounds/effects/ogg/ChargingStarted_48k.ogg
index f09e273ea5ac..9526b08d9b3c 100644
--- a/data/sounds/effects/ogg/ChargingStarted_48k.ogg
+++ b/data/sounds/effects/ogg/ChargingStarted_48k.ogg
Binary files differ
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index f066bf589b64..948091c12721 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -113,12 +113,11 @@ public abstract class CarSystemUIModule {
@Binds
@Singleton
- public abstract BatteryController provideBatteryController(
- BatteryControllerImpl controllerImpl);
+ public abstract BatteryController bindBatteryController(BatteryControllerImpl controllerImpl);
@Binds
@Singleton
- public abstract QSFactory provideQSFactory(QSFactoryImpl qsFactoryImpl);
+ public abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);
@Binds
abstract DockManager bindDockManager(DockManagerImpl dockManager);
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 62335abd4329..3395c71bd5a3 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -205,6 +205,14 @@
far break points. A sensor value less than this is considered "near". -->
<item name="proximity_sensor_threshold" translatable="false" format="float" type="dimen"></item>
+ <!-- Override value to use for proximity sensor as confirmation for proximity_sensor_type. -->
+ <string name="proximity_sensor_secondary_type" translatable="false"></string>
+
+ <!-- If using proximity_sensor_confirmation_type, specifies a threshold value to distinguish
+ near and far break points. A sensor value less than this is considered "near". -->
+ <item name="proximity_sensor_secondary_threshold" translatable="false" format="float"
+ type="dimen"></item>
+
<!-- Doze: pulse parameter - how long does it take to fade in? -->
<integer name="doze_pulse_duration_in">130</integer>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
new file mode 100644
index 000000000000..8a652cb22bb9
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shared.system;
+
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.service.wallpaper.IWallpaperEngine;
+import android.util.Log;
+
+/**
+ * @see IWallpaperEngine
+ */
+public class WallpaperEngineCompat {
+
+ private static final String TAG = "WallpaperEngineCompat";
+
+ private final IWallpaperEngine mWrappedEngine;
+
+ public WallpaperEngineCompat(IWallpaperEngine wrappedEngine) {
+ mWrappedEngine = wrappedEngine;
+ }
+
+ /**
+ * @see IWallpaperEngine#scalePreview(Rect)
+ */
+ public void scalePreview(Rect scaleToRect) {
+ try {
+ mWrappedEngine.scalePreview(scaleToRect);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Couldn't call scalePreview method on WallpaperEngine", e);
+ }
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
index 7570c2cbfe98..af804837228e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
@@ -36,4 +36,12 @@ public class WallpaperManagerCompat {
public void setWallpaperZoomOut(IBinder windowToken, float zoom) {
mWallpaperManager.setWallpaperZoomOut(windowToken, zoom);
}
+
+ /**
+ * @return the max scale for the wallpaper when it's fully zoomed out
+ */
+ public static float getWallpaperZoomOutMaxScale(Context context) {
+ return context.getResources()
+ .getFloat(com.android.internal.R.dimen.config_wallpaperMaxScale);
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 87990cd3bffa..ced77beff642 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -74,6 +74,7 @@ public final class Prefs {
Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP,
Key.HAS_SEEN_BUBBLES_EDUCATION,
Key.HAS_SEEN_BUBBLES_MANAGE_EDUCATION,
+ Key.HAS_SEEN_REVERSE_BOTTOM_SHEET,
Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT
})
public @interface Key {
@@ -122,6 +123,7 @@ public final class Prefs {
String HAS_SEEN_ODI_CAPTIONS_TOOLTIP = "HasSeenODICaptionsTooltip";
String HAS_SEEN_BUBBLES_EDUCATION = "HasSeenBubblesOnboarding";
String HAS_SEEN_BUBBLES_MANAGE_EDUCATION = "HasSeenBubblesManageOnboarding";
+ String HAS_SEEN_REVERSE_BOTTOM_SHEET = "HasSeenReverseBottomSheet";
String CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT = "ControlsStructureSwipeTooltipCount";
/** Tracks whether the user has seen the onboarding screen for priority conversations */
String HAS_SEEN_PRIORITY_ONBOARDING = "HasSeenPriorityOnboarding";
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 79b691bb3e37..cab805848e7b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -87,7 +87,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
mUiBgExecutor = uiBgExecutor;
mStatusBarStateController = statusBarStateController;
mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
- mProximitySensor.setSensorDelay(SensorManager.SENSOR_DELAY_GAME);
+ mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME);
mDeviceConfig = deviceConfig;
mDeviceConfigListener =
properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace());
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index caab18712b0b..fad6aaf06ab3 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -37,6 +37,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.ProximitySensor;
+import com.android.systemui.util.sensors.ThresholdSensor;
import java.io.PrintWriter;
import java.util.ArrayDeque;
@@ -76,7 +77,7 @@ public class BrightLineFalsingManager implements FalsingManager {
private final List<FalsingClassifier> mClassifiers;
- private ProximitySensor.ProximitySensorListener mSensorEventListener = this::onProximityEvent;
+ private ThresholdSensor.Listener mSensorEventListener = this::onProximityEvent;
private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
new KeyguardUpdateMonitorCallback() {
@@ -240,7 +241,7 @@ public class BrightLineFalsingManager implements FalsingManager {
mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent));
}
- private void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {
+ private void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
// TODO: some of these classifiers might allow us to abort early, meaning we don't have to
// make these calls.
mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
index cf088213644e..85e95a66bfe3 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
@@ -96,7 +96,7 @@ abstract class FalsingClassifier {
/**
* Called when a ProximityEvent occurs (change in near/far).
*/
- void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {};
+ void onProximityEvent(ProximitySensor.ThresholdSensorEvent proximityEvent) {};
/**
* The phone screen has turned on and we need to begin falsing detection.
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
index 749914e1b625..b128678af5db 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
@@ -101,8 +101,8 @@ class ProximityClassifier extends FalsingClassifier {
@Override
public void onProximityEvent(
- ProximitySensor.ProximityEvent proximityEvent) {
- boolean near = proximityEvent.getNear();
+ ProximitySensor.ThresholdSensorEvent proximityEvent) {
+ boolean near = proximityEvent.getBelow();
long timestampNs = proximityEvent.getTimestampNs();
logDebug("Sensor is: " + near + " at time " + timestampNs);
update(near, timestampNs);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
index 2b27436c85dd..20b343fed2eb 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
@@ -36,6 +36,7 @@ import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutManager;
import android.content.res.Resources;
+import android.hardware.SensorManager;
import android.hardware.SensorPrivacyManager;
import android.hardware.display.DisplayManager;
import android.media.AudioManager;
@@ -247,6 +248,12 @@ public class SystemServicesModule {
return context.getResources();
}
+ @Provides
+ @Singleton
+ static SensorManager providesSensorManager(Context context) {
+ return context.getSystemService(SensorManager.class);
+ }
+
@Singleton
@Provides
static SensorPrivacyManager provideSensorPrivacyManager(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 8c572fe8f842..7e5a3ae83928 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -83,12 +83,11 @@ public abstract class SystemUIDefaultModule {
@Binds
@Singleton
- public abstract BatteryController provideBatteryController(
- BatteryControllerImpl controllerImpl);
+ public abstract BatteryController bindBatteryController(BatteryControllerImpl controllerImpl);
@Binds
@Singleton
- public abstract QSFactory provideQSFactory(QSFactoryImpl qsFactoryImpl);
+ public abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);
@Binds
abstract DockManager bindDockManager(DockManagerImpl dockManager);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 90cd13fd1330..cb45926d3f24 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.concurrency.ConcurrencyModule;
import com.android.systemui.util.sensors.AsyncSensorManager;
+import com.android.systemui.util.sensors.SensorModule;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.util.time.SystemClockImpl;
@@ -62,7 +63,8 @@ import dagger.Provides;
ConcurrencyModule.class,
LogModule.class,
PeopleHubModule.class,
- SettingsModule.class
+ SensorModule.class,
+ SettingsModule.class,
},
subcomponents = {StatusBarComponent.class,
NotificationRowComponent.class,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 10776c91df84..e4da345af465 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -81,7 +81,8 @@ public class DozeSensors {
public DozeSensors(Context context, AlarmManager alarmManager, AsyncSensorManager sensorManager,
DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
- Callback callback, Consumer<Boolean> proxCallback, DozeLog dozeLog) {
+ Callback callback, Consumer<Boolean> proxCallback, DozeLog dozeLog,
+ ProximitySensor proximitySensor) {
mContext = context;
mAlarmManager = alarmManager;
mSensorManager = sensorManager;
@@ -153,12 +154,12 @@ public class DozeSensors {
dozeLog),
};
- mProximitySensor = new ProximitySensor(context.getResources(), sensorManager);
+ mProximitySensor = proximitySensor;
setProxListening(false); // Don't immediately start listening when we register.
mProximitySensor.register(
proximityEvent -> {
if (proximityEvent != null) {
- mProxCallback.accept(!proximityEvent.getNear());
+ mProxCallback.accept(!proximityEvent.getBelow());
}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 1be4d438683a..01478821a348 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -92,8 +92,8 @@ public class DozeTriggers implements DozeMachine.Part {
AlarmManager alarmManager, AmbientDisplayConfiguration config,
DozeParameters dozeParameters, AsyncSensorManager sensorManager, Handler handler,
WakeLock wakeLock, boolean allowPulseTriggers, DockManager dockManager,
- ProximitySensor proximitySensor,
- DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher) {
+ ProximitySensor proximitySensor, DozeLog dozeLog,
+ BroadcastDispatcher broadcastDispatcher) {
mContext = context;
mMachine = machine;
mDozeHost = dozeHost;
@@ -103,7 +103,8 @@ public class DozeTriggers implements DozeMachine.Part {
mWakeLock = wakeLock;
mAllowPulseTriggers = allowPulseTriggers;
mDozeSensors = new DozeSensors(context, alarmManager, mSensorManager, dozeParameters,
- config, wakeLock, this::onSensor, this::onProximityFar, dozeLog);
+ config, wakeLock, this::onSensor, this::onProximityFar, dozeLog,
+ proximitySensor);
mUiModeManager = mContext.getSystemService(UiModeManager.class);
mDockManager = dockManager;
mProxCheck = new ProximitySensor.ProximityCheck(proximitySensor, handler);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 0680c7f70b97..12ea1004038e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -45,10 +45,10 @@ public class AutoTileManager {
public static final String NIGHT = "night";
public static final String CAST = "cast";
- private final Context mContext;
- private final QSTileHost mHost;
- private final Handler mHandler;
- private final AutoAddTracker mAutoTracker;
+ protected final Context mContext;
+ protected final QSTileHost mHost;
+ protected final Handler mHandler;
+ protected final AutoAddTracker mAutoTracker;
private final HotspotController mHotspotController;
private final DataSaverController mDataSaverController;
private final ManagedProfileController mManagedProfileController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index a81189eaeaf8..21e2e580df4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -53,6 +53,11 @@ public interface BatteryController extends DemoMode, Dumpable,
boolean isAodPowerSave();
/**
+ * Returns {@code true} if the device is currently in wireless charging mode.
+ */
+ default boolean isWirelessCharging() { return false; }
+
+ /**
* Returns {@code true} if reverse is supported.
*/
default boolean isReverseSupported() { return false; }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 95b41a141244..98d01464debd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -58,7 +58,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final EnhancedEstimates mEstimates;
- private final BroadcastDispatcher mBroadcastDispatcher;
+ protected final BroadcastDispatcher mBroadcastDispatcher;
protected final ArrayList<BatteryController.BatteryStateChangeCallback>
mChangeCallbacks = new ArrayList<>();
private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>();
@@ -73,6 +73,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
private boolean mCharged;
protected boolean mPowerSave;
private boolean mAodPowerSave;
+ protected boolean mWirelessCharging;
private boolean mTestmode = false;
private boolean mHasReceivedBattery = false;
private Estimate mEstimate;
@@ -150,6 +151,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
BatteryManager.BATTERY_STATUS_UNKNOWN);
mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
+ mWirelessCharging = mCharging && intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0)
+ == BatteryManager.BATTERY_PLUGGED_WIRELESS;
fireBatteryLevelChanged();
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
@@ -205,6 +208,11 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
}
@Override
+ public boolean isWirelessCharging() {
+ return mWirelessCharging;
+ }
+
+ @Override
public void getEstimatedTimeRemainingString(EstimateFetchCompletion completion) {
// Need to fetch or refresh the estimate, but it may involve binder calls so offload the
// work
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java
index 2224c9cce40a..450336a6b73b 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java
@@ -60,8 +60,8 @@ public class AsyncSensorManager extends SensorManager
private final List<SensorManagerPlugin> mPlugins;
@Inject
- public AsyncSensorManager(Context context, PluginManager pluginManager) {
- this(context.getSystemService(SensorManager.class), pluginManager, null);
+ public AsyncSensorManager(SensorManager sensorManager, PluginManager pluginManager) {
+ this(sensorManager, pluginManager, null);
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/PrimaryProxSensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/PrimaryProxSensor.java
new file mode 100644
index 000000000000..96c76c1a15d0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/PrimaryProxSensor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+@interface PrimaryProxSensor {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index 378dde284747..9be42f3fc5f4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -16,92 +16,119 @@
package com.android.systemui.util.sensors;
-import android.content.res.Resources;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.util.Assert;
+import com.android.systemui.util.concurrency.DelayableExecutor;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import java.util.function.Consumer;
import javax.inject.Inject;
/**
- * Simple wrapper around SensorManager customized for the Proximity sensor.
+ * Wrapper around SensorManager customized for the Proximity sensor.
+ *
+ * The ProximitySensor supports the concept of a primary and a
+ * secondary hardware sensor. The primary sensor is used for a first
+ * pass check if the phone covered. When triggered, it then checks
+ * the secondary sensor for confirmation (if there is one). It does
+ * not send a proximity event until the secondary sensor confirms (or
+ * rejects) the reading. The secondary sensor is, in fact, the source
+ * of truth.
+ *
+ * This is necessary as sometimes keeping the secondary sensor on for
+ * extends periods is undesirable. It may, however, result in increased
+ * latency for proximity readings.
+ *
+ * Phones should configure this via a config.xml overlay. If no
+ * proximity sensor is set (primary or secondary) we fall back to the
+ * default Sensor.TYPE_PROXIMITY. If proximity_sensor_type is set in
+ * config.xml, that will be used as the primary sensor. If
+ * proximity_sensor_secondary_type is set, that will function as the
+ * secondary sensor. If no secondary is set, only the primary will be
+ * used.
*/
-public class ProximitySensor {
+public class ProximitySensor implements ThresholdSensor {
private static final String TAG = "ProxSensor";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final long SECONDARY_PING_INTERVAL_MS = 5000;
- private final Sensor mSensor;
- private final AsyncSensorManager mSensorManager;
- private final float mThreshold;
- private List<ProximitySensorListener> mListeners = new ArrayList<>();
+ private final ThresholdSensor mPrimaryThresholdSensor;
+ private final ThresholdSensor mSecondaryThresholdSensor;
+ private final DelayableExecutor mDelayableExecutor;
+ private final List<ThresholdSensor.Listener> mListeners = new ArrayList<>();
private String mTag = null;
- @VisibleForTesting ProximityEvent mLastEvent;
- private int mSensorDelay = SensorManager.SENSOR_DELAY_NORMAL;
+ private ThresholdSensorEvent mLastPrimaryEvent;
+ @VisibleForTesting
+ ThresholdSensorEvent mLastEvent;
private boolean mPaused;
private boolean mRegistered;
+ private Runnable mCancelSecondaryRunnable;
+ private boolean mInitializedListeners = false;
- private SensorEventListener mSensorEventListener = new SensorEventListener() {
+ private ThresholdSensor.Listener mPrimaryEventListener = new ThresholdSensor.Listener() {
@Override
- public synchronized void onSensorChanged(SensorEvent event) {
- onSensorEvent(event);
+ public void onThresholdCrossed(ThresholdSensorEvent event) {
+ onPrimarySensorEvent(event);
}
+ };
+ private ThresholdSensor.Listener mSecondaryEventListener = new ThresholdSensor.Listener() {
@Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ public void onThresholdCrossed(ThresholdSensorEvent event) {
+ // This sensor should only be used briefly. Turn it off as soon as we get a reading.
+ mSecondaryThresholdSensor.pause();
+
+ // Only check the secondary as long as the primary thinks we're near.
+ if (!mLastPrimaryEvent.getBelow()) {
+ mCancelSecondaryRunnable = null;
+ return;
+ }
+ logDebug("Secondary sensor event: " + event.getBelow() + ".");
+
+ onSensorEvent(event);
+
+ // Check this sensor again in a moment.
+ mCancelSecondaryRunnable = mDelayableExecutor.executeDelayed(
+ mSecondaryThresholdSensor::resume, SECONDARY_PING_INTERVAL_MS);
}
};
@Inject
- public ProximitySensor(@Main Resources resources,
- AsyncSensorManager sensorManager) {
- mSensorManager = sensorManager;
-
- Sensor sensor = findCustomProxSensor(resources);
- float threshold = 0;
- if (sensor != null) {
- try {
- threshold = getCustomProxThreshold(resources);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Can not load custom proximity sensor.", e);
- sensor = null;
- }
- }
- if (sensor == null) {
- sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
- if (sensor != null) {
- threshold = sensor.getMaximumRange();
- }
- }
-
- mThreshold = threshold;
-
- mSensor = sensor;
+ public ProximitySensor(@PrimaryProxSensor ThresholdSensor primary,
+ @SecondaryProxSensor ThresholdSensor secondary,
+ @Main DelayableExecutor delayableExecutor) {
+ mPrimaryThresholdSensor = primary;
+ mSecondaryThresholdSensor = secondary;
+ mDelayableExecutor = delayableExecutor;
}
+ @Override
public void setTag(String tag) {
mTag = tag;
+ mPrimaryThresholdSensor.setTag(tag + ":primary");
+ mSecondaryThresholdSensor.setTag(tag + ":secondary");
}
- public void setSensorDelay(int sensorDelay) {
- mSensorDelay = sensorDelay;
+ @Override
+ public void setDelay(int delay) {
+ Assert.isMainThread();
+ mPrimaryThresholdSensor.setDelay(delay);
+ mSecondaryThresholdSensor.setDelay(delay);
}
/**
* Unregister with the {@link SensorManager} without unsetting listeners on this object.
*/
+ @Override
public void pause() {
+ Assert.isMainThread();
mPaused = true;
unregisterInternal();
}
@@ -109,41 +136,13 @@ public class ProximitySensor {
/**
* Register with the {@link SensorManager}. No-op if no listeners are registered on this object.
*/
+ @Override
public void resume() {
+ Assert.isMainThread();
mPaused = false;
registerInternal();
}
- /**
- * Returns a brightness sensor that can be used for proximity purposes.
- */
- private Sensor findCustomProxSensor(Resources resources) {
- String sensorType = resources.getString(R.string.proximity_sensor_type);
- if (sensorType.isEmpty()) {
- return null;
- }
- List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
- Sensor sensor = null;
- for (Sensor s : sensorList) {
- if (sensorType.equals(s.getStringType())) {
- sensor = s;
- break;
- }
- }
-
- return sensor;
- }
-
- /**
- * Returns a threshold value that can be used along with {@link #findCustomProxSensor}
- */
- private float getCustomProxThreshold(Resources resources) {
- try {
- return resources.getFloat(R.dimen.proximity_sensor_threshold);
- } catch (Resources.NotFoundException e) {
- throw new IllegalStateException("R.dimen.proximity_sensor_threshold must be set.");
- }
- }
/**
* Returns true if we are registered with the SensorManager.
@@ -155,38 +154,46 @@ public class ProximitySensor {
/**
* Returns {@code false} if a Proximity sensor is not available.
*/
- public boolean getSensorAvailable() {
- return mSensor != null;
+ @Override
+ public boolean isLoaded() {
+ return mPrimaryThresholdSensor.isLoaded();
}
/**
* Add a listener.
*
* Registers itself with the {@link SensorManager} if this is the first listener
- * added. If a cool down is currently running, the sensor will be registered when it is over.
+ * added. If the ProximitySensor is paused, it will be registered when resumed.
*/
- public boolean register(ProximitySensorListener listener) {
- if (!getSensorAvailable()) {
- return false;
+ @Override
+ public void register(ThresholdSensor.Listener listener) {
+ Assert.isMainThread();
+ if (!isLoaded()) {
+ return;
}
if (mListeners.contains(listener)) {
- Log.d(TAG, "ProxListener registered multiple times: " + listener);
+ logDebug("ProxListener registered multiple times: " + listener);
} else {
mListeners.add(listener);
}
registerInternal();
-
- return true;
}
protected void registerInternal() {
+ Assert.isMainThread();
if (mRegistered || mPaused || mListeners.isEmpty()) {
return;
}
+ if (!mInitializedListeners) {
+ mPrimaryThresholdSensor.register(mPrimaryEventListener);
+ mSecondaryThresholdSensor.pause();
+ mSecondaryThresholdSensor.register(mSecondaryEventListener);
+ mInitializedListeners = true;
+ }
logDebug("Registering sensor listener");
+ mPrimaryThresholdSensor.resume();
mRegistered = true;
- mSensorManager.registerListener(mSensorEventListener, mSensor, mSensorDelay);
}
/**
@@ -195,7 +202,9 @@ public class ProximitySensor {
* If all listeners are removed from an instance of this class,
* it will unregister itself with the SensorManager.
*/
- public void unregister(ProximitySensorListener listener) {
+ @Override
+ public void unregister(ThresholdSensor.Listener listener) {
+ Assert.isMainThread();
mListeners.remove(listener);
if (mListeners.size() == 0) {
unregisterInternal();
@@ -203,34 +212,77 @@ public class ProximitySensor {
}
protected void unregisterInternal() {
+ Assert.isMainThread();
if (!mRegistered) {
return;
}
logDebug("unregistering sensor listener");
- mSensorManager.unregisterListener(mSensorEventListener);
+ mPrimaryThresholdSensor.pause();
+ mSecondaryThresholdSensor.pause();
+ if (mCancelSecondaryRunnable != null) {
+ mCancelSecondaryRunnable.run();
+ mCancelSecondaryRunnable = null;
+ }
+ mLastPrimaryEvent = null; // Forget what we know.
+ mLastEvent = null;
mRegistered = false;
}
public Boolean isNear() {
- return getSensorAvailable() && mLastEvent != null ? mLastEvent.getNear() : null;
+ return isLoaded() && mLastEvent != null ? mLastEvent.getBelow() : null;
}
/** Update all listeners with the last value this class received from the sensor. */
public void alertListeners() {
- mListeners.forEach(proximitySensorListener ->
- proximitySensorListener.onSensorEvent(mLastEvent));
+ Assert.isMainThread();
+ if (mLastEvent == null) {
+ return;
+ }
+
+ List<ThresholdSensor.Listener> listeners = new ArrayList<>(mListeners);
+ listeners.forEach(proximitySensorListener ->
+ proximitySensorListener.onThresholdCrossed(mLastEvent));
+ }
+
+ private void onPrimarySensorEvent(ThresholdSensorEvent event) {
+ Assert.isMainThread();
+ if (mLastPrimaryEvent != null && event.getBelow() == mLastPrimaryEvent.getBelow()) {
+ return;
+ }
+
+ mLastPrimaryEvent = event;
+
+ if (event.getBelow() && mSecondaryThresholdSensor.isLoaded()) {
+ logDebug("Primary sensor is near. Checking secondary.");
+ if (mCancelSecondaryRunnable == null) {
+ mSecondaryThresholdSensor.resume();
+ }
+ } else {
+ if (!mSecondaryThresholdSensor.isLoaded()) {
+ logDebug("Primary sensor event: " + event.getBelow() + ". No secondary.");
+ } else {
+ logDebug("Primary sensor event: " + event.getBelow() + ".");
+ }
+ onSensorEvent(event);
+ }
}
- private void onSensorEvent(SensorEvent event) {
- boolean near = event.values[0] < mThreshold;
- mLastEvent = new ProximityEvent(near, event.timestamp);
+ private void onSensorEvent(ThresholdSensorEvent event) {
+ Assert.isMainThread();
+ if (mLastEvent != null && event.getBelow() == mLastEvent.getBelow()) {
+ return;
+ }
+
+ mLastEvent = event;
alertListeners();
}
@Override
public String toString() {
- return String.format("{registered=%s, paused=%s, near=%s, sensor=%s}",
- isRegistered(), mPaused, isNear(), mSensor);
+ return String.format("{registered=%s, paused=%s, near=%s, primarySensor=%s, "
+ + "secondarySensor=%s}",
+ isRegistered(), mPaused, isNear(), mPrimaryThresholdSensor,
+ mSecondaryThresholdSensor);
}
/**
@@ -248,11 +300,11 @@ public class ProximitySensor {
mSensor.setTag("prox_check");
mHandler = handler;
mSensor.pause();
- ProximitySensorListener listener = proximityEvent -> {
+ ThresholdSensor.Listener listener = proximityEvent -> {
mCallbacks.forEach(
booleanConsumer ->
booleanConsumer.accept(
- proximityEvent == null ? null : proximityEvent.getNear()));
+ proximityEvent == null ? null : proximityEvent.getBelow()));
mCallbacks.clear();
mSensor.pause();
};
@@ -274,7 +326,7 @@ public class ProximitySensor {
* Query the proximity sensor, timing out if no result.
*/
public void check(long timeoutMs, Consumer<Boolean> callback) {
- if (!mSensor.getSensorAvailable()) {
+ if (!mSensor.isLoaded()) {
callback.accept(null);
}
mCallbacks.add(callback);
@@ -285,43 +337,6 @@ public class ProximitySensor {
}
}
- /** Implement to be notified of ProximityEvents. */
- public interface ProximitySensorListener {
- /** Called when the ProximitySensor changes. */
- void onSensorEvent(ProximityEvent proximityEvent);
- }
-
- /**
- * Returned when the near/far state of a {@link ProximitySensor} changes.
- */
- public static class ProximityEvent {
- private final boolean mNear;
- private final long mTimestampNs;
-
- public ProximityEvent(boolean near, long timestampNs) {
- mNear = near;
- mTimestampNs = timestampNs;
- }
-
- public boolean getNear() {
- return mNear;
- }
-
- public long getTimestampNs() {
- return mTimestampNs;
- }
-
- public long getTimestampMs() {
- return mTimestampNs / 1000000;
- }
-
- @Override
- public String toString() {
- return String.format((Locale) null, "{near=%s, timestamp_ns=%d}", mNear, mTimestampNs);
- }
-
- }
-
private void logDebug(String msg) {
if (DEBUG) {
Log.d(TAG, (mTag != null ? "[" + mTag + "] " : "") + msg);
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/SecondaryProxSensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/SecondaryProxSensor.java
new file mode 100644
index 000000000000..89fc0eabf607
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/SecondaryProxSensor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+@interface SecondaryProxSensor {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
new file mode 100644
index 000000000000..5a93e6c9f77a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+
+import com.android.systemui.R;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger module for Sensor related classes.
+ */
+@Module
+public class SensorModule {
+ @Provides
+ @PrimaryProxSensor
+ static ThresholdSensor providePrimaryProxSensor(SensorManager sensorManager,
+ ThresholdSensorImpl.Builder thresholdSensorBuilder) {
+ try {
+ return thresholdSensorBuilder
+ .setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL)
+ .setSensorResourceId(R.string.proximity_sensor_type)
+ .setThresholdResourceId(R.dimen.proximity_sensor_threshold)
+ .build();
+ } catch (IllegalStateException e) {
+ Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+ return thresholdSensorBuilder
+ .setSensor(defaultSensor)
+ .setThresholdValue(defaultSensor.getMaximumRange())
+ .build();
+ }
+ }
+
+ @Provides
+ @SecondaryProxSensor
+ static ThresholdSensor provideSecondaryProxSensor(
+ ThresholdSensorImpl.Builder thresholdSensorBuilder) {
+ try {
+ return thresholdSensorBuilder
+ .setSensorResourceId(R.string.proximity_sensor_secondary_type)
+ .setThresholdResourceId(R.dimen.proximity_sensor_secondary_threshold)
+ .build();
+ } catch (IllegalStateException e) {
+ return thresholdSensorBuilder.setSensor(null).setThresholdValue(0).build();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java
new file mode 100644
index 000000000000..363a734a6ae5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import java.util.Locale;
+
+/**
+ * A wrapper class for sensors that have a boolean state - above/below.
+ */
+public interface ThresholdSensor {
+ /**
+ * Optional label to use for logging.
+ *
+ * This should be set to something meaningful by owner of the instance.
+ */
+ void setTag(String tag);
+
+ /**
+ * Change the delay used when registering the sensor.
+ *
+ * If the sensor is already registered, this should cause it to re-register with the new
+ * delay.
+ */
+ void setDelay(int delay);
+
+ /**
+ * True if this sensor successfully loads and can be listened to.
+ */
+ boolean isLoaded();
+
+ /**
+ * Registers with the sensor and calls the supplied callback on value change.
+ *
+ * If this instance is paused, the listener will be recorded, but no registration with
+ * the underlying physical sensor will occur until {@link #resume()} is called.
+ *
+ * @see #unregister(Listener)
+ */
+ void register(Listener listener);
+
+ /**
+ * Unregisters from the physical sensor without removing any supplied listeners.
+ *
+ * No events will be sent to listeners as long as this sensor is paused.
+ *
+ * @see #resume()
+ * @see #unregister(Listener)
+ */
+ void pause();
+
+ /**
+ * Resumes listening to the physical sensor after previously pausing.
+ *
+ * @see #pause()
+ */
+ void resume();
+
+ /**
+ * Unregister a listener with the sensor.
+ *
+ * @see #register(Listener)
+ */
+ void unregister(Listener listener);
+
+ /**
+ * Interface for listening to events on {@link ThresholdSensor}
+ */
+ interface Listener {
+ /**
+ * Called whenever the threshold for the registered sensor is crossed.
+ */
+ void onThresholdCrossed(ThresholdSensorEvent event);
+ }
+
+ /**
+ * Returned when the below/above state of a {@link ThresholdSensor} changes.
+ */
+ class ThresholdSensorEvent {
+ private final boolean mBelow;
+ private final long mTimestampNs;
+
+ public ThresholdSensorEvent(boolean below, long timestampNs) {
+ mBelow = below;
+ mTimestampNs = timestampNs;
+ }
+
+ public boolean getBelow() {
+ return mBelow;
+ }
+
+ public long getTimestampNs() {
+ return mTimestampNs;
+ }
+
+ public long getTimestampMs() {
+ return mTimestampNs / 1000000;
+ }
+
+ @Override
+ public String toString() {
+ return String.format((Locale) null, "{near=%s, timestamp_ns=%d}", mBelow, mTimestampNs);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java
new file mode 100644
index 000000000000..546333b3a073
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import android.content.res.Resources;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.util.Assert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+class ThresholdSensorImpl implements ThresholdSensor {
+ private static final String TAG = "ThresholdSensor";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private final AsyncSensorManager mSensorManager;
+ private final Sensor mSensor;
+ private final float mThreshold;
+ private boolean mRegistered;
+ private boolean mPaused;
+ private List<Listener> mListeners = new ArrayList<>();
+ private Boolean mLastBelow;
+ private String mTag;
+ private int mSensorDelay;
+
+ private SensorEventListener mSensorEventListener = new SensorEventListener() {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ boolean below = event.values[0] < mThreshold;
+ logDebug("Sensor value: " + event.values[0]);
+ onSensorEvent(below, event.timestamp);
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+ };
+
+ private ThresholdSensorImpl(AsyncSensorManager sensorManager,
+ Sensor sensor, float threshold, int sensorDelay) {
+ mSensorManager = sensorManager;
+ mSensor = sensor;
+ mThreshold = threshold;
+ mSensorDelay = sensorDelay;
+ }
+
+ @Override
+ public void setTag(String tag) {
+ mTag = tag;
+ }
+
+ @Override
+ public void setDelay(int delay) {
+ if (delay == mSensorDelay) {
+ return;
+ }
+
+ mSensorDelay = delay;
+ if (isLoaded()) {
+ unregisterInternal();
+ registerInternal();
+ }
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return mSensor != null;
+ }
+
+ @VisibleForTesting
+ boolean isRegistered() {
+ return mRegistered;
+ }
+
+ /**
+ * Registers the listener with the sensor.
+ *
+ * Multiple listeners are not supported at this time.
+ *
+ * Returns true if the listener was successfully registered. False otherwise.
+ */
+ @Override
+ public void register(Listener listener) {
+ Assert.isMainThread();
+ if (!mListeners.contains(listener)) {
+ mListeners.add(listener);
+ }
+ registerInternal();
+ }
+
+ @Override
+ public void unregister(Listener listener) {
+ Assert.isMainThread();
+ mListeners.remove(listener);
+ unregisterInternal();
+ }
+
+ /**
+ * Unregister with the {@link SensorManager} without unsetting listeners on this object.
+ */
+ @Override
+ public void pause() {
+ Assert.isMainThread();
+ mPaused = true;
+ unregisterInternal();
+ }
+
+ /**
+ * Register with the {@link SensorManager}. No-op if no listeners are registered on this object.
+ */
+ @Override
+ public void resume() {
+ Assert.isMainThread();
+ mPaused = false;
+ registerInternal();
+ }
+
+ private void alertListenersInternal(boolean below, long timestampNs) {
+ List<Listener> listeners = new ArrayList<>(mListeners);
+ listeners.forEach(listener ->
+ listener.onThresholdCrossed(new ThresholdSensorEvent(below, timestampNs)));
+ }
+
+ private void registerInternal() {
+ Assert.isMainThread();
+ if (mRegistered || mPaused || mListeners.isEmpty()) {
+ return;
+ }
+ logDebug("Registering sensor listener");
+ mSensorManager.registerListener(mSensorEventListener, mSensor, mSensorDelay);
+ mRegistered = true;
+ }
+
+ private void unregisterInternal() {
+ Assert.isMainThread();
+ if (!mRegistered) {
+ return;
+ }
+ logDebug("Unregister sensor listener");
+ mSensorManager.unregisterListener(mSensorEventListener);
+ mRegistered = false;
+ mLastBelow = null; // Forget what we know.
+ }
+
+ private void onSensorEvent(boolean below, long timestampNs) {
+ Assert.isMainThread();
+ if (mLastBelow != null && mLastBelow == below) {
+ return;
+ }
+ mLastBelow = below;
+ alertListenersInternal(below, timestampNs);
+ }
+
+
+ @Override
+ public String toString() {
+ return String.format("{registered=%s, paused=%s, threshold=%s, sensor=%s}",
+ isLoaded(), mRegistered, mPaused, mThreshold, mSensor);
+ }
+
+ private void logDebug(String msg) {
+ if (DEBUG) {
+ Log.d(TAG, (mTag != null ? "[" + mTag + "] " : "") + msg);
+ }
+ }
+
+ static class Builder {
+ private final Resources mResources;
+ private final AsyncSensorManager mSensorManager;
+ private int mSensorDelay = SensorManager.SENSOR_DELAY_NORMAL;;
+ private float mThresholdValue;
+ private Sensor mSensor;
+ private boolean mSensorSet;
+ private boolean mThresholdSet;
+
+ @Inject
+ Builder(@Main Resources resources, AsyncSensorManager sensorManager) {
+ mResources = resources;
+ mSensorManager = sensorManager;
+ }
+
+
+ Builder setSensorDelay(int sensorDelay) {
+ mSensorDelay = sensorDelay;
+ return this;
+ }
+
+ Builder setSensorResourceId(int sensorResourceId) {
+ setSensorType(mResources.getString(sensorResourceId));
+ return this;
+ }
+
+ Builder setThresholdResourceId(int thresholdResourceId) {
+ try {
+ setThresholdValue(mResources.getFloat(thresholdResourceId));
+ } catch (Resources.NotFoundException e) {
+ // no-op
+ }
+ return this;
+ }
+
+ Builder setSensorType(String sensorType) {
+ Sensor sensor = findSensorByType(sensorType);
+ if (sensor != null) {
+ setSensor(sensor);
+ }
+ return this;
+ }
+
+ Builder setThresholdValue(float thresholdValue) {
+ mThresholdValue = thresholdValue;
+ mThresholdSet = true;
+ return this;
+ }
+
+ Builder setSensor(Sensor sensor) {
+ mSensor = sensor;
+ mSensorSet = true;
+ return this;
+ }
+
+ /**
+ * Creates a {@link ThresholdSensor} backed by a {@link ThresholdSensorImpl}.
+ */
+ public ThresholdSensor build() {
+ if (!mSensorSet) {
+ throw new IllegalStateException("A sensor was not successfully set.");
+ }
+
+ if (!mThresholdSet) {
+ throw new IllegalStateException("A threshold was not successfully set.");
+ }
+
+ return new ThresholdSensorImpl(
+ mSensorManager, mSensor, mThresholdValue, mSensorDelay);
+ }
+
+ private Sensor findSensorByType(String sensorType) {
+ if (sensorType.isEmpty()) {
+ return null;
+ }
+
+ List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ Sensor sensor = null;
+ for (Sensor s : sensorList) {
+ if (sensorType.equals(s.getStringType())) {
+ sensor = s;
+ break;
+ }
+ }
+
+ return sensor;
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
index 8b5cc9abb777..ffe062598102 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java
@@ -35,6 +35,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.sensors.ProximitySensor;
+import com.android.systemui.util.sensors.ThresholdSensor;
import org.junit.Before;
import org.junit.Test;
@@ -77,7 +78,7 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
@Test
public void testRegisterSensor() {
mFalsingManager.onScreenTurningOn();
- verify(mProximitySensor).register(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).register(any(ThresholdSensor.Listener.class));
}
@Test
@@ -85,7 +86,7 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
mFalsingManager.onScreenTurningOn();
reset(mProximitySensor);
mFalsingManager.onScreenOff();
- verify(mProximitySensor).unregister(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class));
}
@Test
@@ -93,9 +94,9 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
mFalsingManager.onScreenTurningOn();
reset(mProximitySensor);
mFalsingManager.setQsExpanded(true);
- verify(mProximitySensor).unregister(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class));
mFalsingManager.setQsExpanded(false);
- verify(mProximitySensor).register(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).register(any(ThresholdSensor.Listener.class));
}
@Test
@@ -103,9 +104,9 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
mFalsingManager.onScreenTurningOn();
reset(mProximitySensor);
mFalsingManager.onBouncerShown();
- verify(mProximitySensor).unregister(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class));
mFalsingManager.onBouncerHidden();
- verify(mProximitySensor).register(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).register(any(ThresholdSensor.Listener.class));
}
@Test
@@ -113,6 +114,6 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
mFalsingManager.onScreenTurningOn();
reset(mProximitySensor);
mStatusBarStateController.setState(StatusBarState.SHADE);
- verify(mProximitySensor).unregister(any(ProximitySensor.ProximitySensorListener.class));
+ verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
index 5b32a39403cd..3cebf0d6af57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
@@ -136,7 +136,8 @@ public class ProximityClassifierTest extends ClassifierTest {
motionEvent.recycle();
}
- private ProximitySensor.ProximityEvent createSensorEvent(boolean covered, long timestampMs) {
- return new ProximitySensor.ProximityEvent(covered, timestampMs * NS_PER_MS);
+ private ProximitySensor.ThresholdSensorEvent createSensorEvent(
+ boolean covered, long timestampMs) {
+ return new ProximitySensor.ThresholdSensorEvent(covered, timestampMs * NS_PER_MS);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 317500cf5b02..2208ac0dcbbd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -46,6 +46,7 @@ import com.android.systemui.doze.DozeSensors.TriggerSensor;
import com.android.systemui.plugins.SensorManagerPlugin;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.sensors.AsyncSensorManager;
+import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.wakelock.WakeLock;
import org.junit.Before;
@@ -83,6 +84,9 @@ public class DozeSensorsTest extends SysuiTestCase {
private DozeLog mDozeLog;
@Mock
private Sensor mProximitySensor;
+ @Mock
+ private ProximitySensor mMockProxSensor;
+
private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
private TestableLooper mTestableLooper;
private DozeSensors mDozeSensors;
@@ -104,9 +108,9 @@ public class DozeSensorsTest extends SysuiTestCase {
@Test
public void testRegisterProx() {
// We should not register with the sensor manager initially.
- verify(mSensorManager, never()).registerListener(any(), any(Sensor.class), anyInt());
+ verify(mMockProxSensor).pause();
mDozeSensors.setProxListening(true);
- verify(mSensorManager).registerListener(any(), any(Sensor.class), anyInt());
+ verify(mMockProxSensor).resume();
}
@Test
@@ -169,7 +173,8 @@ public class DozeSensorsTest extends SysuiTestCase {
TestableDozeSensors() {
super(getContext(), mAlarmManager, mSensorManager, mDozeParameters,
- mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog);
+ mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog,
+ mMockProxSensor);
for (TriggerSensor sensor : mSensors) {
if (sensor instanceof PluginSensor
&& ((PluginSensor) sensor).mPluginSensor.getType()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index debc9d6430e0..1d2021721634 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -42,10 +42,13 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.FakeProximitySensor;
import com.android.systemui.util.sensors.FakeSensorManager;
+import com.android.systemui.util.sensors.FakeThresholdSensor;
import com.android.systemui.util.sensors.ProximitySensor;
+import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.wakelock.WakeLock;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -71,10 +74,12 @@ public class DozeTriggersTest extends SysuiTestCase {
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
private DockManager mDockManager;
+
private DozeTriggers mTriggers;
private FakeSensorManager mSensors;
private Sensor mTapSensor;
private FakeProximitySensor mProximitySensor;
+ private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
@Before
public void setUp() throws Exception {
@@ -86,7 +91,10 @@ public class DozeTriggersTest extends SysuiTestCase {
WakeLock wakeLock = new WakeLockFake();
AsyncSensorManager asyncSensorManager =
new AsyncSensorManager(mSensors, null, new Handler());
- mProximitySensor = new FakeProximitySensor(getContext().getResources(), asyncSensorManager);
+
+ FakeThresholdSensor thresholdSensor = new FakeThresholdSensor();
+ thresholdSensor.setLoaded(true);
+ mProximitySensor = new FakeProximitySensor(thresholdSensor, null, mExecutor);
mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, config, parameters,
asyncSensorManager, Handler.createAsync(Looper.myLooper()), wakeLock, true,
@@ -104,17 +112,17 @@ public class DozeTriggersTest extends SysuiTestCase {
mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
clearInvocations(mMachine);
- mProximitySensor.setLastEvent(new ProximitySensor.ProximityEvent(true, 1));
+ mProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(true, 1));
captor.getValue().onNotificationAlerted(null /* pulseSuppressedListener */);
mProximitySensor.alertListeners();
verify(mMachine, never()).requestState(any());
verify(mMachine, never()).requestPulse(anyInt());
- captor.getValue().onNotificationAlerted(null /* pulseSuppressedListener */);
- waitForSensorManager();
- mProximitySensor.setLastEvent(new ProximitySensor.ProximityEvent(false, 2));
+ mProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(false, 2));
mProximitySensor.alertListeners();
+ waitForSensorManager();
+ captor.getValue().onNotificationAlerted(null /* pulseSuppressedListener */);
verify(mMachine).requestPulse(anyInt());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
index 31d884c38f58..16edc9d9cf82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
@@ -16,13 +16,15 @@
package com.android.systemui.util.sensors;
-import android.content.res.Resources;
+import com.android.systemui.util.concurrency.DelayableExecutor;
public class FakeProximitySensor extends ProximitySensor {
private boolean mAvailable;
- public FakeProximitySensor(Resources resources, AsyncSensorManager sensorManager) {
- super(resources, sensorManager);
+ public FakeProximitySensor(ThresholdSensor primary, ThresholdSensor secondary,
+ DelayableExecutor delayableExecutor) {
+ super(primary, secondary == null ? new FakeThresholdSensor() : secondary,
+ delayableExecutor);
mAvailable = true;
}
@@ -30,12 +32,12 @@ public class FakeProximitySensor extends ProximitySensor {
mAvailable = available;
}
- public void setLastEvent(ProximityEvent event) {
+ public void setLastEvent(ThresholdSensorEvent event) {
mLastEvent = event;
}
@Override
- public boolean getSensorAvailable() {
+ public boolean isLoaded() {
return mAvailable;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java
new file mode 100644
index 000000000000..d9f978944cde
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FakeThresholdSensor implements ThresholdSensor {
+ private boolean mIsLoaded;
+ private boolean mPaused;
+ private List<Listener> mListeners = new ArrayList<>();
+
+ public FakeThresholdSensor() {
+ }
+
+ public void setTag(String tag) {
+ }
+
+ @Override
+ public void setDelay(int delay) {
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return mIsLoaded;
+ }
+
+ @Override
+ public void pause() {
+ mPaused = true;
+ }
+
+ @Override
+ public void resume() {
+ mPaused = false;
+ }
+
+ @Override
+ public void register(ThresholdSensor.Listener listener) {
+ mListeners.add(listener);
+ }
+
+ @Override
+ public void unregister(ThresholdSensor.Listener listener) {
+ mListeners.remove(listener);
+ }
+
+ public void setLoaded(boolean loaded) {
+ mIsLoaded = loaded;
+ }
+
+ void triggerEvent(boolean below, long timestampNs) {
+ if (!mPaused) {
+ for (Listener listener : mListeners) {
+ listener.onThresholdCrossed(new ThresholdSensorEvent(below, timestampNs));
+ }
+ }
+ }
+
+ boolean isPaused() {
+ return mPaused;
+ }
+
+ int getNumListeners() {
+ return mListeners.size();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java
new file mode 100644
index 000000000000..a39c20169518
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ProximitySensorDualTest extends SysuiTestCase {
+ private ProximitySensor mProximitySensor;
+ private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+ private FakeThresholdSensor mThresholdSensorPrimary;
+ private FakeThresholdSensor mThresholdSensorSecondary;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ allowTestableLooperAsMainThread();
+ mThresholdSensorPrimary = new FakeThresholdSensor();
+ mThresholdSensorPrimary.setLoaded(true);
+ mThresholdSensorSecondary = new FakeThresholdSensor();
+ mThresholdSensorSecondary.setLoaded(true);
+
+ mProximitySensor = new ProximitySensor(
+ mThresholdSensorPrimary, mThresholdSensorSecondary, mFakeExecutor);
+ }
+
+ @Test
+ public void testSingleListener() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mProximitySensor.isRegistered());
+ mProximitySensor.register(listener);
+ assertTrue(mProximitySensor.isRegistered());
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger second sensor. Nothing should happen yet.
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger first sensor. Our second sensor is now registered.
+ mThresholdSensorPrimary.triggerEvent(true, 0);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertFalse(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger second sensor.
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+ assertTrue(mThresholdSensorSecondary.isPaused());
+
+ mProximitySensor.unregister(listener);
+ }
+
+ @Test
+ public void testSecondaryPausing() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mProximitySensor.isRegistered());
+ mProximitySensor.register(listener);
+ assertTrue(mProximitySensor.isRegistered());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger first sensor. Our second sensor is now registered.
+ mThresholdSensorPrimary.triggerEvent(true, 0);
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger second sensor.
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+ assertTrue(mThresholdSensorSecondary.isPaused());
+
+ // Advance time. Second sensor should resume.
+ mFakeExecutor.advanceClockToNext();
+ mFakeExecutor.runNextReady();
+ assertFalse(mThresholdSensorSecondary.isPaused());
+
+ // Triggering should pause again.
+ mThresholdSensorSecondary.triggerEvent(false, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
+ assertTrue(mThresholdSensorSecondary.isPaused());
+
+ mProximitySensor.unregister(listener);
+ }
+
+ @Test
+ public void testUnregister() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mProximitySensor.isRegistered());
+ mProximitySensor.register(listener);
+ assertTrue(mProximitySensor.isRegistered());
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+
+ mThresholdSensorPrimary.triggerEvent(true, 0);
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+
+ mProximitySensor.unregister(listener);
+ assertTrue(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertFalse(mProximitySensor.isRegistered());
+ }
+
+ @Test
+ public void testPauseAndResume() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mProximitySensor.isRegistered());
+ mProximitySensor.register(listener);
+ assertTrue(mProximitySensor.isRegistered());
+ assertNull(listener.mLastEvent);
+
+ mThresholdSensorPrimary.triggerEvent(true, 0);
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+
+ mProximitySensor.pause();
+ assertFalse(mProximitySensor.isRegistered());
+ assertTrue(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+
+ // More events do nothing when paused.
+ mThresholdSensorSecondary.triggerEvent(false, 1);
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+
+ mProximitySensor.resume();
+ assertTrue(mProximitySensor.isRegistered());
+ // Still matches our previous call
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+
+ // Need to trigger the primary sensor before the secondary re-registers itself.
+ mThresholdSensorPrimary.triggerEvent(true, 3);
+ mThresholdSensorSecondary.triggerEvent(false, 3);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
+
+ mProximitySensor.unregister(listener);
+ assertFalse(mProximitySensor.isRegistered());
+ }
+
+ @Test
+ public void testPrimarySecondaryDisagreement() {
+ TestableListener listener = new TestableListener();
+
+ mProximitySensor.register(listener);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger our sensors with different values. Secondary overrides primary.
+ mThresholdSensorPrimary.triggerEvent(true, 0);
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+ mThresholdSensorSecondary.triggerEvent(false, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+
+ mThresholdSensorSecondary.resume();
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
+
+ mThresholdSensorSecondary.resume();
+ mThresholdSensorSecondary.triggerEvent(false, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(3, listener.mCallCount);
+
+ mProximitySensor.unregister(listener);
+ }
+
+ @Test
+ public void testPrimaryCancelsSecondary() {
+ TestableListener listener = new TestableListener();
+
+ mProximitySensor.register(listener);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ mThresholdSensorPrimary.triggerEvent(true, 0);
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+
+ // When the primary reports false, the secondary is no longer needed. We get an immediate
+ // report.
+ mThresholdSensorPrimary.triggerEvent(false, 1);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
+
+ // The secondary is now ignored. No more work is scheduled.
+ mFakeExecutor.advanceClockToNext();
+ mFakeExecutor.runNextReady();
+ mThresholdSensorSecondary.triggerEvent(true, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
+ assertEquals(0, mFakeExecutor.numPending());
+
+ mProximitySensor.unregister(listener);
+ }
+
+ private static class TestableListener implements ThresholdSensor.Listener {
+ ThresholdSensor.ThresholdSensorEvent mLastEvent;
+ int mCallCount = 0;
+
+ @Override
+ public void onThresholdCrossed(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ mLastEvent = proximityEvent;
+ mCallCount++;
+ }
+ };
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorSingleTest.java
index 526fba726e9d..f1cee5061695 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorSingleTest.java
@@ -21,33 +21,40 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+/**
+ * Tests for ProximitySensor that rely on a single hardware sensor.
+ */
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class ProximitySensorTest extends SysuiTestCase {
-
+public class ProximitySensorSingleTest extends SysuiTestCase {
private ProximitySensor mProximitySensor;
- private FakeSensorManager.FakeProximitySensor mFakeProximitySensor;
+ private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+ private FakeThresholdSensor mThresholdSensor;
@Before
public void setUp() throws Exception {
- FakeSensorManager sensorManager = new FakeSensorManager(getContext());
- AsyncSensorManager asyncSensorManager = new AsyncSensorManager(
- sensorManager, null, new Handler());
- mFakeProximitySensor = sensorManager.getFakeProximitySensor();
- mProximitySensor = new ProximitySensor(getContext().getResources(), asyncSensorManager);
+ MockitoAnnotations.initMocks(this);
+ allowTestableLooperAsMainThread();
+ mThresholdSensor = new FakeThresholdSensor();
+ mThresholdSensor.setLoaded(true);
+
+ mProximitySensor = new ProximitySensor(
+ mThresholdSensor, new FakeThresholdSensor(), mFakeExecutor);
}
@Test
@@ -56,19 +63,17 @@ public class ProximitySensorTest extends SysuiTestCase {
assertFalse(mProximitySensor.isRegistered());
mProximitySensor.register(listener);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
assertNull(listener.mLastEvent);
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 1);
- mFakeProximitySensor.sendProximityResult(false);
- assertTrue(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 2);
+ mThresholdSensor.triggerEvent(false, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+ mThresholdSensor.triggerEvent(true, 0);
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
mProximitySensor.unregister(listener);
- waitForSensorManager();
}
@Test
@@ -79,28 +84,25 @@ public class ProximitySensorTest extends SysuiTestCase {
assertFalse(mProximitySensor.isRegistered());
mProximitySensor.register(listenerA);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
mProximitySensor.register(listenerB);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
assertNull(listenerA.mLastEvent);
assertNull(listenerB.mLastEvent);
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listenerA.mLastEvent.getNear());
- assertFalse(listenerB.mLastEvent.getNear());
- assertEquals(listenerA.mCallCount, 1);
- assertEquals(listenerB.mCallCount, 1);
- mFakeProximitySensor.sendProximityResult(false);
- assertTrue(listenerA.mLastEvent.getNear());
- assertTrue(listenerB.mLastEvent.getNear());
- assertEquals(listenerA.mCallCount, 2);
- assertEquals(listenerB.mCallCount, 2);
+ mThresholdSensor.triggerEvent(false, 0);
+ assertFalse(listenerA.mLastEvent.getBelow());
+ assertFalse(listenerB.mLastEvent.getBelow());
+ assertEquals(1, listenerA.mCallCount);
+ assertEquals(1, listenerB.mCallCount);
+ mThresholdSensor.triggerEvent(true, 1);
+ assertTrue(listenerA.mLastEvent.getBelow());
+ assertTrue(listenerB.mLastEvent.getBelow());
+ assertEquals(2, listenerA.mCallCount);
+ assertEquals(2, listenerB.mCallCount);
mProximitySensor.unregister(listenerA);
mProximitySensor.unregister(listenerB);
- waitForSensorManager();
}
@Test
@@ -110,22 +112,19 @@ public class ProximitySensorTest extends SysuiTestCase {
assertFalse(mProximitySensor.isRegistered());
mProximitySensor.register(listenerA);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
mProximitySensor.register(listenerA);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
assertNull(listenerA.mLastEvent);
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listenerA.mLastEvent.getNear());
- assertEquals(listenerA.mCallCount, 1);
- mFakeProximitySensor.sendProximityResult(false);
- assertTrue(listenerA.mLastEvent.getNear());
- assertEquals(listenerA.mCallCount, 2);
+ mThresholdSensor.triggerEvent(false, 0);
+ assertFalse(listenerA.mLastEvent.getBelow());
+ assertEquals(1, listenerA.mCallCount);
+ mThresholdSensor.triggerEvent(true, 1);
+ assertTrue(listenerA.mLastEvent.getBelow());
+ assertEquals(2, listenerA.mCallCount);
mProximitySensor.unregister(listenerA);
- waitForSensorManager();
}
@Test
public void testUnregister() {
@@ -133,16 +132,14 @@ public class ProximitySensorTest extends SysuiTestCase {
assertFalse(mProximitySensor.isRegistered());
mProximitySensor.register(listener);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
assertNull(listener.mLastEvent);
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 1);
+ mThresholdSensor.triggerEvent(false, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
mProximitySensor.unregister(listener);
- waitForSensorManager();
assertFalse(mProximitySensor.isRegistered());
}
@@ -152,39 +149,35 @@ public class ProximitySensorTest extends SysuiTestCase {
assertFalse(mProximitySensor.isRegistered());
mProximitySensor.register(listener);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
assertNull(listener.mLastEvent);
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 1);
+ mThresholdSensor.triggerEvent(false, 0);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
mProximitySensor.pause();
- waitForSensorManager();
assertFalse(mProximitySensor.isRegistered());
// More events do nothing when paused.
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 1);
- mFakeProximitySensor.sendProximityResult(false);
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 1);
+ mThresholdSensor.triggerEvent(false, 1);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
+ mThresholdSensor.triggerEvent(true, 2);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
mProximitySensor.resume();
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
// Still matches our previous call
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 1);
+ assertFalse(listener.mLastEvent.getBelow());
+ assertEquals(1, listener.mCallCount);
- mFakeProximitySensor.sendProximityResult(true);
- assertFalse(listener.mLastEvent.getNear());
- assertEquals(listener.mCallCount, 2);
+ mThresholdSensor.triggerEvent(true, 3);
+ assertTrue(listener.mLastEvent.getBelow());
+ assertEquals(2, listener.mCallCount);
mProximitySensor.unregister(listener);
- waitForSensorManager();
assertFalse(mProximitySensor.isRegistered());
}
@@ -197,46 +190,35 @@ public class ProximitySensorTest extends SysuiTestCase {
mProximitySensor.register(listenerA);
mProximitySensor.register(listenerB);
- waitForSensorManager();
assertTrue(mProximitySensor.isRegistered());
assertNull(listenerA.mLastEvent);
assertNull(listenerB.mLastEvent);
mProximitySensor.alertListeners();
assertNull(listenerA.mLastEvent);
- assertEquals(listenerA.mCallCount, 1);
+ assertEquals(0, listenerA.mCallCount);
assertNull(listenerB.mLastEvent);
- assertEquals(listenerB.mCallCount, 1);
+ assertEquals(0, listenerB.mCallCount);
- mFakeProximitySensor.sendProximityResult(false);
- assertTrue(listenerA.mLastEvent.getNear());
- assertEquals(listenerA.mCallCount, 2);
- assertTrue(listenerB.mLastEvent.getNear());
- assertEquals(listenerB.mCallCount, 2);
+ mThresholdSensor.triggerEvent(true, 0);
+ assertTrue(listenerA.mLastEvent.getBelow());
+ assertEquals(1, listenerA.mCallCount);
+ assertTrue(listenerB.mLastEvent.getBelow());
+ assertEquals(1, listenerB.mCallCount);
mProximitySensor.unregister(listenerA);
mProximitySensor.unregister(listenerB);
- waitForSensorManager();
}
- class TestableListener implements ProximitySensor.ProximitySensorListener {
- ProximitySensor.ProximityEvent mLastEvent;
+ private static class TestableListener implements ThresholdSensor.Listener {
+ ThresholdSensor.ThresholdSensorEvent mLastEvent;
int mCallCount = 0;
@Override
- public void onSensorEvent(ProximitySensor.ProximityEvent proximityEvent) {
+ public void onThresholdCrossed(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
mLastEvent = proximityEvent;
mCallCount++;
}
-
- void reset() {
- mLastEvent = null;
- mCallCount = 0;
- }
};
- private void waitForSensorManager() {
- TestableLooper.get(this).processAllMessages();
- }
-
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java
new file mode 100644
index 000000000000..09ec8e55efd6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.sensors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Handler;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ThresholdSensorImplTest extends SysuiTestCase {
+
+ private ThresholdSensorImpl mThresholdSensor;
+ private FakeSensorManager.FakeProximitySensor mFakeProximitySensor;
+
+ @Before
+ public void setUp() throws Exception {
+ allowTestableLooperAsMainThread();
+ FakeSensorManager sensorManager = new FakeSensorManager(getContext());
+
+ AsyncSensorManager asyncSensorManager = new AsyncSensorManager(
+ sensorManager, null, new Handler());
+
+ mFakeProximitySensor = sensorManager.getFakeProximitySensor();
+ ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder(
+ null, asyncSensorManager);
+ mThresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder
+ .setSensor(mFakeProximitySensor.getSensor())
+ .setThresholdValue(mFakeProximitySensor.getSensor().getMaximumRange())
+ .build();
+ }
+
+ @Test
+ public void testSingleListener() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mThresholdSensor.isRegistered());
+ mThresholdSensor.register(listener);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ assertEquals(0, listener.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listener.mBelow);
+ assertEquals(1, listener.mCallCount);
+ mFakeProximitySensor.sendProximityResult(false);
+ assertTrue(listener.mBelow);
+ assertEquals(2, listener.mCallCount);
+
+ mThresholdSensor.unregister(listener);
+ waitForSensorManager();
+ }
+
+ @Test
+ public void testMultiListener() {
+ TestableListener listenerA = new TestableListener();
+ TestableListener listenerB = new TestableListener();
+
+ assertFalse(mThresholdSensor.isRegistered());
+
+ mThresholdSensor.register(listenerA);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ mThresholdSensor.register(listenerB);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ assertEquals(0, listenerA.mCallCount);
+ assertEquals(0, listenerB.mCallCount);
+
+
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listenerA.mBelow);
+ assertFalse(listenerB.mBelow);
+ assertEquals(1, listenerA.mCallCount);
+ assertEquals(1, listenerB.mCallCount);
+ mFakeProximitySensor.sendProximityResult(false);
+ assertTrue(listenerA.mBelow);
+ assertTrue(listenerB.mBelow);
+ assertEquals(2, listenerA.mCallCount);
+ assertEquals(2, listenerB.mCallCount);
+
+ mThresholdSensor.unregister(listenerA);
+ mThresholdSensor.unregister(listenerB);
+ waitForSensorManager();
+ }
+
+ @Test
+ public void testDuplicateListener() {
+ TestableListener listenerA = new TestableListener();
+
+ assertFalse(mThresholdSensor.isRegistered());
+
+ mThresholdSensor.register(listenerA);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ mThresholdSensor.register(listenerA);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ assertEquals(0, listenerA.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listenerA.mBelow);
+ assertEquals(1, listenerA.mCallCount);
+ mFakeProximitySensor.sendProximityResult(false);
+ assertTrue(listenerA.mBelow);
+ assertEquals(2, listenerA.mCallCount);
+
+ mThresholdSensor.unregister(listenerA);
+ waitForSensorManager();
+ }
+ @Test
+ public void testUnregister() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mThresholdSensor.isRegistered());
+ mThresholdSensor.register(listener);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ assertEquals(0, listener.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listener.mBelow);
+ assertEquals(1, listener.mCallCount);
+
+ mThresholdSensor.unregister(listener);
+ waitForSensorManager();
+ assertFalse(mThresholdSensor.isRegistered());
+ }
+
+ @Test
+ public void testPauseAndResume() {
+ TestableListener listener = new TestableListener();
+
+ assertFalse(mThresholdSensor.isRegistered());
+ mThresholdSensor.register(listener);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ assertEquals(0, listener.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listener.mBelow);
+ assertEquals(1, listener.mCallCount);
+
+ mThresholdSensor.pause();
+ waitForSensorManager();
+ assertFalse(mThresholdSensor.isRegistered());
+
+ // More events do nothing when paused.
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listener.mBelow);
+ assertEquals(1, listener.mCallCount);
+ mFakeProximitySensor.sendProximityResult(false);
+ assertFalse(listener.mBelow);
+ assertEquals(1, listener.mCallCount);
+
+ mThresholdSensor.resume();
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ // Still matches our previous call
+ assertFalse(listener.mBelow);
+ assertEquals(1, listener.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(false);
+ assertTrue(listener.mBelow);
+ assertEquals(2, listener.mCallCount);
+
+ mThresholdSensor.unregister(listener);
+ waitForSensorManager();
+ assertFalse(mThresholdSensor.isRegistered());
+ }
+
+ @Test
+ public void testAlertListeners() {
+ TestableListener listenerA = new TestableListener();
+ TestableListener listenerB = new TestableListener();
+
+ assertFalse(mThresholdSensor.isRegistered());
+
+ mThresholdSensor.register(listenerA);
+ mThresholdSensor.register(listenerB);
+ waitForSensorManager();
+ assertTrue(mThresholdSensor.isRegistered());
+ assertEquals(0, listenerA.mCallCount);
+ assertEquals(0, listenerB.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(true);
+ assertFalse(listenerA.mBelow);
+ assertEquals(1, listenerA.mCallCount);
+ assertFalse(listenerB.mBelow);
+ assertEquals(1, listenerB.mCallCount);
+
+ mFakeProximitySensor.sendProximityResult(false);
+ assertTrue(listenerA.mBelow);
+ assertEquals(2, listenerA.mCallCount);
+ assertTrue(listenerB.mBelow);
+ assertEquals(2, listenerB.mCallCount);
+
+ mThresholdSensor.unregister(listenerA);
+ mThresholdSensor.unregister(listenerB);
+ waitForSensorManager();
+ }
+
+ static class TestableListener implements ThresholdSensor.Listener {
+ boolean mBelow;
+ long mTimestampNs;
+ int mCallCount;
+
+ @Override
+ public void onThresholdCrossed(ThresholdSensor.ThresholdSensorEvent event) {
+ mBelow = event.getBelow();
+ mTimestampNs = event.getTimestampNs();
+ mCallCount++;
+ }
+ }
+
+ private void waitForSensorManager() {
+ TestableLooper.get(this).processAllMessages();
+ }
+
+}
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index dcdb80b497d0..1ffc8265f48a 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -47,7 +47,9 @@ LOCAL_REQUIRED_MODULES := \
IconPackRoundedThemePickerOverlay \
IconShapeRoundedRectOverlay \
IconShapeSquircleOverlay \
+ IconShapeTaperedRectOverlay \
IconShapeTeardropOverlay \
+ IconShapeVesselOverlay \
NavigationBarMode3ButtonOverlay \
NavigationBarModeGesturalOverlay \
NavigationBarModeGesturalOverlayNarrowBack \
diff --git a/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml b/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml
index 82bff7d53d95..8fb19df33178 100644
--- a/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml
@@ -21,6 +21,7 @@
android:versionName="1.0">
<overlay
android:targetPackage="android"
+ android:targetName="IconShapeCustomization"
android:category="android.theme.customization.adaptive_icon_shape"
android:priority="1"/>
diff --git a/packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml b/packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml
index bf408fd62569..e69de29bb2d1 100644
--- a/packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconShapeHexagonOverlay/AndroidManifest.xml
@@ -1,27 +0,0 @@
-<!--
- ~ Copyright (C) 2020 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.theme.icon.hexagon"
- android:versionCode="1"
- android:versionName="1.0">
- <overlay
- android:targetPackage="android"
- android:category="android.theme.customization.adaptive_icon_shape"
- android:priority="1"/>
-
- <application android:label="@string/icon_shape_hexagon_overlay" android:hasCode="false"/>
-</manifest>
diff --git a/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml b/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml
index d719a97e28f2..6842dde36264 100644
--- a/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml
@@ -21,6 +21,7 @@
android:versionName="1.0">
<overlay
android:targetPackage="android"
+ android:targetName="IconShapeCustomization"
android:category="android.theme.customization.adaptive_icon_shape"
android:priority="1"/>
diff --git a/packages/overlays/IconShapeHexagonOverlay/Android.mk b/packages/overlays/IconShapeTaperedRectOverlay/Android.mk
index 16ef3995dedd..6f1bf2370a15 100644
--- a/packages/overlays/IconShapeHexagonOverlay/Android.mk
+++ b/packages/overlays/IconShapeTaperedRectOverlay/Android.mk
@@ -17,13 +17,13 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_RRO_THEME := IconShapeHexagon
+LOCAL_RRO_THEME := IconShapeTaperedRect
LOCAL_PRODUCT_MODULE := true
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_PACKAGE_NAME := IconShapeHexagonOverlay
+LOCAL_PACKAGE_NAME := IconShapeTaperedRectOverlay
LOCAL_SDK_VERSION := current
include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconShapeTaperedRectOverlay/AndroidManifest.xml b/packages/overlays/IconShapeTaperedRectOverlay/AndroidManifest.xml
new file mode 100644
index 000000000000..363e33ce450e
--- /dev/null
+++ b/packages/overlays/IconShapeTaperedRectOverlay/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon.taperedrect"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay
+ android:targetPackage="android"
+ android:targetName="IconShapeCustomization"
+ android:category="android.theme.customization.adaptive_icon_shape"
+ android:priority="1"/>
+
+ <application android:label="@string/icon_shape_tapered_rect_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconShapeHexagonOverlay/res/values/config.xml b/packages/overlays/IconShapeTaperedRectOverlay/res/values/config.xml
index f7cb5951b4f1..ace06406c13c 100644
--- a/packages/overlays/IconShapeHexagonOverlay/res/values/config.xml
+++ b/packages/overlays/IconShapeTaperedRectOverlay/res/values/config.xml
@@ -16,7 +16,7 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
- <string name="config_icon_mask" translatable="false">"M12,0 88,0 100,50 88,100 12,100 0,50 12,0 Z"</string>
+ <string name="config_icon_mask" translatable="false">"M20,0 80,0 100,20 100,80 80,100 20,100 0,80 0,20 20,0 Z"</string>
<!-- Flag indicating whether round icons should be parsed from the application manifest. -->
<bool name="config_useRoundIcon">false</bool>
<!-- Corner radius of system dialogs -->
diff --git a/packages/overlays/IconShapeHexagonOverlay/res/values/strings.xml b/packages/overlays/IconShapeTaperedRectOverlay/res/values/strings.xml
index e00dc9d938ec..3f36598a89bc 100644
--- a/packages/overlays/IconShapeHexagonOverlay/res/values/strings.xml
+++ b/packages/overlays/IconShapeTaperedRectOverlay/res/values/strings.xml
@@ -14,7 +14,7 @@
~ limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Hexagon icon overlay -->
- <string name="icon_shape_hexagon_overlay" translatable="false">Hexagon</string>
+ <!-- Tapered rect icon overlay -->
+ <string name="icon_shape_tapered_rect_overlay" translatable="false">Tapered Rect</string>
</resources>
diff --git a/packages/overlays/IconShapeFlowerOverlay/Android.mk b/packages/overlays/IconShapeVesselOverlay/Android.mk
index d410bb72b723..0816e6f7800d 100644
--- a/packages/overlays/IconShapeFlowerOverlay/Android.mk
+++ b/packages/overlays/IconShapeVesselOverlay/Android.mk
@@ -17,13 +17,13 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_RRO_THEME := IconShapeFlower
+LOCAL_RRO_THEME := IconShapeVessel
LOCAL_PRODUCT_MODULE := true
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_PACKAGE_NAME := IconShapeFlowerOverlay
+LOCAL_PACKAGE_NAME := IconShapeVesselOverlay
LOCAL_SDK_VERSION := current
include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconShapeFlowerOverlay/AndroidManifest.xml b/packages/overlays/IconShapeVesselOverlay/AndroidManifest.xml
index 9d20c6b6f82c..24f52dd99bd5 100644
--- a/packages/overlays/IconShapeFlowerOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconShapeVesselOverlay/AndroidManifest.xml
@@ -14,13 +14,14 @@
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.theme.icon.flower"
+ package="com.android.theme.icon.vessel"
android:versionCode="1"
android:versionName="1.0">
<overlay
android:targetPackage="android"
+ android:targetName="IconShapeCustomization"
android:category="android.theme.customization.adaptive_icon_shape"
android:priority="1"/>
- <application android:label="@string/icon_shape_flower_overlay" android:hasCode="false"/>
+ <application android:label="@string/icon_shape_vessel_overlay" android:hasCode="false"/>
</manifest>
diff --git a/packages/overlays/IconShapeFlowerOverlay/res/values/config.xml b/packages/overlays/IconShapeVesselOverlay/res/values/config.xml
index 73f4f2175a4b..86d31f6450bc 100644
--- a/packages/overlays/IconShapeFlowerOverlay/res/values/config.xml
+++ b/packages/overlays/IconShapeVesselOverlay/res/values/config.xml
@@ -16,7 +16,7 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
- <string name="config_icon_mask" translatable="false">"M50,0 C60.6,0 69.9,5.3 75.6,13.5 78.5,17.8 82.3,21.5 86.6,24.5 94.7,30.1 100,39.4 100,50 100,60.6 94.7,69.9 86.5,75.6 82.2,78.5 78.5,82.3 75.5,86.6 69.9,94.7 60.6,100 50,100 39.4,100 30.1,94.7 24.4,86.5 21.5,82.2 17.7,78.5 13.4,75.5 5.3,69.9 0,60.6 0,50 0,39.4 5.3,30.1 13.5,24.4 17.8,21.5 21.5,17.7 24.5,13.4 30.1,5.3 39.4,0 50,0 Z"</string>
+ <string name="config_icon_mask" translatable="false">"M12.97,0 C8.41,0 4.14,2.55 2.21,6.68 -1.03,13.61 -0.71,21.78 3.16,28.46 4.89,31.46 4.89,35.2 3.16,38.2 -1.05,45.48 -1.05,54.52 3.16,61.8 4.89,64.8 4.89,68.54 3.16,71.54 -0.71,78.22 -1.03,86.39 2.21,93.32 4.14,97.45 8.41,100 12.97,100 21.38,100 78.62,100 87.03,100 91.59,100 95.85,97.45 97.79,93.32 101.02,86.39 100.71,78.22 96.84,71.54 95.1,68.54 95.1,64.8 96.84,61.8 101.05,54.52 101.05,45.48 96.84,38.2 95.1,35.2 95.1,31.46 96.84,28.46 100.71,21.78 101.02,13.61 97.79,6.68 95.85,2.55 91.59,0 87.03,0 78.62,0 21.38,0 12.97,0 Z"</string>
<!-- Flag indicating whether round icons should be parsed from the application manifest. -->
<bool name="config_useRoundIcon">false</bool>
<!-- Corner radius of system dialogs -->
diff --git a/packages/overlays/IconShapeFlowerOverlay/res/values/strings.xml b/packages/overlays/IconShapeVesselOverlay/res/values/strings.xml
index 47c1479e5a40..a50e7e9a9ab2 100644
--- a/packages/overlays/IconShapeFlowerOverlay/res/values/strings.xml
+++ b/packages/overlays/IconShapeVesselOverlay/res/values/strings.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Flower icon overlay -->
- <string name="icon_shape_flower_overlay" translatable="false">Flower</string>
+ <!-- Vessel icon overlay -->
+ <string name="icon_shape_vessel_overlay" translatable="false">Vessel</string>
</resources>