diff options
18 files changed, 509 insertions, 82 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 625dca7e402e..38ade2f16bdb 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -636,6 +636,11 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +cc_aconfig_library { + name: "aconfig_hardware_flags_c_lib", + aconfig_declarations: "android.hardware.flags-aconfig", +} + // Widget aconfig_declarations { name: "android.widget.flags-aconfig", diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java index fe936f77de07..f42c0ec5ee7c 100644 --- a/core/java/android/window/TransitionRequestInfo.java +++ b/core/java/android/window/TransitionRequestInfo.java @@ -44,10 +44,10 @@ public final class TransitionRequestInfo implements Parcelable { private @Nullable ActivityManager.RunningTaskInfo mTriggerTask; /** - * If non-null, the task containing the pip activity that participates in this - * transition. + * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both + * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity. */ - private @Nullable ActivityManager.RunningTaskInfo mPipTask; + private @Nullable TransitionRequestInfo.PipChange mPipChange; /** If non-null, a remote-transition associated with the source of this transition. */ private @Nullable RemoteTransition mRemoteTransition; @@ -70,7 +70,7 @@ public final class TransitionRequestInfo implements Parcelable { @WindowManager.TransitionType int type, @Nullable ActivityManager.RunningTaskInfo triggerTask, @Nullable RemoteTransition remoteTransition) { - this(type, triggerTask, null /* pipTask */, + this(type, triggerTask, null /* pipChange */, remoteTransition, null /* displayChange */, 0 /* flags */, -1 /* debugId */); } @@ -80,7 +80,7 @@ public final class TransitionRequestInfo implements Parcelable { @Nullable ActivityManager.RunningTaskInfo triggerTask, @Nullable RemoteTransition remoteTransition, int flags) { - this(type, triggerTask, null /* pipTask */, + this(type, triggerTask, null /* pipChange */, remoteTransition, null /* displayChange */, flags, -1 /* debugId */); } @@ -91,7 +91,7 @@ public final class TransitionRequestInfo implements Parcelable { @Nullable RemoteTransition remoteTransition, @Nullable TransitionRequestInfo.DisplayChange displayChange, int flags) { - this(type, triggerTask, null /* pipTask */, remoteTransition, displayChange, flags, + this(type, triggerTask, null /* pipChange */, remoteTransition, displayChange, flags, -1 /* debugId */); } @@ -103,7 +103,9 @@ public final class TransitionRequestInfo implements Parcelable { @Nullable RemoteTransition remoteTransition, @Nullable TransitionRequestInfo.DisplayChange displayChange, int flags) { - this(type, triggerTask, pipTask, remoteTransition, displayChange, flags, -1 /* debugId */); + this(type, triggerTask, + pipTask != null ? new TransitionRequestInfo.PipChange(pipTask) : null, + remoteTransition, displayChange, flags, -1 /* debugId */); } /** @hide */ @@ -252,7 +254,7 @@ public final class TransitionRequestInfo implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - protected DisplayChange(@android.annotation.NonNull android.os.Parcel in) { + /* package-private */ DisplayChange(@android.annotation.NonNull android.os.Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } @@ -289,7 +291,7 @@ public final class TransitionRequestInfo implements Parcelable { }; @DataClass.Generated( - time = 1697564781403L, + time = 1733334462577L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java", inputSignatures = "private final int mDisplayId\nprivate @android.annotation.Nullable android.graphics.Rect mStartAbsBounds\nprivate @android.annotation.Nullable android.graphics.Rect mEndAbsBounds\nprivate int mStartRotation\nprivate int mEndRotation\nprivate boolean mPhysicalDisplayChanged\nclass DisplayChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)") @@ -302,6 +304,143 @@ public final class TransitionRequestInfo implements Parcelable { } + @DataClass(genToString = true, genSetters = true, genBuilder = false, genConstructor = false) + public static final class PipChange implements Parcelable { + // In AE case, we might care about the TF token instead of the task token. + @android.annotation.NonNull + private WindowContainerToken mTaskFragmentToken; + + @android.annotation.NonNull + private ActivityManager.RunningTaskInfo mTaskInfo; + + /** Create empty display-change. */ + public PipChange(ActivityManager.RunningTaskInfo taskInfo) { + mTaskFragmentToken = taskInfo.token; + mTaskInfo = taskInfo; + } + + /** Create a display-change representing a rotation. */ + public PipChange(WindowContainerToken taskFragmentToken, + ActivityManager.RunningTaskInfo taskInfo) { + mTaskFragmentToken = taskFragmentToken; + mTaskInfo = taskInfo; + } + + + + // Code below generated by codegen v1.0.23. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/window/TransitionRequestInfo.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + @DataClass.Generated.Member + public @android.annotation.NonNull WindowContainerToken getTaskFragmentToken() { + return mTaskFragmentToken; + } + + @DataClass.Generated.Member + public @android.annotation.NonNull ActivityManager.RunningTaskInfo getTaskInfo() { + return mTaskInfo; + } + + @DataClass.Generated.Member + public @android.annotation.NonNull PipChange setTaskFragmentToken(@android.annotation.NonNull WindowContainerToken value) { + mTaskFragmentToken = value; + com.android.internal.util.AnnotationValidations.validate( + android.annotation.NonNull.class, null, mTaskFragmentToken); + return this; + } + + @DataClass.Generated.Member + public @android.annotation.NonNull PipChange setTaskInfo(@android.annotation.NonNull ActivityManager.RunningTaskInfo value) { + mTaskInfo = value; + com.android.internal.util.AnnotationValidations.validate( + android.annotation.NonNull.class, null, mTaskInfo); + return this; + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "PipChange { " + + "taskFragmentToken = " + mTaskFragmentToken + ", " + + "taskInfo = " + mTaskInfo + + " }"; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeTypedObject(mTaskFragmentToken, flags); + dest.writeTypedObject(mTaskInfo, flags); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + /* package-private */ PipChange(@android.annotation.NonNull android.os.Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + WindowContainerToken taskFragmentToken = (WindowContainerToken) in.readTypedObject(WindowContainerToken.CREATOR); + ActivityManager.RunningTaskInfo taskInfo = (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR); + + this.mTaskFragmentToken = taskFragmentToken; + com.android.internal.util.AnnotationValidations.validate( + android.annotation.NonNull.class, null, mTaskFragmentToken); + this.mTaskInfo = taskInfo; + com.android.internal.util.AnnotationValidations.validate( + android.annotation.NonNull.class, null, mTaskInfo); + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @android.annotation.NonNull Parcelable.Creator<PipChange> CREATOR + = new Parcelable.Creator<PipChange>() { + @Override + public PipChange[] newArray(int size) { + return new PipChange[size]; + } + + @Override + public PipChange createFromParcel(@android.annotation.NonNull android.os.Parcel in) { + return new PipChange(in); + } + }; + + @DataClass.Generated( + time = 1733334462588L, + codegenVersion = "1.0.23", + sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java", + inputSignatures = "private @android.annotation.NonNull android.window.WindowContainerToken mTaskFragmentToken\nprivate @android.annotation.NonNull android.app.ActivityManager.RunningTaskInfo mTaskInfo\nclass PipChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + + } + @@ -326,9 +465,9 @@ public final class TransitionRequestInfo implements Parcelable { * @param triggerTask * If non-null, the task containing the activity whose lifecycle change (start or * finish) has caused this transition to occur. - * @param pipTask - * If non-null, the task containing the pip activity that participates in this - * transition. + * @param pipChange + * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both + * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity. * @param remoteTransition * If non-null, a remote-transition associated with the source of this transition. * @param displayChange @@ -344,7 +483,7 @@ public final class TransitionRequestInfo implements Parcelable { public TransitionRequestInfo( @WindowManager.TransitionType int type, @Nullable ActivityManager.RunningTaskInfo triggerTask, - @Nullable ActivityManager.RunningTaskInfo pipTask, + @Nullable TransitionRequestInfo.PipChange pipChange, @Nullable RemoteTransition remoteTransition, @Nullable TransitionRequestInfo.DisplayChange displayChange, int flags, @@ -353,7 +492,7 @@ public final class TransitionRequestInfo implements Parcelable { com.android.internal.util.AnnotationValidations.validate( WindowManager.TransitionType.class, null, mType); this.mTriggerTask = triggerTask; - this.mPipTask = pipTask; + this.mPipChange = pipChange; this.mRemoteTransition = remoteTransition; this.mDisplayChange = displayChange; this.mFlags = flags; @@ -380,12 +519,12 @@ public final class TransitionRequestInfo implements Parcelable { } /** - * If non-null, the task containing the pip activity that participates in this - * transition. + * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both + * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity. */ @DataClass.Generated.Member - public @Nullable ActivityManager.RunningTaskInfo getPipTask() { - return mPipTask; + public @Nullable TransitionRequestInfo.PipChange getPipChange() { + return mPipChange; } /** @@ -433,12 +572,12 @@ public final class TransitionRequestInfo implements Parcelable { } /** - * If non-null, the task containing the pip activity that participates in this - * transition. + * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both + * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity. */ @DataClass.Generated.Member - public @android.annotation.NonNull TransitionRequestInfo setPipTask(@android.annotation.NonNull ActivityManager.RunningTaskInfo value) { - mPipTask = value; + public @android.annotation.NonNull TransitionRequestInfo setPipChange(@android.annotation.NonNull TransitionRequestInfo.PipChange value) { + mPipChange = value; return this; } @@ -471,10 +610,10 @@ public final class TransitionRequestInfo implements Parcelable { return "TransitionRequestInfo { " + "type = " + typeToString() + ", " + "triggerTask = " + mTriggerTask + ", " + - "pipTask = " + mPipTask + ", " + + "pipChange = " + mPipChange + ", " + "remoteTransition = " + mRemoteTransition + ", " + "displayChange = " + mDisplayChange + ", " + - "flags = " + Integer.toHexString(mFlags) + ", " + + "flags = " + mFlags + ", " + "debugId = " + mDebugId + " }"; } @@ -487,13 +626,13 @@ public final class TransitionRequestInfo implements Parcelable { byte flg = 0; if (mTriggerTask != null) flg |= 0x2; - if (mPipTask != null) flg |= 0x4; + if (mPipChange != null) flg |= 0x4; if (mRemoteTransition != null) flg |= 0x8; if (mDisplayChange != null) flg |= 0x10; dest.writeByte(flg); dest.writeInt(mType); if (mTriggerTask != null) dest.writeTypedObject(mTriggerTask, flags); - if (mPipTask != null) dest.writeTypedObject(mPipTask, flags); + if (mPipChange != null) dest.writeTypedObject(mPipChange, flags); if (mRemoteTransition != null) dest.writeTypedObject(mRemoteTransition, flags); if (mDisplayChange != null) dest.writeTypedObject(mDisplayChange, flags); dest.writeInt(mFlags); @@ -514,7 +653,7 @@ public final class TransitionRequestInfo implements Parcelable { byte flg = in.readByte(); int type = in.readInt(); ActivityManager.RunningTaskInfo triggerTask = (flg & 0x2) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR); - ActivityManager.RunningTaskInfo pipTask = (flg & 0x4) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR); + TransitionRequestInfo.PipChange pipChange = (flg & 0x4) == 0 ? null : (TransitionRequestInfo.PipChange) in.readTypedObject(TransitionRequestInfo.PipChange.CREATOR); RemoteTransition remoteTransition = (flg & 0x8) == 0 ? null : (RemoteTransition) in.readTypedObject(RemoteTransition.CREATOR); TransitionRequestInfo.DisplayChange displayChange = (flg & 0x10) == 0 ? null : (TransitionRequestInfo.DisplayChange) in.readTypedObject(TransitionRequestInfo.DisplayChange.CREATOR); int flags = in.readInt(); @@ -524,7 +663,7 @@ public final class TransitionRequestInfo implements Parcelable { com.android.internal.util.AnnotationValidations.validate( WindowManager.TransitionType.class, null, mType); this.mTriggerTask = triggerTask; - this.mPipTask = pipTask; + this.mPipChange = pipChange; this.mRemoteTransition = remoteTransition; this.mDisplayChange = displayChange; this.mFlags = flags; @@ -548,10 +687,10 @@ public final class TransitionRequestInfo implements Parcelable { }; @DataClass.Generated( - time = 1697564781438L, + time = 1733334462604L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java", - inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mPipTask\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nprivate final int mDebugId\n java.lang.String typeToString()\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)") + inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.PipChange mPipChange\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nprivate final int mDebugId\n java.lang.String typeToString()\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)") @Deprecated private void __metadata() {} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/HasWMComponent.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/HasWMComponent.kt new file mode 100644 index 000000000000..d5e0240ea9ad --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/HasWMComponent.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 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.wm.shell.dagger + +/** + * An interface implemented by the application that uses [WMComponent]. + * + * This exposes the component to allow classes to do member injection for bindings where constructor + * injection is not possible, e.g. views. + */ +interface HasWMComponent { + fun getWMComponent(): WMComponent +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMComponent.java index a3cdb2eff601..c493aadd57b0 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMComponent.java @@ -14,17 +14,14 @@ * limitations under the License. */ -package com.android.systemui.dagger; +package com.android.wm.shell.dagger; import android.os.HandlerThread; import androidx.annotation.Nullable; -import com.android.systemui.SystemUIInitializer; import com.android.wm.shell.back.BackAnimation; import com.android.wm.shell.bubbles.Bubbles; -import com.android.wm.shell.dagger.WMShellModule; -import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.displayareahelper.DisplayAreaHelper; import com.android.wm.shell.keyguard.KeyguardTransitions; @@ -45,12 +42,11 @@ import java.util.Optional; /** * Dagger Subcomponent for WindowManager. This class explicitly describes the interfaces exported - * from the WM component into the SysUI component (in - * {@link SystemUIInitializer#init(boolean)}), and references the specific dependencies + * from the WM component into the SysUI component, and references the specific dependencies * provided by its particular device/form-factor SystemUI implementation. * - * ie. {@link WMComponent} includes {@link WMShellModule} - * and {@code TvWMComponent} includes {@link com.android.wm.shell.dagger.TvWMShellModule} + * <p> ie. {@link WMComponent} includes {@link WMShellModule} and {@code TvWMComponent} includes + * {@link TvWMShellModule} */ @WMSingleton @Subcomponent(modules = {WMShellModule.class}) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index 1a012e075be5..1efe2ffd804a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -196,7 +196,7 @@ public class PipTransition extends PipTransitionController implements @NonNull TransitionRequestInfo request) { if (isAutoEnterInButtonNavigation(request) || isEnterPictureInPictureModeRequest(request)) { mEnterTransition = transition; - return getEnterPipTransaction(transition, request); + return getEnterPipTransaction(transition, request.getPipChange()); } return null; } @@ -205,7 +205,8 @@ public class PipTransition extends PipTransitionController implements public void augmentRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWct) { if (isAutoEnterInButtonNavigation(request) || isEnterPictureInPictureModeRequest(request)) { - outWct.merge(getEnterPipTransaction(transition, request), true /* transfer */); + outWct.merge(getEnterPipTransaction(transition, request.getPipChange()), + true /* transfer */); mEnterTransition = transition; } } @@ -775,9 +776,9 @@ public class PipTransition extends PipTransitionController implements } private WindowContainerTransaction getEnterPipTransaction(@NonNull IBinder transition, - @NonNull TransitionRequestInfo request) { + @NonNull TransitionRequestInfo.PipChange pipChange) { // cache the original task token to check for multi-activity case later - final ActivityManager.RunningTaskInfo pipTask = request.getPipTask(); + final ActivityManager.RunningTaskInfo pipTask = pipChange.getTaskInfo(); PictureInPictureParams pipParams = pipTask.pictureInPictureParams; mPipTaskListener.setPictureInPictureParams(pipParams); mPipBoundsState.setBoundsStateForEntry(pipTask.topActivity, pipTask.topActivityInfo, @@ -787,14 +788,18 @@ public class PipTransition extends PipTransitionController implements final Rect entryBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); mPipBoundsState.setBounds(entryBounds); + // Operate on the TF token in case we are dealing with AE case; this should avoid marking + // activities in other TFs as config-at-end. + WindowContainerToken token = pipChange.getTaskFragmentToken(); WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.movePipActivityToPinnedRootTask(pipTask.token, entryBounds); - wct.deferConfigToTransitionEnd(pipTask.token); + wct.movePipActivityToPinnedRootTask(token, entryBounds); + wct.deferConfigToTransitionEnd(token); return wct; } private boolean isAutoEnterInButtonNavigation(@NonNull TransitionRequestInfo requestInfo) { - final ActivityManager.RunningTaskInfo pipTask = requestInfo.getPipTask(); + final ActivityManager.RunningTaskInfo pipTask = requestInfo.getPipChange() != null + ? requestInfo.getPipChange().getTaskInfo() : null; if (pipTask == null) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index a46b236d46fb..981732278acd 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -46,6 +46,8 @@ import com.android.systemui.process.ProcessWrapper; import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.ConfigurationForwarder; import com.android.systemui.util.NotificationChannels; +import com.android.wm.shell.dagger.HasWMComponent; +import com.android.wm.shell.dagger.WMComponent; import java.lang.reflect.InvocationTargetException; import java.util.ArrayDeque; @@ -62,7 +64,7 @@ import javax.inject.Provider; * Application class for SystemUI. */ public class SystemUIApplication extends Application implements - SystemUIAppComponentFactoryBase.ContextInitializer { + SystemUIAppComponentFactoryBase.ContextInitializer, HasWMComponent { public static final String TAG = "SystemUIService"; private static final boolean DEBUG = false; @@ -490,4 +492,10 @@ public class SystemUIApplication extends Application implements n.addExtras(extras); } + + @NonNull + @Override + public WMComponent getWMComponent() { + return mInitializer.getWMComponent(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java index 5c75a49818a6..f530522fb707 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java @@ -24,9 +24,9 @@ import android.util.Log; import com.android.systemui.dagger.GlobalRootComponent; import com.android.systemui.dagger.SysUIComponent; -import com.android.systemui.dagger.WMComponent; import com.android.systemui.res.R; import com.android.systemui.util.InitializationChecker; +import com.android.wm.shell.dagger.WMComponent; import com.android.wm.shell.dagger.WMShellConcurrencyModule; import com.android.wm.shell.keyguard.KeyguardTransitions; import com.android.wm.shell.shared.ShellTransitions; diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java index e78ce3bbb0d1..f804c2e80ac6 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java @@ -24,6 +24,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.SystemPropertiesHelper; import com.android.systemui.process.ProcessWrapper; import com.android.systemui.util.InitializationChecker; +import com.android.wm.shell.dagger.WMComponent; import dagger.BindsInstance; diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 073781e6101d..0ec71c21985e 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -48,7 +48,6 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.CoreStartable; import com.android.systemui.communal.ui.viewmodel.CommunalTransitionViewModel; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.dagger.WMComponent; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; @@ -60,6 +59,7 @@ import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.kotlin.JavaAdapter; +import com.android.wm.shell.dagger.WMComponent; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.desktopmode.DesktopRepository; import com.android.wm.shell.onehanded.OneHanded; diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java index 7155cd0fc719..4a533f42ffea 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java @@ -27,6 +27,10 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import com.android.internal.annotations.GuardedBy; + +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -60,6 +64,20 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /** True if this endpoint is registered with the service. */ private AtomicBoolean mIsRegistered = new AtomicBoolean(true); + private final Object mOpenSessionLock = new Object(); + + /** The set of session IDs that are pending remote acceptance */ + @GuardedBy("mOpenSessionLock") + private final Set<Integer> mPendingSessionIds = new HashSet<>(); + + /** The set of session IDs that are actively enabled by this endpoint */ + @GuardedBy("mOpenSessionLock") + private final Set<Integer> mActiveSessionIds = new HashSet<>(); + + /** The set of session IDs that are actively enabled by the remote endpoint */ + @GuardedBy("mOpenSessionLock") + private final Set<Integer> mActiveRemoteSessionIds = new HashSet<>(); + /* package */ ContextHubEndpointBroker( Context context, IContextHubWrapper contextHubProxy, @@ -86,16 +104,24 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered"); int sessionId = mEndpointManager.reserveSessionId(); EndpointInfo halEndpointInfo = ContextHubServiceUtil.convertHalEndpointInfo(destination); - try { - mContextHubProxy.openEndpointSession( - sessionId, halEndpointInfo.id, mHalEndpointInfo.id, serviceDescriptor); - } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { - Log.e(TAG, "Exception while calling HAL openEndpointSession", e); - mEndpointManager.returnSessionId(sessionId); - throw e; - } - return sessionId; + synchronized (mOpenSessionLock) { + try { + mPendingSessionIds.add(sessionId); + mContextHubProxy.openEndpointSession( + sessionId, + halEndpointInfo.id, + mHalEndpointInfo.id, + serviceDescriptor); + } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { + Log.e(TAG, "Exception while calling HAL openEndpointSession", e); + mPendingSessionIds.remove(sessionId); + mEndpointManager.returnSessionId(sessionId); + throw e; + } + + return sessionId; + } } @Override @@ -111,11 +137,6 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } @Override - public void openSessionRequestComplete(int sessionId) { - // TODO(b/378487799): Implement this - } - - @Override public void unregister() { ContextHubServiceUtil.checkPermissions(mContext); mIsRegistered.set(false); @@ -124,11 +145,34 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling HAL unregisterEndpoint", e); } - // TODO(b/378487799): Release reserved session IDs + synchronized (mOpenSessionLock) { + for (int id : mPendingSessionIds) { + mEndpointManager.returnSessionId(id); + } + for (int id : mActiveSessionIds) { + mEndpointManager.returnSessionId(id); + } + mPendingSessionIds.clear(); + mActiveSessionIds.clear(); + mActiveRemoteSessionIds.clear(); + } mEndpointManager.unregisterEndpoint(mEndpointInfo.getIdentifier().getEndpoint()); } @Override + public void openSessionRequestComplete(int sessionId) { + ContextHubServiceUtil.checkPermissions(mContext); + synchronized (mOpenSessionLock) { + try { + mContextHubProxy.endpointSessionOpenComplete(sessionId); + mActiveRemoteSessionIds.add(sessionId); + } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { + Log.e(TAG, "Exception while calling endpointSessionOpenComplete", e); + } + } + } + + @Override public void sendMessage( int sessionId, HubMessage message, IContextHubTransactionCallback callback) { // TODO(b/381102453): Implement this @@ -150,4 +194,53 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub mContextHubEndpointCallback.asBinder().linkToDeath(this, 0 /* flags */); } } + + /* package */ void onEndpointSessionOpenRequest( + int sessionId, HubEndpointInfo initiator, String serviceDescriptor) { + if (mContextHubEndpointCallback != null) { + try { + mContextHubEndpointCallback.onSessionOpenRequest( + sessionId, initiator, serviceDescriptor); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while calling onSessionOpenRequest", e); + } + } + } + + /* package */ void onCloseEndpointSession(int sessionId, byte reason) { + synchronized (mOpenSessionLock) { + mPendingSessionIds.remove(sessionId); + mActiveSessionIds.remove(sessionId); + mActiveRemoteSessionIds.remove(sessionId); + } + if (mContextHubEndpointCallback != null) { + try { + mContextHubEndpointCallback.onSessionClosed(sessionId, reason); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while calling onSessionClosed", e); + } + } + } + + /* package */ void onEndpointSessionOpenComplete(int sessionId) { + synchronized (mOpenSessionLock) { + mPendingSessionIds.remove(sessionId); + mActiveSessionIds.add(sessionId); + } + if (mContextHubEndpointCallback != null) { + try { + mContextHubEndpointCallback.onSessionOpenComplete(sessionId); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while calling onSessionClosed", e); + } + } + } + + /* package */ boolean hasSessionId(int sessionId) { + synchronized (mOpenSessionLock) { + return mPendingSessionIds.contains(sessionId) + || mActiveSessionIds.contains(sessionId) + || mActiveRemoteSessionIds.contains(sessionId); + } + } } diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java index fb64f99e5904..8c5095f35f0d 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java @@ -38,7 +38,8 @@ import java.util.concurrent.ConcurrentHashMap; * * @hide */ -/* package */ class ContextHubEndpointManager { +/* package */ class ContextHubEndpointManager + implements ContextHubHalEndpointCallback.IEndpointSessionCallback { private static final String TAG = "ContextHubEndpointManager"; /** The hub ID of the Context Hub Service. */ @@ -56,6 +57,8 @@ import java.util.concurrent.ConcurrentHashMap; /** The proxy to talk to the Context Hub. */ private final IContextHubWrapper mContextHubProxy; + private final HubInfoRegistry mHubInfoRegistry; + /** A map of endpoint IDs to brokers currently registered. */ private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>(); @@ -85,9 +88,11 @@ import java.util.concurrent.ConcurrentHashMap; /** Initialized to true if all initialization in the constructor succeeds. */ private final boolean mSessionIdsValid; - /* package */ ContextHubEndpointManager(Context context, IContextHubWrapper contextHubProxy) { + /* package */ ContextHubEndpointManager( + Context context, IContextHubWrapper contextHubProxy, HubInfoRegistry hubInfoRegistry) { mContext = context; mContextHubProxy = contextHubProxy; + mHubInfoRegistry = hubInfoRegistry; int[] range = null; try { range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE); @@ -210,6 +215,70 @@ import java.util.concurrent.ConcurrentHashMap; mEndpointMap.remove(endpointId); } + @Override + public void onEndpointSessionOpenRequest( + int sessionId, + HubEndpointInfo.HubEndpointIdentifier destination, + HubEndpointInfo.HubEndpointIdentifier initiator, + String serviceDescriptor) { + if (destination.getHub() != SERVICE_HUB_ID) { + Log.e( + TAG, + "onEndpointSessionOpenRequest: invalid destination hub ID: " + + destination.getHub()); + return; + } + ContextHubEndpointBroker broker = mEndpointMap.get(destination.getEndpoint()); + if (broker == null) { + Log.e( + TAG, + "onEndpointSessionOpenRequest: unknown destination endpoint ID: " + + destination.getEndpoint()); + return; + } + HubEndpointInfo initiatorInfo = mHubInfoRegistry.getEndpointInfo(initiator); + if (initiatorInfo == null) { + Log.e( + TAG, + "onEndpointSessionOpenRequest: unknown initiator endpoint ID: " + + initiator.getEndpoint()); + return; + } + broker.onEndpointSessionOpenRequest(sessionId, initiatorInfo, serviceDescriptor); + } + + @Override + public void onCloseEndpointSession(int sessionId, byte reason) { + boolean callbackInvoked = false; + for (ContextHubEndpointBroker broker : mEndpointMap.values()) { + if (broker.hasSessionId(sessionId)) { + broker.onCloseEndpointSession(sessionId, reason); + callbackInvoked = true; + break; + } + } + + if (!callbackInvoked) { + Log.w(TAG, "onCloseEndpointSession: unknown session ID " + sessionId); + } + } + + @Override + public void onEndpointSessionOpenComplete(int sessionId) { + boolean callbackInvoked = false; + for (ContextHubEndpointBroker broker : mEndpointMap.values()) { + if (broker.hasSessionId(sessionId)) { + broker.onEndpointSessionOpenComplete(sessionId); + callbackInvoked = true; + break; + } + } + + if (!callbackInvoked) { + Log.w(TAG, "onEndpointSessionOpenComplete: unknown session ID " + sessionId); + } + } + /** @return an available endpoint ID */ private long getNewEndpointId() { synchronized (mEndpointLock) { @@ -220,6 +289,9 @@ import java.util.concurrent.ConcurrentHashMap; } } + /** + * @return true if the provided session ID range is valid + */ private boolean isSessionIdRangeValid(int minId, int maxId) { return (minId <= maxId) && (minId >= 0) && (maxId >= 0); } diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java index c05f7a0c0e00..8e72553a9c52 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java @@ -26,6 +26,7 @@ import android.os.RemoteException; public class ContextHubHalEndpointCallback extends android.hardware.contexthub.IEndpointCallback.Stub { private final IEndpointLifecycleCallback mEndpointLifecycleCallback; + private final IEndpointSessionCallback mEndpointSessionCallback; /** Interface for listening for endpoint start and stop events. */ public interface IEndpointLifecycleCallback { @@ -36,8 +37,27 @@ public class ContextHubHalEndpointCallback void onEndpointStopped(HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason); } - ContextHubHalEndpointCallback(IEndpointLifecycleCallback endpointLifecycleCallback) { + /** Interface for listening for endpoint session events. */ + public interface IEndpointSessionCallback { + /** Called when an endpoint session open is requested by the HAL. */ + void onEndpointSessionOpenRequest( + int sessionId, + HubEndpointInfo.HubEndpointIdentifier destinationId, + HubEndpointInfo.HubEndpointIdentifier initiatorId, + String serviceDescriptor); + + /** Called when a endpoint close session is completed. */ + void onCloseEndpointSession(int sessionId, byte reason); + + /** Called when a requested endpoint open session is completed */ + void onEndpointSessionOpenComplete(int sessionId); + } + + ContextHubHalEndpointCallback( + IEndpointLifecycleCallback endpointLifecycleCallback, + IEndpointSessionCallback endpointSessionCallback) { mEndpointLifecycleCallback = endpointLifecycleCallback; + mEndpointSessionCallback = endpointSessionCallback; } @Override @@ -72,14 +92,23 @@ public class ContextHubHalEndpointCallback @Override public void onEndpointSessionOpenRequest( - int i, EndpointId endpointId, EndpointId endpointId1, String s) - throws RemoteException {} + int i, EndpointId destination, EndpointId initiator, String s) throws RemoteException { + HubEndpointInfo.HubEndpointIdentifier destinationId = + new HubEndpointInfo.HubEndpointIdentifier(destination.hubId, destination.id); + HubEndpointInfo.HubEndpointIdentifier initiatorId = + new HubEndpointInfo.HubEndpointIdentifier(initiator.hubId, initiator.id); + mEndpointSessionCallback.onEndpointSessionOpenRequest(i, destinationId, initiatorId, s); + } @Override - public void onCloseEndpointSession(int i, byte b) throws RemoteException {} + public void onCloseEndpointSession(int i, byte b) throws RemoteException { + mEndpointSessionCallback.onCloseEndpointSession(i, b); + } @Override - public void onEndpointSessionOpenComplete(int i) throws RemoteException {} + public void onEndpointSessionOpenComplete(int i) throws RemoteException { + mEndpointSessionCallback.onEndpointSessionOpenComplete(i); + } @Override public int getInterfaceVersion() throws RemoteException { diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java index 0d926b99217d..0b47a61341f7 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -333,7 +333,8 @@ public class ContextHubService extends IContextHubService.Stub { HubInfoRegistry registry; try { registry = new HubInfoRegistry(mContextHubWrapper); - mEndpointManager = new ContextHubEndpointManager(mContext, mContextHubWrapper); + mEndpointManager = + new ContextHubEndpointManager(mContext, mContextHubWrapper, registry); Log.i(TAG, "Enabling generic offload API"); } catch (UnsupportedOperationException e) { mEndpointManager = null; @@ -533,7 +534,7 @@ public class ContextHubService extends IContextHubService.Stub { } try { mContextHubWrapper.registerEndpointCallback( - new ContextHubHalEndpointCallback(mHubInfoRegistry)); + new ContextHubHalEndpointCallback(mHubInfoRegistry, mEndpointManager)); } catch (RemoteException | UnsupportedOperationException e) { Log.e(TAG, "Exception while registering IEndpointCallback", e); } diff --git a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java index d2b2331d54f3..b91249204199 100644 --- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java +++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java @@ -87,6 +87,12 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl } } + public HubEndpointInfo getEndpointInfo(HubEndpointInfo.HubEndpointIdentifier id) { + synchronized (mLock) { + return mHubEndpointInfos.get(id); + } + } + /** Invoked when HAL restarts */ public void onHalRestart() { synchronized (mLock) { diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java index c79dc84ec2af..6cb942980403 100644 --- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java +++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java @@ -261,6 +261,9 @@ public abstract class IContextHubWrapper { public void unregisterEndpoint(android.hardware.contexthub.EndpointInfo info) throws RemoteException {} + /** Notifies the completion of a session opened by the HAL */ + public void endpointSessionOpenComplete(int sessionId) throws RemoteException {} + /** * @return True if this version of the Contexthub HAL supports Location setting notifications. */ @@ -745,6 +748,15 @@ public abstract class IContextHubWrapper { hub.unregisterEndpoint(info); } + @Override + public void endpointSessionOpenComplete(int sessionId) throws RemoteException { + android.hardware.contexthub.IContextHub hub = getHub(); + if (hub == null) { + return; + } + hub.endpointSessionOpenComplete(sessionId); + } + public boolean supportsLocationSettingNotifications() { return true; } diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 8562bb23b30f..f3c03cbfb3b4 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -791,19 +791,30 @@ class TransitionController { ProtoLog.v(WmProtoLogGroups.WM_DEBUG_WINDOW_TRANSITIONS, "Requesting StartTransition: %s", transition); ActivityManager.RunningTaskInfo startTaskInfo = null; - ActivityManager.RunningTaskInfo pipTaskInfo = null; + TransitionRequestInfo.PipChange pipChange = null; if (startTask != null) { startTaskInfo = startTask.getTaskInfo(); } // set the pip task in the request if provided if (transition.getPipActivity() != null) { - pipTaskInfo = transition.getPipActivity().getTask().getTaskInfo(); + ActivityManager.RunningTaskInfo pipTaskInfo = + transition.getPipActivity().getTask().getTaskInfo(); + ActivityRecord pipActivity = transition.getPipActivity(); + if (pipActivity.getTaskFragment() != null + && pipActivity.getTaskFragment() != pipActivity.getTask()) { + // If the PiP activity is in a TF different from its task, this could be + // AE-to-PiP case, so PipChange will have the TF token cached separately. + pipChange = new TransitionRequestInfo.PipChange(pipActivity.getTaskFragment() + .mRemoteToken.toWindowContainerToken(), pipTaskInfo); + } else { + pipChange = new TransitionRequestInfo.PipChange(pipTaskInfo); + } transition.setPipActivity(null); } final TransitionRequestInfo request = new TransitionRequestInfo(transition.mType, - startTaskInfo, pipTaskInfo, remoteTransition, displayChange, + startTaskInfo, pipChange, remoteTransition, displayChange, transition.getFlags(), transition.getSyncId()); transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos(); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index ddff24d35232..66921ff3adeb 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -1335,11 +1335,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } case HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK: { final WindowContainer container = WindowContainer.fromBinder(hop.getContainer()); - Task pipTask = container.asTask(); - if (pipTask == null) { + TaskFragment pipTaskFragment = container.asTaskFragment(); + if (pipTaskFragment == null) { break; } - ActivityRecord pipActivity = pipTask.getActivity( + ActivityRecord pipActivity = pipTaskFragment.getActivity( (activity) -> activity.pictureInPictureArgs != null); if (pipActivity.isState(RESUMED)) { diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 010a32274dcd..e7c9e927b311 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -48,6 +48,7 @@ import android.app.IUidObserver; import android.app.PendingIntent; import android.app.UidObserver; import android.app.admin.DevicePolicyManagerInternal; +import android.app.supervision.SupervisionManagerInternal; import android.app.usage.AppLaunchEstimateInfo; import android.app.usage.AppStandbyInfo; import android.app.usage.BroadcastResponseStatsList; @@ -230,6 +231,7 @@ public class UsageStatsService extends SystemService implements // Do not use directly. Call getDpmInternal() instead DevicePolicyManagerInternal mDpmInternal; // Do not use directly. Call getShortcutServiceInternal() instead + SupervisionManagerInternal mSupervisionManagerInternal; ShortcutServiceInternal mShortcutServiceInternal; private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>(); @@ -439,6 +441,9 @@ public class UsageStatsService extends SystemService implements // initialize mDpmInternal getDpmInternal(); // initialize mShortcutServiceInternal + if (android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()) { + getSupervisionManagerInternal(); + } getShortcutServiceInternal(); mResponseStatsTracker.onSystemServicesReady(getContext()); @@ -604,6 +609,15 @@ public class UsageStatsService extends SystemService implements return mDpmInternal; } + @Nullable + private SupervisionManagerInternal getSupervisionManagerInternal() { + if (mSupervisionManagerInternal == null) { + mSupervisionManagerInternal = + LocalServices.getService(SupervisionManagerInternal.class); + } + return mSupervisionManagerInternal; + } + private ShortcutServiceInternal getShortcutServiceInternal() { if (mShortcutServiceInternal == null) { mShortcutServiceInternal = LocalServices.getService(ShortcutServiceInternal.class); @@ -753,6 +767,16 @@ public class UsageStatsService extends SystemService implements callingPid, callingUid) == PackageManager.PERMISSION_GRANTED); } + private boolean isSupervisionEnabled(int callingUid) { + if (android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()) { + SupervisionManagerInternal smInternal = getSupervisionManagerInternal(); + return smInternal != null && smInternal.isActiveSupervisionApp(callingUid); + } else { + DevicePolicyManagerInternal dpmInternal = getDpmInternal(); + return dpmInternal != null && dpmInternal.isActiveSupervisionApp(callingUid); + } + } + private static void deleteRecursively(final File path) { if (path.isDirectory()) { final File[] files = path.listFiles(); @@ -2929,10 +2953,9 @@ public class UsageStatsService extends SystemService implements long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, String callingPackage) { final int callingUid = Binder.getCallingUid(); - final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (!hasPermissions( Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) - && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { + && !isSupervisionEnabled(callingUid)) { throw new SecurityException("Caller must be the active supervision app or " + "it must have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions"); } @@ -2956,10 +2979,9 @@ public class UsageStatsService extends SystemService implements @Override public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) { final int callingUid = Binder.getCallingUid(); - final DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (!hasPermissions( Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE) - && (dpmInternal == null || !dpmInternal.isActiveSupervisionApp(callingUid))) { + && !isSupervisionEnabled(callingUid)) { throw new SecurityException("Caller must be the active supervision app or " + "it must have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions"); } |