OSDN Git Service

一覧取得のところまで...。
authorMRSa <mrsa@myad.jp>
Sat, 21 Sep 2019 09:50:22 +0000 (18:50 +0900)
committerMRSa <mrsa@myad.jp>
Sat, 21 Sep 2019 09:50:22 +0000 (18:50 +0900)
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/command/IPtpIpMessages.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/CanonImageObjectReceiver.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpImageContentInfo.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpPlaybackControl.java

index 3995074..d92a359 100644 (file)
@@ -16,6 +16,9 @@ public interface IPtpIpMessages
     int GET_STORAGE_ID = 101;
     int GET_STORAGE_INFO = 102;
     int GET_OBJECT_INFO_EX = 103;
+    int GET_OBJECT_INFO_EX_2 = 104;
+    int GET_OBJECT_INFO_EX_3 = 105;
+
 /*
     int SEQ_REGISTRATION = 1;
     int SEQ_START = 2;
index 8cbaa74..f619e41 100644 (file)
@@ -1,17 +1,20 @@
 package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
 
-import android.app.Activity;
 import android.util.Log;
-import android.util.SparseArray;
 
 import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection;
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent;
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback;
-import net.osdn.gokigen.pkremote.camera.utils.SimpleLogDumper;
 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpInterfaceProvider;
 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX_2;
+import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX_3;
 import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_ID;
 import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_INFO;
 import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX;
@@ -19,35 +22,89 @@ import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtp
 public class CanonImageObjectReceiver implements IPtpIpCommandCallback
 {
     private final String TAG = toString();
-    private final Activity activity;
     private final PtpIpInterfaceProvider provider;
+    private List<ICameraContent> imageObjectList;
+    private List<PtpIpImageContentInfo> ptpIpImageObjectList;
+    private ICameraContentListCallback callback = null;
+    private int subDirectoriesCount = -1;
+    private int receivedSubDirectoriesCount = -1;
 
-    CanonImageObjectReceiver(Activity activity, PtpIpInterfaceProvider provider)
+    CanonImageObjectReceiver(PtpIpInterfaceProvider provider)
     {
-        this.activity = activity;
         this.provider = provider;
-
+        this.imageObjectList = new ArrayList<>();
+        this.ptpIpImageObjectList = new ArrayList<>();
     }
 
-
     @Override
     public void receivedMessage(int id, byte[] rx_body)
     {
         try
         {
             IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
-            SimpleLogDumper.dump_bytes(" [RX] ", rx_body);
+            //SimpleLogDumper.dump_bytes(" [RX] ", rx_body);
             switch (id)
             {
                 case GET_STORAGE_ID:
+                    // TODO: ストレージのIDを 0x00100010 で固定にしている。複数スロットある場合もあるので、このタイミングでちゃんと応答を parse してループさせる必要がある
                     publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_INFO, 0x9102, 4, 0x00010001));
+                    subDirectoriesCount = -1;  // ここから画像取得シーケンスに入るので、、、
                     break;
 
                 case GET_STORAGE_INFO:
+                    // TODO: (要検討) ストレージの情報を取得しているが、本当に使わなくてもよい?
                     publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX, 0x9109, 12, 0x00010001, 0xffffffff, 0x00200000));
                     break;
 
                 case GET_OBJECT_INFO_EX:
+                    List<PtpIpImageContentInfo> directries =  parseContentSubdirectories(rx_body, 32);
+                    {
+                        // サブディレクトリの情報を拾う
+                        for (PtpIpImageContentInfo contentInfo : directries)
+                        {
+                            publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX_2, 0x9109, 12, 0x00010001, contentInfo.getId(), 0x00200000));
+                        }
+                    }
+                    break;
+
+                case GET_OBJECT_INFO_EX_2:
+                    List<PtpIpImageContentInfo> subDirectries =  parseContentSubdirectories(rx_body, 32);
+                    {
+                        // 画像の情報を拾う
+                        for (PtpIpImageContentInfo contentInfo : subDirectries)
+                        {
+                            publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX_3, 0x9109, 12, 0x00010001, contentInfo.getId(), 0x00200000));
+                        }
+                        subDirectoriesCount = subDirectries.size();
+                        receivedSubDirectoriesCount = 0;
+                        if (subDirectoriesCount <= 0)
+                        {
+                            // カメラの画像コンテンツが見つからなかった(サブディレクトリがなかった)...ここで画像解析終了の報告をする
+                            callback.onCompleted(imageObjectList);
+                        }
+                    }
+                    break;
+
+                case GET_OBJECT_INFO_EX_3:
+                    //
+                    Log.v(TAG, " --- CONTENT ---");
+                    List<PtpIpImageContentInfo> objects =  parseContentSubdirectories(rx_body, 32);
+                    if (objects.size() > 0)
+                    {
+                        imageObjectList.addAll(objects);
+                        ptpIpImageObjectList.addAll(objects);
+                    }
+                    receivedSubDirectoriesCount++;
+                    if (receivedSubDirectoriesCount >= subDirectoriesCount)
+                    {
+                        // 全コンテンツの受信成功
+                        if(this.callback != null)
+                        {
+                            callback.onCompleted(imageObjectList);
+                        }
+                    }
+                    break;
+
                 default:
                     break;
             }
@@ -58,10 +115,51 @@ public class CanonImageObjectReceiver implements IPtpIpCommandCallback
         }
     }
 
+    private List<PtpIpImageContentInfo> parseContentSubdirectories(byte[] rx_body, int offset)
+    {
+        List<PtpIpImageContentInfo> result = new ArrayList<>();
+        try
+        {
+            int nofObjects = (rx_body[offset] & 0xff);
+            nofObjects = nofObjects + ((rx_body[offset + 1]  & 0xff) << 8);
+            nofObjects = nofObjects + ((rx_body[offset + 2] & 0xff) << 16);
+            nofObjects = nofObjects + ((rx_body[offset + 3] & 0xff) << 24);
+
+            int dataIndex = offset + 4;
+            while (rx_body.length > dataIndex)
+            {
+                int objectSize = (rx_body[dataIndex++] & 0xff);
+                objectSize = objectSize + ((rx_body[dataIndex++]  & 0xff) << 8);
+                objectSize = objectSize + ((rx_body[dataIndex++] & 0xff) << 16);
+                objectSize = objectSize + ((rx_body[dataIndex++] & 0xff) << 24);
+                objectSize = objectSize - 4;  // 抽出したレングス長分減らず
+
+                int id = (rx_body[dataIndex] & 0xff);
+                id = id + ((rx_body[dataIndex + 1]  & 0xff) << 8);
+                id = id + ((rx_body[dataIndex + 2] & 0xff) << 16);
+                id = id + ((rx_body[dataIndex + 3] & 0xff) << 24);
+
+                PtpIpImageContentInfo content = new PtpIpImageContentInfo(id, rx_body, dataIndex, objectSize);
+                result.add(content);
+                dataIndex = dataIndex + objectSize;
+                if (result.size() >= nofObjects)
+                {
+                    // オブジェクトを全部切り出した
+                    break;
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return (result);
+    }
+
     @Override
     public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
     {
-
+        Log.v(TAG, "onReceiveProgress(" + currentBytes + "/" + totalBytes + ")");
     }
 
     @Override
@@ -70,8 +168,9 @@ public class CanonImageObjectReceiver implements IPtpIpCommandCallback
         return (false);
     }
 
-    void getCameraContents(SparseArray<PtpIpImageContentInfo> imageContentInfo, ICameraContentListCallback callback)
+    void getCameraContents(ICameraContentListCallback callback)
     {
+        this.callback = null;
         try
         {
             ICameraConnection connection = provider.getPtpIpCameraConnection();
@@ -84,7 +183,11 @@ public class CanonImageObjectReceiver implements IPtpIpCommandCallback
             IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
             if (publisher != null)
             {
+                // オブジェクト一覧をクリアする
+                this.imageObjectList.clear();
+                this.ptpIpImageObjectList.clear();
                 publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_ID, 0x9101));
+                this.callback = callback;
             }
         }
         catch (Exception e)
@@ -92,95 +195,4 @@ public class CanonImageObjectReceiver implements IPtpIpCommandCallback
             e.printStackTrace();
         }
     }
-
-/*
-    void getCameraContents(SparseArray<PtpIpImageContentInfo> imageContentInfo, ICameraContentListCallback callback)
-    {
-        int nofFiles = -1;
-        try
-        {
-            finishedCallback = callback;
-            ICameraStatus statusListHolder = provider.getCameraStatusListHolder();
-            if (statusListHolder != null) {
-                String count = statusListHolder.getStatus(IMAGE_FILE_COUNT_STR_ID);
-                nofFiles = Integer.parseInt(count);
-                Log.v(TAG, "getCameraContents() : " + nofFiles + " (" + count + ")");
-            }
-            Log.v(TAG, "getCameraContents() : DONE.");
-            if (nofFiles > 0)
-            {
-                // 件数ベースで取得する(情報は、後追いで反映させる...この方式だと、キューに積みまくってるが、、、)
-                checkImageFiles(nofFiles);
-            }
-            else
-            {
-                // 件数が不明だったら、1件づつインデックスの情報を取得する
-                checkImageFileAll();
-            }
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-            finishedCallback.onErrorOccurred(e);
-            finishedCallback = null;
-        }
-    }
-*/
-
-    /**
-     *   最初から取得可能なイメージ情報を(件数ベースで)取得する
-     *
-     */
-/*
-    private void checkImageFiles(int nofFiles)
-    {
-        try
-        {
-            imageContentInfo.clear();
-            //IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
-            //for (int index = nofFiles; index > 0; index--)
-            for (int index = 1; index <= nofFiles; index++)
-            {
-                // ファイル数分、仮のデータを生成する
-                imageContentInfo.append(index, new PtpIpImageContentInfo(index, null));
-
-                //ファイル名などを取得する (メッセージを積んでおく...でも遅くなるので、ここではやらない方がよいかな。)
-                //publisher.enqueueCommand(new GetImageInfo(index, index, info));
-            }
-
-            // インデックスデータがなくなったことを検出...データがそろったとして応答する。
-            Log.v(TAG, "IMAGE LIST : " + imageContentInfo.size() + " (" + nofFiles + ")");
-            finishedCallback.onCompleted(getCameraContentList());
-            finishedCallback = null;
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-*/
-
-    /**
-     *   最初から取得可能なイメージ情報をすべて取得する
-     *
-     */
-    private void checkImageFileAll()
-    {
-        try
-        {
-/*
-            imageContentInfo.clear();
-            indexNumber = 1;
-            IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
-            publisher.enqueueCommand(new GetImageInfo(indexNumber, indexNumber, this));
-*/
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-
-
 }
index 85ee3da..f757b2d 100644 (file)
@@ -3,40 +3,47 @@ package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
 import android.util.Log;
 
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent;
-import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
+import net.osdn.gokigen.pkremote.camera.utils.SimpleLogDumper;
 
-import java.text.SimpleDateFormat;
+import java.util.Arrays;
 import java.util.Date;
-import java.util.Locale;
 
-public class PtpIpImageContentInfo implements ICameraContent, IPtpIpCommandCallback
+
+
+/*
+  --- CONTENT (IMAGE OBJECTS) ---
+  0000:91 99 b8 01 01 00 01 00 01 38 00 00 00 00 00 00
+  0010:20 00 00 00 69 42 58 00 00 00 b8 01 90 99 b8 01
+  0020:49 4d 47 5f 32 34 35 37 2e 4a 50 47 00 00 00 00
+  0030:e6 6b 86 5d
+*/
+
+public class PtpIpImageContentInfo implements ICameraContent
 {
     private final String TAG = toString();
     private final int indexNumber;
-    private boolean isReceived = false;
-    private boolean isDateValid = false;
-    private Date date = null;
-    private String realFileName = null;
+    private boolean isDateValid;
+    private Date date;
+    private String realFileName;
     private byte[] rx_body;
-    PtpIpImageContentInfo(int indexNumber, byte[] rx_body)
+
+    PtpIpImageContentInfo(int indexNumber, byte[] binaryData, int offset, int length)
     {
         this.indexNumber = indexNumber;
-        this.rx_body = rx_body;
-        if (this.rx_body != null)
-        {
-            updateInformation(rx_body);
-        }
-        else
-        {
-            date = new Date();
-            isDateValid = false;
-        }
+        this.rx_body = Arrays.copyOfRange(binaryData, offset, offset + length);
+        Log.v(TAG, " --- CONTENT ---");
+        SimpleLogDumper.dump_bytes(" [(" + length + ")] ", this.rx_body);
+
+        //  動作用...
+        date = new Date();
+        isDateValid = false;
+        realFileName = "";
     }
 
     @Override
     public String getCameraId()
     {
-        return ("FujiX");
+        return ("Canon");
     }
 
     @Override
@@ -94,32 +101,12 @@ public class PtpIpImageContentInfo implements ICameraContent, IPtpIpCommandCallb
         }
     }
 
