1 package net.osdn.gokigen.a01d.camera.nikon.operation;
3 import android.app.Activity;
4 import android.content.SharedPreferences;
5 import android.graphics.PointF;
6 import android.graphics.RectF;
7 import android.util.Log;
8 import android.view.MotionEvent;
10 import androidx.annotation.NonNull;
11 import androidx.preference.PreferenceManager;
13 import net.osdn.gokigen.a01d.camera.IFocusingControl;
14 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback;
15 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.PtpIpCommandPublisher;
16 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
17 import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay;
18 import net.osdn.gokigen.a01d.liveview.IIndicatorControl;
19 import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor;
21 public class NikonFocusingControl implements IFocusingControl, IPtpIpCommandCallback
23 private final String TAG = this.toString();
24 private static final int FOCUS_LOCK_PRE = 15;
25 private static final int FOCUS_LOCK = 16;
26 private static final int FOCUS_MOVE = 17;
27 private static final int FOCUS_UNLOCK = 18;
29 //private final Activity context;
30 private final PtpIpCommandPublisher commandPublisher;
31 private final IAutoFocusFrameDisplay frameDisplayer;
32 private final IIndicatorControl indicator;
34 private float maxPointLimitWidth;
35 private float maxPointLimitHeight;
36 private RectF preFocusFrameRect = null;
37 private boolean isDumpLog = false;
39 public NikonFocusingControl(@NonNull Activity context, @NonNull PtpIpCommandPublisher commandPublisher, IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator)
41 //this.context = context;
42 this.commandPublisher = commandPublisher;
43 this.frameDisplayer = frameDisplayer;
44 this.indicator = indicator;
47 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
48 String focusPoint = preferences.getString(IPreferencePropertyAccessor.NIKON_FOCUS_XY, IPreferencePropertyAccessor.NIKON_FOCUS_XY_DEFAULT_VALUE);
49 String[] focus = focusPoint.split(",");
50 if (focus.length == 2)
52 maxPointLimitWidth = Integer.parseInt(focus[0]);
53 maxPointLimitHeight = Integer.parseInt(focus[1]);
57 maxPointLimitWidth = 6000.0f;
58 maxPointLimitHeight = 4000.0f;
60 Log.v(TAG, "FOCUS RESOLUTION : " + maxPointLimitWidth + "," + maxPointLimitHeight);
65 maxPointLimitWidth = 6000.0f;
66 maxPointLimitHeight = 4000.0f;
71 public boolean driveAutoFocus(final MotionEvent motionEvent)
73 if (motionEvent.getAction() != MotionEvent.ACTION_DOWN)
77 Log.v(TAG, "driveAutoFocus()");
78 Thread thread = new Thread(new Runnable() {
83 PointF point = frameDisplayer.getPointWithEvent(motionEvent);
86 preFocusFrameRect = getPreFocusFrameRect(point);
87 showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Running, 0.0);
88 if (frameDisplayer.isContainsPoint(point))
112 public void unlockAutoFocus()
116 Log.v(TAG, " Unlock AF ");
117 commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_UNLOCK, isDumpLog, 0, 0x9206));
126 public void halfPressShutter(boolean isPressed)
129 commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_MOVE, isDumpLog, 0, 0x90c1));
130 //lockAutoFocus(new PointF(0.5f, 0.5f));
133 private void lockAutoFocus(PointF point)
137 int x = (0x0000ffff & (Math.round(point.x * maxPointLimitWidth) + 1));
138 int y = (0x0000ffff & (Math.round(point.y * maxPointLimitHeight) + 1));
139 Log.v(TAG, "Lock AF: [" + x + ","+ y + "]");
140 commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_LOCK, isDumpLog, 0, 0x9205, 8, x, y));
141 //commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_MOVE, isDumpLog, 0, 0x90c1));
153 private RectF getPreFocusFrameRect(@NonNull PointF point)
155 float imageWidth = frameDisplayer.getContentSizeWidth();
156 float imageHeight = frameDisplayer.getContentSizeHeight();
158 // Display a provisional focus frame at the touched point.
159 float focusWidth = 0.125f; // 0.125 is rough estimate.
160 float focusHeight = 0.125f;
161 if (imageWidth > imageHeight)
163 focusHeight *= (imageWidth / imageHeight);
167 focusHeight *= (imageHeight / imageWidth);
169 return (new RectF(point.x - focusWidth / 2.0f, point.y - focusHeight / 2.0f,
170 point.x + focusWidth / 2.0f, point.y + focusHeight / 2.0f));
177 private void showFocusFrame(RectF rect, IAutoFocusFrameDisplay.FocusFrameStatus status, double duration)
179 frameDisplayer.showFocusFrame(rect, status, duration);
180 indicator.onAfLockUpdate(IAutoFocusFrameDisplay.FocusFrameStatus.Focused == status);
187 private void hideFocusFrame()
189 frameDisplayer.hideFocusFrame();
190 indicator.onAfLockUpdate(false);
195 public void receivedMessage(int id, byte[] rx_body)
199 if (rx_body.length < 10)
201 Log.v(TAG, " --- BODY LENGTH IS SHORT : FOCUS OPERATION ---");
203 preFocusFrameRect = null;
206 int responseCode = (rx_body[8] & 0xff) + ((rx_body[9] & 0xff) * 256);
207 if (responseCode != 0x2001)
209 Log.v(TAG, String.format(" --- RECEIVED NG REPLY. : FOCUS OPERATION (0x%x) ---", responseCode));
211 preFocusFrameRect = null;
215 if ((id == FOCUS_LOCK)||(id == FOCUS_LOCK_PRE))
217 Log.v(TAG, "FOCUS LOCKED");
218 commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_MOVE, isDumpLog, 0, 0x90c1)); // OKのときは駆動
219 if (preFocusFrameRect != null)
221 // showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Focused, 1.0); // 1秒だけ表示
222 showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Focused, -1);
225 else if (id == FOCUS_MOVE)
227 Log.v(TAG, "FOCUS MOVED");
228 //if (preFocusFrameRect != null)
233 else // if (id == FOCUS_UNLOCK)
235 Log.v(TAG, "FOCUS UNLOCKED");
238 preFocusFrameRect = null;
247 public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
249 Log.v(TAG, " " + currentBytes + "/" + totalBytes);
253 public boolean isReceiveMulti()