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";