OSDN Git Service

PowerShotZoomで動作するようにしてみる。
authorMRSa <mrsa@myad.jp>
Sat, 19 Dec 2020 15:15:17 +0000 (00:15 +0900)
committerMRSa <mrsa@myad.jp>
Sat, 19 Dec 2020 15:15:17 +0000 (00:15 +0900)
13 files changed:
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/CanonInterfaceProvider.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequence.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequenceType1.kt [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraDisconnectSequence.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonConnection.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewControl.java
app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/liveview/CanonLiveViewImageReceiver.kt
app/src/main/java/net/osdn/gokigen/a01d/preference/IPreferencePropertyAccessor.java
app/src/main/java/net/osdn/gokigen/a01d/preference/canon/CanonPreferenceFragment.java
app/src/main/res/values-ja/strings.xml
app/src/main/res/values/arrays.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/preferences_canon.xml

index 237e67c..edb0fab 100644 (file)
@@ -69,6 +69,8 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
 
         String ipAddress;
         int delayMs = 30;
+        int sequenceType = 0;
+        boolean isSearchJpegHeader = false;
         try
         {
             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
@@ -93,6 +95,23 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
             {
                 e.printStackTrace();
             }
+            try
+            {
+                String sequenceTypeStr = preferences.getString(IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE, IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE_DEFAULT_VALUE);
+                if (sequenceTypeStr != null)
+                {
+                    sequenceType = Integer.parseInt(sequenceTypeStr);
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+            if (sequenceType == 1)
+            {
+                Log.v(TAG, " --- search JPEG header : true ");
+                isSearchJpegHeader = true;
+            }
         }
         catch (Exception e)
         {
@@ -101,7 +120,7 @@ public class CanonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplay
         }
         Log.v(TAG, " Canon IP : " + ipAddress);
         commandPublisher = new PtpIpCommandPublisher(ipAddress, CONTROL_PORT, false, false);
-        liveViewControl = new CanonLiveViewControl(context, this, delayMs);  //
+        liveViewControl = new CanonLiveViewControl(context, this, delayMs, isSearchJpegHeader);  //
         asyncReceiver = new PtpIpAsyncResponseReceiver(ipAddress, ASYNC_RESPONSE_PORT);
         statusChecker = new CanonStatusChecker(context, commandPublisher, ipAddress, EVENT_PORT);
         canonConnection = new CanonConnection(context, provider, this, statusChecker);
index ff849c0..08872e6 100644 (file)
@@ -1,6 +1,5 @@
 package net.osdn.gokigen.a01d.camera.canon.wrapper.connection;
 
-
 import android.app.Activity;
 import android.graphics.Color;
 import android.util.Log;
@@ -19,6 +18,10 @@ import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages;
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
 
+/**
+ *   従来のCanonカメラ接続シーケンス
+ *
+ */
 public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallback, IPtpIpMessages
 {
     private final String TAG = this.toString();
@@ -157,8 +160,7 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
             case SEQ_GET_EVENT1:
                 Log.v(TAG, " SEQ_GET_EVENT1 ");
                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting7), false, false, 0);
-                //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
-                commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 0x1001));
+                commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
                 break;
 
             case SEQ_DEVICE_INFORMATION:
@@ -208,29 +210,9 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
             case SEQ_SET_DEVICE_PROPERTY_3:
                 Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_3 ");
                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0);
-                //commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 300, 0xd1b0, 0x08));
                 commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08));
                 break;
 
-            case SEQ_SET_REMOTE_SHOOTING_MODE:
-                Log.v(TAG, " SEQ_SET_REMOTE_SHOOTING_MODE ");
-                interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0);
-                try
-                {
-                    // ちょっと(250ms)待つ
-                    Thread.sleep(250);
-
-                    // コマンド発行
-                    //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 0x9086, 4, 0x00000001));
-                    commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x9086, 4, 0x00000001));
-
-                }
-                catch (Exception e)
-                {
-                    e.printStackTrace();
-                }
-                break;
-
             case SEQ_DEVICE_PROPERTY_FINISHED:
                 Log.v(TAG, " SEQ_DEVICE_PROPERTY_FINISHED ");
                 interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0);
