1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.android.tools.sdkcontroller.handlers;
18 
19 import android.graphics.Point;
20 import android.os.Message;
21 import android.util.Log;
22 
23 import com.android.tools.sdkcontroller.lib.Channel;
24 import com.android.tools.sdkcontroller.lib.ProtocolConstants;
25 import com.android.tools.sdkcontroller.service.ControllerService;
26 
27 import java.nio.ByteBuffer;
28 
29 /**
30  * Implements multi-touch emulation.
31  */
32 public class MultiTouchChannel extends Channel {
33 
34     @SuppressWarnings("hiding")
35     private static final String TAG = MultiTouchChannel.class.getSimpleName();
36     /**
37      * A new frame buffer has been received from the emulator.
38      * Parameter {@code obj} is a {@code byte[] array} containing the screen data.
39      */
40     public static final int EVENT_FRAME_BUFFER = 1;
41     /**
42      * A multi-touch "start" command has been received from the emulator.
43      * Parameter {@code obj} is the string parameter from the start command.
44      */
45     public static final int EVENT_MT_START = 2;
46     /**
47      * A multi-touch "stop" command has been received from the emulator. There
48      * is no {@code obj} parameter associated.
49      */
50     public static final int EVENT_MT_STOP = 3;
51 
52     private static final Point mViewSize = new Point(0, 0);
53 
54     /**
55      * Constructs MultiTouchChannel instance.
56      */
MultiTouchChannel(ControllerService service)57     public MultiTouchChannel(ControllerService service) {
58         super(service, Channel.MULTITOUCH_CHANNEL);
59     }
60 
61     /**
62      * Sets size of the display view for emulated screen updates.
63      *
64      * @param width View width in pixels.
65      * @param height View height in pixels.
66      */
setViewSize(int width, int height)67     public void setViewSize(int width, int height) {
68         mViewSize.set(width, height);
69     }
70 
71     /*
72      * Channel abstract implementation.
73      */
74 
75     /**
76      * This method is invoked when this channel is fully connected with its
77      * counterpart in the emulator.
78      */
79     @Override
onEmulatorConnected()80     public void onEmulatorConnected() {
81         if (hasUiHandler()) {
82             enable();
83             notifyUiHandlers(EVENT_MT_START);
84         }
85     }
86 
87     /**
88      * This method is invoked when this channel loses connection with its
89      * counterpart in the emulator.
90      */
91     @Override
onEmulatorDisconnected()92     public void onEmulatorDisconnected() {
93         if (hasUiHandler()) {
94             disable();
95             notifyUiHandlers(EVENT_MT_STOP);
96         }
97     }
98 
99     /**
100      * A message has been received from the emulator.
101      *
102      * @param msg_type Message type.
103      * @param msg_data Packet received from the emulator.
104      */
105     @Override
onEmulatorMessage(int msg_type, ByteBuffer msg_data)106     public void onEmulatorMessage(int msg_type, ByteBuffer msg_data) {
107         switch (msg_type) {
108             case ProtocolConstants.MT_FB_UPDATE:
109                 Message msg = Message.obtain();
110                 msg.what = EVENT_FRAME_BUFFER;
111                 msg.obj = msg_data;
112                 postMessage(ProtocolConstants.MT_FB_ACK, (byte[]) null);
113                 notifyUiHandlers(msg);
114                 break;
115 
116             default:
117                 Log.e(TAG, "Unknown message type " + msg_type);
118         }
119     }
120 
121     /**
122      * A query has been received from the emulator.
123      *
124      * @param query_id Identifies the query. This ID must be used when replying
125      *            to the query.
126      * @param query_type Query type.
127      * @param query_data Query data.
128      */
129     @Override
onEmulatorQuery(int query_id, int query_type, ByteBuffer query_data)130     public void onEmulatorQuery(int query_id, int query_type, ByteBuffer query_data) {
131         Loge("Unexpected query " + query_type + " in multi-touch");
132         sendQueryResponse(query_id, (byte[]) null);
133     }
134 
135     /**
136      * Registers a new UI handler.
137      *
138      * @param uiHandler A non-null UI handler to register. Ignored if the UI
139      *            handler is null or already registered.
140      */
141     @Override
addUiHandler(android.os.Handler uiHandler)142     public void addUiHandler(android.os.Handler uiHandler) {
143         final boolean first_handler = !hasUiHandler();
144         super.addUiHandler(uiHandler);
145         if (first_handler && isConnected()) {
146             enable();
147             notifyUiHandlers(EVENT_MT_START);
148         }
149     }
150 
151     /**
152      * Unregisters an UI handler.
153      *
154      * @param uiHandler A non-null UI listener to unregister. Ignored if the
155      *            listener is null or already registered.
156      */
157     @Override
removeUiHandler(android.os.Handler uiHandler)158     public void removeUiHandler(android.os.Handler uiHandler) {
159         super.removeUiHandler(uiHandler);
160         if (isConnected() && !hasUiHandler()) {
161             disable();
162         }
163     }
164 
165     /***************************************************************************
166      * Logging wrappers
167      **************************************************************************/
168 
Loge(String log)169     private void Loge(String log) {
170         mService.addError(log);
171         Log.e(TAG, log);
172     }
173 }
174