OSDN Git Service

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