diff options
10 files changed, 92 insertions, 109 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipAppOpsListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipAppOpsListener.kt new file mode 100644 index 000000000000..a141ff951684 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipAppOpsListener.kt @@ -0,0 +1,79 @@ +/* + * 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.wm.shell.common.pip + +import android.app.AppOpsManager +import android.content.Context +import android.content.pm.PackageManager +import com.android.wm.shell.common.ShellExecutor +import com.android.wm.shell.pip.PipUtils + +class PipAppOpsListener( + private val mContext: Context, + private val mCallback: Callback, + private val mMainExecutor: ShellExecutor +) { + private val mAppOpsManager: AppOpsManager = checkNotNull( + mContext.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager) + private val mAppOpsChangedListener = AppOpsManager.OnOpChangedListener { _, packageName -> + try { + // Dismiss the PiP once the user disables the app ops setting for that package + val topPipActivityInfo = PipUtils.getTopPipActivity(mContext) + val componentName = topPipActivityInfo.first ?: return@OnOpChangedListener + val userId = topPipActivityInfo.second + val appInfo = mContext.packageManager + .getApplicationInfoAsUser(packageName, 0, userId) + if (appInfo.packageName == componentName.packageName && + mAppOpsManager.checkOpNoThrow( + AppOpsManager.OP_PICTURE_IN_PICTURE, appInfo.uid, + packageName + ) != AppOpsManager.MODE_ALLOWED + ) { + mMainExecutor.execute { mCallback.dismissPip() } + } + } catch (e: PackageManager.NameNotFoundException) { + // Unregister the listener if the package can't be found + unregisterAppOpsListener() + } + } + + fun onActivityPinned(packageName: String) { + // Register for changes to the app ops setting for this package while it is in PiP + registerAppOpsListener(packageName) + } + + fun onActivityUnpinned() { + // Unregister for changes to the previously PiP'ed package + unregisterAppOpsListener() + } + + private fun registerAppOpsListener(packageName: String) { + mAppOpsManager.startWatchingMode( + AppOpsManager.OP_PICTURE_IN_PICTURE, packageName, + mAppOpsChangedListener + ) + } + + private fun unregisterAppOpsListener() { + mAppOpsManager.stopWatchingMode(mAppOpsChangedListener) + } + + /** Callback for PipAppOpsListener to request changes to the PIP window. */ + interface Callback { + /** Dismisses the PIP window. */ + fun dismissPip() + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java index 422e3b0216c8..1a84f4b41b57 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java @@ -44,6 +44,7 @@ import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DockStateReader; +import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.LaunchAdjacentController; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; @@ -73,7 +74,6 @@ import com.android.wm.shell.keyguard.KeyguardTransitionHandler; import com.android.wm.shell.keyguard.KeyguardTransitions; import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.onehanded.OneHandedController; -import com.android.wm.shell.pip.Pip; import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.recents.RecentsTransitionHandler; @@ -122,6 +122,12 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides + static FloatingContentCoordinator provideFloatingContentCoordinator() { + return new FloatingContentCoordinator(); + } + + @WMSingleton + @Provides static DisplayController provideDisplayController(Context context, IWindowManager wmService, ShellInit shellInit, @@ -797,7 +803,6 @@ public abstract class WMShellBaseModule { ShellTaskOrganizer shellTaskOrganizer, Optional<BubbleController> bubblesOptional, Optional<SplitScreenController> splitScreenOptional, - Optional<Pip> pipOptional, FullscreenTaskListener fullscreenTaskListener, Optional<UnfoldAnimationController> unfoldAnimationController, Optional<UnfoldTransitionHandler> unfoldTransitionHandler, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java index 54be90197e47..9bf973f523bf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java @@ -31,13 +31,13 @@ import com.android.wm.shell.common.TabletopModeController; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.common.pip.PhoneSizeSpecSource; +import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.dagger.WMShellBaseModule; import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; -import com.android.wm.shell.pip.PipAppOpsListener; import com.android.wm.shell.pip.PipBoundsAlgorithm; import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipDisplayLayoutState; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java index f29b3a35128d..e8fae2490bc5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1SharedModule.java @@ -21,7 +21,6 @@ import android.content.pm.PackageManager; import android.os.Handler; import com.android.internal.logging.UiEventLogger; -import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.pip.PipMediaController; @@ -37,12 +36,6 @@ import dagger.Provides; */ @Module public abstract class Pip1SharedModule { - @WMSingleton - @Provides - static FloatingContentCoordinator provideFloatingContentCoordinator() { - return new FloatingContentCoordinator(); - } - // Needs handler for registering broadcast receivers @WMSingleton @Provides diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java index 52c6d2008a9d..80ffbb0968f3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java @@ -29,12 +29,12 @@ import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.common.pip.LegacySizeSpecSource; +import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.dagger.WMShellBaseModule; import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; -import com.android.wm.shell.pip.PipAppOpsListener; import com.android.wm.shell.pip.PipDisplayLayoutState; import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipParamsChangedForwarder; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAppOpsListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAppOpsListener.java deleted file mode 100644 index 48a3fc2460a2..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAppOpsListener.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.pip; - -import static android.app.AppOpsManager.MODE_ALLOWED; -import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE; - -import android.app.AppOpsManager; -import android.app.AppOpsManager.OnOpChangedListener; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.util.Pair; - -import com.android.wm.shell.common.ShellExecutor; - -public class PipAppOpsListener { - private static final String TAG = PipAppOpsListener.class.getSimpleName(); - - private Context mContext; - private ShellExecutor mMainExecutor; - private AppOpsManager mAppOpsManager; - private Callback mCallback; - - private AppOpsManager.OnOpChangedListener mAppOpsChangedListener = new OnOpChangedListener() { - @Override - public void onOpChanged(String op, String packageName) { - try { - // Dismiss the PiP once the user disables the app ops setting for that package - final Pair<ComponentName, Integer> topPipActivityInfo = - PipUtils.getTopPipActivity(mContext); - if (topPipActivityInfo.first != null) { - final ApplicationInfo appInfo = mContext.getPackageManager() - .getApplicationInfoAsUser(packageName, 0, topPipActivityInfo.second); - if (appInfo.packageName.equals(topPipActivityInfo.first.getPackageName()) && - mAppOpsManager.checkOpNoThrow(OP_PICTURE_IN_PICTURE, appInfo.uid, - packageName) != MODE_ALLOWED) { - mMainExecutor.execute(() -> mCallback.dismissPip()); - } - } - } catch (NameNotFoundException e) { - // Unregister the listener if the package can't be found - unregisterAppOpsListener(); - } - } - }; - - public PipAppOpsListener(Context context, Callback callback, ShellExecutor mainExecutor) { - mContext = context; - mMainExecutor = mainExecutor; - mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); - mCallback = callback; - } - - public void onActivityPinned(String packageName) { - // Register for changes to the app ops setting for this package while it is in PiP - registerAppOpsListener(packageName); - } - - public void onActivityUnpinned() { - // Unregister for changes to the previously PiP'ed package - unregisterAppOpsListener(); - } - - private void registerAppOpsListener(String packageName) { - mAppOpsManager.startWatchingMode(OP_PICTURE_IN_PICTURE, packageName, - mAppOpsChangedListener); - } - - private void unregisterAppOpsListener() { - mAppOpsManager.stopWatchingMode(mAppOpsChangedListener); - } - - /** Callback for PipAppOpsListener to request changes to the PIP window. */ - public interface Callback { - /** Dismisses the PIP window. */ - void dismissPip(); - } -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index f396f3fedf64..b872267947dc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -75,6 +75,7 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.TabletopModeController; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.pip.IPip; @@ -82,7 +83,6 @@ import com.android.wm.shell.pip.IPipAnimationListener; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; -import com.android.wm.shell.pip.PipAppOpsListener; import com.android.wm.shell.pip.PipBoundsAlgorithm; import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipDisplayLayoutState; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index 43d3f36f1fe5..b251f6f55794 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -41,7 +41,7 @@ import com.android.wm.shell.animation.FloatProperties; import com.android.wm.shell.animation.PhysicsAnimator; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.magnetictarget.MagnetizedObject; -import com.android.wm.shell.pip.PipAppOpsListener; +import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipSnapAlgorithm; import com.android.wm.shell.pip.PipTaskOrganizer; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java index 02eeb2ac4fd5..5e583c20061f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java @@ -47,10 +47,10 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; -import com.android.wm.shell.pip.PipAppOpsListener; import com.android.wm.shell.pip.PipDisplayLayoutState; import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipParamsChangedForwarder; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index 2cc28acd0b17..0ae290847644 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -55,9 +55,9 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TabletopModeController; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.common.pip.PipAppOpsListener; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.PipAnimationController; -import com.android.wm.shell.pip.PipAppOpsListener; import com.android.wm.shell.pip.PipBoundsAlgorithm; import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipDisplayLayoutState; |