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 android.server.wm.app;
18 
19 import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_ON_MOTIONEVENT_DELAY_MS;
20 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
21 
22 import android.app.Service;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.graphics.PixelFormat;
26 import android.hardware.display.DisplayManager;
27 import android.os.Bundle;
28 import android.os.IBinder;
29 import android.os.SystemClock;
30 import android.util.DisplayMetrics;
31 import android.view.Display;
32 import android.view.MotionEvent;
33 import android.view.SurfaceControlViewHost;
34 import android.view.View;
35 import android.view.WindowManager;
36 import android.widget.Button;
37 
38 public class RenderService extends Service {
39     static final String EXTRAS_BUNDLE = "INTENT_BUNDLE";
40     static final String EXTRAS_DISPLAY_ID = "hostDisplayId";
41     static final String EXTRAS_HOST_TOKEN = "hostInputToken";
42     static final String BROADCAST_EMBED_CONTENT
43             = "android.server.wm.app.RenderService.EMBED_CONTENT";
44     static final String EXTRAS_SURFACE_PACKAGE = "surfacePackage";
45 
46     private int mOnMotionEventDelayMs;
47 
onTouch(View v, MotionEvent event)48     private boolean onTouch(View v, MotionEvent event) {
49         SystemClock.sleep(mOnMotionEventDelayMs);
50         // Don't consume the event.
51         return false;
52     }
53 
54     @Override
onBind(Intent intent)55     public IBinder onBind(Intent intent) {
56         Bundle b = intent.getBundleExtra(EXTRAS_BUNDLE);
57         IBinder hostToken = b.getBinder(EXTRAS_HOST_TOKEN);
58         int hostDisplayId = b.getInt(EXTRAS_DISPLAY_ID);
59         mOnMotionEventDelayMs = b.getInt(EXTRA_ON_MOTIONEVENT_DELAY_MS);
60 
61         SurfaceControlViewHost surfaceControlViewHost = getSurfaceControlViewHost(hostToken,
62                 hostDisplayId);
63         sendSurfacePackage(surfaceControlViewHost.getSurfacePackage());
64         return null;
65     }
66 
getSurfaceControlViewHost(IBinder hostToken, int hostDisplayId)67     private SurfaceControlViewHost getSurfaceControlViewHost(IBinder hostToken, int hostDisplayId) {
68         final Context displayContext = getDisplayContext(hostDisplayId);
69         SurfaceControlViewHost surfaceControlViewHost =
70                 new SurfaceControlViewHost(displayContext, displayContext.getDisplay(), hostToken);
71 
72         View embeddedView = new Button(this);
73         embeddedView.setOnTouchListener(this::onTouch);
74         DisplayMetrics metrics = new DisplayMetrics();
75         displayContext.getDisplay().getMetrics(metrics);
76         surfaceControlViewHost.setView(embeddedView, metrics.widthPixels, metrics.heightPixels);
77         return surfaceControlViewHost;
78     }
79 
getDisplayContext(int hostDisplayId)80     private Context getDisplayContext(int hostDisplayId) {
81         final DisplayManager displayManager = getSystemService(DisplayManager.class);
82         final Display targetDisplay = displayManager.getDisplay(hostDisplayId);
83         return createDisplayContext(targetDisplay);
84     }
85 
sendSurfacePackage(SurfaceControlViewHost.SurfacePackage surfacePackage)86     private void sendSurfacePackage(SurfaceControlViewHost.SurfacePackage surfacePackage) {
87         Intent broadcast = new Intent();
88         broadcast.setAction(BROADCAST_EMBED_CONTENT);
89         broadcast.putExtra(EXTRAS_SURFACE_PACKAGE, surfacePackage);
90         sendBroadcast(broadcast);
91     }
92 }
93