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