diff options
12 files changed, 229 insertions, 71 deletions
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index fc728a22ed5a..4708f3e0664f 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -104,6 +104,9 @@ public class CameraDeviceImpl extends CameraDevice private SparseArray<CaptureCallbackHolder> mCaptureCallbackMap = new SparseArray<CaptureCallbackHolder>(); + /** map request IDs which have batchedOutputs to requestCount*/ + private HashMap<Integer, Integer> mBatchOutputMap = new HashMap<>(); + private int mRepeatingRequestId = REQUEST_ID_NONE; // Latest repeating request list's types private int[] mRepeatingRequestTypes; @@ -973,6 +976,7 @@ public class CameraDeviceImpl extends CameraDevice mConfiguredInput = new SimpleEntry<Integer, InputConfiguration>(REQUEST_ID_NONE, null); mIdle = true; mCaptureCallbackMap = new SparseArray<CaptureCallbackHolder>(); + mBatchOutputMap = new HashMap<>(); mFrameNumberTracker = new FrameNumberTracker(); mCurrentSession.closeWithoutDraining(); @@ -1179,6 +1183,41 @@ public class CameraDeviceImpl extends CameraDevice return requestTypes; } + private boolean hasBatchedOutputs(List<CaptureRequest> requestList) { + boolean hasBatchedOutputs = true; + for (int i = 0; i < requestList.size(); i++) { + CaptureRequest request = requestList.get(i); + if (!request.isPartOfCRequestList()) { + hasBatchedOutputs = false; + break; + } + if (i == 0) { + Collection<Surface> targets = request.getTargets(); + if (targets.size() != 2) { + hasBatchedOutputs = false; + break; + } + } + } + return hasBatchedOutputs; + } + + private void updateTracker(int requestId, long frameNumber, + int requestType, CaptureResult result, boolean isPartialResult) { + int requestCount = 1; + // If the request has batchedOutputs update each frame within the batch. + if (mBatchOutputMap.containsKey(requestId)) { + requestCount = mBatchOutputMap.get(requestId); + for (int i = 0; i < requestCount; i++) { + mFrameNumberTracker.updateTracker(frameNumber - (requestCount - 1 - i), + result, isPartialResult, requestType); + } + } else { + mFrameNumberTracker.updateTracker(frameNumber, result, + isPartialResult, requestType); + } + } + private int submitCaptureRequest(List<CaptureRequest> requestList, CaptureCallback callback, Executor executor, boolean repeating) throws CameraAccessException { @@ -1224,6 +1263,14 @@ public class CameraDeviceImpl extends CameraDevice request.recoverStreamIdToSurface(); } + // If the request has batched outputs, then store the + // requestCount and requestId in the map. + boolean hasBatchedOutputs = hasBatchedOutputs(requestList); + if (hasBatchedOutputs) { + int requestCount = requestList.size(); + mBatchOutputMap.put(requestInfo.getRequestId(), requestCount); + } + if (callback != null) { mCaptureCallbackMap.put(requestInfo.getRequestId(), new CaptureCallbackHolder( @@ -1839,8 +1886,18 @@ public class CameraDeviceImpl extends CameraDevice if (DEBUG) { Log.v(TAG, String.format("got error frame %d", frameNumber)); } - mFrameNumberTracker.updateTracker(frameNumber, - /*error*/true, request.getRequestType()); + + // Update FrameNumberTracker for every frame during HFR mode. + if (mBatchOutputMap.containsKey(requestId)) { + for (int i = 0; i < mBatchOutputMap.get(requestId); i++) { + mFrameNumberTracker.updateTracker(frameNumber - (subsequenceId - i), + /*error*/true, request.getRequestType()); + } + } else { + mFrameNumberTracker.updateTracker(frameNumber, + /*error*/true, request.getRequestType()); + } + checkAndFireSequenceComplete(); // Dispatch the failure callback @@ -2023,7 +2080,6 @@ public class CameraDeviceImpl extends CameraDevice public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras, PhysicalCaptureResultInfo physicalResults[]) throws RemoteException { - int requestId = resultExtras.getRequestId(); long frameNumber = resultExtras.getFrameNumber(); @@ -2064,8 +2120,8 @@ public class CameraDeviceImpl extends CameraDevice + frameNumber); } - mFrameNumberTracker.updateTracker(frameNumber, /*result*/null, isPartialResult, - requestType); + updateTracker(requestId, frameNumber, requestType, /*result*/null, + isPartialResult); return; } @@ -2077,8 +2133,9 @@ public class CameraDeviceImpl extends CameraDevice + frameNumber); } - mFrameNumberTracker.updateTracker(frameNumber, /*result*/null, isPartialResult, - requestType); + updateTracker(requestId, frameNumber, requestType, /*result*/null, + isPartialResult); + return; } @@ -2184,9 +2241,7 @@ public class CameraDeviceImpl extends CameraDevice Binder.restoreCallingIdentity(ident); } - // Collect the partials for a total result; or mark the frame as totally completed - mFrameNumberTracker.updateTracker(frameNumber, finalResult, isPartialResult, - requestType); + updateTracker(requestId, frameNumber, requestType, finalResult, isPartialResult); // Fire onCaptureSequenceCompleted if (!isPartialResult) { diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 431bf4c54b4b..217e17ddd7b4 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -258,6 +258,13 @@ public final class DeviceConfig { public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler"; /** + * Namespace for all lmkd related features. + * + * @hide + */ + public static final String NAMESPACE_LMKD_NATIVE = "lmkd_native"; + + /** * Namespace for all location related features. * * @hide diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 954ca14b4960..e511bffad247 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -445,6 +445,9 @@ public class OneHandedController implements RemoteCallable<OneHandedController> mOneHandedSettingsUtil.registerSettingsKeyObserver( Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, mContext.getContentResolver(), mShortcutEnabledObserver, newUserId); + mOneHandedSettingsUtil.registerSettingsKeyObserver( + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, + mContext.getContentResolver(), mShortcutEnabledObserver, newUserId); } private void unregisterSettingObservers() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java index 7cf4fb7a811d..ff333c8c659d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java @@ -171,9 +171,22 @@ public final class OneHandedSettingsUtil { * @return true if user enabled one-handed shortcut in settings, false otherwise. */ public boolean getShortcutEnabled(ContentResolver resolver, int userId) { - final String targets = Settings.Secure.getStringForUser(resolver, + // Checks SOFTWARE_SHORTCUT_KEY + final String targetsSwKey = Settings.Secure.getStringForUser(resolver, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userId); - return TextUtils.isEmpty(targets) ? false : targets.contains(ONE_HANDED_MODE_TARGET_NAME); + if (!TextUtils.isEmpty(targetsSwKey) && targetsSwKey.contains( + ONE_HANDED_MODE_TARGET_NAME)) { + return true; + } + + // Checks HARDWARE_SHORTCUT_KEY + final String targetsHwKey = Settings.Secure.getStringForUser(resolver, + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, userId); + if (!TextUtils.isEmpty(targetsHwKey) && targetsHwKey.contains( + ONE_HANDED_MODE_TARGET_NAME)) { + return true; + } + return false; } /** diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index 9c818fff5018..e232316b8a94 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -40,6 +40,7 @@ import com.android.systemui.util.ViewController import java.io.PrintWriter import javax.inject.Inject import javax.inject.Provider +import com.android.systemui.plugins.statusbar.StatusBarStateController /*** * Controls the ripple effect that shows when authentication is successful. @@ -57,6 +58,7 @@ class AuthRippleController @Inject constructor( private val bypassController: KeyguardBypassController, private val biometricUnlockController: BiometricUnlockController, private val udfpsControllerProvider: Provider<UdfpsController>, + private val statusBarStateController: StatusBarStateController, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView) { var fingerprintSensorLocation: PointF? = null @@ -64,8 +66,11 @@ class AuthRippleController @Inject constructor( private var circleReveal: LightRevealEffect? = null private var udfpsController: UdfpsController? = null + private var dwellScale = 2f private var expandedDwellScale = 2.5f + private var aodDwellScale = 1.9f + private var aodExpandedDwellScale = 2.3f private var udfpsRadius: Float = -1f override fun onInit() { @@ -163,6 +168,22 @@ class AuthRippleController @Inject constructor( Utils.getColorAttr(sysuiContext, android.R.attr.colorAccent).defaultColor) } + private fun showDwellRipple() { + if (statusBarStateController.isDozing) { + mView.startDwellRipple( + /* startRadius */ udfpsRadius, + /* endRadius */ udfpsRadius * aodDwellScale, + /* expandedRadius */ udfpsRadius * aodExpandedDwellScale, + /* isDozing */ true) + } else { + mView.startDwellRipple( + /* startRadius */ udfpsRadius, + /* endRadius */ udfpsRadius * dwellScale, + /* expandedRadius */ udfpsRadius * expandedDwellScale, + /* isDozing */ false) + } + } + private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { override fun onBiometricAuthenticated( @@ -204,10 +225,7 @@ class AuthRippleController @Inject constructor( } mView.setSensorLocation(fingerprintSensorLocation!!) - mView.startDwellRipple( - /* startRadius */ udfpsRadius, - /* endRadius */ udfpsRadius * dwellScale, - /* expandedRadius */ udfpsRadius * expandedDwellScale) + showDwellRipple() } override fun onFingerUp() { @@ -234,14 +252,18 @@ class AuthRippleController @Inject constructor( } inner class AuthRippleCommand : Command { - fun printDwellInfo(pw: PrintWriter) { - pw.println("dwell ripple: " + + fun printLockScreenDwellInfo(pw: PrintWriter) { + pw.println("lock screen dwell ripple: " + "\n\tsensorLocation=$fingerprintSensorLocation" + "\n\tdwellScale=$dwellScale" + - "\n\tdwellAlpha=${mView.dwellAlpha}, " + - "duration=${mView.dwellAlphaDuration}" + - "\n\tdwellExpand=$expandedDwellScale" + - "\n\t(crash systemui to reset to default)") + "\n\tdwellExpand=$expandedDwellScale") + } + + fun printAodDwellInfo(pw: PrintWriter) { + pw.println("aod dwell ripple: " + + "\n\tsensorLocation=$fingerprintSensorLocation" + + "\n\tdwellScale=$aodDwellScale" + + "\n\tdwellExpand=$aodExpandedDwellScale") } override fun execute(pw: PrintWriter, args: List<String>) { @@ -249,40 +271,12 @@ class AuthRippleController @Inject constructor( invalidCommand(pw) } else { when (args[0]) { - "dwellScale" -> { - if (args.size > 1 && args[1].toFloatOrNull() != null) { - dwellScale = args[1].toFloat() - printDwellInfo(pw) - } else { - pw.println("expected float argument <dwellScale>") - } - } - "dwellAlpha" -> { - if (args.size > 2 && args[1].toFloatOrNull() != null && - args[2].toLongOrNull() != null) { - mView.dwellAlpha = args[1].toFloat() - if (args[2].toFloat() > 200L) { - pw.println("alpha animation duration must be less than 200ms.") - } - mView.dwellAlphaDuration = kotlin.math.min(args[2].toLong(), 200L) - printDwellInfo(pw) - } else { - pw.println("expected two float arguments:" + - " <dwellAlpha> <dwellAlphaDuration>") - } - } - "dwellExpand" -> { - if (args.size > 1 && args[1].toFloatOrNull() != null) { - val expandedScale = args[1].toFloat() - if (expandedScale <= dwellScale) { - pw.println("invalid expandedScale. must be greater than " + - "dwellScale=$dwellScale, but given $expandedScale") - } else { - expandedDwellScale = expandedScale - } - printDwellInfo(pw) + "dwell" -> { + showDwellRipple() + if (statusBarStateController.isDozing) { + printAodDwellInfo(pw) } else { - pw.println("expected float argument <expandedScale>") + printLockScreenDwellInfo(pw) } } "fingerprint" -> { @@ -313,9 +307,7 @@ class AuthRippleController @Inject constructor( override fun help(pw: PrintWriter) { pw.println("Usage: adb shell cmd statusbar auth-ripple <command>") pw.println("Available commands:") - pw.println(" dwellScale <200ms_scale: float>") - pw.println(" dwellAlpha <alpha: float> <duration : long>") - pw.println(" dwellExpand <expanded_scale: float>") + pw.println(" dwell") pw.println(" fingerprint") pw.println(" face") pw.println(" custom <x-location: int> <y-location: int>") diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt index 8e1303713171..1113579e417c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt @@ -45,12 +45,18 @@ private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f */ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private val retractInterpolator = PathInterpolator(.05f, .93f, .1f, 1f) - private val dwellPulseDuration = 200L - var dwellAlphaDuration = dwellPulseDuration + + private val dwellPulseDuration = 50L + private val dwellAlphaDuration = dwellPulseDuration + private val dwellAlpha: Float = 1f private val dwellExpandDuration = 1200L - dwellPulseDuration - private val retractDuration = 400L - var dwellAlpha: Float = .5f + private val aodDwellPulseDuration = 50L + private var aodDwellAlphaDuration = aodDwellPulseDuration + private var aodDwellAlpha: Float = .8f + private var aodDwellExpandDuration = 1200L - aodDwellPulseDuration + + private val retractDuration = 400L private var alphaInDuration: Long = 0 private var unlockedRippleInProgress: Boolean = false private val rippleShader = RippleShader() @@ -142,7 +148,12 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at * Ripple that moves animates from an outer ripple ring of * startRadius => endRadius => expandedRadius */ - fun startDwellRipple(startRadius: Float, endRadius: Float, expandedRadius: Float) { + fun startDwellRipple( + startRadius: Float, + endRadius: Float, + expandedRadius: Float, + isDozing: Boolean + ) { if (unlockedRippleInProgress || dwellPulseOutAnimator?.isRunning == true) { return } @@ -153,12 +164,13 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val endInitialDwellProgress = endRadius / radius / 4f val endExpandDwellProgress = expandedRadius / radius / 4f - val pulseOutEndAlpha = (255 * dwellAlpha).toInt() - val expandDwellEndAlpha = kotlin.math.min((255 * (dwellAlpha + .25f)).toInt(), 255) + val alpha = if (isDozing) aodDwellAlpha else dwellAlpha + val pulseOutEndAlpha = (255 * alpha).toInt() + val expandDwellEndAlpha = kotlin.math.min((255 * (alpha + .25f)).toInt(), 255) val dwellPulseOutRippleAnimator = ValueAnimator.ofFloat(startDwellProgress, endInitialDwellProgress).apply { interpolator = Interpolators.LINEAR_OUT_SLOW_IN - duration = dwellPulseDuration + duration = if (isDozing) aodDwellPulseDuration else dwellPulseDuration addUpdateListener { animator -> val now = animator.currentPlayTime rippleShader.progress = animator.animatedValue as Float @@ -170,7 +182,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val dwellPulseOutAlphaAnimator = ValueAnimator.ofInt(0, pulseOutEndAlpha).apply { interpolator = Interpolators.LINEAR - duration = dwellAlphaDuration + duration = if (isDozing) aodDwellAlphaDuration else dwellAlphaDuration addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, @@ -184,7 +196,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val expandDwellRippleAnimator = ValueAnimator.ofFloat(endInitialDwellProgress, endExpandDwellProgress).apply { interpolator = Interpolators.LINEAR_OUT_SLOW_IN - duration = dwellExpandDuration + duration = if (isDozing) aodDwellExpandDuration else dwellExpandDuration addUpdateListener { animator -> val now = animator.currentPlayTime rippleShader.progress = animator.animatedValue as Float @@ -197,7 +209,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at val expandDwellAlphaAnimator = ValueAnimator.ofInt(pulseOutEndAlpha, expandDwellEndAlpha) .apply { interpolator = Interpolators.LINEAR - duration = dwellExpandDuration + duration = if (isDozing) aodDwellExpandDuration else dwellExpandDuration addUpdateListener { animator -> rippleShader.color = ColorUtils.setAlphaComponent( rippleShader.color, diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt index 3f6380f7ef70..d0aa710ecea6 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt @@ -29,6 +29,7 @@ import android.util.Log import androidx.annotation.MainThread import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread +import com.android.internal.logging.UiEventLogger import com.android.systemui.appops.AppOpsController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -67,6 +68,7 @@ class PrivacyDialogController( private val privacyLogger: PrivacyLogger, private val keyguardStateController: KeyguardStateController, private val appOpsController: AppOpsController, + private val uiEventLogger: UiEventLogger, @VisibleForTesting private val dialogProvider: DialogProvider ) { @@ -81,7 +83,8 @@ class PrivacyDialogController( @Main uiExecutor: Executor, privacyLogger: PrivacyLogger, keyguardStateController: KeyguardStateController, - appOpsController: AppOpsController + appOpsController: AppOpsController, + uiEventLogger: UiEventLogger ) : this( permissionManager, packageManager, @@ -93,6 +96,7 @@ class PrivacyDialogController( privacyLogger, keyguardStateController, appOpsController, + uiEventLogger, defaultDialogProvider ) @@ -105,6 +109,7 @@ class PrivacyDialogController( private val onDialogDismissed = object : PrivacyDialog.OnDialogDismissed { override fun onDialogDismissed() { privacyLogger.logPrivacyDialogDismissed() + uiEventLogger.log(PrivacyDialogEvent.PRIVACY_DIALOG_DISMISSED) dialog = null } } @@ -114,6 +119,8 @@ class PrivacyDialogController( val intent = Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS) intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName) intent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)) + uiEventLogger.log(PrivacyDialogEvent.PRIVACY_DIALOG_ITEM_CLICKED_TO_APP_SETTINGS, + userId, packageName) privacyLogger.logStartSettingsActivityFromDialog(packageName, userId) if (!keyguardStateController.isUnlocked) { // If we are locked, hide the dialog so the user can unlock diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogEvent.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogEvent.kt new file mode 100644 index 000000000000..3ecc5a5e5b00 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogEvent.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021 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.privacy + +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger + +enum class PrivacyDialogEvent(private val _id: Int) : UiEventLogger.UiEventEnum { + @UiEvent(doc = "Privacy dialog is clicked by user to go to the app settings page.") + PRIVACY_DIALOG_ITEM_CLICKED_TO_APP_SETTINGS(904), + + @UiEvent(doc = "Privacy dialog is dismissed by user.") + PRIVACY_DIALOG_DISMISSED(905); + + override fun getId() = _id +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 3653b95351b0..720690fde9e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -194,6 +194,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private boolean mLastGesturalNav; private boolean mLastIsDocked; private boolean mLastPulsing; + private boolean mLastAnimatedToSleep; private int mLastBiometricMode; private boolean mQsExpanded; private boolean mAnimatedToSleep; @@ -992,6 +993,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mLastBiometricMode = mBiometricUnlockController.getMode(); mLastGesturalNav = mGesturalNav; mLastIsDocked = mIsDocked; + mLastAnimatedToSleep = mAnimatedToSleep; mStatusBar.onKeyguardViewManagerStatesUpdated(); } @@ -1035,7 +1037,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb boolean hideWhileDozing = mLastDozing && mLastBiometricMode != MODE_WAKE_AND_UNLOCK_PULSING; boolean keyguardWithGestureNav = (keyguardShowing && !mLastDozing || mLastPulsing && !mLastIsDocked) && mLastGesturalNav; - return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing + return (!mLastAnimatedToSleep && !keyguardShowing && !hideWhileDozing || mLastBouncerShowing || mLastRemoteInputActive || keyguardWithGestureNav || mLastGlobalActionsVisible); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt index 8f5eefcff186..5c73077c0e69 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt @@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.phone.BiometricUnlockController @@ -59,6 +60,7 @@ class AuthRippleControllerTest : SysuiTestCase() { @Mock private lateinit var biometricUnlockController: BiometricUnlockController @Mock private lateinit var udfpsControllerProvider: Provider<UdfpsController> @Mock private lateinit var udfpsController: UdfpsController + @Mock private lateinit var statusBarStateController: StatusBarStateController @Before fun setUp() { @@ -76,6 +78,7 @@ class AuthRippleControllerTest : SysuiTestCase() { bypassController, biometricUnlockController, udfpsControllerProvider, + statusBarStateController, rippleView ) controller.init() diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt index 8181d3070618..511848d8a3af 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt @@ -28,6 +28,7 @@ import android.permission.PermGroupUsage import android.permission.PermissionManager import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest +import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpsController import com.android.systemui.plugins.ActivityStarter @@ -54,6 +55,7 @@ import org.mockito.Mockito.`when` import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.mock import org.mockito.Mockito.never +import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -97,6 +99,8 @@ class PrivacyDialogControllerTest : SysuiTestCase() { private lateinit var activityStartedCaptor: ArgumentCaptor<ActivityStarter.Callback> @Captor private lateinit var intentCaptor: ArgumentCaptor<Intent> + @Mock + private lateinit var uiEventLogger: UiEventLogger private val backgroundExecutor = FakeExecutor(FakeSystemClock()) private val uiExecutor = FakeExecutor(FakeSystemClock()) @@ -137,6 +141,7 @@ class PrivacyDialogControllerTest : SysuiTestCase() { privacyLogger, keyguardStateController, appOpsController, + uiEventLogger, dialogProvider ) } @@ -566,6 +571,34 @@ class PrivacyDialogControllerTest : SysuiTestCase() { verify(dialog).show() } + @Test + fun testStartActivityLogs() { + val usage = createMockPermGroupUsage() + `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage)) + controller.showDialog(context) + exhaustExecutors() + + dialogProvider.starter?.invoke(TEST_PACKAGE_NAME, USER_ID) + verify(uiEventLogger).log(PrivacyDialogEvent.PRIVACY_DIALOG_ITEM_CLICKED_TO_APP_SETTINGS, + USER_ID, TEST_PACKAGE_NAME) + } + + @Test + fun testDismissedDialogLogs() { + val usage = createMockPermGroupUsage() + `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage)) + controller.showDialog(context) + exhaustExecutors() + + verify(dialog).addOnDismissListener(capture(dialogDismissedCaptor)) + + dialogDismissedCaptor.value.onDialogDismissed() + + controller.dismissDialog() + + verify(uiEventLogger, times(1)).log(PrivacyDialogEvent.PRIVACY_DIALOG_DISMISSED) + } + private fun exhaustExecutors() { FakeExecutor.exhaustExecutors(backgroundExecutor, uiExecutor) } diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index e022e977e02f..2f20efbf5730 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -84,6 +84,7 @@ public class SettingsToPropertiesMapper { DeviceConfig.NAMESPACE_CONNECTIVITY, DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT, DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS, + DeviceConfig.NAMESPACE_LMKD_NATIVE, DeviceConfig.NAMESPACE_MEDIA_NATIVE, DeviceConfig.NAMESPACE_NETD_NATIVE, DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, |