/*
DataLayerListenerService.java
Copyright (c) 2015NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.wear.activity;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.Asset;
import com.google.android.gms.wearable.Wearable;
import org.deviceconnect.android.deviceplugin.wear.R;
import org.deviceconnect.android.deviceplugin.wear.WearApplication;
import org.deviceconnect.android.deviceplugin.wear.WearConst;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
/**
* Canvas.
*/
public class CanvasActivity extends Activity {
/**
* Defines the timeout.
*/
private static final int TIMEOUT_MS = 10000;
/**
* ImageView.
*/
private ImageView mImageView;
/**
* Wakelock.
*/
private PowerManager.WakeLock mWakeLock;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP), "CanvasWakelockTag");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_canvas);
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
}
mImageView = (ImageView) findViewById(R.id.canvas_image);
mImageView.setVisibility(View.INVISIBLE);
Intent intent = getIntent();
if (intent != null) {
refreshImage(intent);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
@Override
protected void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
refreshImage(intent);
}
}
/**
* Refresh image.
* @param intent Intent
*/
private void refreshImage(final Intent intent) {
String action = intent.getAction();
if (WearConst.ACTION_DELETE_CANVAS.equals(action)) {
finish();
return;
}
(new AsyncTask<Void, LoadingResult, LoadingResult>() {
@Override
protected LoadingResult doInBackground(Void... params) {
Asset asset = intent.getParcelableExtra(WearConst.PARAM_BITMAP);
return loadBitmapFromAsset(asset);
}
@Override
protected void onPostExecute(LoadingResult result) {
String sourceId = intent.getStringExtra(WearConst.PARAM_SOURCE_ID);
String requestId = intent.getStringExtra(WearConst.PARAM_REQUEST_ID);
sendResultToHost(sourceId, requestId, result.getResultCode());
if (!result.isSuccess()) {
finish();
return;
}
Bitmap bitmap = result.getBitmap();
if (bitmap == null) {
return;
}
int x = intent.getIntExtra(WearConst.PARAM_X, 0);
int y = intent.getIntExtra(WearConst.PARAM_Y, 0);
int mode = intent.getIntExtra(WearConst.PARAM_MODE, 0);
setImageBitmap(bitmap, mode, x, y);
}
}).execute();
}
private void sendResultToHost(final String destinationId, final String requestId, final String resultCode) {
String data = requestId + "," + resultCode;
String path = WearConst.WEAR_TO_DEVICE_CANVAS_RESULT;
((WearApplication) getApplication()).sendMessage(destinationId, path, data);
}
/**
* Sets a bitmap to ImageView.
* @param bitmap bitmap
* @param mode mode
* @param x x
* @param y y
*/
private synchronized void setImageBitmap(final Bitmap bitmap, final int mode, final int x, final int y) {
switch (mode) {
default:
case WearConst.MODE_NORMAL:
Matrix matrix = new Matrix();
matrix.postTranslate((float) x, (float) y);
mImageView.setImageBitmap(bitmap);
mImageView.setScaleType(ImageView.ScaleType.MATRIX);
mImageView.setImageMatrix(matrix);
mImageView.setVisibility(View.VISIBLE);
break;
case WearConst.MODE_SCALES:
mImageView.setImageBitmap(bitmap);
mImageView.setScaleType(ImageView.ScaleType.FIT_START);
mImageView.setTranslationX(x);
mImageView.setTranslationY(y);
mImageView.setVisibility(View.VISIBLE);
break;
case WearConst.MODE_FILLS:
BitmapDrawable bd = new BitmapDrawable(getResources(), bitmap);
bd.setTileModeX(Shader.TileMode.REPEAT);
bd.setTileModeY(Shader.TileMode.REPEAT);
mImageView.setImageDrawable(bd);
mImageView.setScaleType(ImageView.ScaleType.FIT_XY);
mImageView.setTranslationX(x);
mImageView.setTranslationY(y);
mImageView.setVisibility(View.VISIBLE);
break;
}
}
/**
* Load a bitmap from Asset.
* @param asset asset
* @return result of loading
*/
private LoadingResult loadBitmapFromAsset(final Asset asset) {
InputStream in = getInputStream(asset);
if (in == null) {
return LoadingResult.errorOnConnection();
}
try {
Bitmap bitmap = BitmapFactory.decodeStream(in);
if (bitmap == null) {
return LoadingResult.errorNotSupportedFormat();
}
return LoadingResult.success(bitmap);
} catch (OutOfMemoryError e) {
return LoadingResult.errorTooLargeBitmap();
}
}
/**
* Get an input stream from Asset.
* @param asset input stream of asset
* @return input stream, null on error
*/
private InputStream getInputStream(final Asset asset) {
if (asset == null) {
return null;
}
GoogleApiClient client = getClient();
ConnectionResult result =
client.blockingConnect(TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!result.isSuccess()) {
return null;
}
// convert asset into a file descriptor and block until it's ready
return Wearable.DataApi.getFdForAsset(client, asset).await().getInputStream();
}
/**
* Gets a GoogleApiClient.
* @return instance of GoogleApiClient
*/
private GoogleApiClient getClient() {
return ((WearApplication) getApplication()).getGoogleApiClient();
}
private static class LoadingResult {
private Bitmap mBitmap;
private String mResultCode;
private LoadingResult() {
}
public Bitmap getBitmap() {
return mBitmap;
}
public String getResultCode() {
return mResultCode;
}
public boolean isSuccess() {
return WearConst.RESULT_SUCCESS.equals(mResultCode);
}
static LoadingResult success(final Bitmap bitmap) {
if (bitmap == null) {
throw new IllegalArgumentException();
}
LoadingResult result = new LoadingResult();
result.mResultCode = WearConst.RESULT_SUCCESS;
result.mBitmap = bitmap;
return result;
}
static LoadingResult errorTooLargeBitmap() {
LoadingResult result = new LoadingResult();
result.mResultCode = WearConst.RESULT_ERROR_TOO_LARGE_BITMAP;
return result;
}
static LoadingResult errorOnConnection() {
LoadingResult result = new LoadingResult();
result.mResultCode = WearConst.RESULT_ERROR_CONNECTION_FAILURE;
return result;
}
static LoadingResult errorNotSupportedFormat() {
LoadingResult result = new LoadingResult();
result.mResultCode = WearConst.RESULT_ERROR_NOT_SUPPORTED_FORMAT;
return result;
}
}
}