-    @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)
-    {
-        Log.v(TAG, "RX : " + indexNumber + "(" + id + ") " + rx_body.length + " bytes.");
-        this.rx_body = rx_body;
-        updateInformation(rx_body);
-
-    }
-
     public int getId()
     {
         return (indexNumber);
     }
 
+/*
     public boolean isReceived()
     {
         return (isReceived);
@@ -148,6 +135,7 @@ public class PtpIpImageContentInfo implements ICameraContent, IPtpIpCommandCallb
         }
     }
 
+ */
     /**
      *   文字列を無理やり切り出す...
      *
index 4185c10..72504e8 100644 (file)
@@ -1,10 +1,7 @@
 package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
 
 import android.app.Activity;
-import android.util.Log;
-import android.util.SparseArray;
 
-import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent;
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback;
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraFileInfo;
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IContentInfoCallback;
@@ -13,33 +10,33 @@ import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentList
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadThumbnailImageCallback;
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl;
 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpInterfaceProvider;
-import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
 
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCallback
+/**
+ *
+ *
+ */
+public class PtpIpPlaybackControl implements IPlaybackControl
 {
-    private final String TAG = toString();
-    private final Activity activity;
-    private final PtpIpInterfaceProvider provider;
+    //private final String TAG = toString();
+    //private final Activity activity;
+    //private final PtpIpInterfaceProvider provider;
     //private List<ICameraContent> imageInfo;
-    private SparseArray<PtpIpImageContentInfo> imageContentInfo;
-    private int indexNumber = 0;
-    private ICameraContentListCallback finishedCallback = null;
+    //private SparseArray<PtpIpImageContentInfo> imageContentInfo;
+    //private int indexNumber = 0;
+    //private ICameraContentListCallback finishedCallback = null;
     private CanonImageObjectReceiver canonImageObjectReceiver;
 
     public PtpIpPlaybackControl(Activity activity, PtpIpInterfaceProvider provider)
     {
-        this.activity = activity;
-        this.provider = provider;
-        canonImageObjectReceiver = new CanonImageObjectReceiver(activity, provider);
-        this.imageContentInfo = new SparseArray<>();
+        // this.activity = activity;
+        //this.provider = provider;
+        canonImageObjectReceiver = new CanonImageObjectReceiver(provider);
+        //this.imageContentInfo = new SparseArray<>();
     }
 
     @Override
-    public String getRawFileSuffix() {
+    public String getRawFileSuffix()
+    {
         return (null);
     }
 
@@ -72,9 +69,9 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
     @Override
     public void downloadContentThumbnail(String path, IDownloadThumbnailImageCallback callback)
     {
+/*
         try
         {
-/*
             int start = 0;
             if (path.indexOf("/") == 0)
             {
@@ -93,20 +90,20 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
                 }
                 publisher.enqueueCommand(new GetThumbNail(index, new PtpIpThumbnailImageReceiver(activity, callback)));
             }
-*/
         }
         catch (Exception e)
         {
             e.printStackTrace();
         }
+*/
     }
 
     @Override
     public void downloadContent(String path, boolean isSmallSize, IDownloadContentCallback callback)
     {
+/*
         try
         {
-/*
             int start = 0;
             if (path.indexOf("/") == 0)
             {
@@ -121,12 +118,12 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
                 IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
                 publisher.enqueueCommand(new GetFullImage(index, new PtpIpFullImageReceiver(callback)));
             }
-*/
         }
         catch (Exception e)
         {
             e.printStackTrace();
         }
+*/
     }
 
     @Override
