diff options
25 files changed, 357 insertions, 259 deletions
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig index 70d8891f0677..a480a3b013bb 100644 --- a/core/java/android/permission/flags.aconfig +++ b/core/java/android/permission/flags.aconfig @@ -493,3 +493,9 @@ flag { bug: "341941666" } +flag { + name: "sqlite_discrete_op_event_logging_enabled" + namespace: "permissions" + description: "Collect sqlite performance metrics for discrete ops." + bug: "377584611" +} diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 992790e092d1..053ccdd73c8c 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -250,11 +250,14 @@ public final class Choreographer { /** * Set flag to indicate that client is blocked waiting for buffer release and - * buffer stuffing recovery should soon begin. + * buffer stuffing recovery should soon begin. This is provided with the + * duration of time in nanoseconds that the client was blocked for. * @hide */ - public void onWaitForBufferRelease() { - mBufferStuffingState.isStuffed.set(true); + public void onWaitForBufferRelease(long durationNanos) { + if (durationNanos > mLastFrameIntervalNanos / 2) { + mBufferStuffingState.isStuffed.set(true); + } } /** diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 780e76122e8a..dd32947c69e4 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -2391,4 +2391,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } } + + @Override + public CharSequence getAccessibilityClassName() { + return SurfaceView.class.getName(); + } } diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index ebc86ee96f75..0c6eaae601a8 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -918,6 +918,11 @@ public class TextureView extends View { mLastFrameTimeMillis = now; } + @Override + public CharSequence getAccessibilityClassName() { + return TextureView.class.getName(); + } + @UnsupportedAppUsage private final SurfaceTexture.OnFrameAvailableListener mUpdateListener = surfaceTexture -> { diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp index 7b61a5db0b41..10d6d33c5a76 100644 --- a/core/jni/android_graphics_BLASTBufferQueue.cpp +++ b/core/jni/android_graphics_BLASTBufferQueue.cpp @@ -107,10 +107,11 @@ public: } } - void onWaitForBufferRelease() { + void onWaitForBufferRelease(const nsecs_t durationNanos) { JNIEnv* env = getenv(mVm); getenv(mVm)->CallVoidMethod(mWaitForBufferReleaseObject, - gWaitForBufferReleaseCallback.onWaitForBufferRelease); + gWaitForBufferReleaseCallback.onWaitForBufferRelease, + durationNanos); DieIfException(env, "Uncaught exception in WaitForBufferReleaseCallback."); } @@ -255,7 +256,9 @@ static void nativeSetWaitForBufferReleaseCallback(JNIEnv* env, jclass clazz, jlo } else { sp<WaitForBufferReleaseCallbackWrapper> wrapper = new WaitForBufferReleaseCallbackWrapper{env, waitForBufferReleaseCallback}; - queue->setWaitForBufferReleaseCallback([wrapper]() { wrapper->onWaitForBufferRelease(); }); + queue->setWaitForBufferReleaseCallback([wrapper](const nsecs_t durationNanos) { + wrapper->onWaitForBufferRelease(durationNanos); + }); } } @@ -305,7 +308,7 @@ int register_android_graphics_BLASTBufferQueue(JNIEnv* env) { jclass waitForBufferReleaseClass = FindClassOrDie(env, "android/graphics/BLASTBufferQueue$WaitForBufferReleaseCallback"); gWaitForBufferReleaseCallback.onWaitForBufferRelease = - GetMethodIDOrDie(env, waitForBufferReleaseClass, "onWaitForBufferRelease", "()V"); + GetMethodIDOrDie(env, waitForBufferReleaseClass, "onWaitForBufferRelease", "(J)V"); return 0; } diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 1c34e0d54908..9b9be244cf90 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -61,8 +61,10 @@ public final class BLASTBufferQueue { /** * Indicates that the client is waiting on buffer release * due to no free buffers being available to render into. + * @param durationNanos The length of time in nanoseconds + * that the client was blocked on buffer release. */ - void onWaitForBufferRelease(); + void onWaitForBufferRelease(long durationNanos); } /** Create a new connection with the surface flinger. */ diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 1a7ae724ec59..f753316cb67a 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1940,3 +1940,10 @@ flag { description: "Force promoted notifications to always be expanded" bug: "380901479" } + +flag { + name: "aod_ui_rich_ongoing" + namespace: "systemui" + description: "Show a rich ongoing notification on the always-on display (depends on ui_rich_ongoing)" + bug: "369151941" +}
\ No newline at end of file diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt index fe9da0ddb3c1..88c8b1fbb4ce 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor import android.app.admin.DevicePolicyManager import android.os.UserHandle +import android.view.accessibility.AccessibilityManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils @@ -96,6 +97,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { @Mock private lateinit var shadeInteractor: ShadeInteractor @Mock private lateinit var logger: KeyguardQuickAffordancesLogger @Mock private lateinit var metricsLogger: KeyguardQuickAffordancesMetricsLogger + @Mock private lateinit var accessibilityManager: AccessibilityManager private lateinit var underTest: KeyguardQuickAffordanceInteractor @@ -199,11 +201,13 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { backgroundDispatcher = kosmos.testDispatcher, appContext = context, communalSettingsInteractor = kosmos.communalSettingsInteractor, + accessibilityManager = accessibilityManager, sceneInteractor = { kosmos.sceneInteractor }, ) kosmos.keyguardQuickAffordanceInteractor = underTest whenever(shadeInteractor.anyExpansion).thenReturn(MutableStateFlow(0f)) + whenever(accessibilityManager.isEnabled()).thenReturn(false) } @Test @@ -672,6 +676,22 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { } @Test + fun useLongPress_withA11yEnabled_isFalse() = + testScope.runTest { + whenever(accessibilityManager.isEnabled()).thenReturn(true) + val useLongPress by collectLastValue(underTest.useLongPress()) + assertThat(useLongPress).isFalse() + } + + @Test + fun useLongPress_withA11yDisabled_isFalse() = + testScope.runTest { + whenever(accessibilityManager.isEnabled()).thenReturn(false) + val useLongPress by collectLastValue(underTest.useLongPress()) + assertThat(useLongPress).isTrue() + } + + @Test fun useLongPress_whenDocked_isFalse() = testScope.runTest { dockManager.setIsDocked(true) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt index b0af8b180cce..75262a4d058d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt @@ -23,6 +23,7 @@ import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos @@ -35,7 +36,14 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.core.StatusBarConnectedDisplays +import com.android.systemui.statusbar.core.StatusBarRootModernization +import com.android.systemui.statusbar.notification.data.model.activeNotificationModel +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository +import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore +import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel +import com.android.systemui.statusbar.notification.shared.CallType +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel @@ -44,6 +52,7 @@ import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runTest import org.junit.runner.RunWith +import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @@ -52,6 +61,7 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class CallChipViewModelTest : SysuiTestCase() { private val kosmos = Kosmos() + private val notificationListRepository = kosmos.activeNotificationListRepository private val testScope = kosmos.testScope private val repo = kosmos.ongoingCallRepository @@ -65,6 +75,8 @@ class CallChipViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } private val underTest by lazy { kosmos.callChipViewModel } @@ -337,6 +349,7 @@ class CallChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_inCall_nullIntent_nullClickListener() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -347,6 +360,7 @@ class CallChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_inCall_positiveStartTime_validIntent_clickListenerLaunchesIntent() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -364,6 +378,7 @@ class CallChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_inCall_zeroStartTime_validIntent_clickListenerLaunchesIntent() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -381,6 +396,72 @@ class CallChipViewModelTest : SysuiTestCase() { verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(pendingIntent, null) } + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_inCall_nullIntent_noneClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + postOngoingCallNotification( + repository = notificationListRepository, + startTimeMs = 1000L, + intent = null, + ) + + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.None::class.java) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_inCall_positiveStartTime_validIntent_clickBehaviorLaunchesIntent() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + val pendingIntent = mock<PendingIntent>() + postOngoingCallNotification( + repository = notificationListRepository, + startTimeMs = 1000L, + intent = pendingIntent, + ) + + val clickBehavior = (latest as OngoingActivityChipModel.Shown).clickBehavior + assertThat(clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + (clickBehavior as OngoingActivityChipModel.ClickBehavior.ExpandAction).onClick( + mockExpandable + ) + + // Ensure that the SysUI didn't modify the notification's intent by verifying it + // directly matches the `PendingIntent` set -- see b/212467440. + verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(pendingIntent, null) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_inCall_zeroStartTime_validIntent_clickBehaviorLaunchesIntent() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + val pendingIntent = mock<PendingIntent>() + postOngoingCallNotification( + repository = notificationListRepository, + startTimeMs = 0L, + intent = pendingIntent, + ) + + val clickBehavior = (latest as OngoingActivityChipModel.Shown).clickBehavior + assertThat(clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + (clickBehavior as OngoingActivityChipModel.ClickBehavior.ExpandAction).onClick( + mockExpandable + ) + + // Ensure that the SysUI didn't modify the notification's intent by verifying it + // directly matches the `PendingIntent` set -- see b/212467440. + verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(pendingIntent, null) + } + companion object { fun createStatusBarIconViewOrNull(): StatusBarIconView? = if (StatusBarConnectedDisplays.isEnabled) { @@ -389,6 +470,27 @@ class CallChipViewModelTest : SysuiTestCase() { mock<StatusBarIconView>() } + fun postOngoingCallNotification( + repository: ActiveNotificationListRepository, + startTimeMs: Long, + intent: PendingIntent?, + ) { + repository.activeNotifications.value = + ActiveNotificationsStore.Builder() + .apply { + addIndividualNotif( + activeNotificationModel( + key = "notif1", + whenTime = startTimeMs, + callType = CallType.Ongoing, + statusBarChipIcon = null, + contentIntent = intent, + ) + ) + } + .build() + } + private val PROMOTED_CONTENT_WITH_COLOR = PromotedNotificationContentModel.Builder("notif") .apply { diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt index f7ea25c8c0ca..b248043067ca 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt @@ -68,3 +68,11 @@ fun View.onTouchListener(listener: View.OnTouchListener): DisposableHandle { setOnTouchListener(listener) return DisposableHandle { setOnTouchListener(null) } } + +/** A null listener should also set the longClickable property to false */ +fun View.updateLongClickListener(listener: View.OnLongClickListener?) { + setOnLongClickListener(listener) + if (listener == null) { + setLongClickable(false) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt index 3911c196e967..e58807763597 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt @@ -31,6 +31,7 @@ import com.android.systemui.statusbar.notification.collection.SortBySectionTimeF import com.android.systemui.statusbar.notification.emptyshade.shared.ModesEmptyShadeFix import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi +import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiForceExpanded import com.android.systemui.statusbar.notification.shared.NotificationAvalancheSuppression import com.android.systemui.statusbar.notification.shared.NotificationMinimalism @@ -55,6 +56,9 @@ class FlagDependencies @Inject constructor(featureFlags: FeatureFlagsClassic, ha ModesEmptyShadeFix.token dependsOn modesUi PromotedNotificationUiForceExpanded.token dependsOn PromotedNotificationUi.token + + PromotedNotificationUiAod.token dependsOn PromotedNotificationUi.token + // SceneContainer dependencies SceneContainerFlag.getFlagDependencies().forEach { (alpha, beta) -> alpha dependsOn beta } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt index 7d8badd232b9..b866fcab2893 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt @@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent import android.util.Log +import android.view.accessibility.AccessibilityManager import com.android.app.tracing.coroutines.withContextTraced as withContext import com.android.compose.animation.scene.ObservableTransitionState import com.android.internal.widget.LockPatternUtils @@ -92,6 +93,7 @@ constructor( private val dockManager: DockManager, private val biometricSettingsRepository: BiometricSettingsRepository, private val communalSettingsInteractor: CommunalSettingsInteractor, + private val accessibilityManager: AccessibilityManager, @Background private val backgroundDispatcher: CoroutineDispatcher, @ShadeDisplayAware private val appContext: Context, private val sceneInteractor: Lazy<SceneInteractor>, @@ -115,7 +117,10 @@ constructor( * * If `false`, the UI goes back to using single taps. */ - fun useLongPress(): Flow<Boolean> = dockManager.retrieveIsDocked().map { !it } + fun useLongPress(): Flow<Boolean> = + dockManager.retrieveIsDocked().map { isDocked -> + !isDocked && !accessibilityManager.isEnabled() + } /** Returns an observable for the quick affordance at the given position. */ suspend fun quickAffordance( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt index 8a2e3dd791c2..f396cf99457f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt @@ -39,6 +39,7 @@ import com.android.systemui.animation.Expandable import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.binder.IconViewBinder +import com.android.systemui.common.ui.view.updateLongClickListener import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceHapticViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel @@ -275,6 +276,7 @@ constructor( ) } else { view.setOnClickListener(OnClickListener(viewModel, checkNotNull(falsingManager))) + view.updateLongClickListener(null) } } else { view.onLongClickListener = null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt index 108d737e7658..99e84729d9b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt @@ -37,6 +37,7 @@ import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel import com.android.systemui.statusbar.core.StatusBarConnectedDisplays +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -93,9 +94,7 @@ constructor( icon = icon, colors = colors, onClickListenerLegacy = getOnClickListener(state), - // TODO(b/372657935): Add click support for the call chip when - // StatusBarChipModernization is enabled. - clickBehavior = OngoingActivityChipModel.ClickBehavior.None, + clickBehavior = getClickBehavior(state), ) } else { val startTimeInElapsedRealtime = @@ -106,9 +105,7 @@ constructor( colors = colors, startTimeMs = startTimeInElapsedRealtime, onClickListenerLegacy = getOnClickListener(state), - // TODO(b/372657935): Add click support for the call chip when - // StatusBarChipModernization is enabled. - clickBehavior = OngoingActivityChipModel.ClickBehavior.None, + clickBehavior = getClickBehavior(state), ) } } @@ -122,6 +119,7 @@ constructor( } return View.OnClickListener { view -> + StatusBarChipsModernization.assertInLegacyMode() logger.log(TAG, LogLevel.INFO, {}, { "Chip clicked" }) val backgroundView = view.requireViewById<ChipBackgroundContainer>(R.id.ongoing_activity_chip_background) @@ -136,6 +134,27 @@ constructor( } } + private fun getClickBehavior( + state: OngoingCallModel.InCall + ): OngoingActivityChipModel.ClickBehavior = + if (state.intent == null) { + OngoingActivityChipModel.ClickBehavior.None + } else { + OngoingActivityChipModel.ClickBehavior.ExpandAction( + onClick = { expandable -> + StatusBarChipsModernization.assertInNewMode() + val animationController = + expandable.activityTransitionController( + InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP + ) + activityStarter.postStartActivityDismissingKeyguard( + state.intent, + animationController, + ) + } + ) + } + companion object { private val phoneIcon = Icon.Resource( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt new file mode 100644 index 000000000000..fa1f32cc367e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationUiAod.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2025 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.statusbar.notification.promoted + +import com.android.systemui.Flags +import com.android.systemui.flags.FlagToken +import com.android.systemui.flags.RefactorFlagUtils + +/** Helper for reading or using the promoted ongoing notifications AOD flag state. */ +object PromotedNotificationUiAod { + /** The aconfig flag name */ + const val FLAG_NAME = Flags.FLAG_AOD_UI_RICH_ONGOING + + /** A token used for dependency declaration */ + val token: FlagToken + get() = FlagToken(FLAG_NAME, isEnabled) + + /** Is the refactor enabled */ + @JvmStatic + inline val isEnabled + get() = Flags.aodUiRichOngoing() + + /** + * Called to ensure code is only run when the flag is enabled. This protects users from the + * unintended behaviors caused by accidentally running new logic, while also crashing on an eng + * build to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun isUnexpectedlyInLegacyMode() = + RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is not enabled to ensure that the refactor author catches issues in testing. + * Caution!! Using this check incorrectly will cause crashes in nextfood builds! + */ + @JvmStatic + inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt index 82bf5e248a50..a3c3d2cdbb43 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt @@ -205,6 +205,7 @@ class CustomizationProviderTest : SysuiTestCase() { biometricSettingsRepository = biometricSettingsRepository, backgroundDispatcher = testDispatcher, appContext = mContext, + accessibilityManager = mock(), communalSettingsInteractor = kosmos.communalSettingsInteractor, sceneInteractor = { kosmos.sceneInteractor }, ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt index 111d819b5a50..21519b0cb38a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt @@ -322,6 +322,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() { biometricSettingsRepository = biometricSettingsRepository, backgroundDispatcher = testDispatcher, appContext = mContext, + accessibilityManager = mock(), communalSettingsInteractor = kosmos.communalSettingsInteractor, sceneInteractor = { kosmos.sceneInteractor }, ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt index 8c00047296d1..caf08efc4b32 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt @@ -325,6 +325,7 @@ class KeyguardQuickAffordanceInteractorSceneContainerTest : SysuiTestCase() { biometricSettingsRepository = biometricSettingsRepository, backgroundDispatcher = testDispatcher, appContext = mContext, + accessibilityManager = mock(), communalSettingsInteractor = kosmos.communalSettingsInteractor, sceneInteractor = { kosmos.sceneInteractor }, ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt index 0b2b86785c75..b5a227104900 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt @@ -294,6 +294,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { biometricSettingsRepository = biometricSettingsRepository, backgroundDispatcher = kosmos.testDispatcher, appContext = mContext, + accessibilityManager = mock(), communalSettingsInteractor = kosmos.communalSettingsInteractor, sceneInteractor = { kosmos.sceneInteractor }, ), diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt index 3b1199a10531..ba64ed78f77c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor import android.app.admin.devicePolicyManager import android.content.applicationContext +import android.view.accessibility.AccessibilityManager import com.android.internal.widget.lockPatternUtils import com.android.keyguard.logging.KeyguardQuickAffordancesLogger import com.android.systemui.animation.dialogTransitionAnimator @@ -54,6 +55,7 @@ var Kosmos.keyguardQuickAffordanceInteractor by Fixture { dockManager = dockManager, biometricSettingsRepository = biometricSettingsRepository, communalSettingsInteractor = communalSettingsInteractor, + accessibilityManager = mock<AccessibilityManager>(), backgroundDispatcher = testDispatcher, appContext = applicationContext, sceneInteractor = { sceneInteractor }, diff --git a/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java b/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java index 695032e6476c..86f5d9bd637f 100644 --- a/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java +++ b/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java @@ -27,9 +27,13 @@ import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteRawStatement; import android.os.Environment; +import android.os.SystemClock; +import android.permission.flags.Flags; import android.util.IntArray; import android.util.Slog; +import com.android.internal.util.FrameworkStatsLog; + import java.io.File; import java.util.ArrayList; import java.util.List; @@ -76,6 +80,10 @@ class DiscreteOpsDbHelper extends SQLiteOpenHelper { if (opEvents.isEmpty()) { return; } + long startTime = 0; + if (Flags.sqliteDiscreteOpEventLoggingEnabled()) { + startTime = SystemClock.elapsedRealtime(); + } SQLiteDatabase db = getWritableDatabase(); // TODO (b/383157289) what if database is busy and can't start a transaction? will read @@ -117,6 +125,11 @@ class DiscreteOpsDbHelper extends SQLiteOpenHelper { + " file size (bytes) : " + getDatabaseFile().length(), exception); } } + if (Flags.sqliteDiscreteOpEventLoggingEnabled()) { + long timeTaken = SystemClock.elapsedRealtime() - startTime; + FrameworkStatsLog.write(FrameworkStatsLog.SQLITE_DISCRETE_OP_EVENT_REPORTED, + -1, timeTaken, getDatabaseFile().length()); + } } private void bindTextOrNull(SQLiteRawStatement statement, int index, @Nullable String text) { @@ -181,7 +194,10 @@ class DiscreteOpsDbHelper extends SQLiteOpenHelper { uidFilter, packageNameFilter, attributionTagFilter, opCodesFilter, opFlagsFilter); String sql = buildSql(conditions, orderByColumn, limit); - + long startTime = 0; + if (Flags.sqliteDiscreteOpEventLoggingEnabled()) { + startTime = SystemClock.elapsedRealtime(); + } SQLiteDatabase db = getReadableDatabase(); List<DiscreteOpsSqlRegistry.DiscreteOp> results = new ArrayList<>(); db.beginTransactionReadOnly(); @@ -225,6 +241,11 @@ class DiscreteOpsDbHelper extends SQLiteOpenHelper { } finally { db.endTransaction(); } + if (Flags.sqliteDiscreteOpEventLoggingEnabled()) { + long timeTaken = SystemClock.elapsedRealtime() - startTime; + FrameworkStatsLog.write(FrameworkStatsLog.SQLITE_DISCRETE_OP_EVENT_REPORTED, + timeTaken, -1, getDatabaseFile().length()); + } return results; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java index 76d16e19e774..a81a0b3251c8 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java @@ -73,9 +73,6 @@ import java.util.stream.Collectors; class ActiveAdmin { - private final int userId; - public final boolean isPermissionBased; - private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features"; private static final String TAG_TEST_ONLY_ADMIN = "test-only-admin"; private static final String TAG_DISABLE_CAMERA = "disable-camera"; @@ -364,23 +361,8 @@ class ActiveAdmin { private static final int PROVISIONING_CONTEXT_LENGTH_LIMIT = 1000; ActiveAdmin(DeviceAdminInfo info, boolean isParent) { - this.userId = -1; this.info = info; this.isParent = isParent; - this.isPermissionBased = false; - } - - ActiveAdmin(int userId, boolean permissionBased) { - if (Flags.activeAdminCleanup()) { - throw new UnsupportedOperationException("permission based admin no longer supported"); - } - if (permissionBased == false) { - throw new IllegalArgumentException("Can only pass true for permissionBased admin"); - } - this.userId = userId; - this.isPermissionBased = permissionBased; - this.isParent = false; - this.info = null; } ActiveAdmin getParentActiveAdmin() { @@ -397,16 +379,10 @@ class ActiveAdmin { } int getUid() { - if (isPermissionBased) { - return -1; - } return info.getActivityInfo().applicationInfo.uid; } public UserHandle getUserHandle() { - if (isPermissionBased) { - return UserHandle.of(userId); - } return UserHandle.of(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid)); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java index c937e10a28ce..89c8b560ea95 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; -import android.app.admin.flags.Flags; import android.content.ComponentName; import android.os.FileUtils; import android.os.PersistableBundle; @@ -125,24 +124,6 @@ class DevicePolicyData { final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>(); - /** - * @deprecated Do not use. Policies set by permission holders must go into DevicePolicyEngine. - */ - @Deprecated - ActiveAdmin mPermissionBasedAdmin; - - // Create or get the permission-based admin. The permission-based admin will not have a - // DeviceAdminInfo or ComponentName. - ActiveAdmin createOrGetPermissionBasedAdmin(int userId) { - if (Flags.activeAdminCleanup()) { - throw new UnsupportedOperationException("permission based admin no longer supported"); - } - if (mPermissionBasedAdmin == null) { - mPermissionBasedAdmin = new ActiveAdmin(userId, /* permissionBased= */ true); - } - return mPermissionBasedAdmin; - } - // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. final ArraySet<String> mAcceptedCaCertificates = new ArraySet<>(); @@ -282,12 +263,6 @@ class DevicePolicyData { } } - if (!Flags.activeAdminCleanup() && policyData.mPermissionBasedAdmin != null) { - out.startTag(null, "permission-based-admin"); - policyData.mPermissionBasedAdmin.writeToXml(out); - out.endTag(null, "permission-based-admin"); - } - if (policyData.mPasswordOwner >= 0) { out.startTag(null, "password-owner"); out.attributeInt(null, "value", policyData.mPasswordOwner); @@ -495,7 +470,6 @@ class DevicePolicyData { policy.mLockTaskPackages.clear(); policy.mAdminList.clear(); policy.mAdminMap.clear(); - policy.mPermissionBasedAdmin = null; policy.mAffiliationIds.clear(); policy.mOwnerInstalledCaCerts.clear(); policy.mUserControlDisabledPackages = null; @@ -523,11 +497,6 @@ class DevicePolicyData { } catch (RuntimeException e) { Slogf.w(TAG, e, "Failed loading admin %s", name); } - } else if (!Flags.activeAdminCleanup() && "permission-based-admin".equals(tag)) { - - ActiveAdmin ap = new ActiveAdmin(policy.mUserId, /* permissionBased= */ true); - ap.readFromXml(parser, /* overwritePolicies= */ false); - policy.mPermissionBasedAdmin = ap; } else if ("delegation".equals(tag)) { // Parse delegation info. final String delegatePackage = parser.getAttributeValue(null, diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index e960abd3b313..4c2c858c86de 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3448,8 +3448,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( admin.info.getComponent(), - admin.getUserHandle().getIdentifier(), - admin); + admin.getUserHandle().getIdentifier() + ); mDevicePolicyEngine.setGlobalPolicy( PolicyDefinition.SECURITY_LOGGING, enforcingAdmin, @@ -3692,8 +3692,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int userId = admin.getUserHandle().getIdentifier(); EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( admin.info.getComponent(), - userId, - admin); + userId + ); Integer passwordComplexity = mDevicePolicyEngine.getLocalPolicySetByAdmin( PolicyDefinition.PASSWORD_COMPLEXITY, @@ -3985,8 +3985,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int N = admins.size(); for (int i = 0; i < N; i++) { ActiveAdmin admin = admins.get(i); - if (((!Flags.activeAdminCleanup() && admin.isPermissionBased) - || admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) + if ((admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) && admin.passwordExpirationTimeout > 0L && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS && admin.passwordExpirationDate > 0L) { @@ -4167,10 +4166,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { EnforcingAdmin oldAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - outgoingReceiver, userHandle, adminToTransfer); + outgoingReceiver, userHandle); EnforcingAdmin newAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - incomingReceiver, userHandle, adminToTransfer); + incomingReceiver, userHandle); mDevicePolicyEngine.transferPolicies(oldAdmin, newAdmin); @@ -4470,7 +4469,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mDevicePolicyEngine.removePoliciesForAdmin( EnforcingAdmin.createEnterpriseEnforcingAdmin( - adminReceiver, userHandle, admin)); + adminReceiver, userHandle)); } private boolean canSetPasswordQualityOnParent(String packageName, final CallerIdentity caller) { @@ -4525,10 +4524,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); if (Flags.unmanagedModeMigration()) { - enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who, - userId, - getActiveAdminForCallerLocked(who, - DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD)); + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); + enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userId); } // If setPasswordQuality is called on the parent, ensure that // the primary admin does not have password complexity state (this is an @@ -5584,17 +5581,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller)); final ActiveAdmin activeAdmin; - if (Flags.activeAdminCleanup()) { - if (admin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) { - synchronized (getLockObject()) { - activeAdmin = getActiveAdminUncheckedLocked( - admin.getComponentName(), admin.getUserId()); - } - } else { - activeAdmin = null; + if (admin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) { + synchronized (getLockObject()) { + activeAdmin = getActiveAdminUncheckedLocked( + admin.getComponentName(), admin.getUserId()); } } else { - activeAdmin = admin.getActiveAdmin(); + activeAdmin = null; } // We require the caller to explicitly clear any password quality requirements set @@ -6331,12 +6324,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { caller.getPackageName(), getAffectedUser(parent) ); - if (Flags.activeAdminCleanup()) { - adminComponent = enforcingAdmin.getComponentName(); - } else { - ActiveAdmin admin = enforcingAdmin.getActiveAdmin(); - adminComponent = admin == null ? null : admin.info.getComponent(); - } + adminComponent = enforcingAdmin.getComponentName(); } else { ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked( null, @@ -7824,19 +7812,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { calledByProfileOwnerOnOrgOwnedDevice, calledOnParentInstance); } - int userId; - ActiveAdmin admin = null; - if (Flags.activeAdminCleanup()) { - userId = enforcingAdmin.getUserId(); - Slogf.i(LOG_TAG, "wipeDataWithReason(%s): admin=%s, user=%d", wipeReasonForUser, - enforcingAdmin, userId); - } else { - admin = enforcingAdmin.getActiveAdmin(); - userId = admin != null ? admin.getUserHandle().getIdentifier() - : caller.getUserId(); - Slogf.i(LOG_TAG, "wipeDataWithReason(%s): admin=%s, user=%d", wipeReasonForUser, admin, - userId); - } + int userId = enforcingAdmin.getUserId(); + Slogf.i(LOG_TAG, "wipeDataWithReason(%s): admin=%s, user=%d", wipeReasonForUser, + enforcingAdmin, userId); if (calledByProfileOwnerOnOrgOwnedDevice) { // When wipeData is called on the parent instance, it implies wiping the entire device. @@ -7858,38 +7836,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final String adminName; final ComponentName adminComp; - if (Flags.activeAdminCleanup()) { - adminComp = enforcingAdmin.getComponentName(); - adminName = adminComp != null - ? adminComp.flattenToShortString() - : enforcingAdmin.getPackageName(); - event.setAdmin(enforcingAdmin.getPackageName()); - // Not including any HSUM handling here because the "else" branch in the "flag off" - // case below is unreachable under normal circumstances and for permission-based - // callers admin won't be null. - } else { - if (admin != null) { - if (admin.isPermissionBased) { - adminComp = null; - adminName = caller.getPackageName(); - event.setAdmin(adminName); - } else { - adminComp = admin.info.getComponent(); - adminName = adminComp.flattenToShortString(); - event.setAdmin(adminComp); - } - } else { - adminComp = null; - adminName = mInjector.getPackageManager().getPackagesForUid(caller.getUid())[0]; - Slogf.i(LOG_TAG, "Logging wipeData() event admin as " + adminName); - event.setAdmin(adminName); - if (mInjector.userManagerIsHeadlessSystemUserMode()) { - // On headless system user mode, the call is meant to factory reset the whole - // device, otherwise the caller could simply remove the current user. - userId = UserHandle.USER_SYSTEM; - } - } - } + adminComp = enforcingAdmin.getComponentName(); + adminName = adminComp != null + ? adminComp.flattenToShortString() + : enforcingAdmin.getPackageName(); + event.setAdmin(enforcingAdmin.getPackageName()); + // Not including any HSUM handling here because the "else" branch in the "flag off" + // case below is unreachable under normal circumstances and for permission-based + // callers admin won't be null. event.write(); String internalReason = String.format( @@ -8375,8 +8329,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle); for (int i = 0; i < admins.size(); i++) { ActiveAdmin admin = admins.get(i); - if ((!Flags.activeAdminCleanup() && admin.isPermissionBased) - || admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) { + if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) { affectedUserIds.add(admin.getUserHandle().getIdentifier()); long timeout = admin.passwordExpirationTimeout; admin.passwordExpirationDate = @@ -8470,9 +8423,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { */ private int getUserIdToWipeForFailedPasswords(ActiveAdmin admin) { final int userId = admin.getUserHandle().getIdentifier(); - if (!Flags.activeAdminCleanup() && admin.isPermissionBased) { - return userId; - } final ComponentName component = admin.info.getComponent(); return isProfileOwnerOfOrganizationOwnedDevice(component, userId) ? getProfileParentId(userId) : userId; @@ -10282,8 +10232,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setGlobalSettingDeviceOwnerType(DEVICE_OWNER_TYPE_DEFAULT); mDevicePolicyEngine.removePoliciesForAdmin( - EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), userId, admin)); + EnforcingAdmin.createEnterpriseEnforcingAdmin(admin.info.getComponent(), userId)); } private void clearApplicationRestrictions(int userId) { @@ -10433,8 +10382,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setNetworkLoggingActiveInternal(false); mDevicePolicyEngine.removePoliciesForAdmin( - EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), userId, admin)); + EnforcingAdmin.createEnterpriseEnforcingAdmin(admin.info.getComponent(), userId)); } @Override @@ -16449,8 +16397,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (admin.mPasswordPolicy.quality < minPasswordQuality) { return false; } - return (!Flags.activeAdminCleanup() && admin.isPermissionBased) - || admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); + return admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); } @Override @@ -20918,8 +20865,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (profileOwner != null) { EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin( profileOwner.info.getComponent(), - profileUserId, - profileOwner); + profileUserId); mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.PERSONAL_APPS_SUSPENDED, admin, @@ -23517,27 +23463,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * * @param callerPackageName The package name of the calling application. * @param adminPolicy The admin policy that should grant holders permission. - * @param permission The name of the permission being checked. - * @param targetUserId The userId of the user which the caller needs permission to act on. - * @throws SecurityException if the caller has not been granted the given permission, - * the associated cross-user permission if the caller's user is different to the target user. - */ - private void enforcePermission(String permission, int adminPolicy, - String callerPackageName, int targetUserId) throws SecurityException { - if (hasAdminPolicy(adminPolicy, callerPackageName)) { - return; - } - enforcePermission(permission, callerPackageName, targetUserId); - } - - /** - * Checks if the calling process has been granted permission to apply a device policy on a - * specific user. - * The given permission will be checked along with its associated cross-user permission if it - * exists and the target user is different to the calling user. - * - * @param callerPackageName The package name of the calling application. - * @param adminPolicy The admin policy that should grant holders permission. * @param permissions The names of the permissions being checked. * @param targetUserId The userId of the user which the caller needs permission to act on. * @throws SecurityException if the caller has not been granted the given permission, @@ -23670,24 +23595,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ComponentName component; synchronized (getLockObject()) { if (who != null) { - admin = getActiveAdminUncheckedLocked(who, userId); component = who; } else { admin = getDeviceOrProfileOwnerAdminLocked(userId); component = admin.info.getComponent(); } } - return EnforcingAdmin.createEnterpriseEnforcingAdmin(component, userId, admin); + return EnforcingAdmin.createEnterpriseEnforcingAdmin(component, userId); } - // Check for non-DPC active admins. + // Check for DA active admins. admin = getActiveAdminForCaller(who, caller); if (admin != null) { - return EnforcingAdmin.createDeviceAdminEnforcingAdmin(admin.info.getComponent(), userId, - admin); + return EnforcingAdmin.createDeviceAdminEnforcingAdmin( + admin.info.getComponent(), userId); } - admin = Flags.activeAdminCleanup() - ? null : getUserData(userId).createOrGetPermissionBasedAdmin(userId); - return EnforcingAdmin.createEnforcingAdmin(caller.getPackageName(), userId, admin); + return EnforcingAdmin.createEnforcingAdmin(caller.getPackageName(), userId); } private EnforcingAdmin getEnforcingAdminForPackage(@Nullable ComponentName who, @@ -23699,19 +23621,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin = getActiveAdminUncheckedLocked(who, userId); } if (admin != null) { - return EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userId, admin); + return EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userId); } } else { - // Check for non-DPC active admins. + // Check for DA active admins. admin = getActiveAdminUncheckedLocked(who, userId); if (admin != null) { - return EnforcingAdmin.createDeviceAdminEnforcingAdmin(who, userId, admin); + return EnforcingAdmin.createDeviceAdminEnforcingAdmin(who, userId); } } } - admin = Flags.activeAdminCleanup() - ? null : getUserData(userId).createOrGetPermissionBasedAdmin(userId); - return EnforcingAdmin.createEnforcingAdmin(packageName, userId, admin); + return EnforcingAdmin.createEnforcingAdmin(packageName, userId); } private int getAffectedUser(boolean calledOnParent) { @@ -24427,9 +24347,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { && admin.getParentActiveAdmin().disableScreenCapture))) { EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - admin.getUserHandle().getIdentifier(), - admin); + admin.info.getComponent(), admin.getUserHandle().getIdentifier()); mDevicePolicyEngine.setGlobalPolicy( PolicyDefinition.SCREEN_CAPTURE_DISABLED, enforcingAdmin, @@ -24442,8 +24360,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (profileOwner != null && profileOwner.disableScreenCapture) { EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( profileOwner.info.getComponent(), - profileOwner.getUserHandle().getIdentifier(), - profileOwner); + profileOwner.getUserHandle().getIdentifier()); mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.SCREEN_CAPTURE_DISABLED, enforcingAdmin, @@ -24485,10 +24402,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void setLockTaskPolicyInPolicyEngine( ActiveAdmin admin, int userId, List<String> packages, int features) { EnforcingAdmin enforcingAdmin = - EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - userId, - admin); + EnforcingAdmin.createEnterpriseEnforcingAdmin(admin.info.getComponent(), userId); mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.LOCK_TASK, enforcingAdmin, @@ -24503,9 +24417,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id); if (admin != null) { EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - admin.getUserHandle().getIdentifier(), - admin); + admin.info.getComponent(), admin.getUserHandle().getIdentifier()); if (admin.permittedInputMethods != null) { mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.PERMITTED_INPUT_METHODS, @@ -24536,9 +24448,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id); if (admin != null) { EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - admin.getUserHandle().getIdentifier(), - admin); + admin.info.getComponent(), admin.getUserHandle().getIdentifier()); for (String accountType : admin.accountTypesWithManagementDisabled) { mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType), @@ -24569,9 +24479,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id); if (admin != null && admin.protectedPackages != null) { EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - admin.getUserHandle().getIdentifier(), - admin); + admin.info.getComponent(), admin.getUserHandle().getIdentifier()); if (isDeviceOwner(admin)) { mDevicePolicyEngine.setGlobalPolicy( PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES, @@ -24599,10 +24507,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (admin == null) continue; ComponentName adminComponent = admin.info.getComponent(); int userId = userInfo.id; - EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - adminComponent, - userId, - admin); + EnforcingAdmin enforcingAdmin = + EnforcingAdmin.createEnterpriseEnforcingAdmin(adminComponent, userId); int ownerType; if (isDeviceOwner(admin)) { ownerType = OWNER_TYPE_DEVICE_OWNER; @@ -24635,9 +24541,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id); if (admin == null) continue; EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - userInfo.id, - admin); + admin.info.getComponent(), userInfo.id); runner.accept(admin, enforcingAdmin); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java index 5a0b079b6a24..aca331564a40 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java @@ -23,7 +23,6 @@ import android.app.admin.DeviceAdminAuthority; import android.app.admin.DpcAuthority; import android.app.admin.RoleAuthority; import android.app.admin.UnknownAuthority; -import android.app.admin.flags.Flags; import android.content.ComponentName; import android.os.UserHandle; @@ -80,36 +79,24 @@ final class EnforcingAdmin { private final int mUserId; private final boolean mIsRoleAuthority; private final boolean mIsSystemAuthority; - private final ActiveAdmin mActiveAdmin; - static EnforcingAdmin createEnforcingAdmin(@NonNull String packageName, int userId, - ActiveAdmin admin) { + static EnforcingAdmin createEnforcingAdmin(@NonNull String packageName, int userId) { Objects.requireNonNull(packageName); - return new EnforcingAdmin(packageName, userId, admin); + return new EnforcingAdmin(packageName, userId); } static EnforcingAdmin createEnterpriseEnforcingAdmin( @NonNull ComponentName componentName, int userId) { Objects.requireNonNull(componentName); return new EnforcingAdmin( - componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY), userId, - /* activeAdmin=*/ null); + componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY), userId); } - static EnforcingAdmin createEnterpriseEnforcingAdmin( - @NonNull ComponentName componentName, int userId, ActiveAdmin activeAdmin) { - Objects.requireNonNull(componentName); - return new EnforcingAdmin( - componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY), userId, - activeAdmin); - } - - static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId, - ActiveAdmin activeAdmin) { + static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId) { Objects.requireNonNull(componentName); return new EnforcingAdmin( componentName.getPackageName(), componentName, Set.of(DEVICE_ADMIN_AUTHORITY), - userId, activeAdmin); + userId); } static EnforcingAdmin createSystemEnforcingAdmin(@NonNull String systemEntity) { @@ -124,24 +111,20 @@ final class EnforcingAdmin { if (DpcAuthority.DPC_AUTHORITY.equals(authority)) { return new EnforcingAdmin( admin.getPackageName(), admin.getComponentName(), - Set.of(DPC_AUTHORITY), admin.getUserHandle().getIdentifier(), - /* activeAdmin = */ null); + Set.of(DPC_AUTHORITY), admin.getUserHandle().getIdentifier()); } else if (DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY.equals(authority)) { return new EnforcingAdmin( admin.getPackageName(), admin.getComponentName(), - Set.of(DEVICE_ADMIN_AUTHORITY), admin.getUserHandle().getIdentifier(), - /* activeAdmin = */ null); + Set.of(DEVICE_ADMIN_AUTHORITY), admin.getUserHandle().getIdentifier()); } else if (authority instanceof RoleAuthority roleAuthority) { return new EnforcingAdmin( admin.getPackageName(), admin.getComponentName(), Set.of(DEVICE_ADMIN_AUTHORITY), admin.getUserHandle().getIdentifier(), - /* activeAdmin = */ null, /* isRoleAuthority = */ true); } // TODO(b/324899199): Consider supporting android.app.admin.SystemAuthority. return new EnforcingAdmin(admin.getPackageName(), admin.getComponentName(), - Set.of(), admin.getUserHandle().getIdentifier(), - /* activeAdmin = */ null); + Set.of(), admin.getUserHandle().getIdentifier()); } static String getRoleAuthorityOf(String roleName) { @@ -167,7 +150,7 @@ final class EnforcingAdmin { private EnforcingAdmin( String packageName, @Nullable ComponentName componentName, Set<String> authorities, - int userId, @Nullable ActiveAdmin activeAdmin) { + int userId) { Objects.requireNonNull(packageName); Objects.requireNonNull(authorities); @@ -179,10 +162,9 @@ final class EnforcingAdmin { mComponentName = componentName; mAuthorities = new HashSet<>(authorities); mUserId = userId; - mActiveAdmin = activeAdmin; } - private EnforcingAdmin(String packageName, int userId, ActiveAdmin activeAdmin) { + private EnforcingAdmin(String packageName, int userId) { Objects.requireNonNull(packageName); // Only role authorities use this constructor. @@ -194,7 +176,6 @@ final class EnforcingAdmin { mComponentName = null; // authorities will be loaded when needed mAuthorities = null; - mActiveAdmin = activeAdmin; } /** Constructor for System authorities. */ @@ -210,12 +191,11 @@ final class EnforcingAdmin { mUserId = UserHandle.USER_SYSTEM; mComponentName = null; mAuthorities = getSystemAuthority(systemEntity); - mActiveAdmin = null; } private EnforcingAdmin( String packageName, @Nullable ComponentName componentName, Set<String> authorities, - int userId, @Nullable ActiveAdmin activeAdmin, boolean isRoleAuthority) { + int userId, boolean isRoleAuthority) { Objects.requireNonNull(packageName); Objects.requireNonNull(authorities); @@ -226,7 +206,6 @@ final class EnforcingAdmin { mComponentName = componentName; mAuthorities = new HashSet<>(authorities); mUserId = userId; - mActiveAdmin = activeAdmin; } private static Set<String> getRoleAuthoritiesOrDefault(String packageName, int userId) { @@ -295,14 +274,6 @@ final class EnforcingAdmin { } @Nullable - public ActiveAdmin getActiveAdmin() { - if (Flags.activeAdminCleanup()) { - throw new UnsupportedOperationException("getActiveAdmin() no longer supported"); - } - return mActiveAdmin; - } - - @Nullable ComponentName getComponentName() { return mComponentName; } @@ -419,7 +390,7 @@ final class EnforcingAdmin { return null; } // TODO(b/281697976): load active admin - return new EnforcingAdmin(packageName, userId, null); + return new EnforcingAdmin(packageName, userId); } else if (isSystemAuthority) { if (systemEntity == null) { Slogf.wtf(TAG, "Error parsing EnforcingAdmin with SystemAuthority, " @@ -439,7 +410,7 @@ final class EnforcingAdmin { ? null : new ComponentName(packageName, className); Set<String> authorities = Set.of(authoritiesStr.split(ATTR_AUTHORITIES_SEPARATOR)); // TODO(b/281697976): load active admin - return new EnforcingAdmin(packageName, componentName, authorities, userId, null); + return new EnforcingAdmin(packageName, componentName, authorities, userId); } } |