OSDN Git Service

いったん保管。
[gokigen/PKRemote.git] / app / src / main / java / net / osdn / gokigen / pkremote / camera / vendor / ptpip / wrapper / playback / PtpIpFullImageReceiver.java
1 package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
2
3 import android.app.Activity;
4 import android.util.Log;
5
6 import androidx.annotation.NonNull;
7
8 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentCallback;
9 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IProgressEvent;
10 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
11 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
12 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
13
14 import java.io.ByteArrayOutputStream;
15
16 public class PtpIpFullImageReceiver implements IPtpIpCommandCallback
17 {
18     private static final String TAG = PtpIpFullImageReceiver.class.getSimpleName();
19
20     private final Activity activity;
21     private final IPtpIpCommandPublisher publisher;
22     private IDownloadContentCallback callback = null;
23
24     private int objectId = 0;
25
26     private int received_total_bytes = 0;
27     private int received_remain_bytes = 0;
28
29     private int target_image_size = 0;
30
31     PtpIpFullImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher)
32     {
33         this.activity = activity;
34         this.publisher = publisher;
35     }
36
37     void issueCommand(int objectId, int imageSize, IDownloadContentCallback callback)
38     {
39         if (this.objectId != 0)
40         {
41             // already issued
42             Log.v(TAG, " COMMAND IS ALREADY ISSUED. : " + objectId);
43             return;
44         }
45         this.callback = callback;
46         this.objectId = objectId;
47         this.target_image_size = imageSize;
48
49         Log.v(TAG, " getPartialObject (id : " + objectId + ", size:" + imageSize + ")");
50         publisher.enqueueCommand(new PtpIpCommandGeneric(this, (objectId + 1), false, objectId, 0x9107, 12, objectId, 0x00, imageSize)); // 0x9107 : GetPartialObject
51     }
52
53     @Override
54     public void receivedMessage(int id, byte[] rx_body)
55     {
56         try
57         {
58             if (id == objectId + 1)
59             {
60                 getPartialObjectFinished();
61             }
62             else if (id == objectId + 2)
63             {
64                 Log.v(TAG, " RECEIVED  : " + id);
65
66                 // end of receive sequence.
67                 callback.onCompleted();
68                 target_image_size = 0;
69                 objectId = 0;
70                 callback = null;
71                 System.gc();
72             }
73             else
74             {
75                 Log.v(TAG, " RECEIVED UNKNOWN ID : " + id);
76             }
77         }
78         catch (Exception e)
79         {
80             e.printStackTrace();
81             {
82                 callback.onErrorOccurred(e);
83             }
84         }
85     }
86
87     @Override
88     public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
89     {
90         // 受信したデータから、通信のヘッダ部分を削除する
91         byte[] body = cutHeader(rx_body);
92         int length = (body == null) ? 0 : body.length;
93         Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes + " (" + length + " bytes.) : image : " + target_image_size);
94         callback.onProgress(body, length, new IProgressEvent() {
95             @Override
96             public float getProgress() {
97                 return ((float) currentBytes / (float) target_image_size);
98             }
99
100             @Override
101             public boolean isCancellable() {
102                 return (false);
103             }
104
105             @Override
106             public void requestCancellation() { }
107         });
108     }
109
110     private byte[] cutHeader(byte[] rx_body)
111     {
112         if (rx_body == null)
113         {
114             return (null);
115         }
116         int length = rx_body.length;
117         int data_position = 0;
118         ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
119         if (received_total_bytes == 0)
120         {
121             // データを最初に読んだとき。ヘッダ部分を読み飛ばす
122             data_position = (int) rx_body[0] & (0xff);
123         }
124         else if (received_remain_bytes > 0)
125         {
126             // データの読み込みが途中だった場合...
127             if (length < received_remain_bytes)
128             {
129                 // 全部コピーする、足りないバイト数は残す
130                 received_remain_bytes = received_remain_bytes - length;
131                 received_total_bytes = received_total_bytes + rx_body.length;
132                 return (rx_body);
133             }
134             else
135             {
136                 byteStream.write(rx_body, data_position, received_remain_bytes);
137                 data_position = received_remain_bytes;
138                 received_remain_bytes = 0;
139             }
140         }
141
142         while (data_position <= (length - 12))
143         {
144             int body_size =  (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1]  & 0xff) << 8) +
145                     ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
146             if (body_size <= 12)
147             {
148                 Log.v(TAG, " --- BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + "  (" + target_image_size + ")");
149                 //int startpos = (data_position > 48) ? (data_position - 48) : 0;
150                 //SimpleLogDumper.dump_bytes(" [xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
151                 break;
152             }
153
154             // 受信データ(のヘッダ部分)をダンプする
155             //Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
156             //SimpleLogDumper.dump_bytes(" [zzz] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 48)));
157
158             if ((data_position + body_size) > length)
159             {
160                 // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
161                 int copysize = (length - ((data_position + 12)));
162                 byteStream.write(rx_body, (data_position + 12), copysize);
163                 received_remain_bytes = body_size - copysize - 12;  // マイナス12は、ヘッダ分
164                 received_total_bytes = received_total_bytes + copysize;
165                 //Log.v(TAG, " ----- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + "  body size : " + body_size);
166                 break;
167             }
168             try
169             {
170                 byteStream.write(rx_body, (data_position + 12), (body_size - 12));
171                 data_position = data_position + body_size;
172                 received_total_bytes = received_total_bytes + 12;
173                 //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
174
175             }
176             catch (Exception e)
177             {
178                 Log.v(TAG, "  pos : " + data_position + "  size : " + body_size + " length : " + length);
179                 e.printStackTrace();
180             }
181         }
182         return (byteStream.toByteArray());
183     }
184
185     @Override
186     public boolean isReceiveMulti()
187     {
188         return (true);
189     }
190
191     private void getPartialObjectFinished()
192     {
193         try
194         {
195             //   すべてのデータを受信した後に...終わりを送信する
196             Log.v(TAG, " getPartialObjectFinished(), id : " + objectId + " (size : " + target_image_size + ")");
197             publisher.enqueueCommand(new PtpIpCommandGeneric(this,  (objectId + 2), false, objectId, 0x9117, 4,0x01));  // 0x9117 : TransferComplete
198         }
199         catch (Throwable t)
200         {
201             t.printStackTrace();
202             System.gc();
203         }
204     }
205 }