From 6bf8b92db7dcf2d739ca0e065e92e99cb1ee64cf Mon Sep 17 00:00:00 2001 From: Tomi Paananen Date: Mon, 11 Jan 2016 13:56:28 +0200 Subject: [PATCH 01/79] Commit to #36: Renamed the native sample to native test. --- .../nativesample/app/MainActivity.java | 537 ------------------ {NativeSampleApp => NativeTestApp}/.gitignore | 0 {NativeSampleApp => NativeTestApp}/LICENSE | 2 +- .../app/.gitignore | 0 .../app/build.gradle | 2 +- .../app/proguard-rules.pro | 0 .../nativesample/app/ApplicationTest.java | 0 .../app/src/main/AndroidManifest.xml | 2 +- .../nativetest/app/ConnectionEngine.java | 371 ++++++++++++ .../nativetest/app/MainActivity.java | 252 ++++++++ .../nativetest/app/TestEngine.java | 19 + .../app/fragments/LogFragment.java | 16 +- .../app/fragments/PeerListFragment.java | 35 +- .../app/fragments/SettingsFragment.java | 1 - .../nativetest}/app/model/Connection.java | 0 .../nativetest}/app/model/LogItem.java | 0 .../app/model/PeerAndConnectionModel.java | 5 +- .../nativetest}/app/model/Settings.java | 0 .../app/slidingtabs/SlidingTabLayout.java | 0 .../app/slidingtabs/SlidingTabStrip.java | 0 .../nativetest/app/test/AbstractTest.java | 49 ++ .../app/test/FindMyBluetoothAddressTest.java | 14 + .../nativetest}/app/utils/MenuUtils.java | 0 .../ic_arrow_downward_black_24dp.png | Bin .../ic_arrow_downward_blue_24dp.png | Bin .../ic_arrow_downward_gray_24dp.png | Bin .../ic_arrow_downward_green_24dp.png | Bin .../ic_arrow_upward_black_24dp.png | Bin .../ic_arrow_upward_blue_24dp.png | Bin .../ic_arrow_upward_gray_24dp.png | Bin .../ic_arrow_upward_green_24dp.png | Bin .../ic_compare_arrows_black_24dp.png | Bin .../ic_compare_arrows_white_24dp.png | Bin .../res/drawable-hdpi/ic_send_black_24dp.png | Bin .../res/drawable-hdpi/ic_send_white_24dp.png | Bin .../ic_swap_horiz_black_24dp.png | Bin .../ic_swap_horiz_white_24dp.png | Bin .../ic_send_black_24dp.png | Bin .../ic_send_black_24dp.png | Bin .../ic_send_black_24dp.png | Bin .../ic_send_black_24dp.png | Bin .../ic_send_black_24dp.png | Bin .../ic_arrow_downward_black_24dp.png | Bin .../ic_arrow_downward_blue_24dp.png | Bin .../ic_arrow_downward_gray_24dp.png | Bin .../ic_arrow_downward_green_24dp.png | Bin .../ic_arrow_upward_black_24dp.png | Bin .../ic_arrow_upward_blue_24dp.png | Bin .../ic_arrow_upward_gray_24dp.png | Bin .../ic_arrow_upward_green_24dp.png | Bin .../ic_compare_arrows_black_24dp.png | Bin .../ic_compare_arrows_white_24dp.png | Bin .../res/drawable-mdpi/ic_send_black_24dp.png | Bin .../res/drawable-mdpi/ic_send_white_24dp.png | Bin .../ic_swap_horiz_black_24dp.png | Bin .../ic_swap_horiz_white_24dp.png | Bin .../ic_arrow_downward_black_24dp.png | Bin .../ic_arrow_downward_blue_24dp.png | Bin .../ic_arrow_downward_gray_24dp.png | Bin .../ic_arrow_downward_green_24dp.png | Bin .../ic_arrow_upward_black_24dp.png | Bin .../ic_arrow_upward_blue_24dp.png | Bin .../ic_arrow_upward_gray_24dp.png | Bin .../ic_arrow_upward_green_24dp.png | Bin .../ic_compare_arrows_black_24dp.png | Bin .../ic_compare_arrows_white_24dp.png | Bin .../res/drawable-xhdpi/ic_send_black_24dp.png | Bin .../res/drawable-xhdpi/ic_send_white_24dp.png | Bin .../ic_swap_horiz_black_24dp.png | Bin .../ic_swap_horiz_white_24dp.png | Bin .../ic_arrow_downward_black_24dp.png | Bin .../ic_arrow_downward_blue_24dp.png | Bin .../ic_arrow_downward_gray_24dp.png | Bin .../ic_arrow_downward_green_24dp.png | Bin .../ic_arrow_upward_black_24dp.png | Bin .../ic_arrow_upward_blue_24dp.png | Bin .../ic_arrow_upward_gray_24dp.png | Bin .../ic_arrow_upward_green_24dp.png | Bin .../ic_compare_arrows_black_24dp.png | Bin .../ic_compare_arrows_white_24dp.png | Bin .../drawable-xxhdpi/ic_send_black_24dp.png | Bin .../drawable-xxhdpi/ic_send_white_24dp.png | Bin .../ic_swap_horiz_black_24dp.png | Bin .../ic_swap_horiz_white_24dp.png | Bin .../ic_arrow_downward_black_24dp.png | Bin .../ic_arrow_downward_blue_24dp.png | Bin .../ic_arrow_downward_gray_24dp.png | Bin .../ic_arrow_downward_green_24dp.png | Bin .../ic_arrow_upward_black_24dp.png | Bin .../ic_arrow_upward_blue_24dp.png | Bin .../ic_arrow_upward_gray_24dp.png | Bin .../ic_arrow_upward_green_24dp.png | Bin .../ic_compare_arrows_black_24dp.png | Bin .../ic_compare_arrows_white_24dp.png | Bin .../drawable-xxxhdpi/ic_send_black_24dp.png | Bin .../drawable-xxxhdpi/ic_send_white_24dp.png | Bin .../ic_swap_horiz_black_24dp.png | Bin .../ic_swap_horiz_white_24dp.png | Bin .../app/src/main/res/layout/activity_main.xml | 0 .../app/src/main/res/layout/fragment_log.xml | 0 .../src/main/res/layout/fragment_peers.xml | 0 .../src/main/res/layout/fragment_settings.xml | 0 .../src/main/res/layout/list_item_peer.xml | 0 .../app/src/main/res/layout/log_item.xml | 0 .../app/src/main/res/menu/menu_main.xml | 0 .../app/src/main/res/menu/menu_peers.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../mipmap-xxhdpi/ic_launcher_original.png | Bin .../app/src/main/res/values-w820dp/dimens.xml | 0 .../app/src/main/res/values/dimens.xml | 0 .../app/src/main/res/values/strings.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../build.gradle | 0 .../gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {NativeSampleApp => NativeTestApp}/gradlew | 0 .../gradlew.bat | 0 .../settings.gradle | 0 122 files changed, 753 insertions(+), 552 deletions(-) delete mode 100644 NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/MainActivity.java rename {NativeSampleApp => NativeTestApp}/.gitignore (100%) rename {NativeSampleApp => NativeTestApp}/LICENSE (97%) rename {NativeSampleApp => NativeTestApp}/app/.gitignore (100%) rename {NativeSampleApp => NativeTestApp}/app/build.gradle (94%) rename {NativeSampleApp => NativeTestApp}/app/proguard-rules.pro (100%) rename {NativeSampleApp => NativeTestApp}/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/AndroidManifest.xml (87%) create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/fragments/LogFragment.java (89%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/fragments/PeerListFragment.java (92%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/fragments/SettingsFragment.java (99%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/model/Connection.java (100%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/model/LogItem.java (100%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/model/PeerAndConnectionModel.java (98%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/model/Settings.java (100%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/slidingtabs/SlidingTabLayout.java (100%) rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/slidingtabs/SlidingTabStrip.java (100%) create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java rename {NativeSampleApp/app/src/main/java/org/thaliproject/nativesample => NativeTestApp/app/src/main/java/org/thaliproject/nativetest}/app/utils/MenuUtils.java (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_downward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_downward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_downward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_downward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_upward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_upward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_upward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_arrow_upward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_compare_arrows_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_compare_arrows_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_send_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_swap_horiz_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-hdpi/ic_swap_horiz_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-ldrtl-hdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-ldrtl-mdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-ldrtl-xhdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-ldrtl-xxhdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-ldrtl-xxxhdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_downward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_downward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_downward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_downward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_upward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_upward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_upward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_arrow_upward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_compare_arrows_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_compare_arrows_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_send_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_swap_horiz_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-mdpi/ic_swap_horiz_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_downward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_downward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_downward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_downward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_upward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_upward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_upward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_arrow_upward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_compare_arrows_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_compare_arrows_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_swap_horiz_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xhdpi/ic_swap_horiz_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_send_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_blue_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_gray_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_green_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_send_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_black_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_white_24dp.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/layout/activity_main.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/layout/fragment_log.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/layout/fragment_peers.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/layout/fragment_settings.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/layout/list_item_peer.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/layout/log_item.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/menu/menu_main.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/menu/menu_peers.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/mipmap-xxhdpi/ic_launcher_original.png (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/values-w820dp/dimens.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/values/dimens.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/values/strings.xml (100%) rename {NativeSampleApp => NativeTestApp}/app/src/main/res/values/styles.xml (100%) rename {NativeSampleApp => NativeTestApp}/build.gradle (100%) rename {NativeSampleApp => NativeTestApp}/gradle.properties (100%) rename {NativeSampleApp => NativeTestApp}/gradle/wrapper/gradle-wrapper.jar (100%) rename {NativeSampleApp => NativeTestApp}/gradle/wrapper/gradle-wrapper.properties (100%) rename {NativeSampleApp => NativeTestApp}/gradlew (100%) rename {NativeSampleApp => NativeTestApp}/gradlew.bat (100%) rename {NativeSampleApp => NativeTestApp}/settings.gradle (100%) diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/MainActivity.java b/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/MainActivity.java deleted file mode 100644 index 8082f5e..0000000 --- a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/MainActivity.java +++ /dev/null @@ -1,537 +0,0 @@ -/* Copyright (c) 2015 Microsoft Corporation. This software is licensed under the MIT License. - * See the license file delivered with this project for further information. - */ -package org.thaliproject.nativesample.app; - -import java.io.IOException; -import java.util.UUID; -import android.bluetooth.BluetoothSocket; -import android.content.Context; -import android.os.Build; -import android.os.CountDownTimer; -import android.os.Handler; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.app.ActionBar; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentPagerAdapter; -import android.os.Bundle; -import android.support.v4.view.ViewPager; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Toast; -import org.thaliproject.nativesample.app.fragments.LogFragment; -import org.thaliproject.nativesample.app.fragments.PeerListFragment; -import org.thaliproject.nativesample.app.fragments.SettingsFragment; -import org.thaliproject.nativesample.app.model.Connection; -import org.thaliproject.nativesample.app.model.PeerAndConnectionModel; -import org.thaliproject.nativesample.app.model.Settings; -import org.thaliproject.nativesample.app.slidingtabs.SlidingTabLayout; -import org.thaliproject.nativesample.app.utils.MenuUtils; -import org.thaliproject.p2p.btconnectorlib.ConnectionManager; -import org.thaliproject.p2p.btconnectorlib.DiscoveryManager; -import org.thaliproject.p2p.btconnectorlib.PeerProperties; -import org.thaliproject.p2p.btconnectorlib.utils.BluetoothSocketIoThread; - -public class MainActivity - extends AppCompatActivity - implements - ConnectionManager.ConnectionManagerListener, - DiscoveryManager.DiscoveryManagerListener, - Connection.Listener, - PeerListFragment.Listener { - - private static final String TAG = MainActivity.class.getName(); - - // Service type and UUID has to be application/service specific. - // The app will only connect to peers with the matching values. - private static final String SERVICE_TYPE = "ThaliNativeSampleApp._tcp"; - private static final String SERVICE_UUID_AS_STRING = "9ab3c173-66d5-4da6-9e23-e8ce520b479b"; - private static final String SERVICE_NAME = "Thali Native Sample App"; - public static final String PEER_NAME = Build.MANUFACTURER + "_" + Build.MODEL; // Use manufacturer and device model name as the peer name - private static final UUID SERVICE_UUID = UUID.fromString(SERVICE_UUID_AS_STRING); - private static final long CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS = 10000; - - /** - * The {@link android.support.v4.view.PagerAdapter} that will provide - * fragments for each of the sections. We use a - * {@link FragmentPagerAdapter} derivative, which will keep every - * loaded fragment in memory. If this becomes too memory intensive, it - * may be best to switch to a - * {@link android.support.v4.app.FragmentStatePagerAdapter}. - */ - private MyFragmentAdapter mMyFragmentAdapter; - - /** - * The {@link ViewPager} that will host the section contents. - */ - private ViewPager mViewPager; - - private SlidingTabLayout mSlidingTabLayout; - private Context mContext = null; - private Settings mSettings = null; - private ConnectionManager mConnectionManager = null; - private DiscoveryManager mDiscoveryManager = null; - private CountDownTimer mCheckConnectionsTimer = null; - private PeerAndConnectionModel mModel = null; - private PeerProperties mSelectedPeerProperties = null; - private PeerListFragment mPeerListFragment = null; - private LogFragment mLogFragment = null; - private SettingsFragment mSettingsFragment = null; - private boolean mShuttingDown = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // Set up the action bar. - final ActionBar actionBar = getSupportActionBar(); - - mMyFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager()); - - mViewPager = (ViewPager)findViewById(R.id.pager); - mViewPager.setAdapter(mMyFragmentAdapter); - - mSlidingTabLayout = (SlidingTabLayout)findViewById(R.id.sliding_tabs); - mSlidingTabLayout.setViewPager(mViewPager); - - mShuttingDown = false; - - mContext = this.getApplicationContext(); - mSettings = Settings.getInstance(mContext); - mSettings.load(); - - if (mConnectionManager == null) { - mModel = PeerAndConnectionModel.getInstance(); - - mCheckConnectionsTimer = new CountDownTimer( - CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS, - CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS) { - @Override - public void onTick(long l) { - // Not used - } - - @Override - public void onFinish() { - sendPingToAllPeers(); - mCheckConnectionsTimer.start(); - } - }; - - mConnectionManager = new ConnectionManager(mContext, this, SERVICE_UUID, SERVICE_NAME); - - mDiscoveryManager = new DiscoveryManager(mContext, this, SERVICE_UUID, SERVICE_TYPE); - mSettings.setDiscoveryManager(mDiscoveryManager); - - mConnectionManager.start(PEER_NAME); - mDiscoveryManager.start(PEER_NAME); - - mPeerListFragment = new PeerListFragment(); - mPeerListFragment.setListener(this); - - mLogFragment = new LogFragment(); - - mSettingsFragment = new SettingsFragment(); - } - } - - @Override - public void onDestroy() { - mShuttingDown = true; - mCheckConnectionsTimer.cancel(); - - mModel.closeAllConnections(); - - mConnectionManager.stop(); - mDiscoveryManager.stop(); - - super.onDestroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.menu_main, menu); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - MenuUtils.PeerMenuItemsAvailability availability = - MenuUtils.resolvePeerMenuItemsAvailability(mSelectedPeerProperties, mModel); - - MenuItem connectMenuItem = menu.getItem(0); - MenuItem sendDataMenuItem = menu.getItem(1); - MenuItem disconnectMenuItem = menu.getItem(2); - MenuItem killAllConnectionsMenuItem = menu.getItem(3); - - connectMenuItem.setVisible(availability.connectMenuItemAvailable); - connectMenuItem.setEnabled(availability.connectMenuItemAvailable); - sendDataMenuItem.setVisible(availability.sendDataMenuItemAvailable); - sendDataMenuItem.setEnabled(availability.sendDataMenuItemAvailable); - disconnectMenuItem.setEnabled(availability.disconnectMenuItemAvailable); - killAllConnectionsMenuItem.setEnabled(availability.killAllConnectionsMenuItemAvailable); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - boolean wasConsumed = false; - - switch (id) { - case R.id.action_connect: - onConnectRequest(mSelectedPeerProperties); // Has a null check - wasConsumed = true; - break; - case R.id.action_disconnect: - if (mSelectedPeerProperties != null) { - if (mModel.closeConnection(mSelectedPeerProperties)) { - wasConsumed = true; - } - } - - break; - case R.id.action_send_data: - onSendDataRequest(mSelectedPeerProperties); // Has a null check - wasConsumed = true; - break; - case R.id.action_kill_all_connections: - mModel.closeAllConnections(); - wasConsumed = true; - break; - } - - return wasConsumed || super.onOptionsItemSelected(item); - } - - @Override - public void onConnectionManagerStateChanged(ConnectionManager.ConnectionManagerState connectionManagerState) { - mLogFragment.logMessage("Connection manager state changed: " + connectionManagerState); - } - - /** - * Constructs a Bluetooth socket IO thread for the new connection and adds it to the list of - * connections. - * @param bluetoothSocket The Bluetooth socket. - * @param isIncoming If true, this is an incoming connection. If false, this is an outgoing connection. - * @param peerProperties The peer properties. - */ - @Override - public void onConnected(BluetoothSocket bluetoothSocket, boolean isIncoming, PeerProperties peerProperties) { - Log.i(TAG, "onConnected: " + (isIncoming ? "Incoming" : "Outgoing") + " connection: " + peerProperties.toString()); - mModel.removePeerBeingConnectedTo(peerProperties); - Connection connection = null; - - try { - connection = new Connection(this, bluetoothSocket, peerProperties, isIncoming); - } catch (Exception e) { - Log.e(TAG, "onConnected: Failed to create a socket IO thread instance: " + e.getMessage(), e); - - try { - bluetoothSocket.close(); - } catch (IOException e2) { - } - } - - if (connection != null) { - final String peerName = connection.getPeerProperties().getName(); - final boolean wasIncoming = connection.getIsIncoming(); - - mModel.addOrRemoveConnection(connection, true); - - showToast(peerName + " connected (is " + (wasIncoming ? "incoming" : "outgoing") + ")"); - - if (isIncoming) { - // Add peer, if it was not discovered before - mModel.addOrUpdatePeer(peerProperties); - mDiscoveryManager.addOrUpdateDiscoveredPeer(peerProperties); - } - - // Update the peer name, if already in the model - mModel.updatePeerName(peerProperties); - - mLogFragment.logMessage((isIncoming ? "Incoming" : "Outgoing") + " connection established to peer " + peerProperties.toString()); - } - - final int totalNumberOfConnections = mModel.getTotalNumberOfConnections(); - - Log.i(TAG, "onConnected: Total number of connections is now " + totalNumberOfConnections); - - if (totalNumberOfConnections == 1) { - mCheckConnectionsTimer.cancel(); - mCheckConnectionsTimer.start(); - } - - invalidateOptionsMenu(); // Update the main menu - } - - @Override - public void onConnectionTimeout(PeerProperties peerProperties) { - Log.i(TAG, "onConnectionTimeout: " + peerProperties); - - if (peerProperties != null) { - mModel.removePeerBeingConnectedTo(peerProperties); - showToast("Failed to connect to " + peerProperties.getName() + ": Connection timeout"); - mLogFragment.logError("Failed to connect to peer " + peerProperties.toString() + ": Connection timeout"); - } else { - showToast("Failed to connect: Connection timeout"); - mLogFragment.logError("Failed to connect: Connection timeout"); - } - - invalidateOptionsMenu(); // Update the main menu - } - - @Override - public void onConnectionFailed(PeerProperties peerProperties, String errorMessage) { - Log.i(TAG, "onConnectionFailed: " + errorMessage + ": " + peerProperties); - - if (peerProperties != null) { - mModel.removePeerBeingConnectedTo(peerProperties); - showToast("Failed to connect to " + peerProperties.getName() - + ((errorMessage != null) ? (": " + errorMessage) : "")); - mLogFragment.logError("Failed to connect to peer " + peerProperties.toString() - + ((errorMessage != null) ? (": " + errorMessage) : "")); - } else { - showToast("Failed to connect" + ((errorMessage != null) ? (": " + errorMessage) : "")); - mLogFragment.logError("Failed to connect" + ((errorMessage != null) ? (": " + errorMessage) : "")); - } - - invalidateOptionsMenu(); // Update the main menu - } - - @Override - public void onDiscoveryManagerStateChanged(DiscoveryManager.DiscoveryManagerState discoveryManagerState) { - mLogFragment.logMessage("Discovery manager state changed: " + discoveryManagerState); - showToast("Discovery manager state changed: " + discoveryManagerState); - } - - @Override - public void onPeerDiscovered(PeerProperties peerProperties) { - Log.i(TAG, "onPeerDiscovered: " + peerProperties.toString()); - - if (mModel.addOrUpdatePeer(peerProperties)) { - mLogFragment.logMessage("Peer " + peerProperties.toString() + " discovered"); - - if (mSettings.getAutoConnect() && !mModel.hasConnectionToPeer(peerProperties, false)) { - if (mSettings.getAutoConnectEvenWhenIncomingConnectionEstablished() - || !mModel.hasConnectionToPeer(peerProperties, true)) { - // Do auto-connect - Log.i(TAG, "onPeerDiscovered: Auto-connecting to peer " + peerProperties.toString()); - mConnectionManager.connect(peerProperties); - } - } - } - } - - @Override - public void onPeerUpdated(PeerProperties peerProperties) { - Log.i(TAG, "onPeerUpdated: " + peerProperties.toString()); - mModel.addOrUpdatePeer(peerProperties); - mLogFragment.logMessage("Peer " + peerProperties.toString() + " updated"); - } - - @Override - public void onPeerLost(PeerProperties peerProperties) { - Log.i(TAG, "onPeerLost: " + peerProperties.toString()); - - if (mModel.hasConnectionToPeer(peerProperties)) { - // We are connected so it can't be lost - mDiscoveryManager.addOrUpdateDiscoveredPeer(peerProperties); - } else { - mModel.removePeer(peerProperties); - mLogFragment.logMessage("Peer " + peerProperties.toString() + " lost"); - } - - if (mSelectedPeerProperties.equals(peerProperties)) { - onPeerSelected(null); - } - } - - @Override - public void onBytesRead(byte[] bytes, int numberOfBytesRead, BluetoothSocketIoThread bluetoothSocketIoThread) { - Log.i(TAG, "onBytesRead: Received " + numberOfBytesRead + " bytes from peer " - + (bluetoothSocketIoThread.getPeerProperties() != null - ? bluetoothSocketIoThread.getPeerProperties().toString() : "")); - } - - @Override - public void onBytesWritten(byte[] bytes, int numberOfBytesWritten, BluetoothSocketIoThread bluetoothSocketIoThread) { - Log.i(TAG, "onBytesWritten: Sent " + numberOfBytesWritten + " bytes to peer " - + (bluetoothSocketIoThread.getPeerProperties() != null - ? bluetoothSocketIoThread.getPeerProperties().toString() : "")); - } - - @Override - public void onDisconnected(String reason, Connection connection) { - Log.i(TAG, "onDisconnected: Peer " + connection.getPeerProperties().toString() - + " disconnected: " + reason); - final Connection finalConnection = connection; - final PeerProperties peerProperties = connection.getPeerProperties(); - final String peerName = peerProperties.getName(); - final boolean wasIncoming = connection.getIsIncoming(); - - synchronized (this) { - new Thread() { - @Override - public void run() { - if (!mModel.addOrRemoveConnection(finalConnection, false) && !mShuttingDown) { - Log.e(TAG, "onDisconnected: Failed to remove the connection, because not found in the list"); - } else if (!mShuttingDown) { - Log.d(TAG, "onDisconnected: Connection " + finalConnection.toString() + " removed from the list"); - } - - finalConnection.close(true); - - final int totalNumberOfConnections = mModel.getTotalNumberOfConnections(); - - Log.i(TAG, "onDisconnected: Total number of connections is now " + totalNumberOfConnections); - - if (totalNumberOfConnections == 0) { - mCheckConnectionsTimer.cancel(); - } - - invalidateOptionsMenu(); // Update the main menu - } - }.start(); - } - - showToast(peerName + " disconnected (was " + (wasIncoming ? "incoming" : "outgoing") + ")"); - mLogFragment.logMessage("Peer " + peerProperties.toString() + " disconnected (was " + (wasIncoming ? "incoming" : "outgoing") + ")"); - } - - @Override - public void onSendDataProgress(float progressInPercentages, float transferSpeed, PeerProperties receivingPeer) { - Log.i(TAG, "onSendDataProgress: " + Math.round(progressInPercentages * 100) + " % " + transferSpeed + " MB/s"); - mModel.requestUpdateUi(); // To update the progress bar - } - - @Override - public void onDataSent(float dataSentInMegaBytes, float transferSpeed, PeerProperties receivingPeer) { - String message = "Sent " + String.format("%.2f", dataSentInMegaBytes) - + " MB with transfer speed of " + String.format("%.3f", transferSpeed) + " MB/s"; - - Log.i(TAG, "onDataSent: " + message + " to peer " + receivingPeer); - mLogFragment.logMessage(message + " to peer " + receivingPeer); - showToast(message + " to peer " + receivingPeer.getName()); - mModel.requestUpdateUi(); // To update the progress bar - invalidateOptionsMenu(); // Update the main menu - } - - @Override - public void onPeerSelected(PeerProperties peerProperties) { - mSelectedPeerProperties = peerProperties; - invalidateOptionsMenu(); // Update the main menu - } - - @Override - public void onConnectRequest(PeerProperties peerProperties) { - if (peerProperties != null) { - if (mConnectionManager.connect(peerProperties)) { - mLogFragment.logMessage("Trying to connect to peer " + peerProperties.toString()); - mModel.addPeerBeingConnectedTo(peerProperties); - invalidateOptionsMenu(); // Update the main menu - } else { - String errorMessageStub = "Failed to start connecting to peer "; - Log.e(TAG, "onConnectRequest: " + errorMessageStub + peerProperties.toString()); - mLogFragment.logError(errorMessageStub + peerProperties.toString()); - showToast(errorMessageStub + peerProperties.getName()); - } - } - } - - @Override - public void onSendDataRequest(PeerProperties peerProperties) { - Connection connection = mModel.getConnectionToPeer(peerProperties, false); - - if (connection == null) { - connection = mModel.getConnectionToPeer(peerProperties, true); - } - - if (connection != null) { - connection.sendData(); - mLogFragment.logMessage("Sending " - + String.format("%.2f", connection.getTotalDataAmountCurrentlySendingInMegaBytes()) - + " MB to peer " + peerProperties.toString()); - mModel.requestUpdateUi(); // To update the progress bar - invalidateOptionsMenu(); // Update the main menu - } else { - Log.e(TAG, "onSendDataRequest: No connection found"); - } - } - - /** - * Sends a ping message to all connected peers. - */ - private synchronized void sendPingToAllPeers() { - for (Connection connection : mModel.getConnections()) { - connection.ping(); - } - } - - /** - * Displays a toast with the given message. - * @param message The message to show. - */ - private void showToast(final String message) { - Handler handler = new Handler(mContext.getMainLooper()); - - handler.post(new Runnable() { - @Override - public void run() { - Context context = getApplicationContext(); - CharSequence text = message; - int duration = Toast.LENGTH_SHORT; - Toast toast = Toast.makeText(context, text, duration); - toast.show(); - } - }); - } - - /** - * The fragment adapter for tabs. - */ - public class MyFragmentAdapter extends FragmentPagerAdapter { - private static final int PEER_LIST_FRAGMENT = 0; - private static final int LOG_FRAGMENT = 1; - private static final int SETTINGS_FRAGMENT = 2; - - public MyFragmentAdapter(FragmentManager fragmentManager) { - super(fragmentManager); - } - - @Override - public Fragment getItem(int index) { - switch (index){ - case PEER_LIST_FRAGMENT: return mPeerListFragment; - case LOG_FRAGMENT: return mLogFragment; - case SETTINGS_FRAGMENT: return mSettingsFragment; - } - - return null; - } - - @Override - public CharSequence getPageTitle(int position) { - switch (position) { - case PEER_LIST_FRAGMENT: return "Peers"; - case LOG_FRAGMENT: return "Log"; - case SETTINGS_FRAGMENT: return "Settings"; - } - - return super.getPageTitle(position); - } - - @Override - public int getCount() { - return 3; - } - } -} diff --git a/NativeSampleApp/.gitignore b/NativeTestApp/.gitignore similarity index 100% rename from NativeSampleApp/.gitignore rename to NativeTestApp/.gitignore diff --git a/NativeSampleApp/LICENSE b/NativeTestApp/LICENSE similarity index 97% rename from NativeSampleApp/LICENSE rename to NativeTestApp/LICENSE index db9a902..c55ad57 100644 --- a/NativeSampleApp/LICENSE +++ b/NativeTestApp/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Microsoft Corporation. +Copyright (c) 2015-2016 Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/NativeSampleApp/app/.gitignore b/NativeTestApp/app/.gitignore similarity index 100% rename from NativeSampleApp/app/.gitignore rename to NativeTestApp/app/.gitignore diff --git a/NativeSampleApp/app/build.gradle b/NativeTestApp/app/build.gradle similarity index 94% rename from NativeSampleApp/app/build.gradle rename to NativeTestApp/app/build.gradle index a5fbb6c..40e65e8 100644 --- a/NativeSampleApp/app/build.gradle +++ b/NativeTestApp/app/build.gradle @@ -17,7 +17,7 @@ android { buildToolsVersion "23.0.2" defaultConfig { - applicationId "org.thaliproject.nativesample.app" + applicationId "org.thaliproject.nativetest.app" minSdkVersion 16 targetSdkVersion 23 versionCode 1 diff --git a/NativeSampleApp/app/proguard-rules.pro b/NativeTestApp/app/proguard-rules.pro similarity index 100% rename from NativeSampleApp/app/proguard-rules.pro rename to NativeTestApp/app/proguard-rules.pro diff --git a/NativeSampleApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java b/NativeTestApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java similarity index 100% rename from NativeSampleApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java rename to NativeTestApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java diff --git a/NativeSampleApp/app/src/main/AndroidManifest.xml b/NativeTestApp/app/src/main/AndroidManifest.xml similarity index 87% rename from NativeSampleApp/app/src/main/AndroidManifest.xml rename to NativeTestApp/app/src/main/AndroidManifest.xml index 637a97e..4468dbe 100644 --- a/NativeSampleApp/app/src/main/AndroidManifest.xml +++ b/NativeTestApp/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:label="@string/app_name" android:theme="@style/AppTheme" > diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java new file mode 100644 index 0000000..7066883 --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java @@ -0,0 +1,371 @@ +/* Copyright (c) 2016 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativesample.app; + +import android.bluetooth.BluetoothSocket; +import android.content.Context; +import android.os.Build; +import android.os.CountDownTimer; +import android.util.Log; +import org.thaliproject.nativesample.app.fragments.LogFragment; +import org.thaliproject.nativesample.app.model.Connection; +import org.thaliproject.nativesample.app.model.PeerAndConnectionModel; +import org.thaliproject.nativesample.app.model.Settings; +import org.thaliproject.p2p.btconnectorlib.ConnectionManager; +import org.thaliproject.p2p.btconnectorlib.DiscoveryManager; +import org.thaliproject.p2p.btconnectorlib.PeerProperties; +import org.thaliproject.p2p.btconnectorlib.utils.BluetoothSocketIoThread; +import java.io.IOException; +import java.util.UUID; + +/** + * This class is responsible for managing both peer discovery and connections. + */ +public class ConnectionEngine implements + ConnectionManager.ConnectionManagerListener, + DiscoveryManager.DiscoveryManagerListener, + Connection.Listener { + private static final String TAG = ConnectionEngine.class.getName(); + + // Service type and UUID has to be application/service specific. + // The app will only connect to peers with the matching values. + private static final String SERVICE_TYPE = "ThaliNativeSampleApp._tcp"; + private static final String SERVICE_UUID_AS_STRING = "9ab3c173-66d5-4da6-9e23-e8ce520b479b"; + private static final String SERVICE_NAME = "Thali Native Sample App"; + public static final String PEER_NAME = Build.MANUFACTURER + "_" + Build.MODEL; // Use manufacturer and device model name as the peer name + private static final UUID SERVICE_UUID = UUID.fromString(SERVICE_UUID_AS_STRING); + private static final long CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS = 10000; + + protected Settings mSettings = null; + protected ConnectionManager mConnectionManager = null; + protected DiscoveryManager mDiscoveryManager = null; + protected PeerAndConnectionModel mModel = null; + protected CountDownTimer mCheckConnectionsTimer = null; + private boolean mShuttingDown = false; + + /** + * Constructor. + */ + public ConnectionEngine(Context context) { + mModel = PeerAndConnectionModel.getInstance(); + mSettings = Settings.getInstance(context); + mSettings.load(); + mConnectionManager = new ConnectionManager(context, this, SERVICE_UUID, SERVICE_NAME); + mDiscoveryManager = new DiscoveryManager(context, this, SERVICE_UUID, SERVICE_TYPE); + mSettings.setDiscoveryManager(mDiscoveryManager); + } + + /** + * Starts both the connection and the discovery manager. + * @return True, if started successfully. False otherwise. + */ + public synchronized boolean start() { + mShuttingDown = false; + boolean wasStarted = false; + + if (mConnectionManager.start(PEER_NAME) && mDiscoveryManager.start(PEER_NAME)) { + if (mCheckConnectionsTimer != null) { + mCheckConnectionsTimer.cancel(); + mCheckConnectionsTimer = null; + } + + mCheckConnectionsTimer = new CountDownTimer( + CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS, + CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS) { + @Override + public void onTick(long l) { + // Not used + } + + @Override + public void onFinish() { + sendPingToAllPeers(); + mCheckConnectionsTimer.start(); + } + }; + + wasStarted = true; + } else { + Log.e(TAG, "start: Failed to start"); + LogFragment.logError("Failed to start either the connection or the discovery manager"); + } + + return wasStarted; + } + + /** + * Stops both the connection and the discovery manager. + */ + public synchronized void stop() { + mShuttingDown = true; + + if (mConnectionManager != null) { + mCheckConnectionsTimer.cancel(); + } + + mModel.closeAllConnections(); + mConnectionManager.stop(); + mDiscoveryManager.stop(); + } + + /** + * Connects to the peer with the given properties. + * @param peerProperties The properties of the peer to connect to. + */ + public synchronized void connect(PeerProperties peerProperties) { + if (peerProperties != null) { + if (mConnectionManager.connect(peerProperties)) { + LogFragment.logMessage("Trying to connect to peer " + peerProperties.toString()); + mModel.addPeerBeingConnectedTo(peerProperties); + MainActivity.updateOptionsMenu(); + } else { + String errorMessageStub = "Failed to start connecting to peer "; + Log.e(TAG, "connect: " + errorMessageStub + peerProperties.toString()); + LogFragment.logError(errorMessageStub + peerProperties.toString()); + MainActivity.showToast(errorMessageStub + peerProperties.getName()); + } + } + } + + /** + * Starts sending data to the peer with the given properties. + * @param peerProperties The properties of the peer to send data to. + */ + public synchronized void startSendingData(PeerProperties peerProperties) { + Connection connection = mModel.getConnectionToPeer(peerProperties, false); + + if (connection == null) { + connection = mModel.getConnectionToPeer(peerProperties, true); + } + + if (connection != null) { + connection.sendData(); + LogFragment.logMessage("Sending " + + String.format("%.2f", connection.getTotalDataAmountCurrentlySendingInMegaBytes()) + + " MB to peer " + peerProperties.toString()); + mModel.requestUpdateUi(); // To update the progress bar + MainActivity.updateOptionsMenu(); + } else { + Log.e(TAG, "startSendingData: No connection found"); + } + } + + @Override + public void onConnectionManagerStateChanged(ConnectionManager.ConnectionManagerState connectionManagerState) { + LogFragment.logMessage("Connection manager state changed: " + connectionManagerState); + } + + /** + * Constructs a Bluetooth socket IO thread for the new connection and adds it to the list of + * connections. + * @param bluetoothSocket The Bluetooth socket. + * @param isIncoming If true, this is an incoming connection. If false, this is an outgoing connection. + * @param peerProperties The peer properties. + */ + @Override + public void onConnected(BluetoothSocket bluetoothSocket, boolean isIncoming, PeerProperties peerProperties) { + Log.i(TAG, "onConnected: " + (isIncoming ? "Incoming" : "Outgoing") + " connection: " + peerProperties.toString()); + mModel.removePeerBeingConnectedTo(peerProperties); + Connection connection = null; + + try { + connection = new Connection(this, bluetoothSocket, peerProperties, isIncoming); + } catch (Exception e) { + Log.e(TAG, "onConnected: Failed to create a socket IO thread instance: " + e.getMessage(), e); + + try { + bluetoothSocket.close(); + } catch (IOException e2) { + } + } + + if (connection != null) { + final String peerName = connection.getPeerProperties().getName(); + final boolean wasIncoming = connection.getIsIncoming(); + + mModel.addOrRemoveConnection(connection, true); + + MainActivity.showToast(peerName + " connected (is " + (wasIncoming ? "incoming" : "outgoing") + ")"); + + if (isIncoming) { + // Add peer, if it was not discovered before + mModel.addOrUpdatePeer(peerProperties); + mDiscoveryManager.addOrUpdateDiscoveredPeer(peerProperties); + } + + // Update the peer name, if already in the model + mModel.updatePeerName(peerProperties); + + LogFragment.logMessage((isIncoming ? "Incoming" : "Outgoing") + " connection established to peer " + peerProperties.toString()); + } + + final int totalNumberOfConnections = mModel.getTotalNumberOfConnections(); + + Log.i(TAG, "onConnected: Total number of connections is now " + totalNumberOfConnections); + + if (totalNumberOfConnections == 1) { + mCheckConnectionsTimer.cancel(); + mCheckConnectionsTimer.start(); + } + + MainActivity.updateOptionsMenu(); + } + + @Override + public void onConnectionTimeout(PeerProperties peerProperties) { + Log.i(TAG, "onConnectionTimeout: " + peerProperties); + + if (peerProperties != null) { + mModel.removePeerBeingConnectedTo(peerProperties); + MainActivity.showToast("Failed to connect to " + peerProperties.getName() + ": Connection timeout"); + LogFragment.logError("Failed to connect to peer " + peerProperties.toString() + ": Connection timeout"); + } else { + MainActivity.showToast("Failed to connect: Connection timeout"); + LogFragment.logError("Failed to connect: Connection timeout"); + } + + MainActivity.updateOptionsMenu(); + } + + @Override + public void onConnectionFailed(PeerProperties peerProperties, String errorMessage) { + Log.i(TAG, "onConnectionFailed: " + errorMessage + ": " + peerProperties); + + if (peerProperties != null) { + mModel.removePeerBeingConnectedTo(peerProperties); + MainActivity.showToast("Failed to connect to " + peerProperties.getName() + + ((errorMessage != null) ? (": " + errorMessage) : "")); + LogFragment.logError("Failed to connect to peer " + peerProperties.toString() + + ((errorMessage != null) ? (": " + errorMessage) : "")); + } else { + MainActivity.showToast("Failed to connect" + ((errorMessage != null) ? (": " + errorMessage) : "")); + LogFragment.logError("Failed to connect" + ((errorMessage != null) ? (": " + errorMessage) : "")); + } + + MainActivity.updateOptionsMenu(); + } + + @Override + public void onDiscoveryManagerStateChanged(DiscoveryManager.DiscoveryManagerState discoveryManagerState) { + LogFragment.logMessage("Discovery manager state changed: " + discoveryManagerState); + MainActivity.showToast("Discovery manager state changed: " + discoveryManagerState); + } + + @Override + public void onPeerDiscovered(PeerProperties peerProperties) { + Log.i(TAG, "onPeerDiscovered: " + peerProperties.toString()); + + if (mModel.addOrUpdatePeer(peerProperties)) { + LogFragment.logMessage("Peer " + peerProperties.toString() + " discovered"); + + if (mSettings.getAutoConnect() && !mModel.hasConnectionToPeer(peerProperties, false)) { + if (mSettings.getAutoConnectEvenWhenIncomingConnectionEstablished() + || !mModel.hasConnectionToPeer(peerProperties, true)) { + // Do auto-connect + Log.i(TAG, "onPeerDiscovered: Auto-connecting to peer " + peerProperties.toString()); + mConnectionManager.connect(peerProperties); + } + } + } + } + + @Override + public void onPeerUpdated(PeerProperties peerProperties) { + Log.i(TAG, "onPeerUpdated: " + peerProperties.toString()); + mModel.addOrUpdatePeer(peerProperties); + LogFragment.logMessage("Peer " + peerProperties.toString() + " updated"); + } + + @Override + public void onPeerLost(PeerProperties peerProperties) { + Log.i(TAG, "onPeerLost: " + peerProperties.toString()); + + if (mModel.hasConnectionToPeer(peerProperties)) { + // We are connected so it can't be lost + mDiscoveryManager.addOrUpdateDiscoveredPeer(peerProperties); + } else { + mModel.removePeer(peerProperties); + LogFragment.logMessage("Peer " + peerProperties.toString() + " lost"); + } + } + + @Override + public void onBytesRead(byte[] bytes, int numberOfBytesRead, BluetoothSocketIoThread bluetoothSocketIoThread) { + Log.v(TAG, "onBytesRead: Received " + numberOfBytesRead + " bytes from peer " + + (bluetoothSocketIoThread.getPeerProperties() != null + ? bluetoothSocketIoThread.getPeerProperties().toString() : "")); + } + + @Override + public void onBytesWritten(byte[] bytes, int numberOfBytesWritten, BluetoothSocketIoThread bluetoothSocketIoThread) { + Log.v(TAG, "onBytesWritten: Sent " + numberOfBytesWritten + " bytes to peer " + + (bluetoothSocketIoThread.getPeerProperties() != null + ? bluetoothSocketIoThread.getPeerProperties().toString() : "")); + } + + @Override + public void onDisconnected(String reason, Connection connection) { + Log.i(TAG, "onDisconnected: Peer " + connection.getPeerProperties().toString() + + " disconnected: " + reason); + final Connection finalConnection = connection; + final PeerProperties peerProperties = connection.getPeerProperties(); + final String peerName = peerProperties.getName(); + final boolean wasIncoming = connection.getIsIncoming(); + + synchronized (this) { + new Thread() { + @Override + public void run() { + if (!mModel.addOrRemoveConnection(finalConnection, false) && !mShuttingDown) { + Log.e(TAG, "onDisconnected: Failed to remove the connection, because not found in the list"); + } else if (!mShuttingDown) { + Log.d(TAG, "onDisconnected: Connection " + finalConnection.toString() + " removed from the list"); + } + + finalConnection.close(true); + + final int totalNumberOfConnections = mModel.getTotalNumberOfConnections(); + + Log.i(TAG, "onDisconnected: Total number of connections is now " + totalNumberOfConnections); + + if (totalNumberOfConnections == 0) { + mCheckConnectionsTimer.cancel(); + } + + MainActivity.updateOptionsMenu(); + } + }.start(); + } + + MainActivity.showToast(peerName + " disconnected (was " + (wasIncoming ? "incoming" : "outgoing") + ")"); + LogFragment.logMessage("Peer " + peerProperties.toString() + " disconnected (was " + (wasIncoming ? "incoming" : "outgoing") + ")"); + } + + @Override + public void onSendDataProgress(float progressInPercentages, float transferSpeed, PeerProperties receivingPeer) { + Log.i(TAG, "onSendDataProgress: " + Math.round(progressInPercentages * 100) + " % " + transferSpeed + " MB/s"); + mModel.requestUpdateUi(); // To update the progress bar + } + + @Override + public void onDataSent(float dataSentInMegaBytes, float transferSpeed, PeerProperties receivingPeer) { + String message = "Sent " + String.format("%.2f", dataSentInMegaBytes) + + " MB with transfer speed of " + String.format("%.3f", transferSpeed) + " MB/s"; + + Log.i(TAG, "onDataSent: " + message + " to peer " + receivingPeer); + LogFragment.logMessage(message + " to peer " + receivingPeer); + MainActivity.showToast(message + " to peer " + receivingPeer.getName()); + mModel.requestUpdateUi(); // To update the progress bar + MainActivity.updateOptionsMenu(); + } + + /** + * Sends a ping message to all connected peers. + */ + protected synchronized void sendPingToAllPeers() { + for (Connection connection : mModel.getConnections()) { + connection.ping(); + } + } +} diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java new file mode 100644 index 0000000..76847dd --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java @@ -0,0 +1,252 @@ +/* Copyright (c) 2015 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativesample.app; + +import android.content.Context; +import android.os.Handler; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.app.ActionBar; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.os.Bundle; +import android.support.v4.view.ViewPager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; +import org.thaliproject.nativesample.app.fragments.LogFragment; +import org.thaliproject.nativesample.app.fragments.PeerListFragment; +import org.thaliproject.nativesample.app.fragments.SettingsFragment; +import org.thaliproject.nativesample.app.model.PeerAndConnectionModel; +import org.thaliproject.nativesample.app.slidingtabs.SlidingTabLayout; +import org.thaliproject.nativesample.app.utils.MenuUtils; +import org.thaliproject.p2p.btconnectorlib.PeerProperties; + +public class MainActivity + extends AppCompatActivity + implements PeerListFragment.Listener, TestEngine.Listener { + + private static final String TAG = MainActivity.class.getName(); + + private static MainActivity mThisInstance = null; + private static Context mContext = null; + + private ConnectionEngine mConnectionEngine = null; + + /** + * The {@link android.support.v4.view.PagerAdapter} that will provide + * fragments for each of the sections. We use a + * {@link FragmentPagerAdapter} derivative, which will keep every + * loaded fragment in memory. If this becomes too memory intensive, it + * may be best to switch to a + * {@link android.support.v4.app.FragmentStatePagerAdapter}. + */ + private MyFragmentAdapter mMyFragmentAdapter; + + /** + * The {@link ViewPager} that will host the section contents. + */ + private ViewPager mViewPager; + + private SlidingTabLayout mSlidingTabLayout; + private PeerListFragment mPeerListFragment = null; + private LogFragment mLogFragment = null; + private SettingsFragment mSettingsFragment = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + mThisInstance = this; + mContext = getApplicationContext(); + + if (mConnectionEngine == null) { + mConnectionEngine = new ConnectionEngine(mContext); + } + + // Set up the action bar. + final ActionBar actionBar = getSupportActionBar(); + + mMyFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager()); + + mViewPager = (ViewPager)findViewById(R.id.pager); + mViewPager.setAdapter(mMyFragmentAdapter); + + mSlidingTabLayout = (SlidingTabLayout)findViewById(R.id.sliding_tabs); + mSlidingTabLayout.setViewPager(mViewPager); + + mPeerListFragment = new PeerListFragment(); + mPeerListFragment.setListener(this); + + mLogFragment = new LogFragment(); + + mSettingsFragment = new SettingsFragment(); + + mConnectionEngine.start(); + } + + /** + * Updates the options menu. + */ + public static void updateOptionsMenu() { + if (mThisInstance != null) { + Log.d(TAG, "updateOptionsMenu"); + mThisInstance.invalidateOptionsMenu(); + } + } + + /** + * Displays a toast with the given message. + * @param message The message to show. + */ + public static void showToast(final String message) { + final Context context = mContext; + + if (context != null) { + Handler handler = new Handler(mContext.getMainLooper()); + + handler.post(new Runnable() { + @Override + public void run() { + CharSequence text = message; + int duration = Toast.LENGTH_SHORT; + Toast toast = Toast.makeText(context, text, duration); + toast.show(); + } + }); + } + } + + @Override + public void onDestroy() { + mConnectionEngine.stop(); + super.onDestroy(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + MenuUtils.PeerMenuItemsAvailability availability = + MenuUtils.resolvePeerMenuItemsAvailability( + mPeerListFragment.getSelectedPeerProperties(), PeerAndConnectionModel.getInstance()); + + MenuItem connectMenuItem = menu.getItem(0); + MenuItem sendDataMenuItem = menu.getItem(1); + MenuItem disconnectMenuItem = menu.getItem(2); + MenuItem killAllConnectionsMenuItem = menu.getItem(3); + + connectMenuItem.setVisible(availability.connectMenuItemAvailable); + connectMenuItem.setEnabled(availability.connectMenuItemAvailable); + sendDataMenuItem.setVisible(availability.sendDataMenuItemAvailable); + sendDataMenuItem.setEnabled(availability.sendDataMenuItemAvailable); + disconnectMenuItem.setEnabled(availability.disconnectMenuItemAvailable); + killAllConnectionsMenuItem.setEnabled(availability.killAllConnectionsMenuItemAvailable); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + boolean wasConsumed = false; + PeerProperties peerProperties = mPeerListFragment.getSelectedPeerProperties(); + PeerAndConnectionModel model = PeerAndConnectionModel.getInstance(); + + switch (id) { + case R.id.action_connect: + onConnectRequest(peerProperties); // Has a null check + wasConsumed = true; + break; + case R.id.action_disconnect: + if (peerProperties != null) { + if (model.closeConnection(peerProperties)) { + wasConsumed = true; + } + } + + break; + case R.id.action_send_data: + onSendDataRequest(peerProperties); // Has a null check + wasConsumed = true; + break; + case R.id.action_kill_all_connections: + model.closeAllConnections(); + wasConsumed = true; + break; + } + + return wasConsumed || super.onOptionsItemSelected(item); + } + + + @Override + public void onPeerSelected(PeerProperties peerProperties) { + updateOptionsMenu(); + } + + @Override + public void onConnectRequest(PeerProperties peerProperties) { + mConnectionEngine.connect(peerProperties); + } + + @Override + public void onSendDataRequest(PeerProperties peerProperties) { + mConnectionEngine.startSendingData(peerProperties); + } + + @Override + public void onTestFinished() { + } + + /** + * The fragment adapter for tabs. + */ + public class MyFragmentAdapter extends FragmentPagerAdapter { + private static final int PEER_LIST_FRAGMENT = 0; + private static final int LOG_FRAGMENT = 1; + private static final int SETTINGS_FRAGMENT = 2; + + public MyFragmentAdapter(FragmentManager fragmentManager) { + super(fragmentManager); + } + + @Override + public Fragment getItem(int index) { + switch (index){ + case PEER_LIST_FRAGMENT: return mPeerListFragment; + case LOG_FRAGMENT: return mLogFragment; + case SETTINGS_FRAGMENT: return mSettingsFragment; + } + + return null; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case PEER_LIST_FRAGMENT: return "Peers"; + case LOG_FRAGMENT: return "Log"; + case SETTINGS_FRAGMENT: return "Settings"; + } + + return super.getPageTitle(position); + } + + @Override + public int getCount() { + return 3; + } + } +} diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java new file mode 100644 index 0000000..27307c9 --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java @@ -0,0 +1,19 @@ +/* Copyright (c) 2016 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativesample.app; + +import android.content.Context; + +/** + * A connection engine to run tests. + */ +public class TestEngine extends ConnectionEngine { + public interface Listener { + void onTestFinished(); + } + + public TestEngine(Context context) { + super(context); + } +} diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/LogFragment.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/LogFragment.java similarity index 89% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/LogFragment.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/LogFragment.java index 017ce2d..1b4e9cb 100644 --- a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/LogFragment.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/LogFragment.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2015 Microsoft Corporation. This software is licensed under the MIT License. +/* Copyright (c) 2015-2016 Microsoft Corporation. This software is licensed under the MIT License. * See the license file delivered with this project for further information. */ package org.thaliproject.nativesample.app.fragments; @@ -27,10 +27,10 @@ public class LogFragment extends Fragment { private static final String TAG = LogFragment.class.getName(); private static final int MAX_NUMBER_OF_LOG_ITEMS = 50; - private Context mContext = null; + private static Context mContext = null; + private static CopyOnWriteArrayList mLog = new CopyOnWriteArrayList(); + private static ListAdapter mListAdapter = null; private ListView mListView = null; - private ListAdapter mListAdapter = null; - private CopyOnWriteArrayList mLog = new CopyOnWriteArrayList(); private ColorStateList mDefaultTextViewColors = null; public LogFragment() { @@ -59,7 +59,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, * Adds a new log item with the given message. * @param message The message for the log item. */ - public void logMessage(String message) { + public static void logMessage(String message) { addLogItem(message, false); } @@ -67,7 +67,7 @@ public void logMessage(String message) { * Adds a new log item with the given error message. * @param errorMessage The error message for the log item. */ - public void logError(String errorMessage) { + public static void logError(String errorMessage) { addLogItem(errorMessage, true); } @@ -76,7 +76,7 @@ public void logError(String errorMessage) { * @param message The message for the log item. * @param isError If true, will mark this message as an error. */ - private synchronized void addLogItem(String message, boolean isError) { + private static synchronized void addLogItem(String message, boolean isError) { Timestamp timestamp = new Timestamp(new Date().getTime()); LogItem logItem = new LogItem(timestamp, message, isError); mLog.add(0, logItem); @@ -85,7 +85,7 @@ private synchronized void addLogItem(String message, boolean isError) { mLog.remove(mLog.size() - 1); // Remove the last item } - if (mContext != null) { + if (mContext != null && mListAdapter != null) { Handler handler = new Handler(mContext.getMainLooper()); handler.post(new Runnable() { diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/PeerListFragment.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/PeerListFragment.java similarity index 92% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/PeerListFragment.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/PeerListFragment.java index 6c03d3f..8aae181 100644 --- a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/PeerListFragment.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/PeerListFragment.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2015 Microsoft Corporation. This software is licensed under the MIT License. +/* Copyright (c) 2015-2016 Microsoft Corporation. This software is licensed under the MIT License. * See the license file delivered with this project for further information. */ package org.thaliproject.nativesample.app.fragments; @@ -95,6 +95,13 @@ public void onNothingSelected(AdapterView adapterView) { } } + /** + * @return The selected peer properties. + */ + public PeerProperties getSelectedPeerProperties() { + return mSelectedPeerProperties; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -198,6 +205,32 @@ public void run() { }); } + @Override + public void onPeerRemoved(final PeerProperties peerProperties) { + Log.i(TAG, "onPeerRemoved: " + peerProperties); + final boolean peerRemovedWasSelected; + + if (mSelectedPeerProperties != null && mSelectedPeerProperties.equals(peerProperties)) { + mSelectedPeerProperties = null; + peerRemovedWasSelected = true; + } else { + peerRemovedWasSelected = false; + } + + Handler handler = new Handler(mContext.getMainLooper()); + + handler.post(new Runnable() { + @Override + public void run() { + if (peerRemovedWasSelected) { + mListener.onPeerSelected(null); + } + + mListAdapter.notifyDataSetChanged(); + } + }); + } + class ListAdapter extends BaseAdapter { private LayoutInflater mInflater = null; private Context mContext; diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/SettingsFragment.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/SettingsFragment.java similarity index 99% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/SettingsFragment.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/SettingsFragment.java index 1ae3dd0..7d79506 100644 --- a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/fragments/SettingsFragment.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/SettingsFragment.java @@ -3,7 +3,6 @@ */ package org.thaliproject.nativesample.app.fragments; -import android.bluetooth.le.AdvertiseSettings; import android.os.Bundle; import android.support.v4.app.Fragment; import android.text.Editable; diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/Connection.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Connection.java similarity index 100% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/Connection.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Connection.java diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/LogItem.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/LogItem.java similarity index 100% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/LogItem.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/LogItem.java diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/PeerAndConnectionModel.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java similarity index 98% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/PeerAndConnectionModel.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java index 971774e..05c958f 100644 --- a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/PeerAndConnectionModel.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2015 Microsoft Corporation. This software is licensed under the MIT License. +/* Copyright (c) 2015-2016 Microsoft Corporation. This software is licensed under the MIT License. * See the license file delivered with this project for further information. */ package org.thaliproject.nativesample.app.model; @@ -15,6 +15,7 @@ public class PeerAndConnectionModel { public interface Listener { void onDataChanged(); + void onPeerRemoved(PeerProperties peerProperties); } private static final String TAG = PeerAndConnectionModel.class.getName(); @@ -122,7 +123,7 @@ public boolean removePeer(final PeerProperties peerProperties) { boolean wasRemoved = removePeerPropertiesFromList(peerProperties, mPeers); if (wasRemoved && mListener != null) { - mListener.onDataChanged(); + mListener.onPeerRemoved(peerProperties); } return wasRemoved; diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/Settings.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Settings.java similarity index 100% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/model/Settings.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Settings.java diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/slidingtabs/SlidingTabLayout.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/slidingtabs/SlidingTabLayout.java similarity index 100% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/slidingtabs/SlidingTabLayout.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/slidingtabs/SlidingTabLayout.java diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/slidingtabs/SlidingTabStrip.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/slidingtabs/SlidingTabStrip.java similarity index 100% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/slidingtabs/SlidingTabStrip.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/slidingtabs/SlidingTabStrip.java diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java new file mode 100644 index 0000000..222d342 --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java @@ -0,0 +1,49 @@ +/* Copyright (c) 2016 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativesample.app.test; + +/** + * An abstract base class for tests. + */ +public abstract class AbstractTest { + public static final long DEFAULT_TEST_TIMEOUT_IN_MILLISECONDS = 30000; + public static final int DEFAULT_NUMBER_OF_DESIRED_PEERS = 1; + + protected long mTestTimeoutInMilliseconds = DEFAULT_TEST_TIMEOUT_IN_MILLISECONDS; + protected int mNumberOfDesiredPeers = DEFAULT_NUMBER_OF_DESIRED_PEERS; + + /** + * @return The test timeout in milliseconds. + */ + public long getTestTimeout() { + return mTestTimeoutInMilliseconds; + } + + /** + * @param testTimeoutInMilliseconds The test timeout in milliseconds. + */ + public void setTestTimeout(long testTimeoutInMilliseconds) { + mTestTimeoutInMilliseconds = testTimeoutInMilliseconds; + } + + public int getNumberOfDesiredPeers() { + return mNumberOfDesiredPeers; + } + + public void setNumberOfDesiredPeers(int numberOfDesiredPeers) { + mNumberOfDesiredPeers = numberOfDesiredPeers; + } + + /** + * Starts the test. + * @return True, if successfully started. False otherwise. + */ + public abstract boolean run(); + + /** + * Cancels the test. + */ + public void cancel() { + } +} diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java new file mode 100644 index 0000000..81cf360 --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java @@ -0,0 +1,14 @@ +/* Copyright (c) 2016 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativesample.app.test; + +/** + * A test for requesting a peer to provide us our Bluetooth MAC address. + */ +public class FindMyBluetoothAddressTest extends AbstractTest { + @Override + public boolean run() { + return false; + } +} diff --git a/NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/utils/MenuUtils.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/utils/MenuUtils.java similarity index 100% rename from NativeSampleApp/app/src/main/java/org/thaliproject/nativesample/app/utils/MenuUtils.java rename to NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/utils/MenuUtils.java diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_downward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_arrow_upward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_compare_arrows_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_send_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_send_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_send_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_send_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-hdpi/ic_swap_horiz_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-ldrtl-hdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-ldrtl-hdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-ldrtl-hdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-ldrtl-hdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-ldrtl-mdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-ldrtl-mdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-ldrtl-mdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-ldrtl-mdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-ldrtl-xhdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-ldrtl-xhdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-ldrtl-xhdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-ldrtl-xhdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-ldrtl-xxhdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-ldrtl-xxhdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-ldrtl-xxhdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-ldrtl-xxhdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-ldrtl-xxxhdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-ldrtl-xxxhdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-ldrtl-xxxhdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-ldrtl-xxxhdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_downward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_arrow_upward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_compare_arrows_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_send_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_send_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_send_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_send_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-mdpi/ic_swap_horiz_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_downward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_arrow_upward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_compare_arrows_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xhdpi/ic_swap_horiz_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_downward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_arrow_upward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_compare_arrows_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_send_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_send_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_send_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_send_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxhdpi/ic_swap_horiz_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_downward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_blue_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_blue_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_blue_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_blue_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_gray_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_gray_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_gray_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_gray_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_green_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_green_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_green_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_arrow_upward_green_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_compare_arrows_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_send_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_send_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_send_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_send_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_black_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_black_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_black_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_black_24dp.png diff --git a/NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_white_24dp.png b/NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_white_24dp.png similarity index 100% rename from NativeSampleApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_white_24dp.png rename to NativeTestApp/app/src/main/res/drawable-xxxhdpi/ic_swap_horiz_white_24dp.png diff --git a/NativeSampleApp/app/src/main/res/layout/activity_main.xml b/NativeTestApp/app/src/main/res/layout/activity_main.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/layout/activity_main.xml rename to NativeTestApp/app/src/main/res/layout/activity_main.xml diff --git a/NativeSampleApp/app/src/main/res/layout/fragment_log.xml b/NativeTestApp/app/src/main/res/layout/fragment_log.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/layout/fragment_log.xml rename to NativeTestApp/app/src/main/res/layout/fragment_log.xml diff --git a/NativeSampleApp/app/src/main/res/layout/fragment_peers.xml b/NativeTestApp/app/src/main/res/layout/fragment_peers.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/layout/fragment_peers.xml rename to NativeTestApp/app/src/main/res/layout/fragment_peers.xml diff --git a/NativeSampleApp/app/src/main/res/layout/fragment_settings.xml b/NativeTestApp/app/src/main/res/layout/fragment_settings.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/layout/fragment_settings.xml rename to NativeTestApp/app/src/main/res/layout/fragment_settings.xml diff --git a/NativeSampleApp/app/src/main/res/layout/list_item_peer.xml b/NativeTestApp/app/src/main/res/layout/list_item_peer.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/layout/list_item_peer.xml rename to NativeTestApp/app/src/main/res/layout/list_item_peer.xml diff --git a/NativeSampleApp/app/src/main/res/layout/log_item.xml b/NativeTestApp/app/src/main/res/layout/log_item.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/layout/log_item.xml rename to NativeTestApp/app/src/main/res/layout/log_item.xml diff --git a/NativeSampleApp/app/src/main/res/menu/menu_main.xml b/NativeTestApp/app/src/main/res/menu/menu_main.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/menu/menu_main.xml rename to NativeTestApp/app/src/main/res/menu/menu_main.xml diff --git a/NativeSampleApp/app/src/main/res/menu/menu_peers.xml b/NativeTestApp/app/src/main/res/menu/menu_peers.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/menu/menu_peers.xml rename to NativeTestApp/app/src/main/res/menu/menu_peers.xml diff --git a/NativeSampleApp/app/src/main/res/mipmap-hdpi/ic_launcher.png b/NativeTestApp/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from NativeSampleApp/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to NativeTestApp/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/NativeSampleApp/app/src/main/res/mipmap-mdpi/ic_launcher.png b/NativeTestApp/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from NativeSampleApp/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to NativeTestApp/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/NativeSampleApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/NativeTestApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from NativeSampleApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to NativeTestApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/NativeSampleApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/NativeTestApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from NativeSampleApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to NativeTestApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/NativeSampleApp/app/src/main/res/mipmap-xxhdpi/ic_launcher_original.png b/NativeTestApp/app/src/main/res/mipmap-xxhdpi/ic_launcher_original.png similarity index 100% rename from NativeSampleApp/app/src/main/res/mipmap-xxhdpi/ic_launcher_original.png rename to NativeTestApp/app/src/main/res/mipmap-xxhdpi/ic_launcher_original.png diff --git a/NativeSampleApp/app/src/main/res/values-w820dp/dimens.xml b/NativeTestApp/app/src/main/res/values-w820dp/dimens.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/values-w820dp/dimens.xml rename to NativeTestApp/app/src/main/res/values-w820dp/dimens.xml diff --git a/NativeSampleApp/app/src/main/res/values/dimens.xml b/NativeTestApp/app/src/main/res/values/dimens.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/values/dimens.xml rename to NativeTestApp/app/src/main/res/values/dimens.xml diff --git a/NativeSampleApp/app/src/main/res/values/strings.xml b/NativeTestApp/app/src/main/res/values/strings.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/values/strings.xml rename to NativeTestApp/app/src/main/res/values/strings.xml diff --git a/NativeSampleApp/app/src/main/res/values/styles.xml b/NativeTestApp/app/src/main/res/values/styles.xml similarity index 100% rename from NativeSampleApp/app/src/main/res/values/styles.xml rename to NativeTestApp/app/src/main/res/values/styles.xml diff --git a/NativeSampleApp/build.gradle b/NativeTestApp/build.gradle similarity index 100% rename from NativeSampleApp/build.gradle rename to NativeTestApp/build.gradle diff --git a/NativeSampleApp/gradle.properties b/NativeTestApp/gradle.properties similarity index 100% rename from NativeSampleApp/gradle.properties rename to NativeTestApp/gradle.properties diff --git a/NativeSampleApp/gradle/wrapper/gradle-wrapper.jar b/NativeTestApp/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from NativeSampleApp/gradle/wrapper/gradle-wrapper.jar rename to NativeTestApp/gradle/wrapper/gradle-wrapper.jar diff --git a/NativeSampleApp/gradle/wrapper/gradle-wrapper.properties b/NativeTestApp/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from NativeSampleApp/gradle/wrapper/gradle-wrapper.properties rename to NativeTestApp/gradle/wrapper/gradle-wrapper.properties diff --git a/NativeSampleApp/gradlew b/NativeTestApp/gradlew similarity index 100% rename from NativeSampleApp/gradlew rename to NativeTestApp/gradlew diff --git a/NativeSampleApp/gradlew.bat b/NativeTestApp/gradlew.bat similarity index 100% rename from NativeSampleApp/gradlew.bat rename to NativeTestApp/gradlew.bat diff --git a/NativeSampleApp/settings.gradle b/NativeTestApp/settings.gradle similarity index 100% rename from NativeSampleApp/settings.gradle rename to NativeTestApp/settings.gradle From ac11c2375a2144b7cceed74b98328cb09d5fd8c7 Mon Sep 17 00:00:00 2001 From: Tomi Paananen Date: Mon, 11 Jan 2016 14:05:59 +0200 Subject: [PATCH 02/79] Commit to #36: Updated the package name in code files to fix the build errors. --- BtConnectorLib/LICENSE | 2 +- LICENSE | 2 +- NativeTestApp/LICENSE | 2 +- .../nativesample/app/ApplicationTest.java | 2 +- NativeTestApp/app/src/main/AndroidManifest.xml | 2 +- .../nativetest/app/ConnectionEngine.java | 10 +++++----- .../thaliproject/nativetest/app/MainActivity.java | 14 +++++++------- .../thaliproject/nativetest/app/TestEngine.java | 2 +- .../nativetest/app/fragments/LogFragment.java | 6 +++--- .../nativetest/app/fragments/PeerListFragment.java | 10 +++++----- .../nativetest/app/fragments/SettingsFragment.java | 6 +++--- .../nativetest/app/model/Connection.java | 2 +- .../thaliproject/nativetest/app/model/LogItem.java | 2 +- .../app/model/PeerAndConnectionModel.java | 2 +- .../nativetest/app/model/Settings.java | 7 ++++--- .../app/slidingtabs/SlidingTabLayout.java | 2 +- .../app/slidingtabs/SlidingTabStrip.java | 2 +- .../nativetest/app/test/AbstractTest.java | 2 +- .../app/test/FindMyBluetoothAddressTest.java | 2 +- .../nativetest/app/utils/MenuUtils.java | 6 +++--- .../app/src/main/res/layout/activity_main.xml | 2 +- NativeTestApp/app/src/main/res/layout/log_item.xml | 2 +- 22 files changed, 45 insertions(+), 44 deletions(-) diff --git a/BtConnectorLib/LICENSE b/BtConnectorLib/LICENSE index b76e652..5aef34c 100644 --- a/BtConnectorLib/LICENSE +++ b/BtConnectorLib/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Microsoft Corporation. +Copyright (c) 2015-2016 Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/LICENSE b/LICENSE index 7b2a400..1d7efe3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Microsoft Corporation. +Copyright (c) 2015-2016 Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/NativeTestApp/LICENSE b/NativeTestApp/LICENSE index c55ad57..5d0419f 100644 --- a/NativeTestApp/LICENSE +++ b/NativeTestApp/LICENSE @@ -20,7 +20,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- The Sliding Tabs UI components (all files in package -`org.thaliproject.nativesample.app.slidingtabs` are part of the Android Open +`org.thaliproject.nativetest.app.slidingtabs` are part of the Android Open Source Project and licensed under Apache License, version 2.0: Copyright (C) 2013 The Android Open Source Project diff --git a/NativeTestApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java b/NativeTestApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java index d17d7f6..37d9939 100644 --- a/NativeTestApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java +++ b/NativeTestApp/app/src/androidTest/java/org/thaliproject/nativesample/app/ApplicationTest.java @@ -1,4 +1,4 @@ -package org.thaliproject.nativesample.app; +package org.thaliproject.nativetest.app; import android.app.Application; import android.test.ApplicationTestCase; diff --git a/NativeTestApp/app/src/main/AndroidManifest.xml b/NativeTestApp/app/src/main/AndroidManifest.xml index 4468dbe..d43be97 100644 --- a/NativeTestApp/app/src/main/AndroidManifest.xml +++ b/NativeTestApp/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="org.thaliproject.nativetest.app" > - diff --git a/NativeTestApp/app/src/main/res/layout/log_item.xml b/NativeTestApp/app/src/main/res/layout/log_item.xml index 729c8fa..6613aab 100644 --- a/NativeTestApp/app/src/main/res/layout/log_item.xml +++ b/NativeTestApp/app/src/main/res/layout/log_item.xml @@ -17,6 +17,6 @@ android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Log message DEVICE SHELL COMMAND: am start -D -n org.thaliproject.nativesample.app/org.thaliproject.nativesample.app.MainActivity -a android.intent.action.MAIN -c android.intent.category.LAUNCHER" + android:text="Log message DEVICE SHELL COMMAND: am start -D -n org.thaliproject.nativetest.app/org.thaliproject.nativetest.app.MainActivity -a android.intent.action.MAIN -c android.intent.category.LAUNCHER" android:textSize="12sp" /> From 256783152395756fe12319b0dd63695f61b47caf Mon Sep 17 00:00:00 2001 From: Tomi Paananen Date: Mon, 11 Jan 2016 16:21:44 +0200 Subject: [PATCH 03/79] Commit to #36: Fixed settings issue with having two connection engines (the other one is the test engine). --- .../app/src/main/AndroidManifest.xml | 2 +- .../nativetest/app/ConnectionEngine.java | 73 ++++++++----- .../nativetest/app/MainActivity.java | 21 +++- .../nativetest/app/TestEngine.java | 59 ++++++++-- .../app/fragments/TestsFragment.java | 101 ++++++++++++++++++ .../app/model/PeerAndConnectionModel.java | 3 +- .../nativetest/app/model/Settings.java | 27 +++-- .../nativetest/app/test/AbstractTest.java | 47 +++++++- .../app/test/FindMyBluetoothAddressTest.java | 16 +++ .../nativetest/app/test/TestListener.java | 16 +++ .../src/main/res/layout/fragment_tests.xml | 35 ++++++ .../app/src/main/res/values/strings.xml | 10 +- 12 files changed, 358 insertions(+), 52 deletions(-) create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/TestsFragment.java create mode 100644 NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/TestListener.java create mode 100644 NativeTestApp/app/src/main/res/layout/fragment_tests.xml diff --git a/NativeTestApp/app/src/main/AndroidManifest.xml b/NativeTestApp/app/src/main/AndroidManifest.xml index d43be97..4a5b643 100644 --- a/NativeTestApp/app/src/main/AndroidManifest.xml +++ b/NativeTestApp/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:label="@string/app_name" android:theme="@style/AppTheme" > diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java index a275c1a..3bf25cf 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/ConnectionEngine.java @@ -26,17 +26,18 @@ public class ConnectionEngine implements ConnectionManager.ConnectionManagerListener, DiscoveryManager.DiscoveryManagerListener, Connection.Listener { - private static final String TAG = ConnectionEngine.class.getName(); + protected static final String TAG = ConnectionEngine.class.getName(); // Service type and UUID has to be application/service specific. // The app will only connect to peers with the matching values. - private static final String SERVICE_TYPE = "ThaliNativeSampleApp._tcp"; - private static final String SERVICE_UUID_AS_STRING = "9ab3c173-66d5-4da6-9e23-e8ce520b479b"; - private static final String SERVICE_NAME = "Thali Native Sample App"; public static final String PEER_NAME = Build.MANUFACTURER + "_" + Build.MODEL; // Use manufacturer and device model name as the peer name - private static final UUID SERVICE_UUID = UUID.fromString(SERVICE_UUID_AS_STRING); - private static final long CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS = 10000; + protected static final String SERVICE_TYPE = "ThaliNativeSampleApp._tcp"; + protected static final String SERVICE_UUID_AS_STRING = "9ab3c173-66d5-4da6-9e23-e8ce520b479b"; + protected static final String SERVICE_NAME = "Thali Native Sample App"; + protected static final UUID SERVICE_UUID = UUID.fromString(SERVICE_UUID_AS_STRING); + protected static final long CHECK_CONNECTIONS_INTERVAL_IN_MILLISECONDS = 10000; + protected Context mContext = null; protected Settings mSettings = null; protected ConnectionManager mConnectionManager = null; protected DiscoveryManager mDiscoveryManager = null; @@ -48,12 +49,19 @@ public class ConnectionEngine implements * Constructor. */ public ConnectionEngine(Context context) { + mContext = context; mModel = PeerAndConnectionModel.getInstance(); - mSettings = Settings.getInstance(context); - mSettings.load(); - mConnectionManager = new ConnectionManager(context, this, SERVICE_UUID, SERVICE_NAME); - mDiscoveryManager = new DiscoveryManager(context, this, SERVICE_UUID, SERVICE_TYPE); + mConnectionManager = new ConnectionManager(mContext, this, SERVICE_UUID, SERVICE_NAME); + mDiscoveryManager = new DiscoveryManager(mContext, this, SERVICE_UUID, SERVICE_TYPE); + } + + /** + * Loads the settings and binds the discovery manager to the settings instance. + */ + public void bindSettings() { + mSettings = Settings.getInstance(mContext); mSettings.setDiscoveryManager(mDiscoveryManager); + mSettings.load(); } /** @@ -64,7 +72,9 @@ public synchronized boolean start() { mShuttingDown = false; boolean wasStarted = false; - if (mConnectionManager.start(PEER_NAME) && mDiscoveryManager.start(PEER_NAME)) { + if (mConnectionManager.start(PEER_NAME) + && (mDiscoveryManager.getState() != DiscoveryManager.DiscoveryManagerState.NOT_STARTED + || mDiscoveryManager.start(PEER_NAME))) { if (mCheckConnectionsTimer != null) { mCheckConnectionsTimer.cancel(); mCheckConnectionsTimer = null; @@ -144,7 +154,7 @@ public synchronized void startSendingData(PeerProperties peerProperties) { LogFragment.logMessage("Sending " + String.format("%.2f", connection.getTotalDataAmountCurrentlySendingInMegaBytes()) + " MB to peer " + peerProperties.toString()); - mModel.requestUpdateUi(); // To update the progress bar + mModel.notifyListenersOnDataChanged(); // To update the progress bar MainActivity.updateOptionsMenu(); } else { Log.e(TAG, "startSendingData: No connection found"); @@ -218,8 +228,11 @@ public void onConnectionTimeout(PeerProperties peerProperties) { if (peerProperties != null) { mModel.removePeerBeingConnectedTo(peerProperties); + MainActivity.showToast("Failed to connect to " + peerProperties.getName() + ": Connection timeout"); LogFragment.logError("Failed to connect to peer " + peerProperties.toString() + ": Connection timeout"); + + autoConnectIfEnabled(peerProperties); } else { MainActivity.showToast("Failed to connect: Connection timeout"); LogFragment.logError("Failed to connect: Connection timeout"); @@ -234,10 +247,14 @@ public void onConnectionFailed(PeerProperties peerProperties, String errorMessag if (peerProperties != null) { mModel.removePeerBeingConnectedTo(peerProperties); + MainActivity.showToast("Failed to connect to " + peerProperties.getName() + ((errorMessage != null) ? (": " + errorMessage) : "")); LogFragment.logError("Failed to connect to peer " + peerProperties.toString() + ((errorMessage != null) ? (": " + errorMessage) : "")); + + autoConnectIfEnabled(peerProperties); + } else { MainActivity.showToast("Failed to connect" + ((errorMessage != null) ? (": " + errorMessage) : "")); LogFragment.logError("Failed to connect" + ((errorMessage != null) ? (": " + errorMessage) : "")); @@ -258,15 +275,7 @@ public void onPeerDiscovered(PeerProperties peerProperties) { if (mModel.addOrUpdatePeer(peerProperties)) { LogFragment.logMessage("Peer " + peerProperties.toString() + " discovered"); - - if (mSettings.getAutoConnect() && !mModel.hasConnectionToPeer(peerProperties, false)) { - if (mSettings.getAutoConnectEvenWhenIncomingConnectionEstablished() - || !mModel.hasConnectionToPeer(peerProperties, true)) { - // Do auto-connect - Log.i(TAG, "onPeerDiscovered: Auto-connecting to peer " + peerProperties.toString()); - mConnectionManager.connect(peerProperties); - } - } + autoConnectIfEnabled(peerProperties); } } @@ -333,6 +342,7 @@ public void run() { mCheckConnectionsTimer.cancel(); } + autoConnectIfEnabled(peerProperties); MainActivity.updateOptionsMenu(); } }.start(); @@ -344,8 +354,8 @@ public void run() { @Override public void onSendDataProgress(float progressInPercentages, float transferSpeed, PeerProperties receivingPeer) { - Log.i(TAG, "onSendDataProgress: " + Math.round(progressInPercentages * 100) + " % " + transferSpeed + " MB/s"); - mModel.requestUpdateUi(); // To update the progress bar + Log.d(TAG, "onSendDataProgress: " + Math.round(progressInPercentages * 100) + " % " + transferSpeed + " MB/s"); + mModel.notifyListenersOnDataChanged(); // To update the progress bar } @Override @@ -356,7 +366,7 @@ public void onDataSent(float dataSentInMegaBytes, float transferSpeed, PeerPrope Log.i(TAG, "onDataSent: " + message + " to peer " + receivingPeer); LogFragment.logMessage(message + " to peer " + receivingPeer); MainActivity.showToast(message + " to peer " + receivingPeer.getName()); - mModel.requestUpdateUi(); // To update the progress bar + mModel.notifyListenersOnDataChanged(); // To update the progress bar MainActivity.updateOptionsMenu(); } @@ -368,4 +378,19 @@ protected synchronized void sendPingToAllPeers() { connection.ping(); } } + + /** + * Tries to connect to the peer with the given properties if the auto-connect is enabled. + * @param peerProperties The peer properties. + */ + protected synchronized void autoConnectIfEnabled(PeerProperties peerProperties) { + if (mSettings.getAutoConnect() && !mModel.hasConnectionToPeer(peerProperties, false)) { + if (mSettings.getAutoConnectEvenWhenIncomingConnectionEstablished() + || !mModel.hasConnectionToPeer(peerProperties, true)) { + // Do auto-connect + Log.i(TAG, "autoConnectIfEnabled: Auto-connecting to peer " + peerProperties.toString()); + mConnectionManager.connect(peerProperties); + } + } + } } diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java index 0641535..a29fdac 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/MainActivity.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2015 Microsoft Corporation. This software is licensed under the MIT License. +/* Copyright (c) 2015-2016 Microsoft Corporation. This software is licensed under the MIT License. * See the license file delivered with this project for further information. */ package org.thaliproject.nativetest.app; @@ -19,14 +19,16 @@ import org.thaliproject.nativetest.app.fragments.LogFragment; import org.thaliproject.nativetest.app.fragments.PeerListFragment; import org.thaliproject.nativetest.app.fragments.SettingsFragment; +import org.thaliproject.nativetest.app.fragments.TestsFragment; import org.thaliproject.nativetest.app.model.PeerAndConnectionModel; import org.thaliproject.nativetest.app.slidingtabs.SlidingTabLayout; +import org.thaliproject.nativetest.app.test.TestListener; import org.thaliproject.nativetest.app.utils.MenuUtils; import org.thaliproject.p2p.btconnectorlib.PeerProperties; public class MainActivity extends AppCompatActivity - implements PeerListFragment.Listener, TestEngine.Listener { + implements PeerListFragment.Listener, TestListener { private static final String TAG = MainActivity.class.getName(); @@ -34,6 +36,7 @@ public class MainActivity private static Context mContext = null; private ConnectionEngine mConnectionEngine = null; + private ConnectionEngine mTestEngine = null; /** * The {@link android.support.v4.view.PagerAdapter} that will provide @@ -54,6 +57,7 @@ public class MainActivity private PeerListFragment mPeerListFragment = null; private LogFragment mLogFragment = null; private SettingsFragment mSettingsFragment = null; + private TestsFragment mTestsFragment = null; @Override protected void onCreate(Bundle savedInstanceState) { @@ -65,6 +69,8 @@ protected void onCreate(Bundle savedInstanceState) { if (mConnectionEngine == null) { mConnectionEngine = new ConnectionEngine(mContext); + mConnectionEngine.bindSettings(); + mTestEngine = new TestEngine(mContext, this); } // Set up the action bar. @@ -85,6 +91,9 @@ protected void onCreate(Bundle savedInstanceState) { mSettingsFragment = new SettingsFragment(); + mTestsFragment = new TestsFragment(); + mTestsFragment.setTestEngine((TestEngine) mTestEngine); + mConnectionEngine.start(); } @@ -207,7 +216,8 @@ public void onSendDataRequest(PeerProperties peerProperties) { } @Override - public void onTestFinished() { + public void onTestFinished(String testName, float successRate, String results) { + showToast("Test \"" + testName + "\" finished with success rate of " + Math.round(successRate * 100) + " %"); } /** @@ -217,6 +227,7 @@ public class MyFragmentAdapter extends FragmentPagerAdapter { private static final int PEER_LIST_FRAGMENT = 0; private static final int LOG_FRAGMENT = 1; private static final int SETTINGS_FRAGMENT = 2; + private static final int TESTS_FRAGMENT = 3; public MyFragmentAdapter(FragmentManager fragmentManager) { super(fragmentManager); @@ -228,6 +239,7 @@ public Fragment getItem(int index) { case PEER_LIST_FRAGMENT: return mPeerListFragment; case LOG_FRAGMENT: return mLogFragment; case SETTINGS_FRAGMENT: return mSettingsFragment; + case TESTS_FRAGMENT: return mTestsFragment; } return null; @@ -239,6 +251,7 @@ public CharSequence getPageTitle(int position) { case PEER_LIST_FRAGMENT: return "Peers"; case LOG_FRAGMENT: return "Log"; case SETTINGS_FRAGMENT: return "Settings"; + case TESTS_FRAGMENT: return "Tests"; } return super.getPageTitle(position); @@ -246,7 +259,7 @@ public CharSequence getPageTitle(int position) { @Override public int getCount() { - return 3; + return 4; } } } diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java index 6926dc8..9d3cbe6 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/TestEngine.java @@ -4,16 +4,63 @@ package org.thaliproject.nativetest.app; import android.content.Context; +import android.util.Log; +import org.thaliproject.nativetest.app.model.PeerAndConnectionModel; +import org.thaliproject.nativetest.app.model.Settings; +import org.thaliproject.nativetest.app.test.AbstractTest; +import org.thaliproject.nativetest.app.test.TestListener; +import org.thaliproject.p2p.btconnectorlib.ConnectionManager; +import org.thaliproject.p2p.btconnectorlib.DiscoveryManager; /** - * A connection engine to run tests. + * A connection engine to runTest tests. */ -public class TestEngine extends ConnectionEngine { - public interface Listener { - void onTestFinished(); - } +public class TestEngine extends ConnectionEngine implements TestListener { + private static final String TAG = TestEngine.class.getName(); + private TestListener mListener = null; + private AbstractTest mCurrentTest = null; - public TestEngine(Context context) { + public TestEngine(Context context, TestListener listener) { super(context); + mListener = listener; + } + + /** + * Runs the given test. + * @param testToRun The test to runTest. + * @return True, if the test was started successfully. False otherwise. + */ + public boolean runTest(AbstractTest testToRun) { + boolean wasStarted = false; + + if (mCurrentTest == null || !mCurrentTest.isRunning()) { + if (testToRun != null) { + mCurrentTest = testToRun; + mCurrentTest.setListener(this); + wasStarted = mCurrentTest.run(); + } else { + Log.e(TAG, "runTest: The given test is null"); + } + } else { + Log.e(TAG, "runTest: Cannot runTest since a previous test is still running"); + } + + return wasStarted; + } + + /** + * Cancels the current test. + */ + public void cancel() { + if (mCurrentTest != null && mCurrentTest.isRunning()) { + mCurrentTest.cancel(); + } + } + + @Override + public void onTestFinished(String testName, float successRate, String results) { + if (mListener != null) { + mListener.onTestFinished(testName, successRate, results); + } } } diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/TestsFragment.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/TestsFragment.java new file mode 100644 index 0000000..94f3575 --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/fragments/TestsFragment.java @@ -0,0 +1,101 @@ +/* Copyright (c) 2016 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativetest.app.fragments; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.*; +import org.thaliproject.nativetest.app.R; +import org.thaliproject.nativetest.app.TestEngine; +import org.thaliproject.nativetest.app.test.AbstractTest; +import org.thaliproject.nativetest.app.test.FindMyBluetoothAddressTest; +import java.util.ArrayList; +import java.util.List; + +/** + * A fragment for selecting and running tests. + */ +public class TestsFragment extends Fragment { + private static final String TAG = TestsFragment.class.getName(); + private TestEngine mTestEngine = null; + private List mTests = new ArrayList(); + private Button mRunTestButton = null; + private int mSelectedTestIndex = 0; + + public TestsFragment() { + mTests.add(new FindMyBluetoothAddressTest()); + } + + public void setTestEngine(TestEngine testEngine) { + mTestEngine = testEngine; + + if (mTestEngine != null && mRunTestButton != null) { + mRunTestButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mTestEngine != null) { + if (mTestEngine.runTest(mTests.get(mSelectedTestIndex))) { + //mRunTestButton.setEnabled(false); + } + } + } + }); + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_tests, container, false); + + Spinner spinner = (Spinner) view.findViewById(R.id.testSelectionSpinner); + String[] testNames = new String[mTests.size()]; + + for (int i = 0; i < mTests.size(); ++i) { + testNames[i] = mTests.get(i).getName(); + } + + ArrayAdapter adapter = new ArrayAdapter( + view.getContext(), android.R.layout.simple_spinner_item, testNames); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int index, long l) { + mSelectedTestIndex = index; + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + } + }); + + mRunTestButton = (Button) view.findViewById(R.id.runTestButton); + mRunTestButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mTestEngine != null) { + if (mTestEngine.runTest(mTests.get(mSelectedTestIndex))) { + //mRunTestButton.setEnabled(false); + } + } + } + }); + + return view; + } + + @Override + public void onDestroy() { + super.onDestroy(); + } +} diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java index 06ceb1c..fc45a4b 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/PeerAndConnectionModel.java @@ -53,7 +53,7 @@ public void setListener(Listener listener) { /** * Notifies the listener that the data of this model has changed. This should update the UI. */ - public void requestUpdateUi() { + public void notifyListenersOnDataChanged() { if (mListener != null) { mListener.onDataChanged(); } @@ -120,6 +120,7 @@ public synchronized boolean addOrUpdatePeer(PeerProperties peerProperties) { * @return True, if the peer was found and removed. False otherwise. */ public boolean removePeer(final PeerProperties peerProperties) { + removePeerBeingConnectedTo(peerProperties); boolean wasRemoved = removePeerPropertiesFromList(peerProperties, mPeers); if (wasRemoved && mListener != null) { diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Settings.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Settings.java index fe3d2ca..951b4ea 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Settings.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/model/Settings.java @@ -5,10 +5,10 @@ import android.content.Context; import android.content.SharedPreferences; +import android.os.Handler; import android.preference.PreferenceManager; import android.util.Log; import org.thaliproject.nativetest.app.ConnectionEngine; -import org.thaliproject.nativetest.app.MainActivity; import org.thaliproject.p2p.btconnectorlib.ConnectionManagerSettings; import org.thaliproject.p2p.btconnectorlib.DiscoveryManager; import org.thaliproject.p2p.btconnectorlib.DiscoveryManagerSettings; @@ -19,6 +19,7 @@ public class Settings { private static final String TAG = Settings.class.getName(); private static Settings mInstance = null; + private static Context mContext = null; private final SharedPreferences mSharedPreferences; private final SharedPreferences.Editor mSharedPreferencesEditor; @@ -33,6 +34,7 @@ public class Settings { private static final String KEY_BUFFER_SIZE = "buffer_size"; private static final String KEY_AUTO_CONNECT = "auto_connect"; private static final String KEY_AUTO_CONNECT_WHEN_INCOMING = "auto_connect_when_incoming"; + private static final long START_DISCOVERY_MANAGER_DELAY_IN_MILLISECONDS = 1000; private DiscoveryManager mDiscoveryManager = null; private long mConnectionTimeoutInMilliseconds = ConnectionManagerSettings.DEFAULT_CONNECTION_TIMEOUT_IN_MILLISECONDS; @@ -54,7 +56,8 @@ public class Settings { */ public static Settings getInstance(Context context) { if (mInstance == null && context != null) { - mInstance = new Settings(context); + mContext = context; + mInstance = new Settings(mContext); } return mInstance; @@ -173,12 +176,20 @@ public void setDesiredDiscoveryMode() { if (desiredMode == DiscoveryManager.DiscoveryMode.NOT_SET) { mDiscoveryManager.stop(); - } else { - mDiscoveryManager.setDiscoveryMode(getDesiredDiscoveryMode(), true); - - if (mDiscoveryManager.getState() == DiscoveryManager.DiscoveryManagerState.NOT_STARTED) { - mDiscoveryManager.start(ConnectionEngine.PEER_NAME); - } + } else { + Log.i(TAG, "setDesiredDiscoveryMode: " + desiredMode); + mDiscoveryManager.setDiscoveryMode(desiredMode, true); + + Handler handler = new Handler(mContext.getMainLooper()); + + handler.postDelayed(new Runnable() { + @Override + public void run() { + if (mDiscoveryManager.getState() == DiscoveryManager.DiscoveryManagerState.NOT_STARTED) { + mDiscoveryManager.start(ConnectionEngine.PEER_NAME); + } + } + }, START_DISCOVERY_MANAGER_DELAY_IN_MILLISECONDS); } } } diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java index d857a88..b5f3a9e 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/AbstractTest.java @@ -3,15 +3,24 @@ */ package org.thaliproject.nativetest.app.test; +import android.os.CountDownTimer; +import android.util.Log; + /** * An abstract base class for tests. */ public abstract class AbstractTest { public static final long DEFAULT_TEST_TIMEOUT_IN_MILLISECONDS = 30000; public static final int DEFAULT_NUMBER_OF_DESIRED_PEERS = 1; + protected static final String TAG = AbstractTest.class.getName(); protected long mTestTimeoutInMilliseconds = DEFAULT_TEST_TIMEOUT_IN_MILLISECONDS; protected int mNumberOfDesiredPeers = DEFAULT_NUMBER_OF_DESIRED_PEERS; + protected TestListener mListener = null; + protected CountDownTimer mTestTimeoutTimer = null; + protected boolean mIsRunning = false; + + public abstract String getName(); /** * @return The test timeout in milliseconds. @@ -21,6 +30,8 @@ public long getTestTimeout() { } /** + * Sets the test timeout. Note that you should do this before starting the test (calling runTest()) + * in order for the given value to have an effect. * @param testTimeoutInMilliseconds The test timeout in milliseconds. */ public void setTestTimeout(long testTimeoutInMilliseconds) { @@ -35,15 +46,49 @@ public void setNumberOfDesiredPeers(int numberOfDesiredPeers) { mNumberOfDesiredPeers = numberOfDesiredPeers; } + public void setListener(TestListener listener) { + mListener = listener; + } + + public boolean isRunning() { + return mIsRunning; + } + /** * Starts the test. * @return True, if successfully started. False otherwise. */ - public abstract boolean run(); + public boolean run() { + mIsRunning = true; + + mTestTimeoutTimer = new CountDownTimer(mTestTimeoutInMilliseconds, mTestTimeoutInMilliseconds) { + @Override + public void onTick(long l) { + // Not used + } + + @Override + public void onFinish() { + Log.d(TAG, "Test timeout"); + onTimeout(); + } + }; + + mTestTimeoutTimer.start(); + return false; + } /** * Cancels the test. */ public void cancel() { } + + protected void stop() { + mIsRunning = false; + } + + protected void onTimeout() { + cancel(); + } } diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java index ed632a7..415cf82 100644 --- a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/FindMyBluetoothAddressTest.java @@ -3,12 +3,28 @@ */ package org.thaliproject.nativetest.app.test; +import android.util.Log; + /** * A test for requesting a peer to provide us our Bluetooth MAC address. */ public class FindMyBluetoothAddressTest extends AbstractTest { + private static final String TAG = FindMyBluetoothAddressTest.class.getName(); + + @Override + public String getName() { + return "Find my Bluetooth address"; + } + @Override public boolean run() { + Log.i(TAG, "runTest"); + super.run(); + + if (mListener != null) { + mListener.onTestFinished(getName(), 0f, "no results"); + } + return false; } } diff --git a/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/TestListener.java b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/TestListener.java new file mode 100644 index 0000000..fd93eb8 --- /dev/null +++ b/NativeTestApp/app/src/main/java/org/thaliproject/nativetest/app/test/TestListener.java @@ -0,0 +1,16 @@ +/* Copyright (c) 2016 Microsoft Corporation. This software is licensed under the MIT License. + * See the license file delivered with this project for further information. + */ +package org.thaliproject.nativetest.app.test; + +/** + * An interface for test listeners. + */ +public interface TestListener { + /** + * Called when a test is runTest or aborted. + * @param successRate The success rate (1.0 is 100 %). + * @param results The test results. + */ + void onTestFinished(String testName, float successRate, String results); +} diff --git a/NativeTestApp/app/src/main/res/layout/fragment_tests.xml b/NativeTestApp/app/src/main/res/layout/fragment_tests.xml new file mode 100644 index 0000000..242dc68 --- /dev/null +++ b/NativeTestApp/app/src/main/res/layout/fragment_tests.xml @@ -0,0 +1,35 @@ + + + + + + + + +