diff options
27 files changed, 525 insertions, 148 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 2ae721648656..895dde760058 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -1507,8 +1507,9 @@ public class ActivityOptions extends ComponentOptions { } /** @hide */ - public void setRemoteTransition(@Nullable RemoteTransition remoteTransition) { + public ActivityOptions setRemoteTransition(@Nullable RemoteTransition remoteTransition) { mRemoteTransition = remoteTransition; + return this; } /** @hide */ diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index da5e40aedbd2..a1dd5a4b60ce 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -11806,6 +11806,34 @@ public class DevicePolicyManager { } /** + * Returns the list of {@link EnforcingAdmin}s who have set this restriction. + * + * <p>Note that for {@link #POLICY_SUSPEND_PACKAGES} it returns the PO or DO to keep the + * behavior the same as before the bug fix for b/192245204. + * + * <p>This API is only callable by the system UID + * + * @param userId The user for whom to retrieve the information. + * @param restriction The restriction enforced by admins. It could be any user restriction or + * policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA} and + * {@link DevicePolicyManager#POLICY_DISABLE_SCREEN_CAPTURE}. + * + * @hide + */ + public @NonNull Set<EnforcingAdmin> getEnforcingAdminsForRestriction(int userId, + @NonNull String restriction) { + if (mService != null) { + try { + return new HashSet<>(mService.getEnforcingAdminsForRestriction( + userId, restriction)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return null; + } + + /** * Hide or unhide packages. When a package is hidden it is unavailable for use, but the data and * actual package file remain. This function can be called by a device owner, profile owner, or * by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via diff --git a/core/java/android/app/admin/EnforcingAdmin.aidl b/core/java/android/app/admin/EnforcingAdmin.aidl new file mode 100644 index 000000000000..bfbfdbeaf9aa --- /dev/null +++ b/core/java/android/app/admin/EnforcingAdmin.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.admin; + +parcelable EnforcingAdmin;
\ No newline at end of file diff --git a/core/java/android/app/admin/EnforcingAdmin.java b/core/java/android/app/admin/EnforcingAdmin.java index 771794dbe0fb..7c718f6651a2 100644 --- a/core/java/android/app/admin/EnforcingAdmin.java +++ b/core/java/android/app/admin/EnforcingAdmin.java @@ -19,6 +19,7 @@ package android.app.admin; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -38,6 +39,11 @@ public final class EnforcingAdmin implements Parcelable { private final UserHandle mUserHandle; /** + * @hide + */ + private final ComponentName mComponentName; + + /** * Creates an enforcing admin with the given params. */ public EnforcingAdmin( @@ -46,6 +52,21 @@ public final class EnforcingAdmin implements Parcelable { mPackageName = Objects.requireNonNull(packageName); mAuthority = Objects.requireNonNull(authority); mUserHandle = Objects.requireNonNull(userHandle); + mComponentName = null; + } + + /** + * Creates an enforcing admin with the given params. + * + * @hide + */ + public EnforcingAdmin( + @NonNull String packageName, @NonNull Authority authority, + @NonNull UserHandle userHandle, @Nullable ComponentName componentName) { + mPackageName = Objects.requireNonNull(packageName); + mAuthority = Objects.requireNonNull(authority); + mUserHandle = Objects.requireNonNull(userHandle); + mComponentName = componentName; } private EnforcingAdmin(Parcel source) { @@ -53,6 +74,7 @@ public final class EnforcingAdmin implements Parcelable { mUserHandle = new UserHandle(source.readInt()); mAuthority = Objects.requireNonNull( source.readParcelable(Authority.class.getClassLoader())); + mComponentName = source.readParcelable(ComponentName.class.getClassLoader()); } /** @@ -86,7 +108,8 @@ public final class EnforcingAdmin implements Parcelable { EnforcingAdmin other = (EnforcingAdmin) o; return Objects.equals(mPackageName, other.mPackageName) && Objects.equals(mAuthority, other.mAuthority) - && Objects.equals(mUserHandle, other.mUserHandle); + && Objects.equals(mUserHandle, other.mUserHandle) + && Objects.equals(mComponentName, other.mComponentName); } @Override @@ -97,7 +120,7 @@ public final class EnforcingAdmin implements Parcelable { @Override public String toString() { return "EnforcingAdmin { mPackageName= " + mPackageName + ", mAuthority= " + mAuthority - + ", mUserHandle= " + mUserHandle + " }"; + + ", mUserHandle= " + mUserHandle + ", mComponentName= " + mComponentName + " }"; } @Override @@ -110,6 +133,7 @@ public final class EnforcingAdmin implements Parcelable { dest.writeString(mPackageName); dest.writeInt(mUserHandle.getIdentifier()); dest.writeParcelable(mAuthority, flags); + dest.writeParcelable(mComponentName, flags); } @NonNull diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 003e804831a4..beb452cf2cfa 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -54,6 +54,7 @@ import android.security.keystore.ParcelableKeyGenParameterSpec; import android.telephony.data.ApnSetting; import com.android.internal.infra.AndroidFuture; import android.app.admin.DevicePolicyState; +import android.app.admin.EnforcingAdmin; import java.util.List; @@ -274,6 +275,7 @@ interface IDevicePolicyManager { Intent createAdminSupportIntent(in String restriction); Bundle getEnforcingAdminAndUserDetails(int userId,String restriction); + List<EnforcingAdmin> getEnforcingAdminsForRestriction(int userId,String restriction); boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden, boolean parent); boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean parent); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 2b39bb4eb7a5..0a726d99723a 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -3023,28 +3023,31 @@ public class ChooserActivity extends ResolverActivity implements return shouldShowTabs() && (mMultiProfilePagerAdapter.getListAdapterForUserHandle( UserHandle.of(UserHandle.myUserId())).getCount() > 0 - || shouldShowContentPreviewWhenEmpty()) + || shouldShowStickyContentPreviewWhenEmpty()) && shouldShowContentPreview(); } /** - * This method could be used to override the default behavior when we hide the preview area - * when the current tab doesn't have any items. + * This method could be used to override the default behavior when we hide the sticky preview + * area when the current tab doesn't have any items. * - * @return true if we want to show the content preview area even if the tab for the current - * user is empty + * @return {@code true} if we want to show the sticky content preview area even if the tab for + * the current user is empty */ - protected boolean shouldShowContentPreviewWhenEmpty() { + protected boolean shouldShowStickyContentPreviewWhenEmpty() { return false; } - /** - * @return true if we want to show the content preview area - */ - protected boolean shouldShowContentPreview() { + @Override + public boolean shouldShowContentPreview() { return isSendAction(getTargetIntent()); } + @Override + public boolean shouldShowServiceTargets() { + return shouldShowContentPreview() && !ActivityManager.isLowRamDeviceStatic(); + } + private void updateStickyContentPreview() { if (shouldShowStickyContentPreviewNoOrientationCheck()) { // The sticky content preview is only shown when we show the work and personal tabs. @@ -3406,11 +3409,7 @@ public class ChooserActivity extends ResolverActivity implements // There can be at most one row in the listview, that is internally // a ViewGroup with 2 rows public int getServiceTargetRowCount() { - if (shouldShowContentPreview() - && !ActivityManager.isLowRamDeviceStatic()) { - return 1; - } - return 0; + return shouldShowServiceTargets() ? 1 : 0; } public int getAzLabelRowCount() { diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java index 1eecb413adcb..36038ae15853 100644 --- a/core/java/com/android/internal/app/ChooserListAdapter.java +++ b/core/java/com/android/internal/app/ChooserListAdapter.java @@ -19,7 +19,6 @@ package com.android.internal.app; import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE; import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER; -import android.app.ActivityManager; import android.app.prediction.AppPredictor; import android.content.ComponentName; import android.content.Context; @@ -425,11 +424,9 @@ public class ChooserListAdapter extends ResolverListAdapter { } public int getServiceTargetCount() { - if (mChooserListCommunicator.isSendAction(mChooserListCommunicator.getTargetIntent()) - && !ActivityManager.isLowRamDeviceStatic()) { + if (mChooserListCommunicator.shouldShowServiceTargets()) { return Math.min(mServiceTargets.size(), mChooserListCommunicator.getMaxRankedTargets()); } - return 0; } @@ -771,6 +768,10 @@ public class ChooserListAdapter extends ResolverListAdapter { void sendListViewUpdateMessage(UserHandle userHandle); boolean isSendAction(Intent targetIntent); + + boolean shouldShowContentPreview(); + + boolean shouldShowServiceTargets(); } /** diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserListAdapterTest.kt b/core/tests/coretests/src/com/android/internal/app/ChooserListAdapterTest.kt index 2eeaf53ef146..1c9f04a299cc 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserListAdapterTest.kt +++ b/core/tests/coretests/src/com/android/internal/app/ChooserListAdapterTest.kt @@ -19,8 +19,12 @@ package com.android.internal.app import android.content.ComponentName import android.content.Context import android.content.Intent +import android.content.pm.ActivityInfo +import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.content.pm.ResolveInfo +import android.content.pm.ShortcutInfo +import android.graphics.drawable.Icon import android.os.Bundle import android.os.UserHandle import android.service.chooser.ChooserTarget @@ -32,12 +36,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.android.internal.R import com.android.internal.app.ChooserListAdapter.LoadDirectShareIconTask +import com.android.internal.app.chooser.DisplayResolveInfo import com.android.internal.app.chooser.SelectableTargetInfo import com.android.internal.app.chooser.SelectableTargetInfo.SelectableTargetInfoCommunicator import com.android.internal.app.chooser.TargetInfo import com.android.server.testutils.any import com.android.server.testutils.mock import com.android.server.testutils.whenever +import com.google.common.truth.Truth.assertThat +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.anyInt @@ -46,22 +53,25 @@ import org.mockito.Mockito.verify @RunWith(AndroidJUnit4::class) class ChooserListAdapterTest { - private val packageManager = mock<PackageManager> { - whenever(resolveActivity(any(), anyInt())).thenReturn(mock()) - } + private val packageManager = + mock<PackageManager> { whenever(resolveActivity(any(), anyInt())).thenReturn(mock()) } private val context = InstrumentationRegistry.getInstrumentation().getContext() private val resolverListController = mock<ResolverListController>() - private val chooserListCommunicator = mock<ChooserListAdapter.ChooserListCommunicator> { - whenever(maxRankedTargets).thenReturn(0) - } - private val selectableTargetInfoCommunicator = - mock<SelectableTargetInfoCommunicator> { - whenever(targetIntent).thenReturn(mock()) + private val chooserListCommunicator = + mock<ChooserListAdapter.ChooserListCommunicator> { + whenever(maxRankedTargets).thenReturn(0) } + private val selectableTargetInfoCommunicator = + mock<SelectableTargetInfoCommunicator> { whenever(targetIntent).thenReturn(mock()) } private val chooserActivityLogger = mock<ChooserActivityLogger>() + @Before + fun setUp() { + whenever(resolverListController.userHandle).thenReturn(UserHandle.CURRENT) + } + private fun createChooserListAdapter( - taskProvider: (SelectableTargetInfo?) -> LoadDirectShareIconTask + taskProvider: (SelectableTargetInfo?) -> LoadDirectShareIconTask = createTaskProvider() ) = ChooserListAdapterOverride( context, @@ -98,9 +108,8 @@ class ChooserListAdapterTest { view.tag = viewHolderOne val targetInfo = createSelectableTargetInfo() val iconTaskOne = mock<LoadDirectShareIconTask>() - val testTaskProvider = mock<() -> LoadDirectShareIconTask> { - whenever(invoke()).thenReturn(iconTaskOne) - } + val testTaskProvider = + mock<() -> LoadDirectShareIconTask> { whenever(invoke()).thenReturn(iconTaskOne) } val testSubject = createChooserListAdapter { testTaskProvider.invoke() } testSubject.testViewBind(view, targetInfo, 0) @@ -114,6 +123,65 @@ class ChooserListAdapterTest { verify(testTaskProvider, times(1)).invoke() } + @Test + fun getServiceTargetCount_shouldNotShowServiceTargets_returnsZero() { + whenever(chooserListCommunicator.shouldShowServiceTargets()).thenReturn(false) + val adapter = createChooserListAdapter() + whenever(chooserListCommunicator.maxRankedTargets).thenReturn(10) + addServiceTargets(adapter, targetCount = 50) + + assertThat(adapter.serviceTargetCount).isEqualTo(0) + } + + private fun createTaskProvider(): (SelectableTargetInfo?) -> LoadDirectShareIconTask { + val iconTaskOne = mock<LoadDirectShareIconTask>() + val testTaskProvider = + mock<() -> LoadDirectShareIconTask> { whenever(invoke()).thenReturn(iconTaskOne) } + return { testTaskProvider.invoke() } + } + + private fun addServiceTargets(adapter: ChooserListAdapter, targetCount: Int) { + val origTarget = + DisplayResolveInfo( + Intent(), + createResolveInfo(), + Intent(), + ResolverListAdapter.ResolveInfoPresentationGetter(context, 200, createResolveInfo()) + ) + val targets = mutableListOf<ChooserTarget>() + for (i in 1..targetCount) { + val score = 1f + val componentName = ComponentName("chooser.list.adapter", "Test$i") + val extras = Bundle() + val icon: Icon? = null + targets += ChooserTarget("Title $i", icon, score, componentName, extras) + } + val directShareToShortcutInfos = mapOf<ChooserTarget, ShortcutInfo>() + adapter.addServiceResults( + origTarget, + targets, + ChooserActivity.TARGET_TYPE_DEFAULT, + directShareToShortcutInfos + ) + } + + private fun createResolveInfo(): ResolveInfo { + val applicationInfo = + ApplicationInfo().apply { + packageName = "chooser.list.adapter" + name = "ChooserListAdapterTestApplication" + } + val activityInfo = + ActivityInfo().apply { + packageName = applicationInfo.packageName + name = "ChooserListAdapterTest" + } + activityInfo.applicationInfo = applicationInfo + val resolveInfo = ResolveInfo() + resolveInfo.activityInfo = activityInfo + return resolveInfo + } + private fun createSelectableTargetInfo(): SelectableTargetInfo = SelectableTargetInfo( context, @@ -125,13 +193,7 @@ class ChooserListAdapterTest { ) private fun createChooserTarget(): ChooserTarget = - ChooserTarget( - "Title", - null, - 1f, - ComponentName("package", "package.Class"), - Bundle() - ) + ChooserTarget("Title", null, 1f, ComponentName("package", "package.Class"), Bundle()) private fun createView(): View { val view = FrameLayout(context) @@ -164,23 +226,23 @@ private class ChooserListAdapterOverride( chooserActivityLogger: ChooserActivityLogger?, initialIntentsUserHandle: UserHandle?, private val taskProvider: (SelectableTargetInfo?) -> LoadDirectShareIconTask -) : ChooserListAdapter( - context, - payloadIntents, - initialIntents, - rList, - filterLastUsed, - resolverListController, - chooserListCommunicator, - selectableTargetInfoCommunicator, - packageManager, - chooserActivityLogger, - initialIntentsUserHandle, -) { +) : + ChooserListAdapter( + context, + payloadIntents, + initialIntents, + rList, + filterLastUsed, + resolverListController, + chooserListCommunicator, + selectableTargetInfoCommunicator, + packageManager, + chooserActivityLogger, + initialIntentsUserHandle, + ) { override fun createLoadDirectShareIconTask( info: SelectableTargetInfo? - ): LoadDirectShareIconTask = - taskProvider.invoke(info) + ): LoadDirectShareIconTask = taskProvider.invoke(info) fun testViewBind(view: View?, info: TargetInfo?, position: Int) { onBindView(view, info, position) diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 4bd69f188d4c..7d5c06cbed1a 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -439,6 +439,12 @@ "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java" }, + "-1700778361": { + "message": "Content Recording: Going ahead with updating recording for display %d to new bounds %s and\/or orientation %d and\/or surface size %s", + "level": "VERBOSE", + "group": "WM_DEBUG_CONTENT_RECORDING", + "at": "com\/android\/server\/wm\/ContentRecorder.java" + }, "-1699018375": { "message": "Adding activity %s to task %s callers: %s", "level": "INFO", @@ -637,12 +643,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayContent.java" }, - "-1480264178": { - "message": "Content Recording: Unable to update recording for display %d to new bounds %s and\/or orientation %d, since the surface is not available.", - "level": "VERBOSE", - "group": "WM_DEBUG_CONTENT_RECORDING", - "at": "com\/android\/server\/wm\/ContentRecorder.java" - }, "-1478175541": { "message": "No longer animating wallpaper targets!", "level": "VERBOSE", @@ -1837,12 +1837,6 @@ "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/Task.java" }, - "-452750194": { - "message": "Content Recording: Going ahead with updating recording for display %d to new bounds %s and\/or orientation %d.", - "level": "VERBOSE", - "group": "WM_DEBUG_CONTENT_RECORDING", - "at": "com\/android\/server\/wm\/ContentRecorder.java" - }, "-451552570": { "message": "Current focused window being animated by recents. Overriding back callback to recents controller callback.", "level": "DEBUG", @@ -3067,12 +3061,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, - "643263584": { - "message": "Content Recording: Apply transformations of shift %d x %d, scale %f, crop %d x %d for display %d", - "level": "VERBOSE", - "group": "WM_DEBUG_CONTENT_RECORDING", - "at": "com\/android\/server\/wm\/ContentRecorder.java" - }, "644675193": { "message": "Real start recents", "level": "DEBUG", @@ -4093,6 +4081,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "1687944543": { + "message": "Content Recording: Unable to update recording for display %d to new bounds %s and\/or orientation %d and\/or surface size %s, since the surface is not available.", + "level": "VERBOSE", + "group": "WM_DEBUG_CONTENT_RECORDING", + "at": "com\/android\/server\/wm\/ContentRecorder.java" + }, "1699269281": { "message": "Don't organize or trigger events for untrusted displayId=%d", "level": "WARN", @@ -4315,6 +4309,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "1936800105": { + "message": "Content Recording: Apply transformations of shift %d x %d, scale %f, crop (aka recorded content size) %d x %d for display %d; display has size %d x %d; surface has size %d x %d", + "level": "VERBOSE", + "group": "WM_DEBUG_CONTENT_RECORDING", + "at": "com\/android\/server\/wm\/ContentRecorder.java" + }, "1945495497": { "message": "Focused window didn't have a valid surface drawn.", "level": "DEBUG", diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java index bb65da3deade..50ba8975802b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java @@ -738,8 +738,17 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { final boolean wasClosing = closingIdx >= 0; t.reparent(target.leash, mInfo.getRoot(rootIdx).getLeash()); t.setLayer(target.leash, layer); - // Hide the animation leash if not already visible, let listener show it - t.setVisibility(target.leash, !wasClosing); + if (wasClosing) { + // App was previously visible and is closing + t.show(target.leash); + t.setAlpha(target.leash, 1f); + // Also override the task alpha as it was set earlier when dispatching + // the transition and setting up the leash to hide the + t.setAlpha(change.getLeash(), 1f); + } else { + // Hide the animation leash, let the listener show it + t.hide(target.leash); + } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " opening new leaf taskId=%d wasClosing=%b", target.taskId, wasClosing); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java index 3990b10267e1..c64ae0106b4a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java @@ -17,6 +17,7 @@ package com.android.keyguard; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; +import static com.android.systemui.statusbar.StatusBarState.SHADE; import android.util.Property; import android.view.View; @@ -124,7 +125,16 @@ public class KeyguardVisibilityHelper { true /* animate */); log("keyguardFadingAway transition w/ Y Aniamtion"); } else if (statusBarState == KEYGUARD) { - if (keyguardFadingAway) { + // Sometimes, device will be unlocked and then locked very quickly. + // keyguardFadingAway hasn't been set to false cause unlock animation hasn't finished + // So we should not animate keyguard fading away in this case (when oldState is SHADE) + if (oldStatusBarState != SHADE) { + log("statusBarState == KEYGUARD && oldStatusBarState != SHADE"); + } else { + log("statusBarState == KEYGUARD && oldStatusBarState == SHADE"); + } + + if (keyguardFadingAway && oldStatusBarState != SHADE) { mKeyguardViewVisibilityAnimating = true; AnimationProperties animProps = new AnimationProperties() .setDelay(0) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index bf0d8adaeb96..2414ef982fb0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -763,13 +763,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } } } - - @Override - public void onStrongAuthStateChanged(int userId) { - if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { - doKeyguardLocked(null); - } - } }; ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { @@ -2184,9 +2177,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, * Enable the keyguard if the settings are appropriate. */ private void doKeyguardLocked(Bundle options) { - // if another app is disabling us, don't show unless we're in lockdown mode - if (!mExternallyEnabled - && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { + // if another app is disabling us, don't show + if (!mExternallyEnabled) { if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); mNeedToReshowWhenReenabled = true; diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt index 60fd10492628..cf64a838c2bf 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt @@ -274,7 +274,9 @@ class MediaProjectionAppSelectorActivity( recentsViewController.hasRecentTasks } - override fun shouldShowContentPreviewWhenEmpty() = shouldShowContentPreview() + override fun shouldShowStickyContentPreviewWhenEmpty() = shouldShowContentPreview() + + override fun shouldShowServiceTargets() = false private fun hasWorkProfile() = mMultiProfilePagerAdapter.count > 1 diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index f73804dbc349..e568c244390c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -175,8 +175,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private @Mock AuthController mAuthController; private @Mock ShadeExpansionStateManager mShadeExpansionStateManager; private @Mock ShadeWindowLogger mShadeWindowLogger; - private @Captor ArgumentCaptor<KeyguardUpdateMonitorCallback> - mKeyguardUpdateMonitorCallbackCaptor; private @Captor ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback; private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake(); @@ -239,25 +237,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { } @Test - @TestableLooper.RunWithLooper(setAsMainLooper = true) - public void onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally() { - // GIVEN keyguard is not enabled and isn't showing - mViewMediator.onSystemReady(); - mViewMediator.setKeyguardEnabled(false); - TestableLooper.get(this).processAllMessages(); - captureKeyguardUpdateMonitorCallback(); - assertFalse(mViewMediator.isShowingAndNotOccluded()); - - // WHEN lockdown occurs - when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true); - mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0); - - // THEN keyguard is shown - TestableLooper.get(this).processAllMessages(); - assertTrue(mViewMediator.isShowingAndNotOccluded()); - } - - @Test public void testOnGoingToSleep_UpdatesKeyguardGoingAway() { mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); verify(mUpdateMonitor).dispatchKeyguardGoingAway(false); @@ -1000,10 +979,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null); } - private void captureKeyguardUpdateMonitorCallback() { - verify(mUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallbackCaptor.capture()); - } - private void captureKeyguardStateControllerCallback() { verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture()); } diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java index 05327dcc7903..a792db0f7c78 100644 --- a/services/backup/java/com/android/server/backup/TransportManager.java +++ b/services/backup/java/com/android/server/backup/TransportManager.java @@ -738,6 +738,9 @@ public class TransportManager { try { String transportName = transport.name(); String transportDirName = transport.transportDirName(); + if (transportName == null || transportDirName == null) { + return BackupManager.ERROR_TRANSPORT_INVALID; + } registerTransport(transportComponent, transport); // If registerTransport() hasn't thrown... Slog.d(TAG, addUserIdToLogMessage(mUserId, "Transport " + transportString diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 967177219475..1fa60fef401b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -314,6 +314,7 @@ import android.net.ConnectivityManager; import android.net.Proxy; import android.net.Uri; import android.os.AppZygote; +import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Binder; import android.os.BinderProxy; @@ -15029,6 +15030,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } + // STOPSHIP(b/298884211): Remove this logging + if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { + final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + if (level < 0) { + Slog.wtf(BroadcastQueue.TAG, "Unexpected broadcast: " + intent + + "; callingUid: " + callingUid + ", callingPid: " + callingPid, + new Throwable()); + } + } + int[] users; if (userId == UserHandle.USER_ALL) { // Caller wants broadcast to go to all started users. diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 5d0fefc75a28..d5343a9777a7 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -59,6 +59,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.BatteryManager; import android.os.Bundle; import android.os.BundleMerger; import android.os.Handler; @@ -1074,6 +1075,16 @@ class BroadcastQueueModernImpl extends BroadcastQueue { queue.lastProcessState = app.mState.getCurProcState(); if (receiver instanceof BroadcastFilter) { notifyScheduleRegisteredReceiver(app, r, (BroadcastFilter) receiver); + // STOPSHIP(b/298884211): Remove this logging + if (Intent.ACTION_BATTERY_CHANGED.equals(receiverIntent.getAction())) { + int level = receiverIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + if (level < 0) { + Slog.wtf(TAG, "Dispatching unexpected broadcast: " + receiverIntent + + " to " + receiver + + "; callingUid: " + r.callingUid + + ", callingPid: " + r.callingPid); + } + } thread.scheduleRegisteredReceiver( ((BroadcastFilter) receiver).receiverList.receiver, receiverIntent, r.resultCode, r.resultData, r.resultExtras, diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java index 52b92c4c7ca6..378cdba09520 100644 --- a/services/core/java/com/android/server/display/RampAnimator.java +++ b/services/core/java/com/android/server/display/RampAnimator.java @@ -31,7 +31,12 @@ class RampAnimator<T> { private final FloatProperty<T> mProperty; private float mCurrentValue; - private float mTargetValue; + + // target in HLG space + private float mTargetHlgValue; + + // target in linear space + private float mTargetLinearValue; private float mRate; private float mAnimationIncreaseMaxTimeSecs; private float mAnimationDecreaseMaxTimeSecs; @@ -78,7 +83,8 @@ class RampAnimator<T> { if (mFirstTime || target != mCurrentValue) { mFirstTime = false; mRate = 0; - mTargetValue = target; + mTargetHlgValue = target; + mTargetLinearValue = targetLinear; mCurrentValue = target; setPropertyValue(target); mAnimating = false; @@ -105,13 +111,14 @@ class RampAnimator<T> { // Otherwise, continue at the previous rate. if (!mAnimating || rate > mRate - || (target <= mCurrentValue && mCurrentValue <= mTargetValue) - || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) { + || (target <= mCurrentValue && mCurrentValue <= mTargetHlgValue) + || (mTargetHlgValue <= mCurrentValue && mCurrentValue <= target)) { mRate = rate; } - final boolean changed = (mTargetValue != target); - mTargetValue = target; + final boolean changed = (mTargetHlgValue != target); + mTargetHlgValue = target; + mTargetLinearValue = targetLinear; // Start animating. if (!mAnimating && target != mCurrentValue) { @@ -135,7 +142,11 @@ class RampAnimator<T> { * into linear space. */ private void setPropertyValue(float val) { - final float linearVal = BrightnessUtils.convertGammaToLinear(val); + // To avoid linearVal inconsistency when converting to HLG and back to linear space + // used original target linear value for final animation step + float linearVal = + val == mTargetHlgValue ? mTargetLinearValue : BrightnessUtils.convertGammaToLinear( + val); mProperty.setValue(mObject, linearVal); } @@ -150,13 +161,13 @@ class RampAnimator<T> { final float scale = ValueAnimator.getDurationScale(); if (scale == 0) { // Animation off. - mAnimatedValue = mTargetValue; + mAnimatedValue = mTargetHlgValue; } else { final float amount = timeDelta * mRate / scale; - if (mTargetValue > mCurrentValue) { - mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue); + if (mTargetHlgValue > mCurrentValue) { + mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetHlgValue); } else { - mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); + mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetHlgValue); } } final float oldCurrentValue = mCurrentValue; @@ -164,7 +175,7 @@ class RampAnimator<T> { if (oldCurrentValue != mCurrentValue) { setPropertyValue(mCurrentValue); } - if (mTargetValue == mCurrentValue) { + if (mTargetHlgValue == mCurrentValue) { mAnimating = false; } } diff --git a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java index e31a7fc5d5ff..198040378dc6 100644 --- a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java +++ b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java @@ -508,7 +508,11 @@ class LegacyBluetoothRouteController implements BluetoothRouteController { case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED: clearActiveRoutesWithType(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); if (device != null) { - addActiveRoute(mBluetoothRoutes.get(device.getAddress())); + if (DEBUG) { + Log.d(TAG, "Setting active a2dp devices. device=" + device); + } + + addActiveDevices(device); } notifyBluetoothRoutesUpdated(); break; diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java index ed3108e8e3ae..b499dad53326 100644 --- a/services/core/java/com/android/server/wm/ContentRecorder.java +++ b/services/core/java/com/android/server/wm/ContentRecorder.java @@ -83,6 +83,11 @@ final class ContentRecorder implements WindowContainerListener { @Nullable private Rect mLastRecordedBounds = null; /** + * The last size of the surface mirrored out to. + */ + @Nullable private Point mLastConsumingSurfaceSize = new Point(0, 0); + + /** * The last configuration orientation. */ @Configuration.Orientation @@ -177,15 +182,17 @@ final class ContentRecorder implements WindowContainerListener { final Rect recordedContentBounds = mRecordedWindowContainer.getBounds(); @Configuration.Orientation int recordedContentOrientation = mRecordedWindowContainer.getConfiguration().orientation; + final Point surfaceSize = fetchSurfaceSizeIfPresent(); if (!mLastRecordedBounds.equals(recordedContentBounds) - || lastOrientation != recordedContentOrientation) { - Point surfaceSize = fetchSurfaceSizeIfPresent(); + || lastOrientation != recordedContentOrientation + || !mLastConsumingSurfaceSize.equals(surfaceSize)) { if (surfaceSize != null) { ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Content Recording: Going ahead with updating recording for display " - + "%d to new bounds %s and/or orientation %d.", + + "%d to new bounds %s and/or orientation %d and/or surface " + + "size %s", mDisplayContent.getDisplayId(), recordedContentBounds, - recordedContentOrientation); + recordedContentOrientation, surfaceSize); updateMirroredSurface(mRecordedWindowContainer.getSyncTransaction(), recordedContentBounds, surfaceSize); } else { @@ -193,10 +200,10 @@ final class ContentRecorder implements WindowContainerListener { // (the display will be off if the surface is removed). ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Content Recording: Unable to update recording for display %d to new " - + "bounds %s and/or orientation %d, since the surface is not " - + "available.", + + "bounds %s and/or orientation %d and/or surface size %s, " + + "since the surface is not available.", mDisplayContent.getDisplayId(), recordedContentBounds, - recordedContentOrientation); + recordedContentOrientation, surfaceSize); } } } @@ -500,10 +507,13 @@ final class ContentRecorder implements WindowContainerListener { } ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, - "Content Recording: Apply transformations of shift %d x %d, scale %f, crop %d x " - + "%d for display %d", + "Content Recording: Apply transformations of shift %d x %d, scale %f, crop (aka " + + "recorded content size) %d x %d for display %d; display has size %d x " + + "%d; surface has size %d x %d", shiftedX, shiftedY, scale, recordedContentBounds.width(), - recordedContentBounds.height(), mDisplayContent.getDisplayId()); + recordedContentBounds.height(), mDisplayContent.getDisplayId(), + mDisplayContent.getConfiguration().screenWidthDp, + mDisplayContent.getConfiguration().screenHeightDp, surfaceSize.x, surfaceSize.y); transaction // Crop the area to capture to exclude the 'extra' wallpaper that is used @@ -517,6 +527,8 @@ final class ContentRecorder implements WindowContainerListener { // the content will no longer be centered in the output surface. .setPosition(mRecordedSurface, shiftedX /* x */, shiftedY /* y */); mLastRecordedBounds = new Rect(recordedContentBounds); + mLastConsumingSurfaceSize.x = surfaceSize.x; + mLastConsumingSurfaceSize.y = surfaceSize.y; // Request to notify the client about the resize. mMediaProjectionManager.notifyActiveProjectionCapturedContentResized( mLastRecordedBounds.width(), mLastRecordedBounds.height()); @@ -525,6 +537,7 @@ final class ContentRecorder implements WindowContainerListener { /** * Returns a non-null {@link Point} if the surface is present, or null otherwise */ + @Nullable private Point fetchSurfaceSizeIfPresent() { // Retrieve the default size of the surface the app provided to // MediaProjection#createVirtualDisplay. Note the app is the consumer of the surface, diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java index c914fa10687f..c8635335a445 100644 --- a/services/core/java/com/android/server/wm/SafeActivityOptions.java +++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java @@ -148,7 +148,8 @@ public class SafeActivityOptions { .setPendingIntentBackgroundActivityStartMode( options.getPendingIntentBackgroundActivityStartMode()) .setPendingIntentCreatorBackgroundActivityStartMode( - options.getPendingIntentCreatorBackgroundActivityStartMode()); + options.getPendingIntentCreatorBackgroundActivityStartMode()) + .setRemoteTransition(options.getRemoteTransition()); } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index bfe055354b9c..74a0bafd3a4c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -1279,6 +1279,7 @@ public class WindowManagerShellCommand extends ShellCommand { mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadiusPx(); mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha(); mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); + mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier(); mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled(); mLetterboxConfiguration.resetIsVerticalReachabilityEnabled(); mLetterboxConfiguration.resetEnabledAutomaticReachabilityInBookMode(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index 9c1d765fe0f9..016e85b075a4 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -624,6 +624,27 @@ final class DevicePolicyEngine { } /** + * Retrieves the global policy set by the admin for the provided {@code policyDefinition} and + * if one was set, otherwise returns {@code null}. + */ + @Nullable + <V> V getGlobalPolicySetByAdmin( + @NonNull PolicyDefinition<V> policyDefinition, + @NonNull EnforcingAdmin enforcingAdmin) { + Objects.requireNonNull(policyDefinition); + Objects.requireNonNull(enforcingAdmin); + + synchronized (mLock) { + if (!hasGlobalPolicyLocked(policyDefinition)) { + return null; + } + PolicyValue<V> value = getGlobalPolicyStateLocked(policyDefinition) + .getPoliciesSetByAdmins().get(enforcingAdmin); + return value == null ? null : value.getValue(); + } + } + + /** * Retrieves the values set for the provided {@code policyDefinition} by each admin. */ @NonNull @@ -1451,11 +1472,10 @@ final class DevicePolicyEngine { synchronized (mLock) { clear(); new DevicePoliciesReaderWriter().readFromFileLocked(); - reapplyAllPoliciesLocked(); } } - private <V> void reapplyAllPoliciesLocked() { + <V> void reapplyAllPoliciesLocked() { for (PolicyKey policy : mGlobalPolicies.keySet()) { PolicyState<?> policyState = mGlobalPolicies.get(policy); // Policy definition and value will always be of the same type diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 9515b7958355..6885a89c507e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2144,9 +2144,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener()); mDeviceManagementResourcesProvider.load(); - if (isPermissionCheckFlagEnabled() || isPolicyEngineForFinanceFlagEnabled()) { - mDevicePolicyEngine.load(); - } + mDevicePolicyEngine.load(); mContactSystemRoleHolders = fetchOemSystemHolders(/* roleResIds...= */ com.android.internal.R.string.config_defaultSms, @@ -3380,6 +3378,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mOwners.systemReady(); applyManagedSubscriptionsPolicyIfRequired(); break; + case SystemService.PHASE_SYSTEM_SERVICES_READY: + synchronized (getLockObject()) { + mDevicePolicyEngine.reapplyAllPoliciesLocked(); + } + break; case SystemService.PHASE_ACTIVITY_MANAGER_READY: synchronized (getLockObject()) { migrateToProfileOnOrganizationOwnedDeviceIfCompLocked(); @@ -9329,16 +9332,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; - if (isPolicyEngineForFinanceFlagEnabled()) { PolicyDefinition<Boolean> policy = PolicyDefinition.getPolicyDefinitionForUserRestriction( UserManager.DISALLOW_CAMERA); if (who != null) { EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackageName); - return Boolean.TRUE.equals( - mDevicePolicyEngine.getLocalPolicySetByAdmin( - policy, admin, affectedUserId)); + Boolean value = null; + if (isDeviceOwner(caller)) { + value = mDevicePolicyEngine.getGlobalPolicySetByAdmin(policy, admin); + } else { + value = mDevicePolicyEngine.getLocalPolicySetByAdmin( + policy, admin, affectedUserId); + } + return Boolean.TRUE.equals(value); } else { return Boolean.TRUE.equals( mDevicePolicyEngine.getResolvedPolicy(policy, affectedUserId)); @@ -16562,6 +16569,83 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } /** + * @param restriction The restriction enforced by admin. It could be any user restriction or + * policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}, + * {@link DevicePolicyManager#POLICY_DISABLE_SCREEN_CAPTURE} and {@link + * DevicePolicyManager#POLICY_SUSPEND_PACKAGES}. + */ + private Set<android.app.admin.EnforcingAdmin> getEnforcingAdminsForRestrictionInternal( + int userId, @NonNull String restriction) { + Objects.requireNonNull(restriction); + Set<android.app.admin.EnforcingAdmin> admins = new HashSet<>(); + // For POLICY_SUSPEND_PACKAGES return PO or DO to keep the behavior same as + // before the bug fix for b/192245204. + if (DevicePolicyManager.POLICY_SUSPEND_PACKAGES.equals( + restriction)) { + ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId); + if (profileOwner != null) { + EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin( + profileOwner, userId); + admins.add(admin.getParcelableAdmin()); + return admins; + } + final Pair<Integer, ComponentName> deviceOwner = + mOwners.getDeviceOwnerUserIdAndComponent(); + if (deviceOwner != null && deviceOwner.first == userId) { + EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin( + deviceOwner.second, deviceOwner.first); + admins.add(admin.getParcelableAdmin()); + return admins; + } + } else { + long ident = mInjector.binderClearCallingIdentity(); + try { + PolicyDefinition<Boolean> policyDefinition = getPolicyDefinitionForRestriction( + restriction); + Boolean value = mDevicePolicyEngine.getResolvedPolicy(policyDefinition, userId); + if (value != null && value) { + Map<EnforcingAdmin, PolicyValue<Boolean>> globalPolicies = + mDevicePolicyEngine.getGlobalPoliciesSetByAdmins(policyDefinition); + for (EnforcingAdmin admin : globalPolicies.keySet()) { + if (globalPolicies.get(admin) != null + && Boolean.TRUE.equals(globalPolicies.get(admin).getValue())) { + admins.add(admin.getParcelableAdmin()); + } + } + + Map<EnforcingAdmin, PolicyValue<Boolean>> localPolicies = + mDevicePolicyEngine.getLocalPoliciesSetByAdmins( + policyDefinition, userId); + for (EnforcingAdmin admin : localPolicies.keySet()) { + if (localPolicies.get(admin) != null + && Boolean.TRUE.equals(localPolicies.get(admin).getValue())) { + admins.add(admin.getParcelableAdmin()); + } + } + return admins; + } + } finally { + mInjector.binderRestoreCallingIdentity(ident); + } + } + return admins; + } + + private static PolicyDefinition<Boolean> getPolicyDefinitionForRestriction( + @NonNull String restriction) { + Objects.requireNonNull(restriction); + if (DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) { + return PolicyDefinition.getPolicyDefinitionForUserRestriction( + UserManager.DISALLOW_CAMERA); + } else if (DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) { + return PolicyDefinition.SCREEN_CAPTURE_DISABLED; + } else { + return PolicyDefinition.getPolicyDefinitionForUserRestriction(restriction); + } + } + + + /** * Excludes restrictions imposed by UserManager. */ private List<UserManager.EnforcingUser> getDevicePolicySources( @@ -16599,6 +16683,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return getEnforcingAdminAndUserDetailsInternal(userId, restriction); } + @Override + public List<android.app.admin.EnforcingAdmin> getEnforcingAdminsForRestriction( + int userId, String restriction) { + Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity())); + return new ArrayList<>(getEnforcingAdminsForRestrictionInternal(userId, restriction)); + } + /** * @param restriction The restriction enforced by admin. It could be any user restriction or * policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA} and diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java index 5243d14af1ab..006642235615 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java @@ -228,7 +228,8 @@ final class EnforcingAdmin { return new android.app.admin.EnforcingAdmin( mPackageName, authority, - UserHandle.of(mUserId)); + UserHandle.of(mUserId), + mComponentName); } /** diff --git a/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java new file mode 100644 index 000000000000..2820da7c49c1 --- /dev/null +++ b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 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.server.display; + +import static org.junit.Assert.assertEquals; + +import android.util.FloatProperty; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +@SmallTest +public class RampAnimatorTest { + + private RampAnimator<TestObject> mRampAnimator; + + private final TestObject mTestObject = new TestObject(); + + private final FloatProperty<TestObject> mTestProperty = new FloatProperty<>("mValue") { + @Override + public void setValue(TestObject object, float value) { + object.mValue = value; + } + + @Override + public Float get(TestObject object) { + return object.mValue; + } + }; + + @Before + public void setUp() { + mRampAnimator = new RampAnimator<>(mTestObject, mTestProperty); + } + + @Test + public void testInitialValueUsedInLastAnimationStep() { + mRampAnimator.setAnimationTarget(0.67f, 0.1f); + + assertEquals(0.67f, mTestObject.mValue, 0); + } + + private static class TestObject { + private float mValue; + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java index b8f6cb8b5eba..e1b11f6c963f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java @@ -303,6 +303,30 @@ public class ContentRecorderTests extends WindowTestsBase { anyFloat(), anyFloat()); } + /** + * Test that resizing the output surface results in resizing the mirrored content to fit. + */ + @Test + public void testOnConfigurationChanged_resizeSurface() { + mContentRecorder.setContentRecordingSession(mDisplaySession); + mContentRecorder.updateRecording(); + + // Resize the output surface. + final Point newSurfaceSize = new Point(Math.round(sSurfaceSize.x / 2f), + Math.round(sSurfaceSize.y * 2)); + doReturn(newSurfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize( + anyInt()); + mContentRecorder.onConfigurationChanged( + mVirtualDisplayContent.getConfiguration().orientation); + + // No resize is issued, only the initial transformations when we started recording. + verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(), + anyFloat()); + verify(mTransaction, atLeast(2)).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(), + anyFloat(), anyFloat()); + + } + @Test public void testOnTaskOrientationConfigurationChanged_resizesSurface() { mContentRecorder.setContentRecordingSession(mTaskSession); |