@@ -142,7 +139,7 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
             Thread thread = new Thread(new Runnable() {
                 @Override
                 public void run() {
-                    canonImageObjectReceiver.getCameraContents(imageContentInfo, callback);
+                    canonImageObjectReceiver.getCameraContents(callback);
                 }
             });
             thread.start();
@@ -154,7 +151,7 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
         }
     }
 
-
+/*
     @Override
     public void onReceiveProgress(int currentBytes, int totalBytes, byte[] body)
     {
@@ -174,14 +171,13 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
         if (rx_body.length < 16)
         {
             // インデックスデータがなくなったことを検出...データがそろったとして応答する。
-            Log.v(TAG, "IMAGE LIST : " + imageContentInfo.size());
+            //Log.v(TAG, "IMAGE LIST : " + imageContentInfo.size());
             finishedCallback.onCompleted(getCameraContentList());
             finishedCallback = null;
             return;
         }
         try
         {
-/*
             Log.v(TAG, "RECEIVED IMAGE INFO : " + indexNumber);
 
             // 受信データを保管しておく
@@ -191,7 +187,6 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
             indexNumber++;
             IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
             publisher.enqueueCommand(new GetImageInfo(indexNumber, indexNumber, this));
-*/
         }
         catch (Exception e)
         {
@@ -201,7 +196,9 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
             finishedCallback = null;
         }
     }
+*/
 
+/*
     private List<ICameraContent> getCameraContentList()
     {
         /// ダサいけど...コンテナクラスを詰め替えて応答する
@@ -213,5 +210,6 @@ public class PtpIpPlaybackControl implements IPlaybackControl, IPtpIpCommandCall
         }
         return (contentList);
     }
+*/
 
 }