OSDN Git Service

FUJIFILM用画像詳細画面で、タイミングによってはスモールイメージを使用できるようにした。
[gokigen/Gr2Control.git] / app / src / main / java / net / osdn / gokigen / gr2control / camera / fuji_x / wrapper / playback / FujiXPlaybackControl.java
1 package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.playback;
2
3 import android.app.Activity;
4 import android.content.SharedPreferences;
5 import android.util.Log;
6 import android.util.SparseArray;
7
8 import androidx.annotation.NonNull;
9 import androidx.annotation.Nullable;
10 import androidx.preference.PreferenceManager;
11
12 import net.osdn.gokigen.gr2control.camera.ICameraFileInfo;
13 import net.osdn.gokigen.gr2control.camera.ICameraStatus;
14 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.FujiXInterfaceProvider;
15 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
16 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandPublisher;
17 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.GetFullImage;
18 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.GetImageInfo;
19 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.GetScreenNail;
20 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.GetThumbNail;
21 import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.SetPropertyValue;
22 import net.osdn.gokigen.gr2control.camera.playback.ICameraContent;
23 import net.osdn.gokigen.gr2control.camera.playback.IContentInfoCallback;
24 import net.osdn.gokigen.gr2control.camera.playback.IDownloadContentCallback;
25 import net.osdn.gokigen.gr2control.camera.playback.ICameraContentListCallback;
26 import net.osdn.gokigen.gr2control.camera.playback.IDownloadThumbnailImageCallback;
27 import net.osdn.gokigen.gr2control.camera.playback.IPlaybackControl;
28 import net.osdn.gokigen.gr2control.preference.IPreferencePropertyAccessor;
29
30 import java.util.ArrayList;
31 import java.util.List;
32
33 import static net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.values.IFujiXCameraProperties.IMAGE_FILE_COUNT_STR_ID;
34
35 public class FujiXPlaybackControl implements IPlaybackControl, IFujiXCommandCallback
36 {
37     private final String TAG = toString();
38     private final Activity activity;
39     private final FujiXInterfaceProvider provider;
40     //private List<ICameraContent> imageInfo;
41     private SparseArray<FujiXImageContentInfo> imageContentInfo;
42
43     private int indexNumber = 0;
44     private ICameraContentListCallback finishedCallback = null;
45
46     public FujiXPlaybackControl(Activity activity, FujiXInterfaceProvider provider)
47     {
48         this.activity = activity;
49         this.provider = provider;
50         this.imageContentInfo = new SparseArray<>();
51     }
52
53     @Override
54     public String getRawFileSuffix() {
55         return (null);
56     }
57
58     @Override
59     public void downloadContentList(@NonNull final ICameraContentListCallback callback)
60     {
61         try
62         {
63             Thread thread = new Thread(new Runnable() {
64                 @Override
65                 public void run() {
66                     getCameraContents(callback);
67                 }
68             });
69             thread.start();
70         }
71         catch (Exception e)
72         {
73             e.printStackTrace();
74             callback.onErrorOccurred(e);
75         }
76     }
77
78     @Override
79     public void getContentInfo(@Nullable String path, @NonNull String name, @NonNull IContentInfoCallback callback)
80     {
81         // showFileInformation
82
83     }
84
85     @Override
86     public void updateCameraFileInfo(ICameraFileInfo info)
87     {
88         //  なにもしない
89         Log.v(TAG, " updateCameraFileInfo() : " + info.getDatetime());
90     }
91
92     @Override
93     public void downloadContentScreennail(@Nullable String path, @NonNull String name, @NonNull IDownloadThumbnailImageCallback callback)
94     {
95         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
96         boolean useSmallImage = preferences.getBoolean(IPreferencePropertyAccessor.FUJI_X_GET_SCREENNAIL_AS_SMALL_PICTURE, false);
97         if (useSmallImage)
98         {
99             // small image を表示する
100             downloadContentScreennailImpl(path, name, callback);
101         }
102         else
103         {
104             // Thumbnail と同じ画像を表示する
105             downloadContentThumbnail(path, name, callback);
106         }
107     }
108
109     private void downloadContentScreennailImpl(@Nullable String path, @NonNull String name, @NonNull IDownloadThumbnailImageCallback callback)
110     {
111         try
112         {
113             Log.v(TAG, " ----- downloadContentScreennailImpl() ");
114             int start = 0;
115             if (name.indexOf("/") == 0)
116             {
117                 start = 1;
118             }
119             Log.v(TAG, "  downloadContentThumbnail() : " + path + " " + name);
120             int index = getIndexNumber(start, name);
121             if ((index > 0)&&(index <= imageContentInfo.size()))
122             {
123                 IFujiXCommandPublisher publisher = provider.getCommandPublisher();
124                 FujiXImageContentInfo contentInfo = imageContentInfo.get(index);
125                 if (contentInfo.isReceived())
126                 {
127                     if (!contentInfo.isMovie())
128                     {
129                         // スモール画像を取得する (たぶんこのシーケンスでいけるはず...)
130                         publisher.enqueueCommand(new SetPropertyValue(new FujiXReplyReceiver(), 0xd226, 2, 0x0001));
131                         publisher.enqueueCommand(new SetPropertyValue(new FujiXReplyReceiver(), 0xd227, 2, 0x0001));
132                         publisher.enqueueCommand(new GetScreenNail(index, 0x00800000, new FujiXThumbnailImageReceiver(activity, callback)));
133                         publisher.enqueueCommand(new SetPropertyValue(new FujiXReplyReceiver(), 0xd226, 2, 0x0000));
134                         publisher.enqueueCommand(new SetPropertyValue(new FujiXReplyReceiver(), 0xd227, 2, 0x0001));
135                     }
136                     else
137                     {
138                         // movieの時は、Small画像を使えないのでThumbnailで代用する。
139                         publisher.enqueueCommand(new GetThumbNail(index, new FujiXThumbnailImageReceiver(activity, callback)));
140                     }
141                 }
142                 else
143                 {
144                     // まだ、ファイル情報を受信していない場合は、サムネイルの情報を流用する
145                     publisher.enqueueCommand(new GetImageInfo(index, index, contentInfo));
146                     publisher.enqueueCommand(new GetThumbNail(index, new FujiXThumbnailImageReceiver(activity, callback)));
147                 }
148             }
149         }
150         catch (Exception e)
151         {
152             e.printStackTrace();
153         }
154     }
155
156     @Override
157     public void downloadContentThumbnail(@Nullable String path, @NonNull String name, @NonNull IDownloadThumbnailImageCallback callback)
158     {
159         try
160         {
161             int start = 0;
162             if (name.indexOf("/") == 0)
163             {
164                 start = 1;
165             }
166             Log.v(TAG, "  downloadContentThumbnail() : " + path + " " + name);
167             int index = getIndexNumber(start, name);
168             if ((index > 0)&&(index <= imageContentInfo.size()))
169             {
170                 IFujiXCommandPublisher publisher = provider.getCommandPublisher();
171                 FujiXImageContentInfo contentInfo = imageContentInfo.get(index);
172                 if (!contentInfo.isReceived())
173                 {
174                     publisher.enqueueCommand(new GetImageInfo(index, index, contentInfo));
175                 }
176                 publisher.enqueueCommand(new GetThumbNail(index, new FujiXThumbnailImageReceiver(activity, callback)));
177             }
178         }
179         catch (Exception e)
180         {
181             e.printStackTrace();
182         }
183     }
184
185     @Override
186     public void downloadContent(@Nullable String path, @NonNull String name, boolean isSmallSize, @NonNull IDownloadContentCallback callback)
187     {
188         try
189         {
190             int start = 0;
191             if (name.indexOf("/") == 0)
192             {
193                 start = 1;
194             }
195             int index = getIndexNumber(start, name);
196             Log.v(TAG, "  FujiX::downloadContent() : " + path + " " + name + " " + index);
197             if ((index > 0)&&(index <= imageContentInfo.size()))
198             {
199                 IFujiXCommandPublisher publisher = provider.getCommandPublisher();
200                 publisher.enqueueCommand(new GetFullImage(index, new FujiXFullImageReceiver(callback)));
201             }
202         }
203         catch (Exception e)
204         {
205             e.printStackTrace();
206         }
207     }
208
209     private int getIndexNumber(int start, @NonNull String name)
210     {
211         String indexStr = name.substring(start, name.indexOf("."));
212         int indexNo = -1;
213         try
214         {
215             indexNo = Integer.parseInt(indexStr);
216         }
217         catch (Exception e)
218         {
219             //e.printStackTrace();
220         }
221         if (indexNo >= 0)
222         {
223             return (indexNo);
224         }
225         indexStr = name.substring(start);
226         int size = imageContentInfo.size();
227         for (int index = 0; index < size; index++)
228         {
229             FujiXImageContentInfo info = imageContentInfo.valueAt(index);
230             String contentName = info.getOriginalName();
231             if (indexStr.matches(contentName))
232             {
233                 return (info.getId());
234             }
235             Log.v(TAG, " contentName : " + contentName);
236         }
237         Log.v(TAG, "index is not found : " + name + " " + indexStr);
238         return (-1);
239     }
240
241     @Override
242     public void showPictureStarted()
243     {
244         try
245         {
246             Log.v(TAG, "   showPictureStarted() ");
247
248             IFujiXCommandPublisher publisher = provider.getCommandPublisher();
249             publisher.flushHoldQueue();
250             System.gc();
251         }
252         catch (Exception e)
253         {
254             e.printStackTrace();
255         }
256     }
257
258     @Override
259     public void showPictureFinished()
260     {
261         try
262         {
263             Log.v(TAG, "   showPictureFinished() ");
264
265             IFujiXCommandPublisher publisher = provider.getCommandPublisher();
266             publisher.flushHoldQueue();
267             System.gc();
268         }
269         catch (Exception e)
270         {
271             e.printStackTrace();
272         }
273     }
274
275     private void getCameraContents(ICameraContentListCallback callback)
276     {
277         int nofFiles = -1;
278         try {
279             finishedCallback = callback;
280             ICameraStatus statusListHolder = provider.getCameraStatusListHolder();
281             if (statusListHolder != null) {
282                 String count = statusListHolder.getStatus(IMAGE_FILE_COUNT_STR_ID);
283                 nofFiles = Integer.parseInt(count);
284                 Log.v(TAG, "getCameraContents() : " + nofFiles + " (" + count + ")");
285             }
286             Log.v(TAG, "getCameraContents() : DONE.");
287             if (nofFiles > 0)
288             {
289                 // 件数ベースで取得する(情報は、後追いで反映させる...この方式だと、キューに積みまくってるが、、、)
290                 checkImageFiles(nofFiles);
291             }
292             else
293             {
294                 // 件数が不明だったら、1件づつインデックスの情報を取得する
295                 checkImageFileAll();
296             }
297         }
298         catch (Exception e)
299         {
300             e.printStackTrace();
301             finishedCallback.onErrorOccurred(e);
302             finishedCallback = null;
303         }
304     }
305
306     /**
307      *   最初から取得可能なイメージ情報を(件数ベースで)取得する
308      *
309      */
310     private void checkImageFiles(int nofFiles)
311     {
312         try
313         {
314             imageContentInfo.clear();
315             //IFujiXCommandPublisher publisher = provider.getCommandPublisher();
316             //for (int index = nofFiles; index > 0; index--)
317             for (int index = 1; index <= nofFiles; index++)
318             {
319                 // ファイル数分、仮のデータを生成する
320                 imageContentInfo.append(index, new FujiXImageContentInfo(index, null));
321
322                 //ファイル名などを取得する (メッセージを積んでおく...でも遅くなるので、ここではやらない方がよいかな。)
323                 //publisher.enqueueCommand(new GetImageInfo(index, index, info));
324             }
325
326             // インデックスデータがなくなったことを検出...データがそろったとして応答する。
327             Log.v(TAG, "IMAGE LIST : " + imageContentInfo.size() + " (" + nofFiles + ")");
328             finishedCallback.onCompleted(getCameraFileInfoList());
329             finishedCallback = null;
330         }
331         catch (Exception e)
332         {
333             e.printStackTrace();
334         }
335     }
336
337     /**
338      *   最初から取得可能なイメージ情報をすべて取得する
339      *
340      */
341     private void checkImageFileAll()
342     {
343         try
344         {
345             imageContentInfo.clear();
346             indexNumber = 1;
347             IFujiXCommandPublisher publisher = provider.getCommandPublisher();
348             publisher.enqueueCommand(new GetImageInfo(indexNumber, indexNumber, this));
349         }
350         catch (Exception e)
351         {
352             e.printStackTrace();
353         }
354     }
355
356     @Override
357     public void onReceiveProgress(int currentBytes, int totalBytes, byte[] body)
358     {
359         Log.v(TAG, " " + currentBytes + "/" + totalBytes);
360     }
361
362     @Override
363     public boolean isReceiveMulti()
364     {
365         return (false);
366     }
367
368     @Override
369     public void receivedMessage(int id, byte[] rx_body)
370     {
371         // イメージ数の一覧が取得できなかった場合にここで作る。
372         if (rx_body.length < 16)
373         {
374             // インデックスデータがなくなったことを検出...データがそろったとして応答する。
375             Log.v(TAG, "IMAGE LIST : " + imageContentInfo.size());
376             finishedCallback.onCompleted(getCameraFileInfoList());
377             finishedCallback = null;
378             return;
379         }
380         try
381         {
382             Log.v(TAG, "RECEIVED IMAGE INFO : " + indexNumber);
383
384             // 受信データを保管しておく
385             imageContentInfo.append(indexNumber, new FujiXImageContentInfo(indexNumber, rx_body));
386
387             // 次のインデックスの情報を要求する
388             indexNumber++;
389             IFujiXCommandPublisher publisher = provider.getCommandPublisher();
390             publisher.enqueueCommand(new GetImageInfo(indexNumber, indexNumber, this));
391         }
392         catch (Exception e)
393         {
394             // エラーになったら、そこで終了にする
395             e.printStackTrace();
396             finishedCallback.onCompleted(getCameraFileInfoList());
397             finishedCallback = null;
398         }
399     }
400
401     private List<ICameraContent> getCameraContentList()
402     {
403         /// ダサいけど...コンテナクラスを詰め替えて応答する
404         List<ICameraContent> contentList = new ArrayList<>();
405         int listSize = imageContentInfo.size();
406         for(int index = 0; index < listSize; index++)
407         {
408             contentList.add(imageContentInfo.valueAt(index));
409         }
410         return (contentList);
411     }
412
413     private List<ICameraFileInfo> getCameraFileInfoList()
414     {
415         Log.v(TAG, " FujiXPlaybackControl::getCameraFileInfoList() ");
416         List<ICameraFileInfo> fileInfoList = new ArrayList<>();
417         try
418         {
419             int listSize = imageContentInfo.size();
420             for(int index = 0; index < listSize; index++)
421             {
422                 FujiXImageContentInfo info = imageContentInfo.valueAt(index);
423                 fileInfoList.add(info);
424             }
425         }
426         catch (Exception e)
427         {
428             e.printStackTrace();
429         }
430         return (fileInfoList);
431     }
432
433 }