IT评测·应用市场-qidao123.com
标题:
android11实现代码进入分屏、代码退出分屏功能
[打印本页]
作者:
星球的眼睛
时间:
2025-3-16 18:31
标题:
android11实现代码进入分屏、代码退出分屏功能
引言
自android7开始,分屏功能官方就已经实现了。Android11的操作方式是点击rescent键,选择一个应用进入分屏,然后系统会主动在下半屏表现另一个应用。
然后客户是客制化的系统,没有任务栏和状态栏。以是需要开发通过代码进入分屏的方式,而且客户盼望可以自由开启一个应用进入上分屏或下分屏,自由退出上分屏或下分屏。这些原生Android11都是没有的,只能新开发。
新开发功能
从taskId进入分屏
启动intent进入分屏
从taskId退出分屏
自由退出分屏
分屏原理分析
首先看一个未分屏状态下的activity栈状态,执行命令
adb shell dumpsys activity activities
复制代码
Task display areas in top down Z order:
TaskDisplayArea DefaultTaskDisplayArea
mLastOrientationSource=Task{5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
mPreferredTopFocusableStack=Task{5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
mLastFocusedStack=Task{5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
Application tokens in top down Z order:
* Task{5ebffec #12 visible=true type=standard mode=fullscreen translucent=false A=10099:com.android.dialer U=0 StackId=12 sz=1}
mLastOrientationSource=ActivityRecord{e499cf9 u0 com.android.dialer/.main.impl.MainActivity t12}
bounds=[0,0][720,1280]
* ActivityRecord{e499cf9 u0 com.android.dialer/.main.impl.MainActivity t12}
* Task{d0d36ff #1 visible=true type=home mode=fullscreen translucent=false I=com.android.launcher3/.uioverrides.QuickstepLauncher U=0 StackId=1 sz=1}
mLastOrientationSource=Task{da384a7 #10 visible=true type=home mode=fullscreen translucent=false I=com.android.launcher3/.uioverrides.QuickstepLauncher U=0 StackId=1 sz=1}
bounds=[0,0][720,1280]
* Task{da384a7 #10 visible=true type=home mode=fullscreen translucent=false I=com.android.launcher3/.uioverrides.QuickstepLauncher U=0 StackId=1 sz=1}
mLastOrientationSource=ActivityRecord{c16f68e u0 com.android.launcher3/.uioverrides.QuickstepLauncher t10}
bounds=[0,0][720,1280]
* ActivityRecord{c16f68e u0 com.android.launcher3/.uioverrides.QuickstepLauncher t10}
* Task{c140c5 #3 visible=false type=undefined mode=split-screen-primary translucent=true ?? U=0 StackId=3 sz=0}
bounds=[0,0][720,606]
* Task{b689f28 #4 visible=false type=undefined mode=split-screen-secondary translucent=true ?? U=0 StackId=4 sz=0}
bounds=[0,626][720,1280]
复制代码
看末了两个task,他们分属于差别的stackId,且都有差别的mode和bounds,mode分别是split-screen-primary和split-screen-secondary。split-screen-primary表示上半屏,且bounds=[0,0][720,606]就是处在上半屏的位置;split-screen-secondary表示下半屏,bounds=[0,626][720,1280]就是处在下半屏的位置。
Android系统其实就是根据stack来实现分屏的,系统启动之初就创建好了几个重要的stack,每个stack规定了本身的bounds和mode,bounds即巨细和表现位置,mode即表现模式。Android系统中的每一个Activity都位于一个Task中,每个task都位于一个ActivityStack中。
全屏模式下大部分activity都处于fullscreen模式下的activityStack,把要分屏表现的activity的task移入分屏ActivityStack即可分屏表现。
从taskId进入分屏
原生android11只支持设置一个taskId表如今上半屏进入分屏状态,我这里实现的可以根据参数设置一个taskId进入上分屏或下分屏。
有四个方法可以实现,分别是:
1 ActivityTaskManager.setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
2 ActivityTaskManager.setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds, boolean showRecents)
3
//注:原生android11只支持进入上分屏
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(true ? WINDOWING_MODE_SPLIT_SCREEN_PRIMARY : WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
options.setSplitScreenCreateMode(true ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
ActivityTaskManager.getService().startActivityFromRecents(getTaskId(), options.toBundle())
4
//注:此方法只适合在已经分屏状态下启动activity进入下半屏
Intent intent = new Intent("android.settings.SETTINGS");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
startActivity(intent);
复制代码
启动intent进入分屏
原生android11只支持在已经分屏状态下启动activity表如今另半屏,我这里实现的可以根据参数设置启动intent进入上分屏或下分屏。
Intent intent = new Intent(this, SubActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY);
intent.putExtra("showOnSpliteScreenPrimary", inflate.cbShowInSplitePrimary.isChecked());
startActivity(intent);
复制代码
从taskId退出分屏
//第二个参数是WindowConfiguration.WINDOWING_MODE_FULLSCREEN
ActivityTaskManager.setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
复制代码
自由退出分屏
//此功能新增的,show_splitScreenPrimary指定全屏显示上半屏幕或下半屏。
ActivityTaskManager.getService().exitSpliteScreenMode(show_splitScreenPrimary);
复制代码
功能实现
上面是摆列客户端的使用接口,下面贴出修改点。
关键修改类:
frameworks/base/core/java/android/content/Intent.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
frameworks/base/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
复制代码
修改如下:
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 24d59a0826c8..8fd92d171cf6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6451,7 +6451,8 @@ public class Intent implements Parcelable, Cloneable {
* required if you want a new instance of an existing activity to be created.
*/
public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000;
-
+ //huanghp add: to enable startActivity into splite-screen-mode
+ public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY = 0x00001001;
/**
* If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 570a4bb3cd12..4ae96665f635 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -523,7 +523,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
update(mDisplayController.getDisplayContext(
mContext.getDisplayId()).getResources().getConfiguration());
// Set resizable directly here because applyEnterSplit already resizes home stack.
- mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
+ //huanghp modify:for apply to different split screen states
+ mHomeStackResizable = mWindowManagerProxy.applyEnterSplit2(mSplits, mSplitLayout);
}
void startDismissSplit() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index 7a313dc0622b..c8e816f3c02f 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -214,6 +214,17 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
Log.d(TAG, " was not in split, but primary is populated, so enter it");
}
mDivider.startEnterSplit();
+ //huanghp add: to enable start splite-screen-mode from secondary splite
+ } else if (!secondaryIsEmpty && primaryWasEmpty && secondaryWasEmpty) {
+ // Wasn't in split-mode (both were empty), but now that the secondary split is
+ // populated, we should fully enter split by moving everything else into primary.
+ // This just tells window-manager to reparent things, the UI will respond
+ // when it gets new task info for the primary split.
+ if (DEBUG) {
+ Log.d(TAG, " was not in split, but secondary is populated, so enter it");
+ }
+ mDivider.startEnterSplit();
+ //huanghp end
}
} else if (secondaryImpliesMinimize) {
// Both splits are populated but the secondary split has a home/recents stack on top,
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 410e3dd39a0b..b13f4195fca7 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -18,6 +18,7 @@ package com.android.systemui.stackdivider;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -229,6 +230,51 @@ public class WindowManagerProxy {
return isHomeResizable;
}
+ //huanghp add: to support moveTaskToStack split-screen-secondary by systemui
+ boolean applyEnterSplit2(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
+ // Set launchtile first so that any stack created after
+ // getAllStackInfos and before reparent (even if unlikely) are placed
+ // correctly.
+ final boolean primaryIsEmpty = tiles.mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
+ TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, primaryIsEmpty ? tiles.mPrimary.token: tiles.mSecondary.token);
+ List<ActivityManager.RunningTaskInfo> rootTasks =
+ TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ if (rootTasks.isEmpty()) {
+ return false;
+ }
+ ActivityManager.RunningTaskInfo topHomeTask = null;
+ for (int i = rootTasks.size() - 1; i >= 0; --i) {
+ final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
+ // Only move resizeable task to split secondary. However, we have an exception
+ // for non-resizable home because we will minimize to show it.
+ if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME) {
+ continue;
+ }
+ // Only move fullscreen tasks to split secondary.
+ if (rootTask.configuration.windowConfiguration.getWindowingMode()
+ != WINDOWING_MODE_FULLSCREEN) {
+ continue;
+ }
+ // Since this iterates from bottom to top, update topHomeTask for every fullscreen task
+ // so it will be left with the status of the top one.
+ topHomeTask = isHomeOrRecentTask(rootTask) ? rootTask : null;
+ wct.reparent(rootTask.token, primaryIsEmpty ? tiles.mPrimary.token: tiles.mSecondary.token, true /* onTop */);
+ }
+ // Move the secondary split-forward.
+ wct.reorder(primaryIsEmpty ? tiles.mPrimary.token: tiles.mSecondary.token, true /* onTop */);
+ boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
+ if (topHomeTask != null) {
+ // Translate/update-crop of secondary out-of-band with sync transaction -- Until BALST
+ // is enabled, this temporarily syncs the home surface position with offset until
+ // sync transaction finishes.
+ wct.setBoundsChangeTransaction(topHomeTask.token, tiles.mHomeBounds);
+ }
+ applySyncTransaction(wct);
+ return isHomeResizable;
+ }
+ //huanghp end
+
static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
final int atype = ti.configuration.windowConfiguration.getActivityType();
return atype == ACTIVITY_TYPE_HOME || atype == ACTIVITY_TYPE_RECENTS;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 4c883805ec8e..f96c42c531ef 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -36,6 +36,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
+import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -110,6 +111,7 @@ import android.service.voice.IVoiceInteractionSession;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DebugUtils;
+import android.util.Log;
import android.util.Pools.SynchronizedPool;
import android.util.Slog;
@@ -1795,6 +1797,18 @@ class ActivityStarter {
}
mOptions.setLaunchWindowingMode(windowingMode);
}
+ //huanghp add: for enable to enter splite-screen from startActivity
+ else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY)!=0){
+ boolean showOnSpliteScreenPrimary = r.intent.getBooleanExtra("showOnSpliteScreenPrimary", false);
+ int windowingMode = showOnSpliteScreenPrimary ? WINDOWING_MODE_SPLIT_SCREEN_PRIMARY : WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+ if (mOptions == null) {
+ mOptions = ActivityOptions.makeBasic();
+ }
+ mOptions.setLaunchWindowingMode(windowingMode);
+ Log.w(TAG, "computeLaunchParams() called with: r = [" + r + "], sourceRecord = ["
+ + sourceRecord + "], targetTask = [" + targetTask + "], showOnSpliteScreenPrimary="+ showOnSpliteScreenPrimary + "]");
+ }
+ //huanghp end
mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b664bb7d9d78..f99c753f73a4 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2389,6 +2389,39 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return null;
}
+ @Override
+ public boolean exitSpliteScreenMode(boolean show_splitScreenPrimary){
+ Log.d(TAG, "exitSpliteScreenMode() called with: showPrimaryScreen = [" + show_splitScreenPrimary + "]");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
+ synchronized (mGlobalLock) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer.getDisplayContent(
+ DEFAULT_DISPLAY).getDefaultTaskDisplayArea();
+ ActivityStack rootSplitScreenPrimaryTask = defaultTaskDisplayArea.getRootSplitScreenPrimaryTask();
+ ActivityStack rootSplitScreenSecondaryTask = defaultTaskDisplayArea.getRootSplitScreenSecondaryTask();
+ if (show_splitScreenPrimary){
+ if (rootSplitScreenPrimaryTask!=null){
+ Task topMostTask = rootSplitScreenPrimaryTask.getTopMostTask();
+ if (topMostTask!=null){
+ return setTaskWindowingMode(topMostTask.mTaskId, WINDOWING_MODE_FULLSCREEN, true);
+ }
+ }
+ }else if (rootSplitScreenSecondaryTask!=null){
+ Task topMostTask = rootSplitScreenSecondaryTask.getTopMostTask();
+ if (topMostTask!=null){
+ return setTaskWindowingMode(topMostTask.mTaskId, WINDOWING_MODE_FULLSCREEN, true);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ return false;
+ }
+
@Override
public boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
@@ -2437,6 +2470,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
+ @Override
+ public void toggleSplitScreen() throws RemoteException {
+
+ }
+
@Override
public String getCallingPackage(IBinder token) {
synchronized (mGlobalLock) {
@@ -2846,8 +2884,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// The task is already in split-screen and with correct windowing mode.
return true;
}
-
- moveTaskToSplitScreenPrimaryTask(task, toTop);
+ //huanghp modify
+ if (windowingMode== WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY){
+ moveTaskToSplitScreenPrimaryTask(task, toTop);
+ }else moveTaskToSplitScreenSecondaryTask(task, toTop);
+ //huanghp end
return prevMode != task.getWindowingMode();
}
@@ -2871,6 +2912,31 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mWindowOrganizerController.applyTransaction(wct);
}
+ //huanghp add
+ void moveTaskToSplitScreenSecondaryTask(Task task, boolean toTop) {
+ Log.d(TAG,
+ "moveTaskToSplitScreenSecondaryTask() called with: task = [" + task + "], toTop = ["
+ + toTop + "]");
+ final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
+ final ActivityStack secondarySplitTask = taskDisplayArea.getRootSplitScreenSecondaryTask();
+ if (secondarySplitTask == null) {
+ throw new IllegalStateException("Can't enter split without associated organized task");
+ }
+
+ if (toTop) {
+ taskDisplayArea.positionStackAt(POSITION_TOP, secondarySplitTask,
+ false /* includingParents */);
+ }
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ // Clear out current windowing mode before reparenting to split taks.
+ wct.setWindowingMode(
+ task.getStack().mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_UNDEFINED);
+ wct.reparent(task.getStack().mRemoteToken.toWindowContainerToken(),
+ secondarySplitTask.mRemoteToken.toWindowContainerToken(), toTop);
+ mWindowOrganizerController.applyTransaction(wct);
+ }
+ //huanghp end
+
/**
* Removes stacks in the input windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 5c1b6eefcecc..41cded3f35fc 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -27,6 +27,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
@@ -133,6 +134,7 @@ import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.IntArray;
+import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -3008,23 +3010,36 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) {
return null;
}
+ //huanghp add: to get the desired splite-window-mode
+ int expectWindowMode=-1;
+ if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY)!=0){
+ boolean showOnSpliteScreenPrimary = r.intent.getBooleanExtra("showOnSpliteScreenPrimary", false);
+ expectWindowMode= showOnSpliteScreenPrimary? WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+ }
+ //huanghp end
// If {@code r} is already in target display area and its task is the same as the candidate
// task, the intention should be getting a launch stack for the reusable activity, so we can
// use the existing stack.
if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
- // TODO(b/153920825): Fix incorrect evaluation of attached state
- final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null
- ? r.getTask().getDisplayArea() : r.getDisplayArea();
- if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
- return candidateTask.getStack();
- }
- // Or the candidate task is already a root task that can be reused by reparenting
- // it to the target display.
- if (candidateTask.isRootTask()) {
- final ActivityStack stack = candidateTask.getStack();
- stack.reparent(taskDisplayArea, true /* onTop */);
- return stack;
+ //huanghp add
+ if (expectWindowMode!=-1 && expectWindowMode!=candidateTask.getWindowingMode()){
+ Log.w(TAG, "getValidLaunchStackInTaskDisplayArea: with expectWindowMode different");
+ }else {
+ huanghp end
+ // TODO(b/153920825): Fix incorrect evaluation of attached state
+ final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null
+ ? r.getTask().getDisplayArea() : r.getDisplayArea();
+ if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
+ return candidateTask.getStack();
+ }
+ // Or the candidate task is already a root task that can be reused by reparenting
+ // it to the target display.
+ if (candidateTask.isRootTask()) {
+ final ActivityStack stack = candidateTask.getStack();
+ stack.reparent(taskDisplayArea, true /* onTop */);
+ return stack;
+ }
}
}
@@ -3072,6 +3087,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
if (stack.mCreatedByOrganizer) {
// Don't launch directly into task created by organizer...but why can't we?
+ //huanghp add: to enable launch activity into splite-screen-mode
+ if (r.supportsSplitScreenWindowingMode() && (r.intent.getFlags()&Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY)!=0){
+ boolean showOnSpliteScreenPrimary = r.intent.getBooleanExtra("showOnSpliteScreenPrimary", false);
+ if ((showOnSpliteScreenPrimary && stack.getWindowingMode()==WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && windowingMode==WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
+ || (!showOnSpliteScreenPrimary && stack.getWindowingMode()==WINDOWING_MODE_SPLIT_SCREEN_SECONDARY && windowingMode==WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)){
+ Log.w(TAG, "isValidLaunchStack() called with FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY: stack = [" + stack + "], r = [" + r + "], windowingMode = [" + windowingMode + "]");
+ return true;
+ }
+ }
+ Log.w(TAG, "isValidLaunchStack() called with##stack.mCreatedByOrganizer: stack = [" + stack + "], r = [" + r
+ + "], windowingMode = [" + windowingMode + "]");
+ //huanghp end
return false;
}
// There is a 1-to-1 relationship between stack and task when not in
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 79f3b8340b21..eccd3594ece6 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1480,6 +1480,13 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
// Switch to the display's windowing mode if we are not in split-screen mode and we are
// trying to launch in split-screen secondary.
windowingMode = WINDOWING_MODE_UNDEFINED;
+ //huanghp add: enable to launch in split-screen secondary or primary
+ if (r!=null && (r.intent.getFlags()&Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT_ARBITRARY)!=0){
+ boolean showOnSpliteScreenPrimary = r.intent.getBooleanExtra(
+ "showOnSpliteScreenPrimary", false);
+ windowingMode= showOnSpliteScreenPrimary? WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:WINDOWING_MODE_SPLIT_SCREEN_SECONDARY ;
+ }
+ //huanghp end
} else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_UNDEFINED) {
windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
}
--
2.34.1
复制代码
end,谢谢!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4