@@ -293,7 +275,7 @@ public class CanonCameraConnectSequence implements Runnable, IPtpIpCommandCallba
             interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connected), false, false, 0);
 
             // ちょっと待つ
-            Thread.sleep(1000);
+            Thread.sleep(500);
 
             // 接続成功!のメッセージを出す
             interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.connect_connected), false, false, 0);
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequenceType1.kt b/app/src/main/java/net/osdn/gokigen/a01d/camera/canon/wrapper/connection/CanonCameraConnectSequenceType1.kt
new file mode 100644 (file)
index 0000000..1975d33
--- /dev/null
@@ -0,0 +1,264 @@
+package net.osdn.gokigen.a01d.camera.canon.wrapper.connection
+
+import android.app.Activity
+import android.graphics.Color
+import android.util.Log
+import net.osdn.gokigen.a01d.R
+import net.osdn.gokigen.a01d.camera.ICameraConnection
+import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver
+import net.osdn.gokigen.a01d.camera.canon.wrapper.command.messages.specific.CanonRegistrationMessage
+import net.osdn.gokigen.a01d.camera.canon.wrapper.command.messages.specific.CanonSetDevicePropertyValue
+import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker
+import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpMessages
+import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.messages.PtpIpCommandGeneric
+
+class CanonCameraConnectSequenceType1(val context: Activity, val cameraStatusReceiver: ICameraStatusReceiver, val cameraConnection: ICameraConnection, val interfaceProvider: IPtpIpInterfaceProvider, val statusChecker: CanonStatusChecker) : Runnable, IPtpIpCommandCallback, IPtpIpMessages
+{
+    private val isDumpLog = false
+    private val commandIssuer = interfaceProvider.commandPublisher
+
+    override fun run()
+    {
+        try
+        {
+            // カメラとTCP接続
+            val issuer = interfaceProvider.commandPublisher
+            if (!issuer.isConnected)
+            {
+                if (!interfaceProvider.commandCommunication.connect())
+                {
+                    // 接続失敗...
+                    interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.dialog_title_connect_failed_canon), false, true, Color.RED)
+                    cameraConnection.alertConnectingFailed(context.getString(R.string.dialog_title_connect_failed_canon))
+                    return
+                }
+            }
+            else
+            {
+                Log.v(TAG, "SOCKET IS ALREADY CONNECTED...")
+            }
+            // コマンドタスクの実行開始
+            issuer.start()
+
+            // 接続シーケンスの開始
+            sendRegistrationMessage()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+            interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.dialog_title_connect_failed_canon), false, true, Color.RED)
+            cameraConnection.alertConnectingFailed(e.message)
+        }
+    }
+
+    override fun onReceiveProgress(currentBytes: Int, totalBytes: Int, body: ByteArray?)
+    {
+        Log.v(TAG, " $currentBytes/$totalBytes")
+    }
+
+    override fun isReceiveMulti(): Boolean
+    {
+        return false
+    }
+
+    @ExperimentalUnsignedTypes
+    override fun receivedMessage(id: Int, rx_body: ByteArray)
+    {
+        when (id)
+        {
+            IPtpIpMessages.SEQ_REGISTRATION -> if (checkRegistrationMessage(rx_body)) {
+                    sendInitEventRequest(rx_body)
+            } else {
+                    cameraConnection.alertConnectingFailed(context.getString(R.string.connect_error_message))
+            }
+            IPtpIpMessages.SEQ_EVENT_INITIALIZE -> if (checkEventInitialize(rx_body)) {
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting1), false, false, 0)
+                commandIssuer!!.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41))
+            } else {
+                cameraConnection.alertConnectingFailed(context.getString(R.string.connect_error_message))
+            }
+            IPtpIpMessages.SEQ_OPEN_SESSION -> {
+                Log.v(TAG, " SEQ_OPEN_SESSION ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting2), false, false, 0)
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_INIT_SESSION, isDumpLog, 0, 0x902f))
+            }
+            IPtpIpMessages.SEQ_INIT_SESSION -> {
+                Log.v(TAG, " SEQ_INIT_SESSION ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting3), false, false, 0)
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_CHANGE_REMOTE, isDumpLog, 0, 0x9114, 4, 0x15))
+            }
+            IPtpIpMessages.SEQ_CHANGE_REMOTE -> {
+                Log.v(TAG, " SEQ_CHANGE_REMOTE ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting4), false, false, 0)
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_SET_EVENT_MODE, isDumpLog, 0, 0x9115, 4, 0x02))
+            }
+            IPtpIpMessages.SEQ_SET_EVENT_MODE -> {
+                Log.v(TAG, " SEQ_SET_EVENT_MODE ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting5), false, false, 0)
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_GET_EVENT, isDumpLog, 0, 0x913d, 4, 0x0fff))
+            }
+            IPtpIpMessages.SEQ_GET_EVENT -> {
+                Log.v(TAG, " SEQ_GET_EVENT ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting6), false, false, 0)
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_GET_EVENT1, isDumpLog, 0, 0x9033, 4, 0x00000000))
+            }
+            IPtpIpMessages.SEQ_GET_EVENT1 -> {
+                Log.v(TAG, " SEQ_GET_EVENT1 ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting7), false, false, 0)
+                //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x1001));
+                commandIssuer!!.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 0x1001))
+            }
+            IPtpIpMessages.SEQ_DEVICE_INFORMATION -> {
+                Log.v(TAG, " SEQ_DEVICE_INFORMATION ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting8), false, false, 0)
+                //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d1a6));
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d1a6))
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d169))
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d16a))
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d16b))
+                commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY, isDumpLog, 0, 0x9127, 4, 0x0000d1af))
+            }
+            IPtpIpMessages.SEQ_DEVICE_PROPERTY -> {
+                Log.v(TAG, " SEQ_DEVICE_PROPERTY ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting9), false, false, 0)
+                if (rx_body[8] == 0x01.toByte() && rx_body[9] == 0x20.toByte()) {
+                    // コマンドが受け付けられたときだけ次に進む!
+                    try {
+                        // ちょっと(250ms)待つ
+                        Thread.sleep(250)
+
+                        // コマンド発行
+                        commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY, isDumpLog, 0, 150, 0xd136, 0x00))
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                    }
+                }
+            }
+            IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY -> {
+                Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting10), false, false, 0)
+                commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_2, isDumpLog, 0, 150, 0xd136, 0x01))
+            }
+            IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_2 -> {
+                Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_2 ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting11), false, false, 0)
+                commandIssuer.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_3, isDumpLog, 0, 150, 0xd136, 0x00))
+            }
+            IPtpIpMessages.SEQ_SET_DEVICE_PROPERTY_3 -> {
+                Log.v(TAG, " SEQ_SET_DEVICE_PROPERTY_3 ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0)
+                //commandIssuer.enqueueCommand(new CanonSetDevicePropertyValue(this, SEQ_SET_REMOTE_SHOOTING_MODE, isDumpLog, 0, 300, 0xd1b0, 0x08));
+                commandIssuer!!.enqueueCommand(CanonSetDevicePropertyValue(this, IPtpIpMessages.SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 300, 0xd1b0, 0x08))
+            }
+            IPtpIpMessages.SEQ_SET_REMOTE_SHOOTING_MODE -> {
+                Log.v(TAG, " SEQ_SET_REMOTE_SHOOTING_MODE ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.canon_connect_connecting12), false, false, 0)
+                try {
+                    // ちょっと(250ms)待つ
+                    Thread.sleep(250)
+
+                    // コマンド発行
+                    //commandIssuer.enqueueCommand(new PtpIpCommandGeneric(this, SEQ_DEVICE_PROPERTY_FINISHED, isDumpLog, 0, 0x9086, 4, 0x00000001));
+                    commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_DEVICE_INFORMATION, isDumpLog, 0, 0x9086, 4, 0x00000001))
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+            }
+            IPtpIpMessages.SEQ_DEVICE_PROPERTY_FINISHED -> {
+                Log.v(TAG, " SEQ_DEVICE_PROPERTY_FINISHED ")
+                interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_connect_finished), false, false, 0)
+                connectFinished()
+                Log.v(TAG, "CHANGED MODE : DONE.")
+            }
+            else -> {
+                Log.v(TAG, "RECEIVED UNKNOWN ID : $id")
+                cameraConnection.alertConnectingFailed(context.getString(R.string.connect_receive_unknown_message))
+            }
+        }
+    }
+
+    private fun sendRegistrationMessage()
+    {
+        interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_start), false, false, 0)
+        cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_start))
+        commandIssuer.enqueueCommand(CanonRegistrationMessage(this))
+    }
+
+    @ExperimentalUnsignedTypes
+    private fun sendInitEventRequest(receiveData: ByteArray)
+    {
+        interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_start_2), false, false, 0)
+        cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_start_2))
+        try
+        {
+            var eventConnectionNumber: Int = receiveData[8].toUByte().toInt() and 0xff
+            eventConnectionNumber += (receiveData[9].toUByte().toInt() and 0xff shl 8)
+            eventConnectionNumber += (receiveData[10].toUByte().toInt() and 0xff shl 16)
+            eventConnectionNumber += (receiveData[11].toUByte().toInt() and 0xff shl 24)
+            statusChecker.setEventConnectionNumber(eventConnectionNumber)
+            interfaceProvider.cameraStatusWatcher.startStatusWatch(interfaceProvider.statusListener)
+            commandIssuer.enqueueCommand(PtpIpCommandGeneric(this, IPtpIpMessages.SEQ_OPEN_SESSION, isDumpLog, 0, 0x1002, 4, 0x41))
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    private fun checkRegistrationMessage(receiveData: ByteArray?): Boolean
+    {
+        // データ(Connection Number)がないときにはエラーと判断する
+        return !(receiveData == null || receiveData.size < 12)
+    }
+
+    private fun checkEventInitialize(receiveData: ByteArray?): Boolean
+    {
+        Log.v(TAG, "checkEventInitialize() ")
+        return receiveData != null
+    }
+
+    private fun connectFinished()
+    {
+        try
+        {
+            // 接続成功のメッセージを出す
+            interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_connected), false, false, 0)
+
+            // ちょっと待つ
+            Thread.sleep(1000)
+
+            // 接続成功!のメッセージを出す
+            interfaceProvider.informationReceiver.updateMessage(context.getString(R.string.connect_connected), false, false, 0)
+            onConnectNotify()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    private fun onConnectNotify()
+    {
+        try
+        {
+            val thread = Thread {
+                // カメラとの接続確立を通知する
+                cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_connected))
+                cameraStatusReceiver.onCameraConnected()
+                Log.v(TAG, " onConnectNotify()")
+            }
+            thread.start()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    companion object
+    {
+        private const val TAG = "CanonConnectSeq.1"
+    }
+}
\ No newline at end of file
index 6ab510d..9f75bec 100644 (file)
@@ -1,7 +1,5 @@
 package net.osdn.gokigen.a01d.camera.canon.wrapper.connection;
 
