1 /*
2  * Copyright (C) 2014 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.cts.verifier.projection;
18 
19 import android.app.Service;
20 import android.content.Intent;
21 import android.hardware.display.DisplayManager;
22 import android.hardware.display.VirtualDisplay;
23 import android.os.Handler;
24 import android.os.IBinder;
25 import android.os.Looper;
26 import android.os.RemoteException;
27 import android.util.Log;
28 import android.view.KeyEvent;
29 import android.view.MotionEvent;
30 import android.view.Surface;
31 
32 import com.android.cts.verifier.projection.cube.CubePresentation;
33 import com.android.cts.verifier.projection.list.ListPresentation;
34 import com.android.cts.verifier.projection.offscreen.OffscreenPresentation;
35 import com.android.cts.verifier.projection.touch.TouchPresentation;
36 import com.android.cts.verifier.projection.video.VideoPresentation;
37 import com.android.cts.verifier.projection.widgets.WidgetPresentation;
38 
39 /**
40  * Service to handle rendering of views on a virtual display and to forward input events to the
41  * display
42  */
43 public class ProjectionService extends Service {
44     private final String TAG = ProjectionService.class.getSimpleName();
45     private final String DISPLAY_NAME = "CtsVerifier Virtual Display";
46 
47     private Handler mUIHandler;
48 
createPresentation(int typeOrdinal)49     private ProjectedPresentation createPresentation(int typeOrdinal) {
50         ProjectionPresentationType type = ProjectionPresentationType.values()[typeOrdinal];
51         switch (type) {
52             case TUMBLING_CUBES:
53                 return new CubePresentation(ProjectionService.this, mDisplay.getDisplay());
54 
55             case BASIC_WIDGETS:
56                 return new WidgetPresentation(ProjectionService.this, mDisplay.getDisplay());
57 
58             case SCROLLING_LIST:
59                 return new ListPresentation(ProjectionService.this, mDisplay.getDisplay());
60 
61             case VIDEO_PLAYBACK:
62                 return new VideoPresentation(ProjectionService.this, mDisplay.getDisplay());
63 
64             case MULTI_TOUCH:
65                 return new TouchPresentation(ProjectionService.this, mDisplay.getDisplay());
66 
67             case OFFSCREEN:
68                 return new OffscreenPresentation(ProjectionService.this, mDisplay.getDisplay());
69         }
70 
71         return null;
72     }
73 
74     private class ProjectionServiceBinder extends IProjectionService.Stub {
75         @Override
startRendering(final Surface surface, final int width, final int height, final int density, final int viewType)76         public void startRendering(final Surface surface, final int width, final int height,
77                 final int density,
78                 final int viewType) throws RemoteException {
79             mUIHandler.post(new Runnable() {
80                 @Override
81                 public void run() {
82                     DisplayManager manager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
83                     Log.i(TAG, "Surface " + surface.toString() + ": "
84                             + Boolean.toString(surface.isValid()));
85                     mDisplay = manager.createVirtualDisplay(DISPLAY_NAME, width, height, density,
86                             surface, 0);
87                     mPresentation = createPresentation(viewType);
88                     if (mPresentation == null) {
89                         return;
90                     }
91 
92                     mPresentation.show();
93                 }
94             });
95         }
96 
97         @Override
stopRendering()98         public void stopRendering() throws RemoteException {
99             mUIHandler.post(new Runnable() {
100 
101                 @Override
102                 public void run() {
103                     if (mPresentation != null) {
104                         mPresentation.dismiss();
105                         mPresentation = null;
106                     }
107                     if (mDisplay != null) {
108                         mDisplay.release();
109                         mDisplay = null;
110                     }
111                 }
112 
113             });
114         }
115 
116         @Override
onTouchEvent(final MotionEvent event)117         public void onTouchEvent(final MotionEvent event) throws RemoteException {
118             mUIHandler.post(new Runnable() {
119 
120                 @Override
121                 public void run() {
122                     if (mPresentation != null) {
123                         mPresentation.injectTouchEvent(event);
124                     }
125                 }
126 
127             });
128         }
129 
130         @Override
onKeyEvent(final KeyEvent event)131         public void onKeyEvent(final KeyEvent event) throws RemoteException {
132             mUIHandler.post(new Runnable() {
133 
134                 @Override
135                 public void run() {
136                     if (mPresentation != null) {
137                         mPresentation.injectKeyEvent(event);
138                     }
139                 }
140 
141             });
142         }
143     }
144 
145     private final IBinder mBinder = new ProjectionServiceBinder();
146     private VirtualDisplay mDisplay;
147     private ProjectedPresentation mPresentation;
148 
149     @Override
onBind(Intent intent)150     public IBinder onBind(Intent intent) {
151         Log.i(TAG, "onBind");
152         mUIHandler = new Handler(Looper.getMainLooper());
153         return mBinder;
154     }
155 }
156