/*
SonyCameraMediaStreamRecordingProfile
Copyright (c) 2014 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.sonycamera.profile;
import android.content.Intent;
import android.os.Bundle;
import org.deviceconnect.android.deviceplugin.sonycamera.SonyCameraDeviceService;
import org.deviceconnect.android.deviceplugin.sonycamera.SonyCameraManager;
import org.deviceconnect.android.deviceplugin.sonycamera.utils.SonyCameraPreview;
import org.deviceconnect.android.event.EventError;
import org.deviceconnect.android.event.EventManager;
import org.deviceconnect.android.message.MessageUtils;
import org.deviceconnect.android.profile.MediaStreamRecordingProfile;
import org.deviceconnect.android.profile.api.DConnectApi;
import org.deviceconnect.android.profile.api.DeleteApi;
import org.deviceconnect.android.profile.api.GetApi;
import org.deviceconnect.android.profile.api.PostApi;
import org.deviceconnect.android.profile.api.PutApi;
import org.deviceconnect.message.DConnectMessage;
import java.util.ArrayList;
import java.util.List;
import static org.deviceconnect.android.deviceplugin.sonycamera.service.SonyCameraService.DEVICE_NAME;
/**
* Sony Camera用 Media Stream Recording プロファイル.
* @author NTT DOCOMO, INC.
*/
public class SonyCameraMediaStreamRecordingProfile extends MediaStreamRecordingProfile {
/** ターゲットID. */
private static final String TARGET_ID = "sonycamera";
// GET /mediaStreamRecording/mediaRecorder
private final DConnectApi mGetMediaRecorderApi = new GetApi() {
@Override
public String getAttribute() {
return ATTRIBUTE_MEDIARECORDER;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onGetMediaRecorder(request, response);
}
};
// POST /mediaStreamRecording/onPhoto
private final DConnectApi mPutOnPhotoApi = new PutApi() {
@Override
public String getAttribute() {
return ATTRIBUTE_ON_PHOTO;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
EventError error = EventManager.INSTANCE.addEvent(request);
if (error == EventError.NONE) {
setResult(response, DConnectMessage.RESULT_OK);
} else {
MessageUtils.setUnknownError(response);
}
return true;
}
};
// PUT /mediaStreamRecording/preview
private final DConnectApi mPutPreviewApi = new PutApi() {
@Override
public String getAttribute() {
return ATTRIBUTE_PREVIEW;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onPutPreview(request, response);
}
};
// DELETE /mediaStreamRecording/onPhoto
private final DConnectApi mDeleteOnPhotoApi = new DeleteApi() {
@Override
public String getAttribute() {
return ATTRIBUTE_ON_PHOTO;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
EventError error = EventManager.INSTANCE.removeEvent(request);
if (error == EventError.NONE) {
setResult(response, DConnectMessage.RESULT_OK);
} else if (error == EventError.INVALID_PARAMETER) {
MessageUtils.setInvalidRequestParameterError(response);
} else if (error == EventError.FAILED) {
MessageUtils.setUnknownError(response, "Failed to uninsert event for db.");
} else if (error == EventError.NOT_FOUND) {
MessageUtils.setUnknownError(response, "Not found event.");
} else {
MessageUtils.setUnknownError(response);
}
return true;
}
};
// DELETE /mediaStreamRecording/preview
private final DConnectApi mDeletePreviewApi = new DeleteApi() {
@Override
public String getAttribute() {
return ATTRIBUTE_PREVIEW;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onDeletePreview(request, response);
}
};
// POST /mediaStreamRecording/takePhoto
private final DConnectApi mPostTakePhotoApi = new PostApi() {
@Override
public String getAttribute() {
return ATTRIBUTE_TAKE_PHOTO;
}
@Override
public boolean onRequest(final Intent request, final Intent response) {
return onPostTakePhoto(request, response);
}
};
public SonyCameraMediaStreamRecordingProfile() {
addApi(mGetMediaRecorderApi);
addApi(mPutOnPhotoApi);
addApi(mPutPreviewApi);
addApi(mDeleteOnPhotoApi);
addApi(mDeletePreviewApi);
addApi(mPostTakePhotoApi);
}
/**
* カメラの情報を取得します.
*
* @param request リクエスト
* @param response レスポンス
* @return 即座にレスポンスする場合はtrue、それ以外はfalse
*/
private boolean onGetMediaRecorder(final Intent request, final Intent response) {
String serviceId = getServiceID(request);
SonyCameraManager manager = getSonyCameraManager();
if (!manager.isConnectedService(serviceId)) {
MessageUtils.setIllegalDeviceStateError(response, "Sony's camera is not ready.");
return true;
}
manager.getCameraState(new SonyCameraManager.OnCameraStateListener() {
@Override
public void onState(final String state, final int[] size) {
List<Bundle> recorders = new ArrayList<>();
Bundle recorder = new Bundle();
recorder.putString("id", TARGET_ID);
recorder.putString("name", DEVICE_NAME);
recorder.putString("state", state);
recorder.putString("mimeType", "image/jpg");
if (size != null) {
recorder.putInt("imageWidth", size[0]);
recorder.putInt("imageHeight", size[1]);
}
recorders.add(recorder);
response.putExtra("recorders", recorders.toArray(new Bundle[recorders.size()]));
setResult(response, DConnectMessage.RESULT_OK);
sendResponse(response);
}
@Override
public void onError() {
MessageUtils.setNotSupportAttributeError(response);
sendResponse(response);
}
});
return false;
}
/**
* プレビューを撮影します.
*
* @param request リクエスト
* @param response レスポンス
*
* @return プレビューの開始ができた場合はtrue、それ以外はfalse
*/
private boolean onPutPreview(final Intent request, final Intent response) {
String serviceId = getServiceID(request);
String target = getTarget(request);
Long timeSlice = getTimeSlice(request);
if (timeSlice == null) {
timeSlice = 100L;
}
SonyCameraManager manager = getSonyCameraManager();
if (!manager.isConnectedService(serviceId)) {
MessageUtils.setIllegalDeviceStateError(response, "Sony's camera is not ready.");
return true;
}
if (target != null && !target.equals(TARGET_ID)) {
MessageUtils.setInvalidRequestParameterError(response, "target is invalid.");
return true;
}
manager.startPreview(timeSlice.intValue(), new SonyCameraPreview.OnPreviewListener() {
@Override
public void onPreviewServer(final String url) {
setResult(response, DConnectMessage.RESULT_OK);
response.putExtra("uri", url);
sendResponse(response);
}
@Override
public void onError() {
MessageUtils.setIllegalDeviceStateError(response);
sendResponse(response);
}
@Override
public void onComplete() {
}
});
return false;
}
/**
* プレビューを停止します.
*
* @param request リクエスト
* @param response レスポンス
* @return result
*/
private boolean onDeletePreview(final Intent request, final Intent response) {
String serviceId = getServiceID(request);
String target = getTarget(request);
SonyCameraManager manager = getSonyCameraManager();
if (!manager.isConnectedService(serviceId)) {
MessageUtils.setIllegalDeviceStateError(response, "Sony's camera is not ready.");
return true;
}
if (target != null && !target.equals(TARGET_ID)) {
MessageUtils.setInvalidRequestParameterError(response, "target is invalid.");
return true;
}
if (!manager.isPreview()) {
MessageUtils.setIllegalDeviceStateError(response, "Sony's camera is not running a preview.");
return true;
}
manager.stopPreview();
setResult(response, DConnectMessage.RESULT_OK);
return true;
}
/**
* 写真を撮影します.
*
* @param request リクエスト
* @param response レスポンス
* @return 即座にレスポンスを返す場合はtrue、それ以外はfalse
*/
private boolean onPostTakePhoto(final Intent request, final Intent response) {
final String serviceId = getServiceID(request);
final String target = getTarget(request);
SonyCameraManager manager = getSonyCameraManager();
if (!manager.isConnectedService(serviceId)) {
MessageUtils.setIllegalDeviceStateError(response, "Sony's camera is not ready.");
return true;
}
if (target != null && !target.equals(TARGET_ID)) {
MessageUtils.setInvalidRequestParameterError(response, "target is invalid.");
return true;
}
if (manager.isRecording()) {
// 撮影中は、さらに撮影できないのでエラーを返す
MessageUtils.setIllegalDeviceStateError(response);
return true;
}
manager.takePicture(new SonyCameraManager.OnTakePictureListener() {
@Override
public void onSuccess(final String postImageUrl) {
response.putExtra("uri", postImageUrl);
setResult(response, DConnectMessage.RESULT_OK);
sendResponse(response);
}
@Override
public void onError() {
MessageUtils.setIllegalDeviceStateError(response);
sendResponse(response);
}
});
return false;
}
private SonyCameraManager getSonyCameraManager() {
return ((SonyCameraDeviceService) getContext()).getSonyCameraManager();
}
}