• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.test.taskembed;
18 
19 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
20 
21 import android.app.Activity;
22 import android.app.ActivityManager;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.graphics.Canvas;
26 import android.graphics.Color;
27 import android.graphics.Rect;
28 import android.os.Bundle;
29 import android.view.Gravity;
30 import android.view.SurfaceControl;
31 import android.widget.FrameLayout;
32 import android.widget.TextView;
33 import android.window.TaskOrganizer;
34 import android.window.WindowContainerTransactionCallback;
35 
36 import java.util.concurrent.CountDownLatch;
37 
38 public class TaskOrganizerMultiWindowTest extends Activity {
39     private CountDownLatch mTasksReadyLatch;
40     private CountDownLatch mTasksResizeLatch;
41 
42     class Organizer extends TaskOrganizer {
43         private int mReceivedTransactions = 0;
44         private SurfaceControl.Transaction mMergedTransaction = new SurfaceControl.Transaction();
45         WindowContainerTransactionCallback mTransactionCallback =
46                 new WindowContainerTransactionCallback() {
47             @Override
48             public void onTransactionReady(int id, SurfaceControl.Transaction t) {
49                 mMergedTransaction.merge(t);
50                 mReceivedTransactions++;
51                 if (mReceivedTransactions == 2) {
52                     mReceivedTransactions = 0;
53                     mMergedTransaction.apply(true);
54                     if (mTasksResizeLatch != null) {
55                         mTasksResizeLatch.countDown();
56                     }
57                 }
58             }
59         };
60 
61         @Override
onTaskAppeared(ActivityManager.RunningTaskInfo ti, SurfaceControl leash)62         public void onTaskAppeared(ActivityManager.RunningTaskInfo ti, SurfaceControl leash) {
63             if (ti.baseActivity == null) {
64                 return;
65             }
66 
67             final String clsName = ti.baseActivity.getClassName();
68             if (clsName.contentEquals(TestActivity1.class.getName())) {
69                 mTaskView1.reparentTask(ti.token, leash);
70                 mOrganizer.setInterceptBackPressedOnTaskRoot(ti.token, true);
71                 mTasksReadyLatch.countDown();
72             } else if (clsName.contentEquals(TestActivity2.class.getName())) {
73                 mTaskView2.reparentTask(ti.token, leash);
74                 mOrganizer.setInterceptBackPressedOnTaskRoot(ti.token, true);
75                 mTasksReadyLatch.countDown();
76             }
77         }
78 
79         @Override
onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo)80         public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
81             getMainThreadHandler().post(() -> {
82                 finish();
83             });
84         }
85     }
86 
87     private Organizer mOrganizer = new Organizer();
88     private FrameLayout mTasksLayout;
89     private TaskView mTaskView1;
90     private TaskView mTaskView2;
91     @Override
onCreate(Bundle savedInstanceState)92     protected void onCreate(Bundle savedInstanceState) {
93         super.onCreate(savedInstanceState);
94         getWindow().getAttributes().layoutInDisplayCutoutMode =
95                 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
96 
97         mTasksLayout = new FrameLayout(this);
98         setContentView(mTasksLayout);
99 
100         mOrganizer.registerOrganizer();
101     }
102 
103     @Override
onDestroy()104     protected void onDestroy() {
105         super.onDestroy();
106         mOrganizer.unregisterOrganizer();
107         mTasksLayout.removeAllViews();
108     }
109 
makeActivityIntent(final Class<?> clazz)110     private Intent makeActivityIntent(final Class<?> clazz) {
111         Intent intent = new Intent(this, clazz);
112         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION
113                 | Intent.FLAG_ACTIVITY_CLEAR_TASK);
114         return intent;
115     }
116 
openTaskView(Rect firstBounds, Rect secondBounds)117     public CountDownLatch openTaskView(Rect firstBounds, Rect secondBounds) {
118         mTasksReadyLatch = new CountDownLatch(2);
119         mTaskView1 = new TaskView(this, mOrganizer, makeActivityIntent(TestActivity1.class));
120         mTaskView1.setBackgroundColor(Color.DKGRAY);
121 
122         FrameLayout.LayoutParams viewLayout1 =
123                 new FrameLayout.LayoutParams(firstBounds.width(), firstBounds.height(),
124                         Gravity.TOP | Gravity.LEFT);
125         viewLayout1.setMargins(firstBounds.left, firstBounds.top, 0, 0);
126         mTasksLayout.addView(mTaskView1, viewLayout1);
127 
128         mTaskView2 = new TaskView(this, mOrganizer, makeActivityIntent(TestActivity2.class));
129         mTaskView2.setBackgroundColor(Color.LTGRAY);
130         FrameLayout.LayoutParams viewLayout2 =
131                 new FrameLayout.LayoutParams(secondBounds.width(), secondBounds.height(),
132                         Gravity.TOP | Gravity.LEFT);
133         viewLayout2.setMargins(secondBounds.left, secondBounds.top, 0, 0);
134         mTasksLayout.addView(mTaskView2, viewLayout2);
135         return mTasksReadyLatch;
136     }
137 
resizeTaskView(Rect firstBounds, Rect secondBounds)138     public CountDownLatch resizeTaskView(Rect firstBounds, Rect secondBounds) {
139         mTasksResizeLatch = new CountDownLatch(1);
140 
141         mTaskView1.resizeTask(firstBounds.width(), firstBounds.height());
142         mTaskView2.resizeTask(secondBounds.width(), secondBounds.height());
143 
144         return mTasksResizeLatch;
145     }
146 
147     static class InstrumentedTextView extends TextView {
148         private final boolean mSlowDraw;
InstrumentedTextView(Context context, boolean slowDraw)149         InstrumentedTextView(Context context, boolean slowDraw) {
150             super(context);
151             mSlowDraw = slowDraw;
152         }
153 
154         @Override
onDraw(Canvas canvas)155         protected void onDraw(Canvas canvas) {
156             super.onDraw(canvas);
157             if (mSlowDraw) {
158                 try {
159                     Thread.sleep(20);
160                 } catch (InterruptedException e) {
161                     e.printStackTrace();
162                 }
163             }
164         }
165     }
166 
167     public static class TestActivity1 extends Activity {
168         @Override
onCreate(Bundle savedInstanceState)169         protected void onCreate(Bundle savedInstanceState) {
170             super.onCreate(savedInstanceState);
171             getWindow().getAttributes().layoutInDisplayCutoutMode =
172                     LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
173 
174             TextView v = new InstrumentedTextView(this, true);
175             v.setText("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
176                     + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
177             v.setBackgroundColor(Color.RED);
178             v.setTextColor(Color.BLACK);
179             setContentView(v);
180         }
181     }
182 
183     public static class TestActivity2 extends Activity {
184         @Override
onCreate(Bundle savedInstanceState)185         protected void onCreate(Bundle savedInstanceState) {
186             super.onCreate(savedInstanceState);
187             getWindow().getAttributes().layoutInDisplayCutoutMode =
188                     LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
189             TextView v = new InstrumentedTextView(this, false);
190             v.setText("ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
191                     + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
192             v.setBackgroundColor(Color.GREEN);
193             v.setTextColor(Color.BLACK);
194             setContentView(v);
195         }
196     }
197 }
198