Loading services/core/java/com/android/server/wm/TaskOrganizerController.java +5 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import android.os.IBinder; import android.os.RemoteException; Loading Loading @@ -106,9 +107,11 @@ class TaskOrganizerController { * and receive taskVanished callbacks in the process. */ void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) { if (windowingMode != WINDOWING_MODE_PINNED) { if (windowingMode != WINDOWING_MODE_PINNED && windowingMode != WINDOWING_MODE_MULTI_WINDOW) { throw new UnsupportedOperationException( "As of now only Pinned windowing mode is supported for registerTaskOrganizer"); "As of now only Pinned and Multiwindow windowing modes are" + " supported for registerTaskOrganizer"); } clearIfNeeded(windowingMode); Loading services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java +26 −8 Original line number Diff line number Diff line Loading @@ -16,9 +16,9 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; Loading Loading @@ -63,20 +63,24 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(WindowTestRunner.class) public class TaskOrganizerTests extends WindowTestsBase { private ITaskOrganizer makeAndRegisterMockOrganizer() { private ITaskOrganizer registerMockOrganizer(int windowingMode) { final ITaskOrganizer organizer = mock(ITaskOrganizer.class); when(organizer.asBinder()).thenReturn(new Binder()); mWm.mAtmService.registerTaskOrganizer(organizer, WINDOWING_MODE_PINNED); mWm.mAtmService.registerTaskOrganizer(organizer, windowingMode); return organizer; } private ITaskOrganizer registerMockOrganizer() { return registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); } @Test public void testAppearVanish() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(); task.setTaskOrganizer(organizer); verify(organizer).taskAppeared(any(), any()); Loading @@ -89,8 +93,8 @@ public class TaskOrganizerTests extends WindowTestsBase { public void testSwapOrganizer() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer2 = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); task.setTaskOrganizer(organizer); verify(organizer).taskAppeared(any(), any()); Loading @@ -99,11 +103,25 @@ public class TaskOrganizerTests extends WindowTestsBase { verify(organizer2).taskAppeared(any(), any()); } @Test public void testSwapWindowingModes() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); verify(organizer).taskAppeared(any(), any()); stack.setWindowingMode(WINDOWING_MODE_PINNED); verify(organizer).taskVanished(any()); verify(organizer2).taskAppeared(any(), any()); } @Test public void testClearOrganizer() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(); stack.setTaskOrganizer(organizer); verify(organizer).taskAppeared(any(), any()); Loading @@ -116,7 +134,7 @@ public class TaskOrganizerTests extends WindowTestsBase { @Test public void testRegisterTaskOrganizerStackWindowingModeChanges() throws RemoteException { final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED); final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); Loading tests/TaskOrganizerTest/AndroidManifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -19,5 +19,11 @@ <service android:name=".TaskOrganizerPipTest" android:exported="true"> </service> <activity android:name="TaskOrganizerMultiWindowTest" android:label="TaskOrganizer MW Test"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest> tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.test.taskembed; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import android.app.ActivityManager; import android.app.Activity; import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.Rect; import android.os.Bundle; import android.view.ITaskOrganizer; import android.view.IWindowContainer; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.ViewGroup; import android.widget.FrameLayout; public class TaskOrganizerMultiWindowTest extends Activity { class TaskLaunchingView extends TaskView { TaskLaunchingView(Context c, ITaskOrganizer o, int windowingMode) { super(c, o, windowingMode); } @Override public void surfaceChanged(SurfaceHolder h, int format, int width, int height) { startCalculatorActivity(width, height); } } TaskView mView; class Organizer extends ITaskOrganizer.Stub { @Override public void taskAppeared(IWindowContainer wc, ActivityManager.RunningTaskInfo ti) { mView.reparentTask(wc); } public void taskVanished(IWindowContainer wc) { } public void transactionReady(int id, SurfaceControl.Transaction t) { } } Organizer mOrganizer = new Organizer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mView = new TaskLaunchingView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW); setContentView(mView); } Intent makeCalculatorIntent() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_APP_CALCULATOR); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); return intent; } Bundle makeLaunchOptions(int width, int height) { ActivityOptions o = ActivityOptions.makeBasic(); o.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW); o.setLaunchBounds(new Rect(0, 0, width, height)); return o.toBundle(); } void startCalculatorActivity(int width, int height) { startActivity(makeCalculatorIntent(), makeLaunchOptions(width, height)); } } tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java +6 −41 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.test.taskembed; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.Service; Loading @@ -38,48 +40,11 @@ public class TaskOrganizerPipTest extends Service { static final int PIP_WIDTH = 640; static final int PIP_HEIGHT = 360; class PipOrgView extends SurfaceView implements SurfaceHolder.Callback { PipOrgView(Context c) { super(c); getHolder().addCallback(this); setZOrderOnTop(true); } @Override public void surfaceCreated(SurfaceHolder holder) { try { ActivityTaskManager.getService().registerTaskOrganizer(mOrganizer, WindowConfiguration.WINDOWING_MODE_PINNED); } catch (Exception e) { } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } void reparentTask(IWindowContainer wc) { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); SurfaceControl leash = null; try { leash = wc.getLeash(); } catch (Exception e) { // System server died.. oh well } t.reparent(leash, getSurfaceControl()) .setPosition(leash, 0, 0) .apply(); } } PipOrgView mPipView; TaskView mTaskView; class Organizer extends ITaskOrganizer.Stub { public void taskAppeared(IWindowContainer wc, ActivityManager.RunningTaskInfo ti) { mPipView.reparentTask(wc); mTaskView.reparentTask(wc); final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.scheduleFinishEnterPip(wc, new Rect(0, 0, PIP_WIDTH, PIP_HEIGHT)); Loading Loading @@ -113,8 +78,8 @@ public class TaskOrganizerPipTest extends Service { FrameLayout layout = new FrameLayout(this); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(PIP_WIDTH, PIP_HEIGHT); mPipView = new PipOrgView(this); layout.addView(mPipView, lp); mTaskView = new TaskView(this, mOrganizer, WINDOWING_MODE_PINNED); layout.addView(mTaskView, lp); WindowManager wm = getSystemService(WindowManager.class); wm.addView(layout, wlp); Loading Loading
services/core/java/com/android/server/wm/TaskOrganizerController.java +5 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import android.os.IBinder; import android.os.RemoteException; Loading Loading @@ -106,9 +107,11 @@ class TaskOrganizerController { * and receive taskVanished callbacks in the process. */ void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode) { if (windowingMode != WINDOWING_MODE_PINNED) { if (windowingMode != WINDOWING_MODE_PINNED && windowingMode != WINDOWING_MODE_MULTI_WINDOW) { throw new UnsupportedOperationException( "As of now only Pinned windowing mode is supported for registerTaskOrganizer"); "As of now only Pinned and Multiwindow windowing modes are" + " supported for registerTaskOrganizer"); } clearIfNeeded(windowingMode); Loading
services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java +26 −8 Original line number Diff line number Diff line Loading @@ -16,9 +16,9 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; Loading Loading @@ -63,20 +63,24 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(WindowTestRunner.class) public class TaskOrganizerTests extends WindowTestsBase { private ITaskOrganizer makeAndRegisterMockOrganizer() { private ITaskOrganizer registerMockOrganizer(int windowingMode) { final ITaskOrganizer organizer = mock(ITaskOrganizer.class); when(organizer.asBinder()).thenReturn(new Binder()); mWm.mAtmService.registerTaskOrganizer(organizer, WINDOWING_MODE_PINNED); mWm.mAtmService.registerTaskOrganizer(organizer, windowingMode); return organizer; } private ITaskOrganizer registerMockOrganizer() { return registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); } @Test public void testAppearVanish() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(); task.setTaskOrganizer(organizer); verify(organizer).taskAppeared(any(), any()); Loading @@ -89,8 +93,8 @@ public class TaskOrganizerTests extends WindowTestsBase { public void testSwapOrganizer() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer2 = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); task.setTaskOrganizer(organizer); verify(organizer).taskAppeared(any(), any()); Loading @@ -99,11 +103,25 @@ public class TaskOrganizerTests extends WindowTestsBase { verify(organizer2).taskAppeared(any(), any()); } @Test public void testSwapWindowingModes() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED); stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); verify(organizer).taskAppeared(any(), any()); stack.setWindowingMode(WINDOWING_MODE_PINNED); verify(organizer).taskVanished(any()); verify(organizer2).taskAppeared(any(), any()); } @Test public void testClearOrganizer() throws RemoteException { final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(); stack.setTaskOrganizer(organizer); verify(organizer).taskAppeared(any(), any()); Loading @@ -116,7 +134,7 @@ public class TaskOrganizerTests extends WindowTestsBase { @Test public void testRegisterTaskOrganizerStackWindowingModeChanges() throws RemoteException { final ITaskOrganizer organizer = makeAndRegisterMockOrganizer(); final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED); final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent); final Task task = createTaskInStack(stack, 0 /* userId */); Loading
tests/TaskOrganizerTest/AndroidManifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -19,5 +19,11 @@ <service android:name=".TaskOrganizerPipTest" android:exported="true"> </service> <activity android:name="TaskOrganizerMultiWindowTest" android:label="TaskOrganizer MW Test"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerMultiWindowTest.java 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.test.taskembed; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import android.app.ActivityManager; import android.app.Activity; import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.Rect; import android.os.Bundle; import android.view.ITaskOrganizer; import android.view.IWindowContainer; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.ViewGroup; import android.widget.FrameLayout; public class TaskOrganizerMultiWindowTest extends Activity { class TaskLaunchingView extends TaskView { TaskLaunchingView(Context c, ITaskOrganizer o, int windowingMode) { super(c, o, windowingMode); } @Override public void surfaceChanged(SurfaceHolder h, int format, int width, int height) { startCalculatorActivity(width, height); } } TaskView mView; class Organizer extends ITaskOrganizer.Stub { @Override public void taskAppeared(IWindowContainer wc, ActivityManager.RunningTaskInfo ti) { mView.reparentTask(wc); } public void taskVanished(IWindowContainer wc) { } public void transactionReady(int id, SurfaceControl.Transaction t) { } } Organizer mOrganizer = new Organizer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mView = new TaskLaunchingView(this, mOrganizer, WINDOWING_MODE_MULTI_WINDOW); setContentView(mView); } Intent makeCalculatorIntent() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_APP_CALCULATOR); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); return intent; } Bundle makeLaunchOptions(int width, int height) { ActivityOptions o = ActivityOptions.makeBasic(); o.setLaunchWindowingMode(WINDOWING_MODE_MULTI_WINDOW); o.setLaunchBounds(new Rect(0, 0, width, height)); return o.toBundle(); } void startCalculatorActivity(int width, int height) { startActivity(makeCalculatorIntent(), makeLaunchOptions(width, height)); } }
tests/TaskOrganizerTest/src/com/android/test/taskembed/TaskOrganizerPipTest.java +6 −41 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.test.taskembed; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.Service; Loading @@ -38,48 +40,11 @@ public class TaskOrganizerPipTest extends Service { static final int PIP_WIDTH = 640; static final int PIP_HEIGHT = 360; class PipOrgView extends SurfaceView implements SurfaceHolder.Callback { PipOrgView(Context c) { super(c); getHolder().addCallback(this); setZOrderOnTop(true); } @Override public void surfaceCreated(SurfaceHolder holder) { try { ActivityTaskManager.getService().registerTaskOrganizer(mOrganizer, WindowConfiguration.WINDOWING_MODE_PINNED); } catch (Exception e) { } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } void reparentTask(IWindowContainer wc) { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); SurfaceControl leash = null; try { leash = wc.getLeash(); } catch (Exception e) { // System server died.. oh well } t.reparent(leash, getSurfaceControl()) .setPosition(leash, 0, 0) .apply(); } } PipOrgView mPipView; TaskView mTaskView; class Organizer extends ITaskOrganizer.Stub { public void taskAppeared(IWindowContainer wc, ActivityManager.RunningTaskInfo ti) { mPipView.reparentTask(wc); mTaskView.reparentTask(wc); final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.scheduleFinishEnterPip(wc, new Rect(0, 0, PIP_WIDTH, PIP_HEIGHT)); Loading Loading @@ -113,8 +78,8 @@ public class TaskOrganizerPipTest extends Service { FrameLayout layout = new FrameLayout(this); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(PIP_WIDTH, PIP_HEIGHT); mPipView = new PipOrgView(this); layout.addView(mPipView, lp); mTaskView = new TaskView(this, mOrganizer, WINDOWING_MODE_PINNED); layout.addView(mTaskView, lp); WindowManager wm = getSystemService(WindowManager.class); wm.addView(layout, wlp); Loading