From 133cabeed8cd8d3358b124fe5633b2a7d9a4d05f Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Wed, 19 Aug 2015 16:50:35 +1000 Subject: [PATCH] Let user select wifi network. Prevent "Send F-Droid" if no bluetooth. Include support for libaccesspoint to control the WiFiAP of a device. Selecting wifi networks i snow possible by touching the name of the wifi network in the "Start Swap" screen (sometimes it will say "No network yet"). This exhibits the same behaviour as the "Join Wifi" screen used to (and still does) do. On emulators (is there other devices too?), Bluetooth is unavailable, but the "Send F-Droid" is still there. I could remove it, but then people may get confused as to why it is not there. Instead, there is now a dialog which explains why it can't be sent (no Bluetooth). --- F-Droid/AndroidManifest.xml | 1 + F-Droid/build.gradle | 2 + F-Droid/res/values/strings.xml | 11 ++-- .../fdroid/fdroid/localrepo/SwapService.java | 3 +- .../fdroid/views/swap/StartSwapView.java | 19 ++++-- .../views/swap/SwapWorkflowActivity.java | 66 +++++++++++++++++++ 6 files changed, 93 insertions(+), 9 deletions(-) diff --git a/F-Droid/AndroidManifest.xml b/F-Droid/AndroidManifest.xml index 25d3aa94e..e440e9976 100644 --- a/F-Droid/AndroidManifest.xml +++ b/F-Droid/AndroidManifest.xml @@ -42,6 +42,7 @@ + diff --git a/F-Droid/build.gradle b/F-Droid/build.gradle index 5f6240f5a..baa444197 100644 --- a/F-Droid/build.gradle +++ b/F-Droid/build.gradle @@ -20,6 +20,8 @@ if ( !hasProperty( 'sourceDeps' ) ) { 'com.android.support:appcompat-v7:22.1.0', 'com.android.support:support-annotations:22.1.0', + 'cc.mvdan.accesspoint:library:0.1.1', + 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0', 'com.nostra13.universalimageloader:universal-image-loader:1.9.4', 'com.google.zxing:core:3.2.0', diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml index b3fee4969..f1abf2c2f 100644 --- a/F-Droid/res/values/strings.xml +++ b/F-Droid/res/values/strings.xml @@ -263,6 +263,8 @@ App icon Repo icon + WiFi + Hotspot Children Development @@ -314,6 +316,7 @@ Touch to swap If your friend has F-Droid and NFC turned on touch your phones together. Join the same WiFi + To swap using WiFi, ensure you are on the same network. If you don\'t have access to the same network, one of you can create a WiFi Hotspot. Help your friend join your hotspot Use Bluetooth instead Learn more about Wifi @@ -321,7 +324,7 @@ Swap apps Swap success! No network yet - Your hotspot is active + %1$s (your hotspot) Tap to open available networks Tap to switch to a WiFi network It\'s not working @@ -352,8 +355,8 @@ Connecting Confirm swap The QR code you scanned doesn\'t look like a swap code. - - + Bluetooth unavailable + Cannot send F-Droid, because Bluetooth is unavailable on this device. Loading… TRY TO INSTALL An error occurred while connecting to device, we can\'t seem to swap with it :( @@ -388,7 +391,7 @@ Provided by %1$s. Downloading… - + B KiB MiB diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java index b9a838219..b5aa52b27 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java @@ -61,8 +61,9 @@ import java.util.TimerTask; * to enable p2p swapping of apps. * * The following UI elements don't do anything: - * + TODO: Change wifi by touching network name during swap start screen + * + TODO: Be notified of changes to wifi state correctly, particularly from the WiFi AP (https://github.com/mvdan/accesspoint/issues/5) * + TODO: The "?" button in the top right of the swap start screen doesn't do anything + * (This has been commented out for now, but it is still preferable to have a working help mechanism) * * TODO: Show "Waiting for other device to finish setting up swap" when only F-Droid shown in swap * TODO: Handle "not connected to wifi" more gracefully. For example, Bonjour discovery falls over. diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java index 309b80df1..a91a980c9 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java @@ -6,6 +6,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.wifi.WifiConfiguration; import android.os.Build; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; @@ -37,6 +38,8 @@ import org.fdroid.fdroid.net.WifiStateChangeService; import java.util.ArrayList; +import cc.mvdan.accesspoint.WifiApControl; + public class StartSwapView extends ScrollView implements SwapWorkflowActivity.InnerView { private static final String TAG = "StartSwapView"; @@ -310,6 +313,13 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In } }, new IntentFilter(SwapService.BONJOUR_STATE_CHANGE)); + viewWifiNetwork.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + getActivity().promptToSelectWifiNetwork(); + } + }); + uiUpdateWifiNetwork(); } @@ -318,12 +328,13 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In viewWifiId.setText(FDroidApp.ipAddressString); viewWifiId.setVisibility(TextUtils.isEmpty(FDroidApp.ipAddressString) ? View.GONE : View.VISIBLE); - if (TextUtils.isEmpty(FDroidApp.bssid) && !TextUtils.isEmpty(FDroidApp.ipAddressString)) { - // empty bssid with an ipAddress means hotspot mode - viewWifiNetwork.setText(getContext().getString(R.string.swap_active_hotspot)); + WifiApControl wifiAp = WifiApControl.getInstance(getActivity()); + if (wifiAp.isWifiApEnabled()) { + WifiConfiguration config = wifiAp.getConfiguration(); + viewWifiNetwork.setText(getContext().getString(R.string.swap_active_hotspot, config.SSID)); } else if (TextUtils.isEmpty(FDroidApp.ssid)) { // not connected to or setup with any wifi network - viewWifiNetwork.setText(getContext().getString(R.string.swap_no_wifi_network)); + viewWifiNetwork.setText(R.string.swap_no_wifi_network); } else { // connected to a regular wifi network viewWifiNetwork.setText(FDroidApp.ssid); diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java index 23eabd8ec..a9528bf9c 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java @@ -8,6 +8,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.net.Uri; +import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; @@ -56,6 +57,8 @@ import java.util.Set; import java.util.Timer; import java.util.TimerTask; +import cc.mvdan.accesspoint.WifiApControl; + /** * This activity will do its best to show the most relevant screen about swapping to the user. * The problem comes when there are two competing goals - 1) Show the user a list of apps from another @@ -214,6 +217,55 @@ public class SwapWorkflowActivity extends AppCompatActivity { } } + public void promptToSelectWifiNetwork() { + // + // On Android >= 5.0, the neutral button is the one by itself off to the left of a dialog + // (not the negative button). Thus, the layout of this dialogs buttons should be: + // + // | | + // +---------------------------------+ + // | Cancel Hotspot WiFi | + // +---------------------------------+ + // + // TODO: Investigate if this should be set dynamically for earlier APIs. + // + new AlertDialog.Builder(this) + .setTitle(R.string.swap_join_same_wifi) + .setMessage(R.string.swap_join_same_wifi_desc) + .setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Do nothing + } + } + ).setPositiveButton(R.string.wifi, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + startActivity(new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK)); + } + } + ).setNegativeButton(R.string.wifi_ap, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + promptToSetupWifiAP(); + } + } + ).create().show(); + } + + private void promptToSetupWifiAP() { + WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); + WifiApControl ap = WifiApControl.getInstance(this); + wifiManager.setWifiEnabled(false); + if (!ap.enable()) { + Log.e(TAG, "Could not enable WiFi AP."); + // TODO: Feedback to user? + } else { + Log.d(TAG, "WiFi AP enabled."); + // TODO: Seems to be broken some times... + } + } + private void showRelevantView() { showRelevantView(false); } @@ -365,6 +417,17 @@ public class SwapWorkflowActivity extends AppCompatActivity { } else { sendFDroidApk(); } + } else { + new AlertDialog.Builder(this) + .setTitle(R.string.bluetooth_unavailable) + .setMessage(R.string.swap_cant_send_no_bluetooth) + .setNegativeButton( + R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) {} + } + ).create().show(); } } @@ -676,6 +739,9 @@ public class SwapWorkflowActivity extends AppCompatActivity { class SwapDebug { public void logStatus() { + + if (true) return; + String message = ""; if (service == null) { message = "No swap service";