-import android.app.Activity;
-
 import androidx.annotation.NonNull;
 
 import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
@@ -9,15 +7,12 @@ import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommunication;
 
 class CanonCameraDisconnectSequence implements Runnable
 {
-    private final String TAG = this.toString();
-    private final Activity activity;
     private final IPtpIpCommunication command;
     private final IPtpIpCommunication async;
     private final IPtpIpCommunication liveview;
 
-    CanonCameraDisconnectSequence(Activity activity, @NonNull IPtpIpInterfaceProvider interfaceProvider)
+    CanonCameraDisconnectSequence(@NonNull IPtpIpInterfaceProvider interfaceProvider)
     {
-        this.activity = activity;
         this.command = interfaceProvider.getCommandCommunication();
         this.async = interfaceProvider.getAsyncEventCommunication();
         this.liveview = interfaceProvider.getLiveviewCommunication();
index d903dba..28f4e69 100644 (file)
@@ -6,6 +6,7 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
@@ -14,12 +15,14 @@ import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
+import androidx.preference.PreferenceManager;
 
 import net.osdn.gokigen.a01d.R;
 import net.osdn.gokigen.a01d.camera.ICameraConnection;
 import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver;
 import net.osdn.gokigen.a01d.camera.ptpip.IPtpIpInterfaceProvider;
 import net.osdn.gokigen.a01d.camera.canon.wrapper.status.CanonStatusChecker;
+import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor;
 
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -211,10 +214,10 @@ public class CanonConnection implements ICameraConnection
      */
     private void disconnectFromCamera(final boolean powerOff)
     {
-        Log.v(TAG, " disconnectFromCamera()");
+        Log.v(TAG, " disconnectFromCamera() : " + powerOff);
         try
         {
-            cameraExecutor.execute(new CanonCameraDisconnectSequence(context, interfaceProvider));
+            cameraExecutor.execute(new CanonCameraDisconnectSequence(interfaceProvider));
         }
         catch (Exception e)
         {
@@ -231,7 +234,14 @@ public class CanonConnection implements ICameraConnection
         connectionStatus = CameraConnectionStatus.CONNECTING;
         try
         {
-            cameraExecutor.execute(new CanonCameraConnectSequence(context, statusReceiver, this, interfaceProvider, statusChecker));
+            if (getConnectSequenceType() == 0)
+            {
+                cameraExecutor.execute(new CanonCameraConnectSequence(context, statusReceiver, this, interfaceProvider, statusChecker));
+            }
+            else
+            {
+                cameraExecutor.execute(new CanonCameraConnectSequenceType1(context, statusReceiver, this, interfaceProvider, statusChecker));
+            }
         }
         catch (Exception e)
         {
@@ -239,4 +249,24 @@ public class CanonConnection implements ICameraConnection
             e.printStackTrace();
         }
     }
+
+    private int getConnectSequenceType()
+    {
+        int sequenceType = 0;
+        try
+        {
+            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+            String sequenceTypeStr = preferences.getString(IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE, IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE_DEFAULT_VALUE);
+            if (sequenceTypeStr != null)
+            {
+                sequenceType = Integer.parseInt(sequenceTypeStr);
+            }
+            Log.v(TAG, " Canon ConnectionSequence [" + sequenceType + "] " + sequenceTypeStr);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return (sequenceType);
+    }
 }
index 8f2c441..d849167 100644 (file)
@@ -24,18 +24,21 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
     private final String TAG = this.toString();
     private final IPtpIpCommandPublisher commandIssuer;
     private final int delayMs;
-    //private CanonLiveViewImageReceiver imageReceiver;
+    private final boolean isDumpLog = false;
+    private final boolean isSearchJpegHeader;
+    private final int retryCount = 1500;
     private final CanonLiveViewImageReceiver imageReceiver;
     private IImageDataReceiver dataReceiver = null;
     private boolean liveViewIsReceiving = false;
     private boolean commandIssued = false;
 
-    public CanonLiveViewControl(@NonNull Activity context, @NonNull IPtpIpInterfaceProvider interfaceProvider, int delayMs)
+    public CanonLiveViewControl(@NonNull Activity context, @NonNull IPtpIpInterfaceProvider interfaceProvider, int delayMs, boolean isSearchJpegHeader)
     {
         this.commandIssuer = interfaceProvider.getCommandPublisher();
+        this.isSearchJpegHeader = isSearchJpegHeader;
         this.delayMs = delayMs;
         //this.imageReceiver = new CanonLiveViewImageReceiver(this);
-        this.imageReceiver = new CanonLiveViewImageReceiver(this);
+        this.imageReceiver = new CanonLiveViewImageReceiver(context,this);
         Log.v(TAG, " -=-=-=-=-=- CanonLiveViewControl : delay " + delayMs + " ms");
     }
 
@@ -67,8 +70,12 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
                         {
                             if (!commandIssued)
                             {
+                                if (isDumpLog)
+                                {
+                                    Log.v(TAG, " enqueueCommand() ");
+                                }
                                 commandIssued = true;
-                                commandIssuer.enqueueCommand(new PtpIpCommandGenericWithRetry(imageReceiver, SEQ_GET_VIEWFRAME, delayMs, 2000, false, false, 0, 0x9153, 12, 0x00200000, 0x01, 0x00, 0x00));
+                                commandIssuer.enqueueCommand(new PtpIpCommandGenericWithRetry(imageReceiver, SEQ_GET_VIEWFRAME, delayMs, retryCount, false, false, 0, 0x9153, 12, 0x00200000, 0x01, 0x00, 0x00));
                             }
                             try
                             {
@@ -155,11 +162,14 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
         {
             if ((dataReceiver != null)&&(data != null))
             {
-                Log.v(TAG, "  ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
-                //dataReceiver.setImageData(data, metadata);
-                if (data.length > 8)
+                if (isDumpLog)
                 {
-                    dataReceiver.setImageData(Arrays.copyOfRange(data, 8, data.length), metadata);  // ヘッダ部分を切り取って送る
+                    Log.v(TAG, "  ---+++--- RECEIVED LV IMAGE ---+++--- : " + data.length + " bytes.");
+                }
+                int headerSize = searchJpegHeader(data);
+                if (headerSize >= 0)
+                {
+                    dataReceiver.setImageData(Arrays.copyOfRange(data, headerSize, data.length), metadata);  // ヘッダ部分を切り取って送る
                 }
             }
         }
@@ -170,6 +180,39 @@ public class CanonLiveViewControl implements ILiveViewControl, ILiveViewListener
         commandIssued = false;
     }
 
+    private int searchJpegHeader(byte[] data)
+    {
+        if (data.length <= 8)
+        {
+            return (-1);
+        }
+        if (!isSearchJpegHeader)
+        {
+            // JPEG ヘッダを探さない場合は、8バイト固定とする
+            return (8);
+        }
+        try
+        {
+            int size = data.length - 1;
+            int index = 0;
+            while (index < size)
+            {
+                if ((data[index] == (byte) 0xff)&&(data[index + 1] == (byte) 0xd8))
+                {
+                    return (index);
+                }
+                index++;
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+        // 見つからなかったときは 8 を返す
+        return (8);
+    }
+
     @Override
     public void onErrorOccurred(Exception e)
     {
index cf00b22..0fca70a 100644 (file)
@@ -1,5 +1,6 @@
 package net.osdn.gokigen.a01d.camera.canon.wrapper.liveview
 
+import android.app.Activity
 import android.util.Log
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.command.IPtpIpCommandCallback
 import net.osdn.gokigen.a01d.camera.ptpip.wrapper.liveview.IPtpIpLiveViewImageCallback
@@ -7,7 +8,7 @@ import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper
 import java.io.ByteArrayOutputStream
 import java.util.*
 
-class CanonLiveViewImageReceiver(val callback: IPtpIpLiveViewImageCallback) : IPtpIpCommandCallback
+class CanonLiveViewImageReceiver(val activity: Activity, val callback: IPtpIpLiveViewImageCallback) : IPtpIpCommandCallback
 {
     private val isDumpLog = false
     private val byteStream = ByteArrayOutputStream()
@@ -15,6 +16,7 @@ class CanonLiveViewImageReceiver(val callback: IPtpIpLiveViewImageCallback) : IP
     private var receivedTotalBytes = 0
     private var receivedRemainBytes = 0
     private var receivedFirstData = false
+    private var dumpImageSize = -1   // 値をゼロにするとisDumpLogがtrueのときに受信データをファイルに出力する
 
     override fun receivedMessage(id: Int, rx_body: ByteArray?)
     {
@@ -133,12 +135,18 @@ class CanonLiveViewImageReceiver(val callback: IPtpIpLiveViewImageCallback) : IP
             {
                 val thumbNail = byteStream.toByteArray()
                 var dumpLength = thumbNail.size
-                if (dumpLength > 256)
+                if (dumpLength > 96)
                 {
-                    dumpLength = 256
+                    dumpLength = 96
                 }
                 SimpleLogDumper.dump_bytes(" [--ID:$id(>)--]", Arrays.copyOfRange(thumbNail, 0, dumpLength))
                 SimpleLogDumper.dump_bytes(" [-ID:$id(<)-]", Arrays.copyOfRange(thumbNail, thumbNail.size - dumpLength, thumbNail.size))
+                Log.v(TAG, " RECEIVED LENGTH : $thumbNail.size")
+                if ((dumpImageSize > 0)&&(dumpImageSize < 30))
+                {
+                    SimpleLogDumper.binaryOutputToFile(activity, "CANON-${dumpImageSize}_", byteStream.toByteArray())
+                    dumpImageSize++
+                }
             }
             callback.onCompleted(byteStream.toByteArray(), null)
             receivedFirstData = false
@@ -153,8 +161,6 @@ class CanonLiveViewImageReceiver(val callback: IPtpIpLiveViewImageCallback) : IP
         }
     }
 
-
-
     override fun isReceiveMulti(): Boolean
     {
         return (true)
index d20d2dd..c789131 100644 (file)
@@ -123,6 +123,9 @@ public interface IPreferencePropertyAccessor
     String CANON_LIVEVIEW_WAIT = "canon_liveview_wait";
     String CANON_LIVEVIEW_WAIT_DEFAULT_VALUE = "25";
 
+    String CANON_CONNECTION_SEQUENCE = "canon_connection_mode";
+    String CANON_CONNECTION_SEQUENCE_DEFAULT_VALUE = "0";
+
  /*
     int CHOICE_SPLASH_SCREEN = 10;
 
index 90d93a8..4492739 100644 (file)
@@ -139,6 +139,9 @@ public class CanonPreferenceFragment extends PreferenceFragmentCompat implements
             if (!items.containsKey(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT)) {
                 editor.putString(IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT, IPreferencePropertyAccessor.CANON_LIVEVIEW_WAIT_DEFAULT_VALUE);
             }
+            if (!items.containsKey(IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE)) {
+                editor.putString(IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE, IPreferencePropertyAccessor.CANON_CONNECTION_SEQUENCE_DEFAULT_VALUE);
+            }
             editor.apply();
         }
         catch (Exception e)
index fd49387..b783d04 100644 (file)
     <string name="pref_canon_liveview_wait">LV画像受信待ち間隔(default: 25)</string>
     <string name="pref_summary_canon_liveview_wait">ライブビュー画像受信間隔を指定します</string>
 
+    <string name="pref_canon_connection_mode">接続シーケンス</string>
+    <string name="pref_summary_canon_connection_mode">通常、変更は不要です (初期値: TYPE0)</string>
+
 </resources>
index 60dd56c..52010d0 100644 (file)
         <item>AUTO</item>
     </string-array>
 
+    <string-array name="canon_connection_mode">
+        <item>TYPE0</item>
+        <item>TYPE1</item>
+        <item>TYPE2</item>
+    </string-array>
+
+    <string-array name="canon_connection_mode_value">
+        <item>0</item>
+        <item>1</item>
+        <item>2</item>
+    </string-array>
+
 </resources>
index 03c2cfe..ea8a17f 100644 (file)
     <string name="pref_canon_liveview_wait">Liveview receive wait (default: 25)</string>
     <string name="pref_summary_canon_liveview_wait"> </string>
 
+    <string name="pref_canon_connection_mode">Connection Sequence</string>
+    <string name="pref_summary_canon_connection_mode">default: TYPE0 </string>
+
 </resources>
index 5ef8b9e..e4cb72a 100644 (file)
             android:defaultValue="25"
             android:summary="@string/pref_summary_canon_liveview_wait" />
 
+        <ListPreference
+            android:title="@string/pref_canon_connection_mode"
+            android:summary="@string/pref_summary_canon_connection_mode"
+            android:entryValues="@array/canon_connection_mode_value"
+            android:entries="@array/canon_connection_mode"
+            android:key="canon_connection_mode"
+            android:defaultValue="0"/>
+
 <!--
         <CheckBoxPreference
             android:key="capture_both_camera_and_live_view"