Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2e935ae authored by Rob Carr's avatar Rob Carr Committed by Android (Google) Code Review
Browse files

Merge "TaskOrganizer: Add WINDOWING_MODE_MULTI_WINDOW support"

parents 17a89a56 00c0dbe2
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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);
+26 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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());
@@ -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());
@@ -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());
@@ -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 */);
+6 −0
Original line number Diff line number Diff line
@@ -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>
+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));
    }
}
+6 −41
Original line number Diff line number Diff line
@@ -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;
@@ -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));
@@ -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