/*
HostLightProfile.java
Copyright (c) 2017 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.deviceplugin.host.profile;
import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import org.deviceconnect.android.activity.PermissionUtility;
import org.deviceconnect.android.deviceplugin.host.profile.utils.FlashingExecutor;
import org.deviceconnect.android.deviceplugin.host.recorder.HostDevicePhotoRecorder;
import org.deviceconnect.android.deviceplugin.host.recorder.HostDeviceRecorder;
import org.deviceconnect.android.deviceplugin.host.recorder.HostDeviceRecorderManager;
import org.deviceconnect.android.deviceplugin.host.recorder.HostDeviceStreamRecorder;
import org.deviceconnect.android.message.MessageUtils;
import org.deviceconnect.android.profile.LightProfile;
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.message.DConnectMessage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Light Profile.
*
* @author NTT DOCOMO, INC.
*/
public class HostLightProfile extends LightProfile {
/** ライトID. */
private static final String HOST_LIGHT_ID = "0";
/** ライト名称の初期値. */
private static final String HOST_DEFAULT_LIGHT_NAME = "Host Light";
/** 点滅制御用Map. */
private Map<String, FlashingExecutor> mFlashingMap = new HashMap<>();
/** Camera クラスインスタンス. */
private Camera mCamera = null;
/** ライト点灯/消灯状態. */
private boolean isOn = false;
/** Contextインスタンス. */
private Context mContext = null;
/** HostDeviceRecorderManagerインスタンス. */
private HostDeviceRecorderManager mMgr = null;
/** HostDevicePhotoRecorderインスタンス. */
private HostDevicePhotoRecorder mPhotoRec = null;
/**
* Get Light API.
*/
private final DConnectApi mGetLightApi = new GetApi() {
@Override
public boolean onRequest(final Intent request, final Intent response) {
PermissionUtility.requestPermissions(mContext,
new Handler(Looper.getMainLooper()), new String[]{Manifest.permission.CAMERA},
new PermissionUtility.PermissionRequestCallback() {
@Override
public void onSuccess() {
if (!(initCameraInstance())) {
MessageUtils.setIllegalDeviceStateError(response, "Camera device is already running.");
sendResponse(response);
return;
}
Bundle lightParam = new Bundle();
setName(lightParam, HOST_DEFAULT_LIGHT_NAME);
setConfig(lightParam, "");
setLightId(lightParam, HOST_LIGHT_ID);
isOn = mPhotoRec.isFlashLightState();
setOn(lightParam, isOn);
List<Bundle> lightParams = new ArrayList<>();
lightParams.add(lightParam);
setLights(response, lightParams);
setResult(response, DConnectMessage.RESULT_OK);
sendResponse(response);
}
@Override
public void onFail(@NonNull String deniedPermission) {
MessageUtils.setIllegalServerStateError(response,
"CAMERA permission not granted.");
sendResponse(response);
}
});
return false;
}
};
/**
* Post Light API.
*/
private final DConnectApi mPostLightApi = new PostApi() {
@Override
public boolean onRequest(final Intent request, final Intent response) {
final String lightId = getLightId(request);
final long[] flashing = getFlashing(request);
if (lightId != null && lightId.length() == 0) {
MessageUtils.setInvalidRequestParameterError(response, "lightId is not specified.");
return true;
}
if (lightId != null && !(lightId.equals(HOST_LIGHT_ID))) {
MessageUtils.setInvalidRequestParameterError(response, "lightId is not specified.");
return true;
}
PermissionUtility.requestPermissions(mContext,
new Handler(Looper.getMainLooper()), new String[]{Manifest.permission.CAMERA},
new PermissionUtility.PermissionRequestCallback() {
@Override
public void onSuccess() {
if (!(initCameraInstance())) {
MessageUtils.setIllegalDeviceStateError(response, "Camera device is already running.");
sendResponse(response);
return;
}
if (flashing != null) {
flashing(HOST_LIGHT_ID, flashing);
setResult(response, DConnectMessage.RESULT_OK);
} else {
isOn = true;
mPhotoRec.turnOnFlashLight();
setResult(response, DConnectMessage.RESULT_OK);
}
sendResponse(response);
}
@Override
public void onFail(@NonNull String deniedPermission) {
MessageUtils.setIllegalDeviceStateError(response,
"CAMERA permission not granted.");
sendResponse(response);
}
});
return false;
}
};
/**
* Delete Light API.
*/
private final DConnectApi mDeleteLightApi = new DeleteApi() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onRequest(final Intent request, final Intent response) {
String lightId = getLightId(request);
if (lightId != null && lightId.length() == 0) {
MessageUtils.setInvalidRequestParameterError(response, "lightId is not specified.");
return true;
}
if (lightId != null && !(lightId.equals(HOST_LIGHT_ID))) {
MessageUtils.setInvalidRequestParameterError(response, "lightId is not specified.");
return true;
}
PermissionUtility.requestPermissions(mContext,
new Handler(Looper.getMainLooper()), new String[]{Manifest.permission.CAMERA},
new PermissionUtility.PermissionRequestCallback() {
@Override
public void onSuccess() {
if (!(initCameraInstance())) {
MessageUtils.setIllegalDeviceStateError(response, "Camera device is already running.");
sendResponse(response);
return;
}
isOn = false;
mPhotoRec.turnOffFlashLight();
setResult(response, DConnectMessage.RESULT_OK);
sendResponse(response);
}
@Override
public void onFail(@NonNull String deniedPermission) {
MessageUtils.setIllegalServerStateError(response,
"CAMERA permission not granted.");
sendResponse(response);
}
});
return false;
}
};
/**
* Constructor.
* @param context context.
* @param manager HostDeviceRecorderManager.
*/
public HostLightProfile(final Context context, final HostDeviceRecorderManager manager) {
mContext = context;
mMgr = manager;
addApi(mGetLightApi);
addApi(mPostLightApi);
addApi(mDeleteLightApi);
PermissionUtility.requestPermissions(mContext,
new Handler(Looper.getMainLooper()), new String[]{Manifest.permission.CAMERA},
new PermissionUtility.PermissionRequestCallback() {
@Override
public void onSuccess() {
initCameraInstance();
}
@Override
public void onFail(@NonNull String deniedPermission) {
}
});
}
/**
* Cameraインスタンス生成.
* @return 正常終了時はtrue, カメラデバイス使用時はfalse.
*/
private boolean initCameraInstance() {
mMgr.initialize();
mPhotoRec = mMgr.getCameraRecorder(null);
if (((HostDeviceRecorder) mPhotoRec).getState() != HostDeviceRecorder.RecorderState.INACTTIVE) {
return false;
}
final HostDeviceStreamRecorder recorder = mMgr.getStreamRecorder(null);
if (recorder != null) {
if (recorder.getState() != HostDeviceRecorder.RecorderState.INACTTIVE) {
return false;
}
}
return true;
}
/**
* 点滅制御.
* @param id ライトID.
* @param flashing 点滅パターン.
*/
private void flashing(String id, long[] flashing) {
FlashingExecutor exe = mFlashingMap.get(id);
if (exe == null) {
exe = new FlashingExecutor();
mFlashingMap.put(id, exe);
}
exe.setLightControllable(new FlashingExecutor.LightControllable() {
@Override
public void changeLight(boolean isState, FlashingExecutor.CompleteListener listener) {
if (isState) {
isOn = true;
mPhotoRec.turnOnFlashLight();
} else {
isOn = false;
mPhotoRec.turnOffFlashLight();
}
listener.onComplete();
}
});
exe.start(flashing);
}
}