Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(513)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/DesktopView.java

Issue 2256943002: [Remoting Android] Remove old renderer code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chromoting;
6
7 import android.graphics.Bitmap;
8 import android.graphics.Canvas;
9 import android.graphics.Color;
10 import android.graphics.Paint;
11 import android.graphics.Point;
12 import android.os.Looper;
13 import android.os.SystemClock;
14 import android.view.SurfaceHolder;
15
16 import org.chromium.base.Log;
17 import org.chromium.chromoting.jni.Client;
18 import org.chromium.chromoting.jni.Display;
19
20 /**
21 * The user interface for viewing and interacting with a specific remote host.
22 * It provides a canvas onto which the video feed is rendered, handles
23 * multitouch pan and zoom gestures, and collects and forwards input events.
24 */
25 /** GUI element that holds the drawing canvas. */
26 public class DesktopView extends AbstractDesktopView implements SurfaceHolder.Ca llback {
27 private static final String TAG = "Chromoting";
28
29 private final Display mDisplay;
30
31
32 // Flag to prevent multiple repaint requests from being backed up. Requests for repainting will
33 // be dropped if this is already set to true. This is used by the main threa d and the painting
34 // thread, so the access should be synchronized on |mRenderData|.
35 private boolean mRepaintPending;
36
37 // Flag used to ensure that the SurfaceView is only painted between calls to surfaceCreated()
38 // and surfaceDestroyed(). Accessed on main thread and display thread, so th is should be
39 // synchronized on |mRenderData|.
40 private boolean mSurfaceCreated = false;
41
42 private final Event.Raisable<PaintEventParameter> mOnPaint = new Event.Raisa ble<>();
43
44 // Variables to control animation by the TouchInputHandler.
45
46 /** Protects mInputAnimationRunning. */
47 private final Object mAnimationLock = new Object();
48
49 /** Whether the TouchInputHandler has requested animation to be performed. * /
50 private boolean mInputAnimationRunning = false;
51
52 public DesktopView(Display display, Desktop desktop, Client client) {
53 super(desktop, client);
54 Preconditions.notNull(display);
55 mDisplay = display;
56
57 mRepaintPending = false;
58
59 getHolder().addCallback(this);
60
61 attachRedrawCallback();
62 }
63
64 public Event<PaintEventParameter> onPaint() {
65 return mOnPaint;
66 }
67
68 /** Request repainting of the desktop view. */
69 void requestRepaint() {
70 synchronized (mRenderData) {
71 if (mRepaintPending) {
72 return;
73 }
74 mRepaintPending = true;
75 }
76 mDisplay.redrawGraphics();
77 }
78
79 /**
80 * Redraws the canvas. This should be done on a non-UI thread or it could
81 * cause the UI to lag. Specifically, it is currently invoked on the native
82 * graphics thread using a JNI.
83 */
84 public void paint() {
85 long startTimeMs = SystemClock.uptimeMillis();
86
87 if (Looper.myLooper() == Looper.getMainLooper()) {
88 Log.w(TAG, "Canvas being redrawn on UI thread");
89 }
90
91 Bitmap image = mDisplay.getVideoFrame();
92 synchronized (mRenderData) {
93 mRepaintPending = false;
94 }
95 if (image == null) {
96 // This can happen if the client is connected, but a complete video frame has not yet
97 // been decoded.
98 return;
99 }
100
101 int width = image.getWidth();
102 int height = image.getHeight();
103 boolean sizeChanged = false;
104 synchronized (mRenderData) {
105 if (mRenderData.imageWidth != width || mRenderData.imageHeight != he ight) {
106 // TODO(lambroslambrou): Move this code into a sizeChanged() cal lback, to be
107 // triggered from native code (on the display thread) when the r emote screen size
108 // changes.
109 mRenderData.imageWidth = width;
110 mRenderData.imageHeight = height;
111 sizeChanged = true;
112 }
113 }
114 if (sizeChanged) {
115 mOnHostSizeChanged.raise(new SizeChangedEventParameter(width, height ));
116 }
117
118 Canvas canvas;
119 Point cursorPosition;
120 boolean drawCursor;
121 synchronized (mRenderData) {
122 // Don't try to lock the canvas before it is ready, as the implement ation of
123 // lockCanvas() may throttle these calls to a slow rate in order to avoid consuming CPU.
124 // Note that a successful call to lockCanvas() will prevent the fram ework from
125 // destroying the Surface until it is unlocked.
126 if (!mSurfaceCreated) {
127 return;
128 }
129 canvas = getHolder().lockCanvas();
130 if (canvas == null) {
131 return;
132 }
133 canvas.setMatrix(mRenderData.transform);
134 drawCursor = mRenderData.drawCursor;
135 cursorPosition = mRenderData.getCursorPosition();
136 }
137
138 canvas.drawColor(Color.BLACK);
139 canvas.drawBitmap(image, 0, 0, new Paint());
140
141 float scaleFactor;
142 synchronized (mRenderData) {
143 scaleFactor = mRenderData.transform.mapRadius(1);
144 }
145 mOnPaint.raise(new PaintEventParameter(cursorPosition, canvas, scaleFact or));
146
147 if (drawCursor) {
148 Bitmap cursorBitmap = mDisplay.getCursorBitmap();
149 if (cursorBitmap != null) {
150 Point hotspot = mDisplay.getCursorHotspot();
151 canvas.drawBitmap(cursorBitmap, cursorPosition.x - hotspot.x,
152 cursorPosition.y - hotspot.y, new Paint());
153 }
154 }
155
156 getHolder().unlockCanvasAndPost(canvas);
157
158 synchronized (mAnimationLock) {
159 if (mInputAnimationRunning || !mOnPaint.isEmpty()) {
160 getHandler().postAtTime(new Runnable() {
161 @Override
162 public void run() {
163 processAnimation();
164 }
165 }, startTimeMs + 30);
166 }
167 }
168 }
169
170 private void processAnimation() {
171 boolean running;
172 synchronized (mAnimationLock) {
173 running = mInputAnimationRunning;
174 }
175 if (running) {
176 mInputHandler.processAnimation();
177 requestRepaint();
178 } else if (!mOnPaint.isEmpty()) {
179 requestRepaint();
180 }
181 }
182
183 /**
184 * Called after the canvas is initially created, then after every subsequent resize, as when
185 * the display is rotated.
186 */
187 @Override
188 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
189 synchronized (mRenderData) {
190 mRenderData.screenWidth = width;
191 mRenderData.screenHeight = height;
192 }
193
194 mOnClientSizeChanged.raise(new SizeChangedEventParameter(width, height)) ;
195 requestRepaint();
196 }
197
198 public void attachRedrawCallback() {
199 mDisplay.provideRedrawCallback(new Runnable() {
200 @Override
201 public void run() {
202 paint();
203 }
204 });
205 }
206
207 /** Called when the canvas is first created. */
208 @Override
209 public void surfaceCreated(SurfaceHolder holder) {
210 synchronized (mRenderData) {
211 mSurfaceCreated = true;
212 }
213 }
214
215 /**
216 * Called when the canvas is finally destroyed. Marks the canvas as needing a redraw so that it
217 * will not be blank if the user later switches back to our window.
218 */
219 @Override
220 public void surfaceDestroyed(SurfaceHolder holder) {
221 synchronized (mRenderData) {
222 mSurfaceCreated = false;
223 }
224 }
225
226 @Override
227 public void showInputFeedback(InputFeedbackType feedbackToShow, Point pos) {
228 float radius = getFeedbackRadius(feedbackToShow);
229 if (radius <= 0.0f) {
230 return;
231 }
232 FeedbackAnimator.startAnimation(this, pos, radius);
233 requestRepaint();
234 }
235
236 @Override
237 public void transformationChanged() {
238 requestRepaint();
239 }
240
241 @Override
242 public void cursorMoved() {
243 // For current implementation, cursorMoved() is always followed by trans formationChanged()
244 // even if the canvas isn't really changed. For future we should improve this by not calling
245 // transformationChanged() if the cursor is moved but the canvas is not changed.
246 }
247
248 @Override
249 public void cursorVisibilityChanged() {
250 requestRepaint();
251 }
252
253 @Override
254 public void setAnimationEnabled(boolean enabled) {
255 synchronized (mAnimationLock) {
256 if (enabled && !mInputAnimationRunning) {
257 requestRepaint();
258 }
259 mInputAnimationRunning = enabled;
260 }
261 }
262 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698