{
boolean driveAutoFocus(MotionEvent motionEvent);
void unlockAutoFocus();
+ void halfPressShutter(boolean isPressed);
}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.operation;
+
+import net.osdn.gokigen.gr2control.camera.ICameraButtonControl;
+
+public class FujiXButtonControl implements ICameraButtonControl
+{
+ public FujiXButtonControl()
+ {
+
+
+ }
+
+ @Override
+ public boolean pushedButton(String code, boolean isLongPress)
+ {
+ return (false);
+ }
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.operation;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.gr2control.camera.ICaptureControl;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandPublisher;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.CaptureCommand;
+import net.osdn.gokigen.gr2control.liveview.IAutoFocusFrameDisplay;
+
+public class FujiXCaptureControl implements ICaptureControl, IFujiXCommandCallback
+{
+ private final String TAG = this.toString();
+ private final IFujiXCommandPublisher issuer;
+ private final IAutoFocusFrameDisplay frameDisplay;
+
+
+ public FujiXCaptureControl(@NonNull IFujiXCommandPublisher issuer, IAutoFocusFrameDisplay frameDisplay)
+ {
+ this.issuer = issuer;
+ this.frameDisplay = frameDisplay;
+
+ }
+
+ @Override
+ public void doCapture(int kind)
+ {
+ try
+ {
+ boolean ret = issuer.enqueueCommand(new CaptureCommand(this));
+ if (!ret)
+ {
+ Log.v(TAG, "enqueue ERROR");
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ Log.v(TAG, "Response Received.");
+ frameDisplay.hideFocusFrame();
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] body)
+ {
+ Log.v(TAG, " " + currentBytes + "/" + totalBytes);
+ }
+
+ @Override
+ public boolean isReceiveMulti()
+ {
+ return (false);
+ }
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.operation;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+
+import net.osdn.gokigen.gr2control.camera.IFocusingControl;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandPublisher;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.FocusLock;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.FocusUnlock;
+import net.osdn.gokigen.gr2control.liveview.IAutoFocusFrameDisplay;
+import net.osdn.gokigen.gr2control.liveview.IIndicatorControl;
+import net.osdn.gokigen.gr2control.preference.IPreferencePropertyAccessor;
+
+public class FujiXFocusingControl implements IFocusingControl, IFujiXCommandCallback
+{
+ private final String TAG = this.toString();
+
+ public static final int FOCUS_LOCK = 0;
+ public static final int FOCUS_UNLOCK = 1;
+
+ private float maxPointLimitWidth;
+ private float maxPointLimitHeight;
+
+ private final IFujiXCommandPublisher issuer;
+ private final IAutoFocusFrameDisplay frameDisplayer;
+ private final IIndicatorControl indicator;
+ private RectF preFocusFrameRect = null;
+
+
+ public FujiXFocusingControl(@NonNull Activity activity, @NonNull IFujiXCommandPublisher issuer, @NonNull final IAutoFocusFrameDisplay frameDisplayer, @NonNull final IIndicatorControl indicator)
+ {
+ this.issuer = issuer;
+ this.frameDisplayer = frameDisplayer;
+ this.indicator = indicator;
+ try
+ {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+ String focusPoint = preferences.getString(IPreferencePropertyAccessor.FUJI_X_FOCUS_XY, IPreferencePropertyAccessor.FUJI_X_FOCUS_XY_DEFAULT_VALUE);
+ String[] focus = focusPoint.split(",");
+ if (focus.length == 2)
+ {
+ maxPointLimitWidth = Integer.parseInt(focus[0]);
+ maxPointLimitHeight = Integer.parseInt(focus[1]);
+ }
+ else
+ {
+ maxPointLimitWidth = 7.0f;
+ maxPointLimitHeight = 7.0f;
+ }
+ Log.v(TAG, "FOCUS RESOLUTION : " + maxPointLimitWidth + "," + maxPointLimitHeight);
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ maxPointLimitWidth = 7.0f;
+ maxPointLimitHeight = 7.0f;
+ }
+ }
+
+ @Override
+ public boolean driveAutoFocus(final MotionEvent motionEvent)
+ {
+ Log.v(TAG, "driveAutoFocus()");
+ if (motionEvent.getAction() != MotionEvent.ACTION_DOWN)
+ {
+ return (false);
+ }
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try
+ {
+ PointF point = frameDisplayer.getPointWithEvent(motionEvent);
+ if (point != null)
+ {
+ preFocusFrameRect = getPreFocusFrameRect(point);
+ showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Running, 0.0);
+ if (frameDisplayer.isContainsPoint(point))
+ {
+ lockAutoFocus(point);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ });
+ try
+ {
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return (false);
+ }
+
+ @Override
+ public void unlockAutoFocus()
+ {
+ try
+ {
+ issuer.enqueueCommand(new FocusUnlock(this));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void halfPressShutter(boolean isPressed)
+ {
+ lockAutoFocus(new PointF(0.5f, 0.5f));
+ }
+
+ private void lockAutoFocus(PointF point)
+ {
+ try
+ {
+ byte x = (byte) (0x000000ff & (Math.round(point.x * maxPointLimitWidth) + 1));
+ byte y = (byte) (0x000000ff & (Math.round(point.y * maxPointLimitHeight) + 1));
+ Log.v(TAG, "Lock AF: [" + x + ","+ y + "]");
+ issuer.enqueueCommand(new FocusLock(x, y, this));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private RectF getPreFocusFrameRect(@NonNull PointF point)
+ {
+ float imageWidth = frameDisplayer.getContentSizeWidth();
+ float imageHeight = frameDisplayer.getContentSizeHeight();
+
+ // Display a provisional focus frame at the touched point.
+ float focusWidth = 0.125f; // 0.125 is rough estimate.
+ float focusHeight = 0.125f;
+ if (imageWidth > imageHeight)
+ {
+ focusHeight *= (imageWidth / imageHeight);
+ }
+ else
+ {
+ focusHeight *= (imageHeight / imageWidth);
+ }
+ return (new RectF(point.x - focusWidth / 2.0f, point.y - focusHeight / 2.0f,
+ point.x + focusWidth / 2.0f, point.y + focusHeight / 2.0f));
+ }
+
+ /**
+ *
+ *
+ */
+ private void showFocusFrame(RectF rect, IAutoFocusFrameDisplay.FocusFrameStatus status, double duration)
+ {
+ frameDisplayer.showFocusFrame(rect, status, duration);
+ indicator.onAfLockUpdate(IAutoFocusFrameDisplay.FocusFrameStatus.Focused == status);
+ }
+
+ /**
+ *
+ *
+ */
+ private void hideFocusFrame()
+ {
+ frameDisplayer.hideFocusFrame();
+ indicator.onAfLockUpdate(false);
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] body)
+ {
+ Log.v(TAG, " " + currentBytes + "/" + totalBytes);
+ }
+
+ @Override
+ public boolean isReceiveMulti()
+ {
+ return (false);
+ }
+
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ if (id == FOCUS_LOCK)
+ {
+ Log.v(TAG, "FOCUS LOCKED");
+ if (preFocusFrameRect != null)
+ {
+ showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Focused, 1.0); // いったん1秒だけ表示
+ }
+ }
+ else // if (id == FOCUS_UNLOCK)
+ {
+ Log.v(TAG, "FOCUS UNLOCKED");
+ hideFocusFrame();
+
+ }
+ preFocusFrameRect = null;
+ }
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.operation;
+
+import net.osdn.gokigen.gr2control.camera.ICameraHardwareStatus;
+
+import java.util.Map;
+
+public class FujiXHardwareStatus implements ICameraHardwareStatus
+{
+ @Override
+ public boolean isAvailableHardwareStatus()
+ {
+ return (false);
+ }
+
+ @Override
+ public String getLensMountStatus()
+ {
+ return (null);
+ }
+
+ @Override
+ public String getMediaMountStatus()
+ {
+ return (null);
+ }
+
+ @Override
+ public float getMinimumFocalLength()
+ {
+ return (0);
+ }
+
+ @Override
+ public float getMaximumFocalLength()
+ {
+ return (0);
+ }
+
+ @Override
+ public float getActualFocalLength()
+ {
+ return (0);
+ }
+
+ @Override
+ public Map<String, Object> inquireHardwareInformation()
+ {
+ return (null);
+ }
+
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.operation;
+
+import net.osdn.gokigen.gr2control.camera.IZoomLensControl;
+
+public class FujiXZoomControl implements IZoomLensControl
+{
+
+ @Override
+ public boolean canZoom()
+ {
+ return (false);
+ }
+
+ @Override
+ public void updateStatus()
+ {
+
+ }
+
+ @Override
+ public float getMaximumFocalLength()
+ {
+ return (0);
+ }
+
+ @Override
+ public float getMinimumFocalLength()
+ {
+ return (0);
+ }
+
+ @Override
+ public float getCurrentFocalLength()
+ {
+ return (0);
+ }
+
+ @Override
+ public void driveZoomLens(float targetLength)
+ {
+
+ }
+
+ @Override
+ public void driveZoomLens(boolean isZoomIn)
+ {
+
+ }
+
+ @Override
+ public void moveInitialZoomPosition()
+ {
+
+ }
+
+ @Override
+ public boolean isDrivingZoomLens()
+ {
+ return (false);
+ }
+}
import net.osdn.gokigen.gr2control.camera.ILiveViewControl;
import net.osdn.gokigen.gr2control.camera.IZoomLensControl;
import net.osdn.gokigen.gr2control.camera.fuji_x.IFujiXInterfaceProvider;
+import net.osdn.gokigen.gr2control.camera.fuji_x.operation.FujiXButtonControl;
+import net.osdn.gokigen.gr2control.camera.fuji_x.operation.FujiXCaptureControl;
+import net.osdn.gokigen.gr2control.camera.fuji_x.operation.FujiXFocusingControl;
+import net.osdn.gokigen.gr2control.camera.fuji_x.operation.FujiXHardwareStatus;
+import net.osdn.gokigen.gr2control.camera.fuji_x.operation.FujiXZoomControl;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.FujiXAsyncResponseReceiver;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.FujiXCommandPublisher;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandPublisher;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommunication;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.connection.FujiXConnection;
import net.osdn.gokigen.gr2control.camera.playback.IPlaybackControl;
-import net.osdn.gokigen.gr2control.camera.ricohgr2.operation.RicohGr2CameraButtonControl;
-import net.osdn.gokigen.gr2control.camera.ricohgr2.operation.RicohGr2CameraCaptureControl;
-import net.osdn.gokigen.gr2control.camera.ricohgr2.operation.RicohGr2CameraFocusControl;
-import net.osdn.gokigen.gr2control.camera.ricohgr2.operation.RicohGr2CameraZoomLensControl;
-import net.osdn.gokigen.gr2control.camera.ricohgr2.operation.RicohGr2HardwareStatus;
-import net.osdn.gokigen.gr2control.camera.ricohgr2.wrapper.connection.RicohGr2Connection;
import net.osdn.gokigen.gr2control.liveview.IAutoFocusFrameDisplay;
import net.osdn.gokigen.gr2control.liveview.ICameraStatusUpdateNotify;
import net.osdn.gokigen.gr2control.liveview.IIndicatorControl;
public class FujiXInterfaceProvider implements IFujiXInterfaceProvider, IDisplayInjector
{
private final String TAG = toString();
- //private final Activity activity;
+
+ private static final int STREAM_PORT = 55742;
+ private static final int ASYNC_RESPONSE_PORT = 55741;
+ private static final int CONTROL_PORT = 55740;
+ private static final String CAMERA_IP = "192.168.0.1";
+
+ private final Activity activity;
//private final ICameraStatusReceiver provider;
- private final RicohGr2Connection gr2Connection;
- private final RicohGr2CameraButtonControl buttonControl;
+ private final FujiXCommandPublisher commandPublisher;
+ private final FujiXLiveViewControl liveViewControl;
+ private final FujiXAsyncResponseReceiver asyncReceiver;
+ private final FujiXConnection fujiXConnection;
+
+ private final FujiXButtonControl buttonControl;
private final FujiXStatusChecker statusChecker;
private final FujiXPlaybackControl playbackControl;
- private final RicohGr2HardwareStatus hardwareStatus;
+ private final FujiXHardwareStatus hardwareStatus;
private final FujiXRunMode runMode;
+ private final FujiXZoomControl zoomControl;
- private FujiXLiveViewControl liveViewControl;
- private RicohGr2CameraCaptureControl captureControl;
- private RicohGr2CameraZoomLensControl zoomControl;
- private RicohGr2CameraFocusControl focusControl;
+ private FujiXCaptureControl captureControl = null;
+ private FujiXFocusingControl focusControl = null;
/**
*
{
e.printStackTrace();
}
- //this.activity = context;
+ this.activity = context;
//this.provider = provider;
- gr2Connection = new RicohGr2Connection(context, provider);
- liveViewControl = new FujiXLiveViewControl();
- zoomControl = new RicohGr2CameraZoomLensControl();
- buttonControl = new RicohGr2CameraButtonControl();
+ this.commandPublisher = new FujiXCommandPublisher(CAMERA_IP, CONTROL_PORT);
+ fujiXConnection = new FujiXConnection(context, provider, this);
+ liveViewControl = new FujiXLiveViewControl(context, CAMERA_IP, STREAM_PORT);
+ asyncReceiver = new FujiXAsyncResponseReceiver(CAMERA_IP, ASYNC_RESPONSE_PORT);
+ zoomControl = new FujiXZoomControl();
+ buttonControl = new FujiXButtonControl();
statusChecker = new FujiXStatusChecker(500);
playbackControl = new FujiXPlaybackControl(communicationTimeoutMs);
- hardwareStatus = new RicohGr2HardwareStatus();
+ hardwareStatus = new FujiXHardwareStatus();
runMode = new FujiXRunMode();
}
public void injectDisplay(IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator, IFocusingModeNotify focusingModeNotify)
{
Log.v(TAG, "injectDisplay()");
- focusControl = new RicohGr2CameraFocusControl(true, frameDisplayer, indicator);
- captureControl = new RicohGr2CameraCaptureControl(true, false, frameDisplayer, statusChecker);
+ focusControl = new FujiXFocusingControl(activity, commandPublisher, frameDisplayer, indicator);
+ captureControl = new FujiXCaptureControl(commandPublisher, frameDisplayer);
}
@Override
public ICameraConnection getCameraConnection()
{
- return (gr2Connection);
+ return (fujiXConnection);
}
@Override
}
@Override
- public ICameraStatusUpdateNotify getStatusListener() {
+ public ICameraStatusUpdateNotify getStatusListener()
+ {
return null;
}
@Override
public IFujiXCommandPublisher getCommandPublisher()
{
- return null;
+ return (commandPublisher);
}
@Override
public void setAsyncEventReceiver(@NonNull IFujiXCommandCallback receiver)
{
-
+ asyncReceiver.setEventSubscriber(receiver);
}
}
package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper;
+import android.app.Activity;
+
+import androidx.annotation.NonNull;
+
import net.osdn.gokigen.gr2control.camera.ILiveViewControl;
import net.osdn.gokigen.gr2control.liveview.liveviewlistener.CameraLiveViewListenerImpl;
import net.osdn.gokigen.gr2control.liveview.liveviewlistener.ILiveViewListener;
public class FujiXLiveViewControl implements ILiveViewControl
{
private final String TAG = toString();
+
+ private final String ipAddress;
+ private final int portNumber;
+
private final CameraLiveViewListenerImpl liveViewListener;
/**
*
*
*/
- FujiXLiveViewControl()
+ FujiXLiveViewControl(@NonNull Activity activity, String ip, int portNumber)
{
- this.liveViewListener = new CameraLiveViewListenerImpl();
+ this.ipAddress = ip;
+ this.portNumber = portNumber;
+ liveViewListener = new CameraLiveViewListenerImpl();
}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.InputStream;
+import java.net.Socket;
+
+public class FujiXAsyncResponseReceiver implements IFujiXCommunication
+{
+ private final String TAG = toString();
+ private final String ipAddress;
+ private final int portNumber;
+ private static final int BUFFER_SIZE = 1280 + 8;
+ private static final int WAIT_MS = 250; // 250ms
+ private static final int ERROR_LIMIT = 30;
+ private IFujiXCommandCallback receiver = null;
+ private boolean isStart = false;
+
+ public FujiXAsyncResponseReceiver(@NonNull String ip, int portNumber)
+ {
+ this.ipAddress = ip;
+ this.portNumber = portNumber;
+ }
+
+ public void setEventSubscriber(@NonNull IFujiXCommandCallback receiver)
+ {
+ this.receiver = receiver;
+ }
+
+ @Override
+ public boolean connect()
+ {
+ start();
+ return (true);
+ }
+
+ @Override
+ public void disconnect()
+ {
+ isStart = false;
+ }
+
+ public void start()
+ {
+ if (isStart)
+ {
+ // すでに受信スレッド動作中なので抜ける
+ return;
+ }
+ isStart = true;
+ Thread thread = new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ Socket socket = new Socket(ipAddress, portNumber);
+ startReceive(socket);
+ }
+ catch (Exception e)
+ {
+ Log.v(TAG, " IP : " + ipAddress + " port : " + portNumber);
+ e.printStackTrace();
+ }
+ }
+ });
+ try
+ {
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void stop()
+ {
+ isStart = false;
+ }
+
+ private void startReceive(Socket socket)
+ {
+ int errorCount = 0;
+ InputStream isr;
+ byte[] byte_array;
+ try
+ {
+ isr = socket.getInputStream();
+ byte_array = new byte[BUFFER_SIZE];
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ Log.v(TAG, "===== startReceive() aborted.");
+ return;
+ }
+ Log.v(TAG, "startReceive() start.");
+ while (isStart)
+ {
+ try
+ {
+ int read_bytes = isr.read(byte_array, 0, BUFFER_SIZE);
+ Log.v(TAG, "RECEIVE ASYNC : " + read_bytes + " bytes.");
+ if (receiver != null)
+ {
+ try
+ {
+ receiver.receivedMessage(0, byte_array);
+ }
+ catch (Exception ee)
+ {
+ ee.printStackTrace();
+ }
+ }
+ Thread.sleep(WAIT_MS);
+ errorCount = 0;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ errorCount++;
+ }
+ if (errorCount > ERROR_LIMIT)
+ {
+ // エラーが連続でたくさん出たらループをストップさせる
+ isStart = false;
+ }
+ }
+ try
+ {
+ isr.close();
+ socket.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ Log.v(TAG, "startReceive() end.");
+ }
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Queue;
+
+public class FujiXCommandPublisher implements IFujiXCommandPublisher, IFujiXCommunication
+{
+ private final String TAG = toString();
+
+ private static final int SEQUENCE_START_NUMBER = 1;
+ private static final int BUFFER_SIZE = 1024 * 1024 + 8;
+ private static final int COMMAND_SEND_RECEIVE_DURATION_MS = 10;
+ private static final int COMMAND_SEND_RECEIVE_DURATION_MAX = 1000;
+ private static final int COMMAND_POLL_QUEUE_MS = 10;
+
+ private final String ipAddress;
+ private final int portNumber;
+
+ private boolean isStart = false;
+ private Socket socket = null;
+ private DataOutputStream dos = null;
+ private BufferedReader bufferedReader = null;
+ private int sequenceNumber = SEQUENCE_START_NUMBER;
+ private Queue<IFujiXCommand> commandQueue;
+
+
+ public FujiXCommandPublisher(@NonNull String ip, int portNumber)
+ {
+ this.ipAddress = ip;
+ this.portNumber = portNumber;
+ this.commandQueue = new ArrayDeque<>();
+ commandQueue.clear();
+ }
+
+ @Override
+ public boolean isConnected()
+ {
+ return (socket != null);
+ }
+
+ @Override
+ public boolean connect()
+ {
+ try
+ {
+ socket = new Socket(ipAddress, portNumber);
+ return (true);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ socket = null;
+ }
+ return (false);
+ }
+
+ @Override
+ public void disconnect()
+ {
+ // ストリームを全部閉じる
+ try
+ {
+ dos.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ dos = null;
+
+ try
+ {
+ bufferedReader.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ bufferedReader = null;
+
+ try
+ {
+ socket.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ socket = null;
+ sequenceNumber = SEQUENCE_START_NUMBER;
+ System.gc();
+ }
+
+ @Override
+ public void start()
+ {
+ if (isStart)
+ {
+ // すでにコマンドのスレッド動作中なので抜ける
+ return;
+ }
+ isStart = true;
+ Thread thread = new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ while (isStart)
+ {
+ try
+ {
+ IFujiXCommand command = commandQueue.poll();
+ if (command != null)
+ {
+ issueCommand(command);
+ }
+ Thread.sleep(COMMAND_POLL_QUEUE_MS);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Log.v(TAG, "<<<<< IP : " + ipAddress + " port : " + portNumber + " >>>>>");
+ e.printStackTrace();
+ }
+ }
+ });
+ try
+ {
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void stop()
+ {
+ isStart = false;
+ commandQueue.clear();
+ }
+
+ @Override
+ public boolean enqueueCommand(@NonNull IFujiXCommand command)
+ {
+ try
+ {
+ //Log.v(TAG, "Enqueue : " + command.getId());
+ return (commandQueue.offer(command));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return (false);
+ }
+
+ private void issueCommand(@NonNull IFujiXCommand command)
+ {
+ try
+ {
+ //Log.v(TAG, "issueCommand : " + command.getId());
+ byte[] commandBody = command.commandBody();
+ if (commandBody != null)
+ {
+ // コマンドボディが入っていた場合には、コマンド送信(入っていない場合は受信待ち)
+ send_to_camera(command.dumpLog(), commandBody, command.useSequenceNumber());
+ byte[] commandBody2 = command.commandBody2();
+ if (commandBody2 != null)
+ {
+ // コマンドボディの2つめが入っていた場合には、コマンドを連続送信する
+ send_to_camera(command.dumpLog(), commandBody2, command.useSequenceNumber());
+ }
+ if (command.isIncrementSeqNumber())
+ {
+ // シーケンス番号を更新する
+ sequenceNumber++;
+ }
+ }
+ int delayMs = command.receiveDelayMs();
+ if ((delayMs < 0)||(delayMs > COMMAND_SEND_RECEIVE_DURATION_MAX))
+ {
+ delayMs = COMMAND_SEND_RECEIVE_DURATION_MS;
+ }
+ receive_from_camera(command.dumpLog(), command.getId(), command.responseCallback(), command.receiveAgainShortLengthMessage(), delayMs);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * カメラにコマンドを送信する(メイン部分)
+ *
+ */
+ private void send_to_camera(boolean isDumpReceiveLog, byte[] byte_array, boolean useSequenceNumber)
+ {
+ try
+ {
+ dos = new DataOutputStream(socket.getOutputStream());
+
+ // メッセージボディを加工: 最初に4バイトのレングス長をつける
+ byte[] sendData = new byte[byte_array.length + 4];
+
+ sendData[0] = (byte) (byte_array.length + 4);
+ sendData[1] = 0x00;
+ sendData[2] = 0x00;
+ sendData[3] = 0x00;
+ System.arraycopy(byte_array,0,sendData,4, byte_array.length);
+
+ if (useSequenceNumber)
+ {
+ // Sequence Number を反映させる
+ sendData[8] = (byte) ((0x000000ff & sequenceNumber));
+ sendData[9] = (byte) (((0x0000ff00 & sequenceNumber) >>> 8) & 0x000000ff);
+ sendData[10] = (byte) (((0x00ff0000 & sequenceNumber) >>> 16) & 0x000000ff);
+ sendData[11] = (byte) (((0xff000000 & sequenceNumber) >>> 24) & 0x000000ff);
+ if (isDumpReceiveLog)
+ {
+ Log.v(TAG, "SEQ No. : " + sequenceNumber);
+ }
+ }
+
+ if (isDumpReceiveLog)
+ {
+ // ログに送信メッセージを出力する
+ dump_bytes("SEND[" + sendData.length + "] ", sendData);
+ }
+
+ // (データを)送信
+ dos.write(sendData);
+ dos.flush();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void sleep(int delayMs)
+ {
+ try
+ {
+ Thread.sleep(delayMs);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * カメラからにコマンドの結果を受信する(メイン部分)
+ *
+ */
+ private void receive_from_camera(boolean isDumpReceiveLog, int id, IFujiXCommandCallback callback, boolean receiveAgain, int delayMs)
+ {
+ try
+ {
+ sleep(delayMs);
+ byte[] byte_array = new byte[BUFFER_SIZE];
+ InputStream is = socket.getInputStream();
+ if (is != null)
+ {
+ int read_bytes = is.read(byte_array, 0, BUFFER_SIZE);
+ byte[] receive_body;
+ if (read_bytes > 4)
+ {
+ if (receiveAgain)
+ {
+ int length = ((((int) byte_array[3]) & 0xff) << 24) + ((((int) byte_array[2]) & 0xff) << 16) + ((((int) byte_array[1]) & 0xff) << 8) + (((int) byte_array[0]) & 0xff);
+ if ((length > read_bytes)||((length == read_bytes)&&((int) byte_array[4] == 0x02)))
+ {
+ // データについて、もう一回受信が必要な場合...
+ if (isDumpReceiveLog)
+ {
+ Log.v(TAG, "--- RECEIVE AGAIN --- [" + length + "(" + read_bytes + ") " + byte_array[4]+ "] ");
+ }
+ sleep(delayMs);
+ int read_bytes2 = is.read(byte_array, read_bytes, BUFFER_SIZE - read_bytes);
+ if (read_bytes2 > 0)
+ {
+ read_bytes = read_bytes + read_bytes2;
+ }
+ }
+ }
+ receive_body = Arrays.copyOfRange(byte_array, 0, read_bytes);
+ }
+ else
+ {
+ receive_body = new byte[1];
+ }
+ if (isDumpReceiveLog)
+ {
+ // ログに受信メッセージを出力する
+ Log.v(TAG, "receive_from_camera() : " + read_bytes + " bytes.");
+ dump_bytes("RECV[" + receive_body.length + "] ", receive_body);
+ }
+ if (callback != null)
+ {
+ callback.receivedMessage(id, receive_body);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * デバッグ用:ログにバイト列を出力する
+ *
+ */
+ private void dump_bytes(String header, byte[] data)
+ {
+ int index = 0;
+ StringBuffer message;
+ message = new StringBuffer();
+ for (byte item : data)
+ {
+ index++;
+ message.append(String.format("%02x ", item));
+ if (index >= 8)
+ {
+ Log.v(TAG, header + " " + message);
+ index = 0;
+ message = new StringBuffer();
+ }
+ }
+ if (index != 0)
+ {
+ Log.v(TAG, header + " " + message);
+ }
+ System.gc();
+ }
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXBatteryMode
+{
+ int BATTERY_CRITICAL =1;
+ int BATTERY_ONE_BAR =2;
+ int BATTERY_TWO_BAR =3;
+ int BATTERY_FULL =4;
+ int BATTERY_126S_CRITICAL =6;
+ int BATTERY_126S_ONE_BAR =7;
+ int BATTERY_126S_TWO_BAR =8;
+ int BATTERY_126S_THREE_BAR =9;
+ int BATTERY_126S_FOUR_BAR =10;
+ int BATTERY_126S_FULL =11;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXCameraProperties
+{
+ int BATTERY_LEVEL = 0x5001;
+ int WHITE_BALANCE = 0x5005;
+ int APERTURE = 0x5007;
+ int FOCUS_MODE = 0x500a;
+ int SHOOTING_MODE = 0x500e;
+ int FLASH = 0x500c;
+ int EXPOSURE_COMPENSATION = 0x5010;
+ int SELF_TIMER = 0x5012;
+ int FILM_SIMULATION = 0xd001;
+ int IMAGE_FORMAT = 0xd018;
+ int RECMODE_ENABLE = 0xd019;
+ int F_SS_CONTROL = 0xd028;
+ int ISO = 0xd02a;
+ int MOVIE_ISO = 0xd02b;
+ int FOCUS_POINT = 0xd17c;
+ int FOCUS_LOCK = 0xd209;
+ int DEVICE_ERROR = 0xd21b;
+ int IMAGE_FILE_COUNT = 0xd222;
+ int SDCARD_REMAIN_SIZE = 0xd229;
+ int MOVIE_REMAINING_TIME = 0xd22a;
+ int SHUTTER_SPEED = 0xd240;
+ int IMAGE_ASPECT = 0xd241;
+ int BATTERY_LEVEL_2 = 0xd242;
+ int UNKNOWN_DF00 = 0xdf00;
+ int PICTURE_JPEG_COUNT = 0xd220;
+ int UNKNOWN_D400 = 0xd400;
+ int UNKNOWN_D401 = 0xd401;
+ int UNKNOWN_D52F = 0xd52f;
+
+
+
+ String BATTERY_LEVEL_STR = "Battery";
+ String WHITE_BALANCE_STR = "WhiteBalance";
+ String APERTURE_STR = "Aperture";
+ String FOCUS_MODE_STR = "FocusMode";
+ String SHOOTING_MODE_STR = "ShootingMode";
+ String FLASH_STR = "FlashMode";
+ String EXPOSURE_COMPENSATION_STR = "ExposureCompensation";
+ String SELF_TIMER_STR = "SelfTimer";
+ String FILM_SIMULATION_STR = "FilmSimulation";
+ String IMAGE_FORMAT_STR = "ImageFormat";
+ String RECMODE_ENABLE_STR = "RecModeEnable";
+ String F_SS_CONTROL_STR = "F_SS_Control";
+ String ISO_STR = "Iso";
+ String MOVIE_ISO_STR = "MovieIso";
+ String FOCUS_POINT_STR = "FocusPoint";
+ String FOCUS_LOCK_STR = "FocusLock";
+ String DEVICE_ERROR_STR = "DeviceError";
+ String IMAGE_FILE_COUNT_STR = "ImageFileCount";
+ String SDCARD_REMAIN_SIZE_STR = "ImageRemainCount";
+ String MOVIE_REMAINING_TIME_STR = "MovieRemainTime";
+ String SHUTTER_SPEED_STR = "ShutterSpeed";
+ String IMAGE_ASPECT_STR = "ImageAspect";
+ String BATTERY_LEVEL_2_STR = "BatteryLevel";
+
+ String UNKNOWN_DF00_STR = "0xdf00";
+ String PICTURE_JPEG_COUNT_STR = "PictureCount";
+ String UNKNOWN_D400_STR = "0xd400";
+ String UNKNOWN_D401_STR = "0xd401";
+ String UNKNOWN_D52F_STR = "0xd52f";
+
+
+ String BATTERY_LEVEL_STR_ID = "0x5001";
+ String WHITE_BALANCE_STR_ID = "0x5005";
+ String APERTURE_STR_ID = "0x5007";
+ String FOCUS_MODE_STR_ID = "0x500a";
+ String SHOOTING_MODE_STR_ID = "0x500e";
+ String FLASH_STR_ID = "0x500c";
+ String EXPOSURE_COMPENSATION_STR_ID = "0x5010";
+ String SELF_TIMER_STR_ID = "0x5012";
+ String FILM_SIMULATION_STR_ID = "0xd001";
+ String IMAGE_FORMAT_STR_ID = "0xd018";
+ String RECMODE_ENABLE_STR_ID = "0xd019";
+ String F_SS_CONTROL_STR_ID = "0xd028";
+ String ISO_STR_ID = "0xd02a";
+ String MOVIE_ISO_STR_ID = "0xd02b";
+ String FOCUS_POINT_STR_ID = "0xd17c";
+ String FOCUS_LOCK_STR_ID = "0xd209";
+ String DEVICE_ERROR_STR_ID = "0xd21b";
+ String IMAGE_FILE_COUNT_STR_ID = "0xd222";
+ String SDCARD_REMAIN_SIZE_STR_ID = "0xd229";
+ String MOVIE_REMAINING_TIME_STR_ID = "0xd22a";
+ String SHUTTER_SPEED_STR_ID = "0xd240";
+ String IMAGE_ASPECT_STR_ID = "0xd241";
+ String BATTERY_LEVEL_2_STR_ID = "0xd242";
+
+ String UNKNOWN_DF00_STR_ID = "0xdf00";
+ String PICTURE_JPEG_COUNT_STR_ID = "0xd220";
+ String UNKNOWN_D400_STR_ID = "0xd400";
+ String UNKNOWN_D401_STR_ID = "0xd401";
+ String UNKNOWN_D52F_STR_ID = "0xd52f";
+
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXFSSControl
+{
+ int F_SS_CTRL_BOTH = 0;
+ int F_SS_CTRL_F = 1;
+ int F_SS_CTRL_SS = 2;
+ int F_SS_CTRL_NONE = 3;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXFilmSimulation
+{
+ int FILM_SIMULATION_MIN = 1;
+ int FILM_SIMULATION_PROVIA =1;
+ int FILM_SIMULATION_VELVIA =2;
+ int FILM_SIMULATION_ASTIA =3;
+ int FILM_SIMULATION_MONOCHROME =4;
+ int FILM_SIMULATION_SEPIA =5;
+ int FILM_SIMULATION_PRO_NEG_HI =6;
+ int FILM_SIMULATION_PRO_NEG_STD =7;
+ int FILM_SIMULATION_MONOCHROME_Y_FILTER =8;
+ int FILM_SIMULATION_MONOCHROME_R_FILTER =9;
+ int FILM_SIMULATION_MONOCHROME_G_FILTER =10;
+ int FILM_SIMULATION_CLASSIC_CHROME =11;
+ int FILM_SIMULATION_ACROS =12;
+ int FILM_SIMULATION_ACROS_Y =13;
+ int FILM_SIMULATION_ACROS_R =14;
+ int FILM_SIMULATION_ACROS_G =15;
+ int FILM_SIMULATION_ETERNA =16;
+ int FILM_SIMULATION_MAX = 17;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXFlashMode
+{
+ int FLASH_AUTO =1;
+ int FLASH_OFF =2;
+ int FLASH_FILL =3;
+ int FLASH_REDEYE_AUTO =4;
+ int FLASH_REDEYE_FILL =5;
+ int FLASH_EXTERNAL_SYNC =6;
+ int FLASH_ON =0x8001;
+ int FLASH_REDEYE =0x8002;
+ int FLASH_REDEYE_ON =0x8003;
+ int FLASH_REDEYE_SYNC =0x8004;
+ int FLASH_REDEYE_REAR =0x8005;
+ int FLASH_SLOW_SYNC =0x8006;
+ int FLASH_REAR_SYNC =0x8007;
+ int FLASH_COMMANDER =0x8008;
+ int FLASH_DISABLE =0x8009;
+ int FLASH_ENABLE =0x800a;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXFocusingMode
+{
+ int FOCUS_MANUAL = 1;
+ int FOCUS_SINGLE_AUTO = 0x8001;
+ int FOCUS_CONTINUOUS_AUTO = 0x8002;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXImageAspectMode
+{
+ int IMAGE_ASPECT_MIN = 2;
+ int IMAGE_ASPECT_S_3x2 = 2;
+ int IMAGE_ASPECT_S_16x9 = 3;
+ int IMAGE_ASPECT_S_1x1 = 4;
+ int IMAGE_ASPECT_M_3x2 = 6;
+ int IMAGE_ASPECT_M_16x9 = 7;
+ int IMAGE_ASPECT_M_1x1 = 8;
+ int IMAGE_ASPECT_L_3x2 = 10;
+ int IMAGE_ASPECT_L_16x9 = 11;
+ int IMAGE_ASPECT_L_1x1 = 12;
+ int IMAGE_ASPECT_MAX = 12;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXImageFormatMode
+{
+ int IMAGE_FORMAT_FINE = 2;
+ int IMAGE_FORMAT_NORMAL = 3;
+ int IMAGE_FORMAT_FINE_RAW = 4;
+ int IMAGE_FORMAT_NORMAL_RAW = 5;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXShootingMode
+{
+ int SHOOTING_MANUAL = 1;
+ int SHOOTING_PROGRAM = 2;
+ int SHOOTING_APERTURE = 3;
+ int SHOOTING_SHUTTER = 4;
+ int SHOOTING_CUSTOM = 5;
+ int SHOOTING_AUTO = 6;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXTimerMode
+{
+ int TIMER_OFF =0;
+ int TIMER_1SEC =1;
+ int TIMER_2SEC =2;
+ int TIMER_5SEC =3;
+ int TIMER_10SEC =4;
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values;
+
+public interface IFujiXWhiteBalanceMode
+{
+ int WHITE_BALANCE_AUTO = 2;
+ int WHITE_BALANCE_FINE = 4;
+ int WHITE_BALANCE_INCANDESCENT = 6;
+ int WHITE_BALANCE_FLUORESCENT_1 = 0x8001;
+ int WHITE_BALANCE_FLUORESCENT_2 = 0x8002;
+ int WHITE_BALANCE_FLUORESCENT_3 = 0x8003;
+ int WHITE_BALANCE_SHADE = 0x8006;
+ int WHITE_BALANCE_UNDERWATER = 0x800a;
+ int WHITE_BALANCE_TEMPERATURE = 0x800b;
+ int WHITE_BALANCE_CUSTOM =0X800c;
+}
}
}
+ @Override
+ public void halfPressShutter(boolean isPressed)
+ {
+
+ }
+
}
{
afControl.unlockAutoFocus();
}
+
+ @Override
+ public void halfPressShutter(boolean isPressed)
+ {
+
+ }
}
import android.app.Activity;
import android.content.SharedPreferences;
+import android.os.Vibrator;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
+import static android.content.Context.VIBRATOR_SERVICE;
+
/**
*
*
public void onClick(View view)
{
int id = view.getId();
+ boolean isVibrate = true;
//Log.v(TAG, "onClick() : " + id);
try
{
case R.id.hideControlPanelTextView:
// 制御パネルを隠す
showHideControlPanel(false);
+ isVibrate = false;
break;
case R.id.showControlPanelTextView:
// 制御パネルを表示する
showHideControlPanel(true);
+ isVibrate = false;
break;
case R.id.showKeyPanelImageView:
// キーパネルを表示する
showHideKeyPanel(true);
+ isVibrate = false;
break;
case R.id.hideKeyPanelTextView:
// キーパネルを隠す
showHideKeyPanel(false);
+ isVibrate = false;
break;
case R.id.connect_disconnect_button:
// カメラと接続・切断のボタンが押された
changeScene.changeCameraConnection();
+ //isVibrate = true;
break;
case R.id.shutter_button:
// シャッターボタンが押された (撮影)
pushedShutterButton();
+ isVibrate = false;
break;
case R.id.focusUnlockImageView:
// フォーカスアンロックボタンが押された
pushedFocusUnlock();
+ isVibrate = false;
break;
case R.id.show_images_button:
// 画像一覧表示ボタンが押された...画像一覧画面を開く
changeScene.changeScenceToImageList();
+ //isVibrate = true;
break;
case R.id.camera_power_off_button:
// 電源ボタンが押された...終了してよいか確認して、終了する
confirmExitApplication();
+ //isVibrate = true;
break;
case R.id.show_preference_button:
// カメラの設定
changeScene.changeSceneToConfiguration();
+ //isVibrate = true;
break;
case R.id.show_hide_grid_button:
// グリッドの ON/OFF
statusNotify.toggleShowGridFrame();
statusViewDrawer.updateGridIcon();
+ isVibrate = false;
break;
case R.id.zoom_in_button:
// ズームインのボタンが押された
actionZoomin();
+ isVibrate = false;
break;
case R.id.zoom_out_button:
// ズームアウトのボタンが押された
actionZoomout();
+ isVibrate = false;
break;
case R.id.specialButtonImageView:
// スペシャルボタンが押された
pushedSpecialButton();
+ isVibrate = false;
break;
/*
case R.id.camera_property_settings_button:
// カメラのプロパティ設定
changeScene.changeSceneToCameraPropertyList();
+ isVibrate = false;
break;
case R.id.focusing_button:
// AF と MFの切り替えボタンが押された
changeFocusingMode();
+ isVibrate = false;
break;
case R.id.live_view_scale_button:
// ライブビューの倍率を更新する
statusViewDrawer.updateLiveViewScale(true);
+ isVibrate = false;
break;
case R.id.show_favorite_settings_button:
// お気に入り設定のダイアログを表示する
showFavoriteDialog();
+ isVibrate = false;
break;
*/
default:
Log.v(TAG, "onClick() : " + id);
+ isVibrate = false;
break;
}
+ if (isVibrate)
+ {
+ vibrate();
+ }
}
catch (Exception e)
{
{
// 確認ダイアログの生成と表示
ConfirmationDialog dialog = ConfirmationDialog.newInstance(context);
- dialog.show(R.string.dialog_title_confirmation, R.string.dialog_message_power_off, new ConfirmationDialog.Callback() {
+ dialog.show(R.string.dialog_title_confirmation, R.string.dialog_message_exit, new ConfirmationDialog.Callback() {
@Override
public void confirm()
{
}
return (false);
}
+
+
+ /**
+ *
+ *
+ */
+ private void vibrate()
+ {
+ try {
+ Vibrator vibrator = (Vibrator) context.getSystemService(VIBRATOR_SERVICE);
+ if (vibrator != null)
+ {
+ vibrator.vibrate(50);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
}