Unverified Commit cf7e6107 authored by Gus Grubba's avatar Gus Grubba Committed by GitHub

Merge pull request #7131 from MatejFranceskin/pr-taisync-android

PR Taisync support for Android
parents 36fcd714 868b12c9
...@@ -36,6 +36,7 @@ linux { ...@@ -36,6 +36,7 @@ linux {
DEFINES += __android__ DEFINES += __android__
DEFINES += __STDC_LIMIT_MACROS DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_BLUETOOTH DEFINES += QGC_ENABLE_BLUETOOTH
DEFINES += QGC_GST_TAISYNC_ENABLED
target.path = $$DESTDIR target.path = $$DESTDIR
equals(ANDROID_TARGET_ARCH, x86) { equals(ANDROID_TARGET_ARCH, x86) {
CONFIG += Androidx86Build CONFIG += Androidx86Build
......
...@@ -15,7 +15,8 @@ OTHER_FILES += \ ...@@ -15,7 +15,8 @@ OTHER_FILES += \
$$PWD/android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java \ $$PWD/android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java \
$$PWD/android/src/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java \ $$PWD/android/src/com/hoho/android/usbserial/driver/UsbSerialRuntimeException.java \
$$PWD/android/src/org/mavlink/qgroundcontrol/QGCActivity.java \ $$PWD/android/src/org/mavlink/qgroundcontrol/QGCActivity.java \
$$PWD/android/src/org/mavlink/qgroundcontrol/UsbIoManager.java $$PWD/android/src/org/mavlink/qgroundcontrol/UsbIoManager.java \
$$PWD/android/src/org/mavlink/qgroundcontrol/TaiSync.java
DISTFILES += \ DISTFILES += \
$$PWD/android/gradle/wrapper/gradle-wrapper.jar \ $$PWD/android/gradle/wrapper/gradle-wrapper.jar \
......
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/> <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
</intent-filter> </intent-filter>
<meta-data android:resource="@xml/device_filter" android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> <meta-data android:resource="@xml/device_filter" android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
<meta-data android:resource="@xml/device_filter" android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/> <meta-data android:resource="@xml/device_filter" android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
<meta-data android:resource="@xml/device_filter" android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
<!-- Rest of Standard Manifest --> <!-- Rest of Standard Manifest -->
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
...@@ -60,13 +62,14 @@ ...@@ -60,13 +62,14 @@
<!-- Support devices without USB host mode since there are other connection types --> <!-- Support devices without USB host mode since there are other connection types -->
<uses-feature android:name="android.hardware.usb.host" android:required="false"/> <uses-feature android:name="android.hardware.usb.host" android:required="false"/>
<!-- Support devices without Bluetooth since there are other connection types --> <!-- Support devices without Bluetooth since there are other connection types -->
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/> <uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<!-- Support devices that don't have location services --> <!-- Support devices that don't have location services -->
<uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false"/> <uses-feature android:name="android.hardware.location.network" android:required="false"/>
<uses-feature android:name="android.hardware.location" android:required="false"/> <uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.usb.accessory"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
......
...@@ -2,5 +2,6 @@ ...@@ -2,5 +2,6 @@
<resources> <resources>
<!-- Allow anything connected --> <!-- Allow anything connected -->
<usb-device /> <usb-device />
<usb-accessory model="android.usbaoa" manufacturer="taisync" version="1.0"/>
</resources> </resources>
...@@ -29,11 +29,14 @@ package org.mavlink.qgroundcontrol; ...@@ -29,11 +29,14 @@ package org.mavlink.qgroundcontrol;
// //
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.Timer;
import java.util.TimerTask;
import java.io.IOException; import java.io.IOException;
import android.app.Activity; import android.app.Activity;
...@@ -42,12 +45,16 @@ import android.content.BroadcastReceiver; ...@@ -42,12 +45,16 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.hardware.usb.*; import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.widget.Toast; import android.widget.Toast;
import android.util.Log; import android.util.Log;
import android.os.PowerManager; import android.os.PowerManager;
import android.view.WindowManager;
import android.os.Bundle; import android.os.Bundle;
import android.app.PendingIntent;
import android.view.WindowManager;
import com.hoho.android.usbserial.driver.*; import com.hoho.android.usbserial.driver.*;
import org.qtproject.qt5.android.bindings.QtActivity; import org.qtproject.qt5.android.bindings.QtActivity;
...@@ -63,8 +70,10 @@ public class QGCActivity extends QtActivity ...@@ -63,8 +70,10 @@ public class QGCActivity extends QtActivity
private static HashMap<Integer, Integer> _userDataHashByDeviceId; private static HashMap<Integer, Integer> _userDataHashByDeviceId;
private static final String TAG = "QGC_QGCActivity"; private static final String TAG = "QGC_QGCActivity";
private static PowerManager.WakeLock _wakeLock; private static PowerManager.WakeLock _wakeLock;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; // private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private static final String ACTION_USB_PERMISSION = "org.mavlink.qgroundcontrol.action.USB_PERMISSION";
private static PendingIntent _usbPermissionIntent = null; private static PendingIntent _usbPermissionIntent = null;
private TaiSync taiSync = null;
public static Context m_context; public static Context m_context;
...@@ -87,6 +96,26 @@ public class QGCActivity extends QtActivity ...@@ -87,6 +96,26 @@ public class QGCActivity extends QtActivity
} }
}; };
private final BroadcastReceiver mOpenAccessoryReceiver =
new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
openAccessory(accessory);
}
} else if( UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null) {
closeAccessory(accessory);
}
}
}
};
private static UsbSerialDriver _findDriverByDeviceId(int deviceId) { private static UsbSerialDriver _findDriverByDeviceId(int deviceId) {
for (UsbSerialDriver driver: _drivers) { for (UsbSerialDriver driver: _drivers) {
if (driver.getDevice().getDeviceId() == deviceId) { if (driver.getDevice().getDeviceId() == deviceId) {
...@@ -169,7 +198,7 @@ public class QGCActivity extends QtActivity ...@@ -169,7 +198,7 @@ public class QGCActivity extends QtActivity
_usbManager = (UsbManager)_instance.getSystemService(Context.USB_SERVICE); _usbManager = (UsbManager)_instance.getSystemService(Context.USB_SERVICE);
// Register for USB Detach and USB Permission intent // Register for USB Detach and USB Permission intent
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(ACTION_USB_PERMISSION); filter.addAction(ACTION_USB_PERMISSION);
...@@ -177,11 +206,24 @@ public class QGCActivity extends QtActivity ...@@ -177,11 +206,24 @@ public class QGCActivity extends QtActivity
// Create intent for usb permission request // Create intent for usb permission request
_usbPermissionIntent = PendingIntent.getBroadcast(_instance, 0, new Intent(ACTION_USB_PERMISSION), 0); _usbPermissionIntent = PendingIntent.getBroadcast(_instance, 0, new Intent(ACTION_USB_PERMISSION), 0);
try {
taiSync = new TaiSync();
IntentFilter accessoryFilter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(mOpenAccessoryReceiver, accessoryFilter);
probeAccessories();
} catch(Exception e) {
Log.e(TAG, "Exception: " + e);
}
} }
@Override @Override
protected void onDestroy() protected void onDestroy()
{ {
unregisterReceiver(mOpenAccessoryReceiver);
try { try {
if(_wakeLock != null) { if(_wakeLock != null) {
_wakeLock.release(); _wakeLock.release();
...@@ -611,5 +653,61 @@ public class QGCActivity extends QtActivity ...@@ -611,5 +653,61 @@ public class QGCActivity extends QtActivity
else else
return connectL.getFileDescriptor(); return connectL.getFileDescriptor();
} }
UsbAccessory openUsbAccessory = null;
Object openAccessoryLock = new Object();
private void openAccessory(UsbAccessory usbAccessory)
{
Log.i(TAG, "openAccessory: " + usbAccessory.getSerial());
try {
synchronized(openAccessoryLock) {
if ((openUsbAccessory != null && !taiSync.isRunning()) || openUsbAccessory == null) {
openUsbAccessory = usbAccessory;
taiSync.open(_usbManager.openAccessory(usbAccessory));
}
}
} catch (IOException e) {
Log.e(TAG, "openAccessory exception: " + e);
taiSync.close();
closeAccessory(openUsbAccessory);
}
}
private void closeAccessory(UsbAccessory usbAccessory)
{
Log.i(TAG, "closeAccessory");
synchronized(openAccessoryLock) {
if (openUsbAccessory != null && usbAccessory == openUsbAccessory && taiSync.isRunning()) {
taiSync.close();
openUsbAccessory = null;
}
}
}
private void probeAccessories()
{
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run()
{
// Log.i(TAG, "probeAccessories");
UsbAccessory[] accessories = _usbManager.getAccessoryList();
if (accessories != null) {
for (UsbAccessory usbAccessory : accessories) {
if (_usbManager.hasPermission(usbAccessory)) {
openAccessory(usbAccessory);
} else {
Log.i(TAG, "requestPermission");
_usbManager.requestPermission(usbAccessory, pendingIntent);
}
}
}
}
}, 0, 3000);
}
} }
This diff is collapsed.
...@@ -70,16 +70,19 @@ The installer places them under ~/Library/Developer/GStreamer/iPhone.sdk/GStream ...@@ -70,16 +70,19 @@ The installer places them under ~/Library/Developer/GStreamer/iPhone.sdk/GStream
### Android ### Android
Binaries found in http://gstreamer.freedesktop.org/data/pkg/android Binaries found in http://gstreamer.freedesktop.org/data/pkg/android
Download the [gstreamer-1.0-android-armv7-1.5.2.tar.bz2](http://gstreamer.freedesktop.org/data/pkg/android/1.5.2/gstreamer-1.0-android-armv7-1.5.2.tar.bz2) archive (assuming you want the ARM V7 platform. For x86, replace `armv7` with `x86` accordingly). Download the [gstreamer-1.0-android-universal-1.14.4.tar.bz2](https://gstreamer.freedesktop.org/data/pkg/android/1.14.4/gstreamer-1.0-android-universal-1.14.4.tar.bz2) archive.
Create a directory named "gstreamer-1.0-android-armv7-1.5.2" under the root qgroundcontrol directory (the same directory qgroundcontrol.pro is located). Extract the gstreamer tar file under this directory. That's where the build system will look for it. Make sure your archive tool doesn't create any additional top level directories. The structure after extracting the archive should look like this: Create a directory named "gstreamer-1.0-android-universal-1.14.4" under the root qgroundcontrol directory (the same directory qgroundcontrol.pro is located). Extract the downloaded archive under this directory. That's where the build system will look for it. Make sure your archive tool doesn't create any additional top level directories. The structure after extracting the archive should look like this:
``` ```
qgroundcontrol qgroundcontrol
├── gstreamer-1.0-android-armv7-1.5.2 ├── gstreamer-1.0-android-universal-1.14.4
│   ├── etc │ │
│   ├── include │   ├──armv7
│   ├── lib │   │   ├── etc
│   └── share │   │   ├── include
│   │   ├── lib
│   │   └── share
│   ├──x86
``` ```
### Windows ### Windows
......
...@@ -539,7 +539,8 @@ VideoReceiver::_shutdownPipeline() { ...@@ -539,7 +539,8 @@ VideoReceiver::_shutdownPipeline() {
void void
VideoReceiver::_handleError() { VideoReceiver::_handleError() {
qCDebug(VideoReceiverLog) << "Gstreamer error!"; qCDebug(VideoReceiverLog) << "Gstreamer error!";
_shutdownPipeline(); stop();
start();
} }
#endif #endif
...@@ -554,7 +555,8 @@ VideoReceiver::_handleEOS() { ...@@ -554,7 +555,8 @@ VideoReceiver::_handleEOS() {
_shutdownRecordingBranch(); _shutdownRecordingBranch();
} else { } else {
qWarning() << "VideoReceiver: Unexpected EOS!"; qWarning() << "VideoReceiver: Unexpected EOS!";
_shutdownPipeline(); stop();
start();
} }
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment