1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-02 10:24:11 +01:00

Merge remote-tracking branch 'origin/next' into brian/rfm22_multibind

This commit is contained in:
Brian Webb 2013-02-17 23:43:14 +00:00
commit 07eb3ba13d
15 changed files with 442 additions and 68 deletions

View File

@ -1,71 +1,98 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.openpilot.androidgcs" android:versionCode="1" package="org.openpilot.androidgcs"
android:versionName="1.0"> android:versionCode="1"
<uses-sdk android:minSdkVersion="14" /> android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" /> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.usb.host" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:icon="@drawable/ic_logo" android:label="@string/app_name" android:theme="@android:style/Theme.Holo"> <uses-feature android:name="android.hardware.usb.host" />
<!-- for map overlay -->
<uses-library android:name="com.google.android.maps" />
<!-- Object browser - main activity at the moment --> <application
<activity android:name="HomePage" android:label="@string/app_name"> android:icon="@drawable/ic_logo"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo"
android:allowBackup="false">
<intent-filter> <!-- for map overlay -->
<action android:name="android.intent.action.MAIN" /> <uses-library android:name="com.google.android.maps" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- <intent-filter> --> <!-- Object browser - main activity at the moment -->
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> --> <activity
<!-- </intent-filter> --> android:name="HomePage"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!-- <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" --> <category android:name="android.intent.category.LAUNCHER" />
<!-- android:resource="@xml/device_filter" /> --> </intent-filter>
</activity>
<activity android:name="ObjectBrowser" android:label="@string/object_browser_name" /> <!-- <intent-filter> -->
<activity android:name="PfdActivity" android:label="PFD" /> <!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
<activity android:name="Controller" android:label="@string/controller_name" /> <!-- </intent-filter> -->
<activity android:name="Preferences" android:label="@string/preference_title" />
<activity android:name="UAVLocation" android:label="@string/location_name" />
<activity android:name="SystemAlarmActivity" android:label="System Alarms" />
<activity android:name="TuningActivity" android:label="Tuning" />
<activity android:name="ObjectEditor" android:label="ObjectEditor"
android:theme="@android:style/Theme.Dialog" />
<activity android:name="Logger" android:label="Logger"
android:theme="@android:style/Theme.Dialog" />
<!-- <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" -->
<activity <!-- android:resource="@xml/device_filter" /> -->
android:name="FragmentTester" </activity>
android:label="FragmentTester" /> <activity
android:name="ObjectBrowser"
android:label="@string/object_browser_name" />
<activity
android:name="PfdActivity"
android:label="PFD" />
<activity
android:name="Controller"
android:label="@string/controller_name" />
<activity
android:name="Preferences"
android:label="@string/preference_title" />
<activity
android:name="UAVLocation"
android:label="@string/location_name" />
<activity
android:name="SystemAlarmActivity"
android:label="System Alarms" />
<activity
android:name="TuningActivity"
android:label="Tuning" />
<activity
android:name="ObjectEditor"
android:label="ObjectEditor"
android:theme="@android:style/Theme.Dialog" />
<activity
android:name="Logger"
android:label="Logger"
android:theme="@android:style/Theme.Dialog" />
<activity
android:name="FragmentTester"
android:label="FragmentTester" />
<activity <activity
android:name="OsgViewer" android:name="OsgViewer"
android:label="3DView" /> android:label="3DView" />
<receiver android:name="TelemetryWidget"> <receiver android:name="TelemetryWidget" >
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="org.openpilot.intent.action.CONNECTED" /> <action android:name="org.openpilot.intent.action.CONNECTED" />
<action android:name="org.openpilot.intent.action.DISCONNECTED" /> <action android:name="org.openpilot.intent.action.DISCONNECTED" />
</intent-filter> </intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/telemetry_widget_info" /> <meta-data
</receiver> android:name="android.appwidget.provider"
android:resource="@xml/telemetry_widget_info" />
</receiver>
<service android:name="org.openpilot.androidgcs.telemetry.OPTelemetryService" >
</service>
</application>
<service android:name="org.openpilot.androidgcs.telemetry.OPTelemetryService"></service>
</application>
</manifest> </manifest>

View File

