/* PebbleCanvasProfile.java Copyright (c) 2014 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.pebble.profile; import android.content.Intent; import com.getpebble.android.kit.util.PebbleDictionary; import org.deviceconnect.android.deviceplugin.pebble.PebbleDeviceService; import org.deviceconnect.android.deviceplugin.pebble.util.PebbleManager; import org.deviceconnect.android.deviceplugin.pebble.util.PebbleManager.OnSendCommandListener; import org.deviceconnect.android.deviceplugin.pebble.util.PebbleManager.OnSendDataListener; import org.deviceconnect.android.message.MessageUtils; import org.deviceconnect.android.profile.CanvasProfile; import org.deviceconnect.android.profile.api.DConnectApi; import org.deviceconnect.android.profile.api.DeleteApi; import org.deviceconnect.android.profile.api.PostApi; import org.deviceconnect.message.DConnectMessage; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Pattern; /** * Pebble 用 Canvasプロファイル. * * @author NTT DOCOMO, INC. */ public class PebbleCanvasProfile extends CanvasProfile { private ExecutorService mImageService = Executors.newSingleThreadExecutor(); private final Pattern PATTERN_MIME_TYPE = Pattern.compile("^[^/]+/[^/]+$"); private boolean isMIMEType(final String mimeType) { return PATTERN_MIME_TYPE.matcher(mimeType).matches(); } private final DConnectApi mPostDrawImageApi = new PostApi() { @Override public String getAttribute() { return ATTRIBUTE_DRAW_IMAGE; } @Override public boolean onRequest(final Intent request, final Intent response) { final byte[] data = getData(request); final String mode = getMode(request); final double x = getX(request); final double y = getY(request); final String mimeType = getMIMEType(request); if (mimeType != null) { boolean isValid = isMIMEType(mimeType); if (!isValid) { MessageUtils.setInvalidRequestParameterError(response, "mimeType is invalid: " + mimeType); return true; } else if (!mimeType.startsWith("image/")) { MessageUtils.setInvalidRequestParameterError(response, "this mimeType is unsupported: " + mimeType); return true; } } if (data == null) { mImageService.execute(new Runnable() { @Override public void run() { String uri = getURI(request); byte[] result = getData(uri); if (result == null) { MessageUtils.setInvalidRequestParameterError(response, "could not get image from uri."); sendResponse(response); return; } if (drawImage(response, result, mode, x, y)) { sendResponse(response); } } }); return false; } else { try { return drawImage(response, data, mode, x, y); } catch (Throwable e) { e.printStackTrace(); MessageUtils.setUnknownError(response, e.getMessage()); return true; } } } }; private final DConnectApi mDeleteDrawImage = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_DRAW_IMAGE; } @Override public boolean onRequest(final Intent request, final Intent response) { PebbleDeviceService service = (PebbleDeviceService) getContext(); PebbleManager mgr = service.getPebbleManager(); PebbleDictionary dic = new PebbleDictionary(); dic.addInt8(PebbleManager.KEY_PROFILE, (byte) PebbleManager.PROFILE_CANVAS); dic.addInt8(PebbleManager.KEY_ATTRIBUTE, (byte) PebbleManager.CANVAS_ATTRBIUTE_DRAW_IMAGE); dic.addInt8(PebbleManager.KEY_ACTION, (byte) PebbleManager.ACTION_DELETE); mgr.sendCommandToPebble(dic, new OnSendCommandListener() { @Override public void onReceivedData(final PebbleDictionary dic) { if (dic == null) { MessageUtils.setUnknownError(response); } else { setResult(response, DConnectMessage.RESULT_OK); } sendResponse(response); } }); return false; } }; public PebbleCanvasProfile() { addApi(mPostDrawImageApi); addApi(mDeleteDrawImage); } private boolean drawImage(final Intent response, byte[] data, String mode, double x, double y) { PebbleManager mgr = ((PebbleDeviceService) getContext()).getPebbleManager(); byte[] buf = PebbleManager.convertImage(data, mode, x, y); if (buf == null) { // unknown mode-value MessageUtils.setInvalidRequestParameterError(response); return true; } mgr.sendDataToPebble(buf, new OnSendDataListener() { @Override public void onSend(final boolean successed) { if (successed) { setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setUnknownError(response); } sendResponse(response); } }); return false; } }