diff options
Diffstat (limited to 'apps/SdkController/src/com/android/tools/sdkcontroller/activities')
4 files changed, 0 insertions, 1093 deletions
diff --git a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java b/apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java deleted file mode 100755 index ab5306ddc..000000000 --- a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.tools.sdkcontroller.activities; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; -import android.util.Log; - -import com.android.tools.sdkcontroller.service.ControllerService; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerBinder; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerListener; - -/** - * Base activity class that knows how to bind and unbind from the - * {@link ControllerService}. - */ -public abstract class BaseBindingActivity extends Activity { - - public static String TAG = BaseBindingActivity.class.getSimpleName(); - private static boolean DEBUG = true; - private ServiceConnection mServiceConnection; - private ControllerBinder mServiceBinder; - - /** - * Returns the binder. Activities can use that to query the controller service. - * @return An existing {@link ControllerBinder}. - * The binder is only valid between calls {@link #onServiceConnected()} and - * {@link #onServiceDisconnected()}. Returns null when not valid. - */ - public ControllerBinder getServiceBinder() { - return mServiceBinder; - } - - /** - * Called when the activity resumes. - * This automatically binds to the service, starting it as needed. - * <p/> - * Since on resume we automatically bind to the service, the {@link ServiceConnection} - * will is restored and {@link #onServiceConnected()} is called as necessary. - * Derived classes that need to initialize anything that is related to the service - * (e.g. getting their handler) should thus do so in {@link #onServiceConnected()} and - * <em>not</em> in {@link #onResume()} -- since binding to the service is asynchronous - * there is <em>no</em> guarantee that {@link #getServiceBinder()} returns non-null - * when this call finishes. - */ - @Override - protected void onResume() { - super.onResume(); - bindToService(); - } - - /** - * Called when the activity is paused. - * This automatically unbinds from the service but does not stop it. - */ - @Override - protected void onPause() { - super.onPause(); - unbindFromService(); - } - - // ---------- - - /** - * Called when binding to the service to get the activity's {@link ControllerListener}. - * @return A new non-null {@link ControllerListener}. - */ - protected abstract ControllerListener createControllerListener(); - - /** - * Called by the service once the activity is connected (bound) to it. - * <p/> - * When this is called, {@link #getServiceBinder()} returns a non-null binder that - * can be used by the activity to control the service. - */ - protected abstract void onServiceConnected(); - - /** - * Called by the service when it is forcibly disconnected OR when we know - * we're unbinding the service. - * <p/> - * When this is called, {@link #getServiceBinder()} returns a null binder and - * the activity should stop using that binder and remove any reference to it. - */ - protected abstract void onServiceDisconnected(); - - /** - * Starts the service and binds to it. - */ - protected void bindToService() { - if (mServiceConnection == null) { - final ControllerListener listener = createControllerListener(); - - mServiceConnection = new ServiceConnection() { - /** - * Called when the service is connected. - * Allows us to retrieve the binder to talk to the service. - */ - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - if (DEBUG) Log.d(TAG, "Activity connected to service"); - mServiceBinder = (ControllerBinder) service; - mServiceBinder.addControllerListener(listener); - BaseBindingActivity.this.onServiceConnected(); - } - - /** - * Called when the service got disconnected, e.g. because it crashed. - * This is <em>not</em> called when we unbind from the service. - */ - @Override - public void onServiceDisconnected(ComponentName name) { - if (DEBUG) Log.d(TAG, "Activity disconnected from service"); - mServiceBinder = null; - BaseBindingActivity.this.onServiceDisconnected(); - } - }; - } - - // Start service so that it doesn't stop when we unbind - if (DEBUG) Log.d(TAG, "start requested & bind service"); - Intent service = new Intent(this, ControllerService.class); - startService(service); - bindService(service, - mServiceConnection, - Context.BIND_AUTO_CREATE); - } - - /** - * Unbinds from the service but does not actually stop the service. - * This lets us have it run in the background even if this isn't the active activity. - */ - protected void unbindFromService() { - if (mServiceConnection != null) { - if (DEBUG) Log.d(TAG, "unbind service"); - mServiceConnection.onServiceDisconnected(null /*name*/); - unbindService(mServiceConnection); - mServiceConnection = null; - } - } -}
\ No newline at end of file diff --git a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/MainActivity.java b/apps/SdkController/src/com/android/tools/sdkcontroller/activities/MainActivity.java deleted file mode 100755 index 47692454c..000000000 --- a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/MainActivity.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.tools.sdkcontroller.activities; - -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.webkit.WebView; -import android.widget.Button; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.TextView; -import android.widget.ToggleButton; - -import com.android.tools.sdkcontroller.R; -import com.android.tools.sdkcontroller.service.ControllerService; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerBinder; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerListener; - -/** - * Main activity. It's the entry point for the application. - * It allows the user to start/stop the service and see it's current state and errors. - * It also has buttons to start either the sensor control activity or the multitouch activity. - */ -public class MainActivity extends BaseBindingActivity { - - @SuppressWarnings("hiding") - public static String TAG = MainActivity.class.getSimpleName(); - private static boolean DEBUG = true; - private Button mBtnOpenMultitouch; - private Button mBtnOpenSensors; - private ToggleButton mBtnToggleService; - private TextView mTextError; - private TextView mTextStatus; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - - mTextError = (TextView) findViewById(R.id.textError); - mTextStatus = (TextView) findViewById(R.id.textStatus); - - WebView wv = (WebView) findViewById(R.id.webIntro); - wv.loadUrl("file:///android_asset/intro_help.html"); - - setupButtons(); - } - - @Override - protected void onResume() { - // BaseBindingActivity.onResume will bind to the service. - super.onResume(); - updateError(); - } - - @Override - protected void onPause() { - // BaseBindingActivity.onResume will unbind from (but not stop) the service. - super.onPause(); - } - - @Override - public void onBackPressed() { - if (DEBUG) Log.d(TAG, "onBackPressed"); - // If back is pressed, we stop the service automatically. - // It seems more intuitive that way. - stopService(); - super.onBackPressed(); - } - - // ---------- - - @Override - protected void onServiceConnected() { - updateButtons(); - } - - @Override - protected void onServiceDisconnected() { - updateButtons(); - } - - @Override - protected ControllerListener createControllerListener() { - return new MainControllerListener(); - } - - // ---------- - - private void setupButtons() { - mBtnOpenMultitouch = (Button) findViewById(R.id.btnOpenMultitouch); - mBtnOpenSensors = (Button) findViewById(R.id.btnOpenSensors); - - mBtnOpenMultitouch.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - // Open the multi-touch activity. - Intent i = new Intent(MainActivity.this, MultiTouchActivity.class); - startActivity(i); - } - }); - - mBtnOpenSensors.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - // Open the sensor activity. - Intent i = new Intent(MainActivity.this, SensorActivity.class); - startActivity(i); - } - }); - - mBtnToggleService = (ToggleButton) findViewById(R.id.toggleService); - - // set initial state - updateButtons(); - - mBtnToggleService.setOnCheckedChangeListener(new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - bindToService(); - updateButtons(); - } else { - stopService(); - updateButtons(); - } - } - }); - - } - - private void updateButtons() { - boolean running = ControllerService.isServiceIsRunning(); - mBtnOpenMultitouch.setEnabled(running); - mBtnOpenSensors.setEnabled(running); - mBtnToggleService.setChecked(running); - } - - /** - * Unbind and then actually stops the service. - */ - private void stopService() { - Intent service = new Intent(this, ControllerService.class); - unbindFromService(); - if (DEBUG) Log.d(TAG, "stop service requested"); - stopService(service); - } - - private class MainControllerListener implements ControllerListener { - @Override - public void onErrorChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - updateError(); - } - }); - } - - @Override - public void onStatusChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - updateStatus(); - } - }); - } - } - - private void updateError() { - ControllerBinder binder = getServiceBinder(); - String error = binder == null ? "" : binder.getServiceError(); - if (error == null) { - error = ""; - } - - mTextError.setVisibility(error.length() == 0 ? View.GONE : View.VISIBLE); - mTextError.setText(error); - } - - private void updateStatus() { - ControllerBinder binder = getServiceBinder(); - boolean connected = binder == null ? false : binder.isEmuConnected(); - mTextStatus.setText( - getText(connected ? R.string.main_service_status_connected - : R.string.main_service_status_disconnected)); - - } -}
\ No newline at end of file diff --git a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/MultiTouchActivity.java b/apps/SdkController/src/com/android/tools/sdkcontroller/activities/MultiTouchActivity.java deleted file mode 100755 index faba8828f..000000000 --- a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/MultiTouchActivity.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.tools.sdkcontroller.activities; - -import java.io.ByteArrayInputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import android.graphics.Color; -import android.os.Bundle; -import android.os.Message; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; -import android.widget.TextView; - -import com.android.tools.sdkcontroller.R; -import com.android.tools.sdkcontroller.handlers.MultiTouchChannel; -import com.android.tools.sdkcontroller.lib.Channel; -import com.android.tools.sdkcontroller.lib.ProtocolConstants; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerBinder; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerListener; -import com.android.tools.sdkcontroller.utils.ApiHelper; -import com.android.tools.sdkcontroller.views.MultiTouchView; - -/** - * Activity that controls and displays the {@link MultiTouchChannel}. - */ -public class MultiTouchActivity extends BaseBindingActivity - implements android.os.Handler.Callback { - - @SuppressWarnings("hiding") - private static String TAG = MultiTouchActivity.class.getSimpleName(); - private static boolean DEBUG = true; - - private volatile MultiTouchChannel mHandler; - - private TextView mTextError; - private TextView mTextStatus; - private MultiTouchView mImageView; - /** Width of the emulator's display. */ - private int mEmulatorWidth = 0; - /** Height of the emulator's display. */ - private int mEmulatorHeight = 0; - /** Bitmap storage. */ - private int[] mColors; - - private final TouchListener mTouchListener = new TouchListener(); - private final android.os.Handler mUiHandler = new android.os.Handler(this); - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.multitouch); - mImageView = (MultiTouchView) findViewById(R.id.imageView); - mTextError = (TextView) findViewById(R.id.textError); - mTextStatus = (TextView) findViewById(R.id.textStatus); - updateStatus("Waiting for connection"); - - ApiHelper ah = ApiHelper.get(); - ah.View_setSystemUiVisibility(mImageView, View.SYSTEM_UI_FLAG_LOW_PROFILE); - } - - @Override - protected void onResume() { - if (DEBUG) Log.d(TAG, "onResume"); - // BaseBindingActivity.onResume will bind to the service. - // Note: any initialization related to the service or the handler should - // go in onServiceConnected() since in this call the service may not be - // bound yet. - super.onResume(); - updateError(); - } - - @Override - protected void onPause() { - if (DEBUG) Log.d(TAG, "onPause"); - // BaseBindingActivity.onResume will unbind from (but not stop) the service. - super.onPause(); - mImageView.setEnabled(false); - updateStatus("Paused"); - } - - // ---------- - - @Override - protected void onServiceConnected() { - if (DEBUG) Log.d(TAG, "onServiceConnected"); - mHandler = (MultiTouchChannel) getServiceBinder().getChannel(Channel.MULTITOUCH_CHANNEL); - if (mHandler != null) { - mHandler.setViewSize(mImageView.getWidth(), mImageView.getHeight()); - mHandler.addUiHandler(mUiHandler); - } - } - - @Override - protected void onServiceDisconnected() { - if (DEBUG) Log.d(TAG, "onServiceDisconnected"); - if (mHandler != null) { - mHandler.removeUiHandler(mUiHandler); - mHandler = null; - } - } - - @Override - protected ControllerListener createControllerListener() { - return new MultiTouchControllerListener(); - } - - // ---------- - - private class MultiTouchControllerListener implements ControllerListener { - @Override - public void onErrorChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - updateError(); - } - }); - } - - @Override - public void onStatusChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - ControllerBinder binder = getServiceBinder(); - if (binder != null) { - boolean connected = binder.isEmuConnected(); - mImageView.setEnabled(connected); - updateStatus(connected ? "Emulator connected" : "Emulator disconnected"); - } - } - }); - } - } - - // ---------- - - /** - * Implements OnTouchListener interface that receives touch screen events, - * and reports them to the emulator application. - */ - class TouchListener implements OnTouchListener { - /** - * Touch screen event handler. - */ - @Override - public boolean onTouch(View v, MotionEvent event) { - ByteBuffer bb = null; - final int action = event.getAction(); - final int action_code = action & MotionEvent.ACTION_MASK; - final int action_pid_index = action >> MotionEvent.ACTION_POINTER_ID_SHIFT; - int msg_type = 0; - MultiTouchChannel h = mHandler; - - // Build message for the emulator. - switch (action_code) { - case MotionEvent.ACTION_MOVE: - if (h != null) { - bb = ByteBuffer.allocate( - event.getPointerCount() * ProtocolConstants.MT_EVENT_ENTRY_SIZE); - bb.order(h.getEndian()); - for (int n = 0; n < event.getPointerCount(); n++) { - mImageView.constructEventMessage(bb, event, n); - } - msg_type = ProtocolConstants.MT_MOVE; - } - break; - case MotionEvent.ACTION_DOWN: - if (h != null) { - bb = ByteBuffer.allocate(ProtocolConstants.MT_EVENT_ENTRY_SIZE); - bb.order(h.getEndian()); - mImageView.constructEventMessage(bb, event, action_pid_index); - msg_type = ProtocolConstants.MT_FISRT_DOWN; - } - break; - case MotionEvent.ACTION_UP: - if (h != null) { - bb = ByteBuffer.allocate(ProtocolConstants.MT_EVENT_ENTRY_SIZE); - bb.order(h.getEndian()); - bb.putInt(event.getPointerId(action_pid_index)); - msg_type = ProtocolConstants.MT_LAST_UP; - } - break; - case MotionEvent.ACTION_POINTER_DOWN: - if (h != null) { - bb = ByteBuffer.allocate(ProtocolConstants.MT_EVENT_ENTRY_SIZE); - bb.order(h.getEndian()); - mImageView.constructEventMessage(bb, event, action_pid_index); - msg_type = ProtocolConstants.MT_POINTER_DOWN; - } - break; - case MotionEvent.ACTION_POINTER_UP: - if (h != null) { - bb = ByteBuffer.allocate(ProtocolConstants.MT_EVENT_ENTRY_SIZE); - bb.order(h.getEndian()); - bb.putInt(event.getPointerId(action_pid_index)); - msg_type = ProtocolConstants.MT_POINTER_UP; - } - break; - default: - Log.w(TAG, "Unknown action type: " + action_code); - return true; - } - - if (DEBUG && bb != null) Log.d(TAG, bb.toString()); - - if (h != null && bb != null) { - h.postMessage(msg_type, bb); - } - return true; - } - } // TouchListener - - /** Implementation of Handler.Callback */ - @Override - public boolean handleMessage(Message msg) { - switch (msg.what) { - case MultiTouchChannel.EVENT_MT_START: - MultiTouchChannel h = mHandler; - if (h != null) { - mImageView.setEnabled(true); - mImageView.setOnTouchListener(mTouchListener); - } - break; - case MultiTouchChannel.EVENT_MT_STOP: - mImageView.setOnTouchListener(null); - break; - case MultiTouchChannel.EVENT_FRAME_BUFFER: - onFrameBuffer(((ByteBuffer) msg.obj).array()); - mHandler.postMessage(ProtocolConstants.MT_FB_HANDLED, (byte[]) null); - break; - } - return true; // we consumed this message - } - - /** - * Called when a BLOB query is received from the emulator. - * <p/> - * This query is used to deliver framebuffer updates in the emulator. The - * blob contains an update header, followed by the bitmap containing updated - * rectangle. The header is defined as MTFrameHeader structure in - * external/qemu/android/multitouch-port.h - * <p/> - * NOTE: This method is called from the I/O loop, so all communication with - * the emulator will be "on hold" until this method returns. - * - * TODO ===> CHECK that we can consume that array from a different thread than the producer's. - * E.g. does the produce reuse the same array or does it generate a new one each time? - * - * @param array contains BLOB data for the query. - */ - private void onFrameBuffer(byte[] array) { - final ByteBuffer bb = ByteBuffer.wrap(array); - bb.order(ByteOrder.LITTLE_ENDIAN); - - // Read frame header. - final int header_size = bb.getInt(); - final int disp_width = bb.getInt(); - final int disp_height = bb.getInt(); - final int x = bb.getInt(); - final int y = bb.getInt(); - final int w = bb.getInt(); - final int h = bb.getInt(); - final int bpl = bb.getInt(); - final int bpp = bb.getInt(); - final int format = bb.getInt(); - - // Update application display. - updateDisplay(disp_width, disp_height); - - if (format == ProtocolConstants.MT_FRAME_JPEG) { - /* - * Framebuffer is in JPEG format. - */ - - final ByteArrayInputStream jpg = new ByteArrayInputStream(bb.array()); - // Advance input stream to JPEG image. - jpg.skip(header_size); - // Draw the image. - mImageView.drawJpeg(x, y, w, h, jpg); - } else { - /* - * Framebuffer is in a raw RGB format. - */ - - final int pixel_num = h * w; - // Advance stream to the beginning of framebuffer data. - bb.position(header_size); - - // Make sure that mColors is large enough to contain the - // update bitmap. - if (mColors == null || mColors.length < pixel_num) { - mColors = new int[pixel_num]; - } - - // Convert the blob bitmap into bitmap that we will display. - if (format == ProtocolConstants.MT_FRAME_RGB565) { - for (int n = 0; n < pixel_num; n++) { - // Blob bitmap is in RGB565 format. - final int color = bb.getShort(); - final int r = ((color & 0xf800) >> 8) | ((color & 0xf800) >> 14); - final int g = ((color & 0x7e0) >> 3) | ((color & 0x7e0) >> 9); - final int b = ((color & 0x1f) << 3) | ((color & 0x1f) >> 2); - mColors[n] = Color.rgb(r, g, b); - } - } else if (format == ProtocolConstants.MT_FRAME_RGB888) { - for (int n = 0; n < pixel_num; n++) { - // Blob bitmap is in RGB565 format. - final int r = bb.getChar(); - final int g = bb.getChar(); - final int b = bb.getChar(); - mColors[n] = Color.rgb(r, g, b); - } - } else { - Log.w(TAG, "Invalid framebuffer format: " + format); - return; - } - mImageView.drawBitmap(x, y, w, h, mColors); - } - } - - /** - * Updates application's screen accordingly to the emulator screen. - * - * @param e_width Width of the emulator screen. - * @param e_height Height of the emulator screen. - */ - private void updateDisplay(int e_width, int e_height) { - if (e_width != mEmulatorWidth || e_height != mEmulatorHeight) { - mEmulatorWidth = e_width; - mEmulatorHeight = e_height; - - boolean rotateDisplay = false; - int w = mImageView.getWidth(); - int h = mImageView.getHeight(); - if (w > h != e_width > e_height) { - rotateDisplay = true; - int tmp = w; - w = h; - h = tmp; - } - - float dx = (float) w / (float) e_width; - float dy = (float) h / (float) e_height; - mImageView.setDxDy(dx, dy, rotateDisplay); - if (DEBUG) Log.d(TAG, "Dispay updated: " + e_width + " x " + e_height + - " -> " + w + " x " + h + " ratio: " + - dx + " x " + dy); - } - } - - // ---------- - - private void updateStatus(String status) { - mTextStatus.setVisibility(status == null ? View.GONE : View.VISIBLE); - if (status != null) mTextStatus.setText(status); - } - - private void updateError() { - ControllerBinder binder = getServiceBinder(); - String error = binder == null ? "" : binder.getServiceError(); - if (error == null) { - error = ""; - } - - mTextError.setVisibility(error.length() == 0 ? View.GONE : View.VISIBLE); - mTextError.setText(error); - } -} diff --git a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/SensorActivity.java b/apps/SdkController/src/com/android/tools/sdkcontroller/activities/SensorActivity.java deleted file mode 100755 index 61c308152..000000000 --- a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/SensorActivity.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.tools.sdkcontroller.activities; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import android.os.Bundle; -import android.os.Message; -import android.util.Log; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnFocusChangeListener; -import android.view.View.OnKeyListener; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import com.android.tools.sdkcontroller.R; -import com.android.tools.sdkcontroller.handlers.SensorChannel; -import com.android.tools.sdkcontroller.handlers.SensorChannel.MonitoredSensor; -import com.android.tools.sdkcontroller.lib.Channel; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerBinder; -import com.android.tools.sdkcontroller.service.ControllerService.ControllerListener; - -/** - * Activity that displays and controls the sensors from {@link SensorChannel}. - * For each sensor it displays a checkbox that is enabled if the sensor is supported - * by the emulator. The user can select whether the sensor is active. It also displays - * data from the sensor when available. - */ -public class SensorActivity extends BaseBindingActivity - implements android.os.Handler.Callback { - - @SuppressWarnings("hiding") - public static String TAG = SensorActivity.class.getSimpleName(); - private static boolean DEBUG = true; - - private static final int MSG_UPDATE_ACTUAL_HZ = 0x31415; - - private TableLayout mTableLayout; - private TextView mTextError; - private TextView mTextStatus; - private TextView mTextTargetHz; - private TextView mTextActualHz; - private SensorChannel mSensorHandler; - - private final Map<MonitoredSensor, DisplayInfo> mDisplayedSensors = - new HashMap<SensorChannel.MonitoredSensor, SensorActivity.DisplayInfo>(); - private final android.os.Handler mUiHandler = new android.os.Handler(this); - private int mTargetSampleRate; - private long mLastActualUpdateMs; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.sensors); - mTableLayout = (TableLayout) findViewById(R.id.tableLayout); - mTextError = (TextView) findViewById(R.id.textError); - mTextStatus = (TextView) findViewById(R.id.textStatus); - mTextTargetHz = (TextView) findViewById(R.id.textSampleRate); - mTextActualHz = (TextView) findViewById(R.id.textActualRate); - updateStatus("Waiting for connection"); - - mTextTargetHz.setOnKeyListener(new OnKeyListener() { - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - updateSampleRate(); - return false; - } - }); - mTextTargetHz.setOnFocusChangeListener(new OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - updateSampleRate(); - } - }); - } - - @Override - protected void onResume() { - if (DEBUG) Log.d(TAG, "onResume"); - // BaseBindingActivity.onResume will bind to the service. - super.onResume(); - updateError(); - } - - @Override - protected void onPause() { - if (DEBUG) Log.d(TAG, "onPause"); - // BaseBindingActivity.onResume will unbind from (but not stop) the service. - super.onPause(); - } - - @Override - protected void onDestroy() { - if (DEBUG) Log.d(TAG, "onDestroy"); - super.onDestroy(); - removeSensorUi(); - } - - // ---------- - - @Override - protected void onServiceConnected() { - if (DEBUG) Log.d(TAG, "onServiceConnected"); - createSensorUi(); - } - - @Override - protected void onServiceDisconnected() { - if (DEBUG) Log.d(TAG, "onServiceDisconnected"); - removeSensorUi(); - } - - @Override - protected ControllerListener createControllerListener() { - return new SensorsControllerListener(); - } - - // ---------- - - private class SensorsControllerListener implements ControllerListener { - @Override - public void onErrorChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - updateError(); - } - }); - } - - @Override - public void onStatusChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - ControllerBinder binder = getServiceBinder(); - if (binder != null) { - boolean connected = binder.isEmuConnected(); - mTableLayout.setEnabled(connected); - updateStatus(connected ? "Emulated connected" : "Emulator disconnected"); - } - } - }); - } - } - - private void createSensorUi() { - final LayoutInflater inflater = getLayoutInflater(); - - if (!mDisplayedSensors.isEmpty()) { - removeSensorUi(); - } - - mSensorHandler = (SensorChannel) getServiceBinder().getChannel(Channel.SENSOR_CHANNEL); - if (mSensorHandler != null) { - mSensorHandler.addUiHandler(mUiHandler); - mUiHandler.sendEmptyMessage(MSG_UPDATE_ACTUAL_HZ); - - assert mDisplayedSensors.isEmpty(); - List<MonitoredSensor> sensors = mSensorHandler.getSensors(); - for (MonitoredSensor sensor : sensors) { - final TableRow row = (TableRow) inflater.inflate(R.layout.sensor_row, - mTableLayout, - false); - mTableLayout.addView(row); - mDisplayedSensors.put(sensor, new DisplayInfo(sensor, row)); - } - } - } - - private void removeSensorUi() { - if (mSensorHandler != null) { - mSensorHandler.removeUiHandler(mUiHandler); - mSensorHandler = null; - } - mTableLayout.removeAllViews(); - for (DisplayInfo info : mDisplayedSensors.values()) { - info.release(); - } - mDisplayedSensors.clear(); - } - - private class DisplayInfo implements CompoundButton.OnCheckedChangeListener { - private MonitoredSensor mSensor; - private CheckBox mChk; - private TextView mVal; - - public DisplayInfo(MonitoredSensor sensor, TableRow row) { - mSensor = sensor; - - // Initialize displayed checkbox for this sensor, and register - // checked state listener for it. - mChk = (CheckBox) row.findViewById(R.id.row_checkbox); - mChk.setText(sensor.getUiName()); - mChk.setEnabled(sensor.isEnabledByEmulator()); - mChk.setChecked(sensor.isEnabledByUser()); - mChk.setOnCheckedChangeListener(this); - - // Initialize displayed text box for this sensor. - mVal = (TextView) row.findViewById(R.id.row_textview); - mVal.setText(sensor.getValue()); - } - - /** - * Handles checked state change for the associated CheckBox. If check - * box is checked we will register sensor change listener. If it is - * unchecked, we will unregister sensor change listener. - */ - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (mSensor != null) { - mSensor.onCheckedChanged(isChecked); - } - } - - public void release() { - mChk = null; - mVal = null; - mSensor = null; - - } - - public void updateState() { - if (mChk != null && mSensor != null) { - mChk.setEnabled(mSensor.isEnabledByEmulator()); - mChk.setChecked(mSensor.isEnabledByUser()); - } - } - - public void updateValue() { - if (mVal != null && mSensor != null) { - mVal.setText(mSensor.getValue()); - } - } - } - - /** Implementation of Handler.Callback */ - @Override - public boolean handleMessage(Message msg) { - DisplayInfo info = null; - switch (msg.what) { - case SensorChannel.SENSOR_STATE_CHANGED: - info = mDisplayedSensors.get(msg.obj); - if (info != null) { - info.updateState(); - } - break; - case SensorChannel.SENSOR_DISPLAY_MODIFIED: - info = mDisplayedSensors.get(msg.obj); - if (info != null) { - info.updateValue(); - } - if (mSensorHandler != null) { - updateStatus(Integer.toString(mSensorHandler.getMsgSentCount()) + " events sent"); - - // Update the "actual rate" field if the value has changed - long ms = mSensorHandler.getActualUpdateMs(); - if (ms != mLastActualUpdateMs) { - mLastActualUpdateMs = ms; - String hz = mLastActualUpdateMs <= 0 ? "--" : - Integer.toString((int) Math.ceil(1000. / ms)); - mTextActualHz.setText(hz); - } - } - break; - case MSG_UPDATE_ACTUAL_HZ: - if (mSensorHandler != null) { - // Update the "actual rate" field if the value has changed - long ms = mSensorHandler.getActualUpdateMs(); - if (ms != mLastActualUpdateMs) { - mLastActualUpdateMs = ms; - String hz = mLastActualUpdateMs <= 0 ? "--" : - Integer.toString((int) Math.ceil(1000. / ms)); - mTextActualHz.setText(hz); - } - mUiHandler.sendEmptyMessageDelayed(MSG_UPDATE_ACTUAL_HZ, 1000 /*1s*/); - } - } - return true; // we consumed this message - } - - private void updateStatus(String status) { - mTextStatus.setVisibility(status == null ? View.GONE : View.VISIBLE); - if (status != null) mTextStatus.setText(status); - } - - private void updateError() { - ControllerBinder binder = getServiceBinder(); - String error = binder == null ? "" : binder.getServiceError(); - if (error == null) { - error = ""; - } - - mTextError.setVisibility(error.length() == 0 ? View.GONE : View.VISIBLE); - mTextError.setText(error); - } - - private void updateSampleRate() { - String str = mTextTargetHz.getText().toString(); - try { - int hz = Integer.parseInt(str.trim()); - - // Cap the value. 50 Hz is a reasonable max value for the emulator. - if (hz <= 0 || hz > 50) { - hz = 50; - } - - if (hz != mTargetSampleRate) { - mTargetSampleRate = hz; - if (mSensorHandler != null) { - mSensorHandler.setUpdateTargetMs(hz <= 0 ? 0 : (int)(1000.0f / hz)); - } - } - } catch (Exception ignore) {} - } -} |