@ -65,6 +65,8 @@ public class HidUAVTalk extends TelemetryTask {
private boolean readPending = false; private boolean readPending = false;
private boolean writePending = false; private boolean writePending = false;
private IntentFilter deviceAttachedFilter; private IntentFilter deviceAttachedFilter;
private boolean usbReceiverRegistered = false;
private boolean usbPermissionReceiverRegistered = false;
public HidUAVTalk(OPTelemetryService service) { public HidUAVTalk(OPTelemetryService service) {
super(service); super(service);
@ -74,8 +76,14 @@ public class HidUAVTalk extends TelemetryTask {
public void disconnect() { public void disconnect() {
CleanUpAndClose(); CleanUpAndClose();
telemService.unregisterReceiver(usbReceiver); if(usbReceiverRegistered){
telemService.unregisterReceiver(usbPermissionReceiver); telemService.unregisterReceiver(usbReceiver);
usbReceiverRegistered = false;
}
if(usbPermissionReceiverRegistered){
telemService.unregisterReceiver(usbPermissionReceiver);
usbPermissionReceiverRegistered = false;
}
super.disconnect(); super.disconnect();
@ -110,11 +118,13 @@ public class HidUAVTalk extends TelemetryTask {
permissionIntent = PendingIntent.getBroadcast(telemService, 0, new Intent(ACTION_USB_PERMISSION), 0); permissionIntent = PendingIntent.getBroadcast(telemService, 0, new Intent(ACTION_USB_PERMISSION), 0);
permissionFilter = new IntentFilter(ACTION_USB_PERMISSION); permissionFilter = new IntentFilter(ACTION_USB_PERMISSION);
telemService.registerReceiver(usbPermissionReceiver, permissionFilter); telemService.registerReceiver(usbPermissionReceiver, permissionFilter);
usbPermissionReceiverRegistered = true;
deviceAttachedFilter = new IntentFilter(); deviceAttachedFilter = new IntentFilter();
deviceAttachedFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); deviceAttachedFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
deviceAttachedFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); deviceAttachedFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
telemService.registerReceiver(usbReceiver, deviceAttachedFilter); telemService.registerReceiver(usbReceiver, deviceAttachedFilter);
usbReceiverRegistered = true;
// Go through all the devices plugged in // Go through all the devices plugged in
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList(); HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

View File

@ -55,6 +55,8 @@ import android.widget.Toast;
import dalvik.system.DexClassLoader; import dalvik.system.DexClassLoader;
public class OPTelemetryService extends Service { public class OPTelemetryService extends Service {
// Track lifecycle
private static int _startupRequests = 0;
// Logging settings // Logging settings
private final String TAG = OPTelemetryService.class.getSimpleName(); private final String TAG = OPTelemetryService.class.getSimpleName();
@ -66,6 +68,7 @@ public class OPTelemetryService extends Service {
public final static String INTENT_CATEGORY_GCS = "org.openpilot.intent.category.GCS"; public final static String INTENT_CATEGORY_GCS = "org.openpilot.intent.category.GCS";
// Intent actions // Intent actions
public final static String INTENT_ACTION_TELEMETRYTASK_STARTED = "org.openpilot.intent.action.TELEMETRYTASK_STARTED";
public final static String INTENT_ACTION_CONNECTED = "org.openpilot.intent.action.CONNECTED"; public final static String INTENT_ACTION_CONNECTED = "org.openpilot.intent.action.CONNECTED";
public final static String INTENT_ACTION_DISCONNECTED = "org.openpilot.intent.action.DISCONNECTED"; public final static String INTENT_ACTION_DISCONNECTED = "org.openpilot.intent.action.DISCONNECTED";
@ -139,6 +142,9 @@ public class OPTelemetryService extends Service {
throw new Error("Unsupported"); throw new Error("Unsupported");
} }
activeTelem.start(); activeTelem.start();
Intent startedIntent = new Intent();
startedIntent.setAction(OPTelemetryService.INTENT_ACTION_TELEMETRYTASK_STARTED);
sendBroadcast(startedIntent,null);
break; break;
case MSG_DISCONNECT: case MSG_DISCONNECT:
Toast.makeText(getApplicationContext(), "Disconnect requested", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), "Disconnect requested", Toast.LENGTH_SHORT).show();
@ -184,6 +190,9 @@ public class OPTelemetryService extends Service {
* and based on the stored preference will send itself a connect signal if needed. * and based on the stored preference will send itself a connect signal if needed.
*/ */
public void startup() { public void startup() {
synchronized (this) {
_startupRequests++;
}
Toast.makeText(getApplicationContext(), "Telemetry service starting", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), "Telemetry service starting", Toast.LENGTH_SHORT).show();
thread = new HandlerThread("TelemetryServiceHandler", Process.THREAD_PRIORITY_BACKGROUND); thread = new HandlerThread("TelemetryServiceHandler", Process.THREAD_PRIORITY_BACKGROUND);
@ -232,11 +241,20 @@ public class OPTelemetryService extends Service {
telemTask = null; telemTask = null;
try { try {
activeTelem.join(); // Race condition - if we shut the service down before the telemetry task
// thread has started, this will hang so we need to check thread is runnable.
if(activeTelem.getState() == Thread.State.RUNNABLE){
activeTelem.join();
}else{
Log.d(TAG, "onDestroy() shut down telemetry task before it has started");
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
synchronized (this) {
_startupRequests = 0;
}
Log.d(TAG, "onDestory() shut down telemetry task"); Log.d(TAG, "onDestory() shut down telemetry task");
Toast.makeText(this, "Telemetry service done", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Telemetry service done", Toast.LENGTH_SHORT).show();
} }
@ -247,6 +265,9 @@ public class OPTelemetryService extends Service {
return telemTask.getTelemTaskIface(); return telemTask.getTelemTaskIface();
return null; return null;
} }
public TelemetryTask getTelemetryTask(int id){
return telemTask;
}
public void openConnection() { public void openConnection() {
Toast.makeText(getApplicationContext(), "Requested open connection", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), "Requested open connection", Toast.LENGTH_SHORT).show();
Message msg = mServiceHandler.obtainMessage(); Message msg = mServiceHandler.obtainMessage();
@ -410,4 +431,8 @@ public class OPTelemetryService extends Service {
return true; return true;
} }
public static int getNumStartupRequests() {
return _startupRequests;
}
} }

View File

@ -142,12 +142,16 @@ public abstract class TelemetryTask implements Runnable {
} }
// Stop the master telemetry thread // Stop the master telemetry thread
handler.post(new Runnable() { // Check handler is not null: if we attempt to disconnect before
@Override // the connect process has completed, handler may be null.
public void run() { if(handler != null){
Looper.myLooper().quit(); handler.post(new Runnable() {
} @Override
}); public void run() {
Looper.myLooper().quit();
}
});
}
if (inputProcessThread != null) { if (inputProcessThread != null) {
inputProcessThread.interrupt(); inputProcessThread.interrupt();

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry combineaccessrules="false" kind="src" path="/androidgcs"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

33
androidgcstests/.project Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>androidgcstests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.openpilot.androidgcs.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="org.openpilot.androidgcs" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-14

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AndroidGCSTestTest</string>
</resources>

View File

@ -0,0 +1,207 @@
/**
******************************************************************************
* @file OPTelemetryServiceTests.java
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief Tests for the OPTelemetryService class
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.openpilot.androidgcs.test.telemetryservice;
import org.openpilot.androidgcs.telemetry.HidUAVTalk;
import org.openpilot.androidgcs.telemetry.TcpUAVTalk;
import org.openpilot.androidgcs.telemetry.BluetoothUAVTalk;
import org.openpilot.androidgcs.telemetry.OPTelemetryService;
import org.openpilot.androidgcs.telemetry.OPTelemetryService.LocalBinder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.test.ServiceTestCase;
import android.test.mock.MockApplication;
import android.test.mock.MockContext;
public class OPTelemetryServiceTests extends
ServiceTestCase<OPTelemetryService> {
private static final int PREF_BLUETOOTH_CONN = 2;
private static final int PREF_TCP_CONN = 3;
private static final int PREF_USB_CONN = 4;
private Object _syncTelemetryTaskStarted = new Object();
private Object _syncTelemetryConnected = new Object();
private BroadcastReceiver _connectBroadcastReceiver;
public class MockAndroidGCSApplication extends MockApplication {
}
class MockAndroidGCSContext extends MockContext {
}
public OPTelemetryServiceTests() {
this(OPTelemetryService.class);
}
public OPTelemetryServiceTests(Class<OPTelemetryService> serviceClass) {
super(serviceClass);
_connectBroadcastReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(OPTelemetryService.INTENT_ACTION_CONNECTED)) {
if(_syncTelemetryConnected != null){
synchronized (_syncTelemetryConnected) {
_syncTelemetryConnected.notify();
}
}
}else if(intent.getAction().equals(OPTelemetryService.INTENT_ACTION_TELEMETRYTASK_STARTED)) {
// Not looked into why _syncTelemetryTaskStarted could possibly be null
// here but sometimes it is...
if(_syncTelemetryTaskStarted != null){
synchronized (_syncTelemetryTaskStarted) {
_syncTelemetryTaskStarted.notify();
}
}
}
}
};
}
@Override
protected void setUp() throws Exception {
super.setUp();
IntentFilter filter = new IntentFilter();
filter.addCategory(OPTelemetryService.INTENT_CATEGORY_GCS);
filter.addAction(OPTelemetryService.INTENT_ACTION_CONNECTED);
filter.addAction(OPTelemetryService.INTENT_ACTION_TELEMETRYTASK_STARTED);
getContext().registerReceiver(_connectBroadcastReceiver, filter);
// setApplication(new MockAndroidGCSApplication());
// setContext(new MockAndroidGCSContext());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
// getContext().unregisterReceiver(_connectBroadcastReceiver);
}
public void testLifecycleSingleStart(){
bindService(new Intent(getContext(),
org.openpilot.androidgcs.telemetry.OPTelemetryService.class));
assertEquals(1, OPTelemetryService.getNumStartupRequests());
shutdownService();
assertEquals(0, OPTelemetryService.getNumStartupRequests());
}
public void testLifecycleMultiStart(){
bindService(new Intent(getContext(),
org.openpilot.androidgcs.telemetry.OPTelemetryService.class));
bindService(new Intent(getContext(),
org.openpilot.androidgcs.telemetry.OPTelemetryService.class));
assertEquals(1, OPTelemetryService.getNumStartupRequests());
shutdownService();
assertEquals(0, OPTelemetryService.getNumStartupRequests());
}
public void testStartBluetoothTelemetryTask(){
LocalBinder binder = startTelemetryTask(Integer.valueOf(PREF_BLUETOOTH_CONN));
assertTrue("Started wrong telemetry service type", binder.getTelemetryTask(0) instanceof BluetoothUAVTalk);
}
public void testStartBluetoothConnection() throws InterruptedException{
LocalBinder binder = startTelemetryTask(Integer.valueOf(PREF_BLUETOOTH_CONN));
synchronized (_syncTelemetryConnected) {
_syncTelemetryConnected.wait(2000);
}
assertTrue("Failed to connect to telemetry service", binder.isConnected());
assertTrue("Started wrong telemetry service type", binder.getTelemetryTask(0) instanceof BluetoothUAVTalk);
}
public void testStartTCPTelemetryTask(){
LocalBinder binder = startTelemetryTask(Integer.valueOf(PREF_TCP_CONN));
assertTrue("Started wrong telemetry service type", binder.getTelemetryTask(0) instanceof TcpUAVTalk);
}
public void testStartTCPConnection() throws InterruptedException{
LocalBinder binder = startTelemetryTask(Integer.valueOf(PREF_TCP_CONN));
synchronized (_syncTelemetryConnected) {
_syncTelemetryConnected.wait(2000);
}
assertTrue("Failed to connect to telemetry service", binder.isConnected());
assertTrue("Started wrong telemetry service type", binder.getTelemetryTask(0) instanceof TcpUAVTalk);
}
public void testStartUSBTelemetryTask(){
LocalBinder binder = startTelemetryTask(Integer.valueOf(PREF_USB_CONN));
assertTrue("Started wrong telemetry service type", binder.getTelemetryTask(0) instanceof HidUAVTalk);
}
public void testStartUSBConnection() throws InterruptedException{
LocalBinder binder = startTelemetryTask(Integer.valueOf(PREF_USB_CONN));
synchronized (_syncTelemetryConnected) {
_syncTelemetryConnected.wait(2000);
}
assertTrue("Failed to connect to telemetry service", binder.isConnected());
assertTrue("Started wrong telemetry service type", binder.getTelemetryTask(0) instanceof HidUAVTalk);
}
private LocalBinder startTelemetryTask(Integer telemetryType) {
LocalBinder binder = (LocalBinder) bindService(new Intent(getContext(),
org.openpilot.androidgcs.telemetry.OPTelemetryService.class));
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = prefs.edit();
editor.putString("connection_type", telemetryType.toString());
editor.apply();
binder.openConnection();
synchronized (_syncTelemetryTaskStarted) {
try {
_syncTelemetryTaskStarted.wait(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return binder;
}
}