OSDN Git Service

安定性調査中。
[gokigen/A01d.git] / app / src / main / java / net / osdn / gokigen / a01d / camera / nikon / operation / NikonFocusingControl.java
1 package net.osdn.gokigen.a01d.camera.nikon.operation;
2
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;
9
10 import androidx.annotation.NonNull;
11 import androidx.preference.PreferenceManager;
12
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;
20
21 public class NikonFocusingControl implements IFocusingControl, IPtpIpCommandCallback
22 {
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;
28
29     //private final Activity context;
30     private final PtpIpCommandPublisher commandPublisher;
31     private final IAutoFocusFrameDisplay frameDisplayer;
32     private final IIndicatorControl indicator;
33
34     private float maxPointLimitWidth;
35     private float maxPointLimitHeight;
36     private RectF preFocusFrameRect = null;
37     private boolean isDumpLog = false;
38
39     public NikonFocusingControl(@NonNull Activity context, @NonNull PtpIpCommandPublisher commandPublisher, IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator)
40     {
41         //this.context = context;
42         this.commandPublisher = commandPublisher;
43         this.frameDisplayer = frameDisplayer;
44         this.indicator = indicator;
45         try
46         {
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)
51             {
52                 maxPointLimitWidth = Integer.parseInt(focus[0]);
53                 maxPointLimitHeight = Integer.parseInt(focus[1]);
54             }
55             else
56             {
57                 maxPointLimitWidth = 6000.0f;
58                 maxPointLimitHeight = 4000.0f;
59             }
60             Log.v(TAG, "FOCUS RESOLUTION : " + maxPointLimitWidth + "," + maxPointLimitHeight);
61         }
62         catch (Exception e)
63         {
64             e.printStackTrace();
65             maxPointLimitWidth = 6000.0f;
66             maxPointLimitHeight = 4000.0f;
67         }
68     }
69
70     @Override
71     public boolean driveAutoFocus(final MotionEvent motionEvent)
72     {
73         if (motionEvent.getAction() != MotionEvent.ACTION_DOWN)
74         {
75             return (false);
76         }
77         Log.v(TAG, "driveAutoFocus()");
78         Thread thread = new Thread(new Runnable() {
79             @Override
80             public void run() {
81                 try
82                 {
83                     PointF point = frameDisplayer.getPointWithEvent(motionEvent);
84                     if (point != null)
85                     {
86                         preFocusFrameRect = getPreFocusFrameRect(point);
87                         showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Running, 0.0);
88                         if (frameDisplayer.isContainsPoint(point))
89                         {
90                             lockAutoFocus(point);
91                         }
92                     }
93                 }
94                 catch (Exception e)
95                 {
96                     e.printStackTrace();
97                 }
98             }
99         });
100         try
101         {
102             thread.start();
103         }
104         catch (Exception e)
105         {
106             e.printStackTrace();
107         }
108         return (false);
109     }
110
111     @Override
112     public void unlockAutoFocus()
113     {
114         try
115         {
116             Log.v(TAG, " Unlock AF ");
117             commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_UNLOCK, isDumpLog, 0, 0x9206));
118         }
119         catch (Exception e)
120         {
121             e.printStackTrace();
122         }
123     }
124
125     @Override
126     public void halfPressShutter(boolean isPressed)
127     {
128         //unlockAutoFocus();
129         commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_MOVE, isDumpLog, 0, 0x90c1));
130         //lockAutoFocus(new PointF(0.5f, 0.5f));
131     }
132
133     private void lockAutoFocus(PointF point)
134     {
135         try
136         {
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));
142         }
143         catch (Exception e)
144         {
145             e.printStackTrace();
146         }
147     }
148
149     /**
150      *
151      *
152      */
153     private RectF getPreFocusFrameRect(@NonNull PointF point)
154     {
155         float imageWidth =  frameDisplayer.getContentSizeWidth();
156         float imageHeight =  frameDisplayer.getContentSizeHeight();
157
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)
162         {
163             focusHeight *= (imageWidth / imageHeight);
164         }
165         else
166         {
167             focusHeight *= (imageHeight / imageWidth);
168         }
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));
171     }
172
173     /**
174      *
175      *
176      */
177     private void showFocusFrame(RectF rect, IAutoFocusFrameDisplay.FocusFrameStatus status, double duration)
178     {
179         frameDisplayer.showFocusFrame(rect, status, duration);
180         indicator.onAfLockUpdate(IAutoFocusFrameDisplay.FocusFrameStatus.Focused == status);
181     }
182
183     /**
184      *
185      *
186      */
187     private void hideFocusFrame()
188     {
189         frameDisplayer.hideFocusFrame();
190         indicator.onAfLockUpdate(false);
191     }
192
193
194     @Override
195     public void receivedMessage(int id, byte[] rx_body)
196     {
197         try
198         {
199             if (rx_body.length < 10)
200             {
201                 Log.v(TAG, " --- BODY LENGTH IS SHORT : FOCUS OPERATION ---");
202                 hideFocusFrame();
203                 preFocusFrameRect = null;
204                 return;
205             }
206             int responseCode = (rx_body[8] & 0xff) + ((rx_body[9] & 0xff) * 256);
207             if (responseCode != 0x2001)
208             {
209                 Log.v(TAG, String.format(" --- RECEIVED NG REPLY. : FOCUS OPERATION (0x%x) ---", responseCode));
210                 hideFocusFrame();
211                 preFocusFrameRect = null;
212                 return;
213             }
214
215             if ((id == FOCUS_LOCK)||(id == FOCUS_LOCK_PRE))
216             {
217                 Log.v(TAG, "FOCUS LOCKED");
218                 commandPublisher.enqueueCommand(new PtpIpCommandGeneric(this, FOCUS_MOVE, isDumpLog, 0, 0x90c1));  // OKのときは駆動
219                 if (preFocusFrameRect != null)
220                 {
221                     // showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Focused, 1.0);  // 1秒だけ表示
222                     showFocusFrame(preFocusFrameRect, IAutoFocusFrameDisplay.FocusFrameStatus.Focused, -1);
223                 }
224             }
225             else if (id == FOCUS_MOVE)
226             {
227                 Log.v(TAG, "FOCUS MOVED");
228                 //if (preFocusFrameRect != null)
229                 //{
230                 //    hideFocusFrame();
231                 //}
232             }
233             else // if (id == FOCUS_UNLOCK)
234             {
235                 Log.v(TAG, "FOCUS UNLOCKED");
236                 hideFocusFrame();
237             }
238             preFocusFrameRect = null;
239         }
240         catch (Exception e)
241         {
242             e.printStackTrace();
243         }
244     }
245
246     @Override
247     public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
248     {
249         Log.v(TAG, " " + currentBytes + "/" + totalBytes);
250     }
251
252     @Override
253     public boolean isReceiveMulti()
254     {
255         return (false);
256     }
257 }