diff --git a/app/src/full/java/org/fdroid/fdroid/localrepo/SwapService.java b/app/src/full/java/org/fdroid/fdroid/localrepo/SwapService.java index d4d95e597..66290c1f8 100644 --- a/app/src/full/java/org/fdroid/fdroid/localrepo/SwapService.java +++ b/app/src/full/java/org/fdroid/fdroid/localrepo/SwapService.java @@ -33,8 +33,6 @@ import org.fdroid.fdroid.data.Schema; import org.fdroid.fdroid.localrepo.peers.Peer; import org.fdroid.fdroid.localrepo.peers.PeerFinder; import org.fdroid.fdroid.localrepo.type.BluetoothSwap; -import org.fdroid.fdroid.localrepo.type.SwapType; -import org.fdroid.fdroid.localrepo.type.WifiSwap; import org.fdroid.fdroid.net.Downloader; import org.fdroid.fdroid.net.WifiStateChangeService; import org.fdroid.fdroid.views.swap.SwapWorkflowActivity; @@ -336,27 +334,6 @@ public class SwapService extends Service { swapPreferences.edit().putBoolean(SwapService.KEY_WIFI_ENABLED_BEFORE_SWAP, visible).apply(); } - /** - * Handles checking if the {@link SwapService} is running, and only restarts it if it was running. - */ - public void stopWifiIfEnabled(final boolean restartAfterStopping) { - if (wifiSwap.isConnected()) { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - Utils.debugLog(TAG, "Stopping the currently running WiFi swap service (on background thread)"); - wifiSwap.stop(); - - if (restartAfterStopping) { - Utils.debugLog(TAG, "Restarting WiFi swap service after stopping (still on background thread)"); - wifiSwap.start(); - } - return null; - } - }.execute(); - } - } - public boolean isEnabled() { return bluetoothSwap.isConnected() || LocalHTTPDManager.isAlive(); } @@ -373,9 +350,7 @@ public class SwapService extends Service { // Old SwapService stuff being merged into that. // =============================================================== - public static final String BONJOUR_STATE_CHANGE = "org.fdroid.fdroid.BONJOUR_STATE_CHANGE"; public static final String BLUETOOTH_STATE_CHANGE = "org.fdroid.fdroid.BLUETOOTH_STATE_CHANGE"; - public static final String WIFI_STATE_CHANGE = "org.fdroid.fdroid.WIFI_STATE_CHANGE"; public static final String EXTRA_STARTING = "STARTING"; public static final String EXTRA_STARTED = "STARTED"; public static final String EXTRA_STOPPING = "STOPPING"; @@ -384,8 +359,7 @@ public class SwapService extends Service { private static final int NOTIFICATION = 1; private final Binder binder = new Binder(); - private SwapType bluetoothSwap; - private WifiSwap wifiSwap; + private BluetoothSwap bluetoothSwap; private static final int TIMEOUT = 15 * 60 * 1000; // 15 mins @@ -395,14 +369,10 @@ public class SwapService extends Service { @Nullable private Timer timer; - public SwapType getBluetoothSwap() { + public BluetoothSwap getBluetoothSwap() { return bluetoothSwap; } - public WifiSwap getWifiSwap() { - return wifiSwap; - } - public class Binder extends android.os.Binder { public SwapService getService() { return SwapService.this; @@ -415,6 +385,8 @@ public class SwapService extends Service { localBroadcastManager = LocalBroadcastManager.getInstance(this); swapPreferences = getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); + LocalHTTPDManager.start(this); + bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter != null) { SwapService.putBluetoothEnabledBeforeSwap(bluetoothAdapter.isEnabled()); @@ -427,7 +399,6 @@ public class SwapService extends Service { appsToSwap.addAll(deserializePackages(swapPreferences.getString(KEY_APPS_TO_SWAP, ""))); bluetoothSwap = BluetoothSwap.create(this); - wifiSwap = new WifiSwap(this, wifiManager); Preferences.get().registerLocalRepoHttpsListeners(httpsEnabledListener); @@ -435,8 +406,6 @@ public class SwapService extends Service { new IntentFilter(WifiStateChangeService.BROADCAST)); localBroadcastManager.registerReceiver(onBluetoothSwapStateChange, new IntentFilter(SwapService.BLUETOOTH_STATE_CHANGE)); - localBroadcastManager.registerReceiver(onWifiSwapStateChange, - new IntentFilter(SwapService.WIFI_STATE_CHANGE)); if (getBluetoothVisibleUserPreference()) { Utils.debugLog(TAG, "Previously the user enabled Bluetooth swap, so enabling again automatically."); @@ -445,12 +414,8 @@ public class SwapService extends Service { Utils.debugLog(TAG, "Bluetooth was NOT enabled last time user swapped, starting not visible."); } - if (getWifiVisibleUserPreference()) { - Utils.debugLog(TAG, "Previously the user enabled WiFi swap, so enabling again automatically."); - wifiSwap.startInBackground(); // TODO replace with Intent to SwapService - } else { - Utils.debugLog(TAG, "WiFi was NOT enabled last time user swapped, starting not visible."); - } + BonjourManager.start(this); + BonjourManager.setVisible(this, getWifiVisibleUserPreference()); } /** @@ -478,12 +443,12 @@ public class SwapService extends Service { Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener); localBroadcastManager.unregisterReceiver(onWifiChange); localBroadcastManager.unregisterReceiver(onBluetoothSwapStateChange); - localBroadcastManager.unregisterReceiver(onWifiSwapStateChange); if (bluetoothAdapter != null && !wasBluetoothEnabledBeforeSwap()) { bluetoothAdapter.disable(); } + BonjourManager.stop(this); LocalHTTPDManager.stop(this); if (wifiManager != null && !wasWifiEnabledBeforeSwap()) { wifiManager.setWifiEnabled(false); @@ -492,7 +457,6 @@ public class SwapService extends Service { stopPollingConnectedSwapRepo(); //TODO getBluetoothSwap().stopInBackground(); - getWifiSwap().stopInBackground(); if (timer != null) { timer.cancel(); @@ -574,24 +538,33 @@ public class SwapService extends Service { }, TIMEOUT); } + private void restartWiFiServices() { + boolean hasIp = FDroidApp.ipAddressString != null; + if (hasIp) { + LocalHTTPDManager.restart(this); + BonjourManager.restart(this); + BonjourManager.setVisible(this, getWifiVisibleUserPreference()); + } else { + BonjourManager.stop(this); + LocalHTTPDManager.stop(this); + } + } + private final Preferences.ChangeListener httpsEnabledListener = new Preferences.ChangeListener() { @Override public void onPreferenceChange() { - Log.i(TAG, "Swap over HTTPS preference changed."); - stopWifiIfEnabled(true); + restartWiFiServices(); } }; private final BroadcastReceiver onWifiChange = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent i) { - boolean hasIp = FDroidApp.ipAddressString != null; - stopWifiIfEnabled(hasIp); + restartWiFiServices(); } }; private final BroadcastReceiver onBluetoothSwapStateChange = new SwapStateChangeReceiver(); - private final BroadcastReceiver onWifiSwapStateChange = new SwapStateChangeReceiver(); /** * When swapping is setup, then start the index polling. diff --git a/app/src/full/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java b/app/src/full/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java index 7ab9735b1..4e34de4e0 100644 --- a/app/src/full/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java +++ b/app/src/full/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java @@ -5,15 +5,17 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.localrepo.SwapService; import org.fdroid.fdroid.net.bluetooth.BluetoothServer; @SuppressWarnings("LineLength") -public final class BluetoothSwap extends SwapType { +public class BluetoothSwap { private static final String TAG = "BluetoothSwap"; public static final String BLUETOOTH_NAME_TAG = "FDroid:"; @@ -24,12 +26,17 @@ public final class BluetoothSwap extends SwapType { private final BluetoothAdapter adapter; private boolean isDiscoverable; + private boolean isConnected; + + @NonNull + protected final Context context; + @Nullable private BluetoothServer server; private String deviceBluetoothName; - public static SwapType create(@NonNull Context context) { + public static BluetoothSwap create(@NonNull Context context) { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { return new NoBluetoothType(context); @@ -42,21 +49,18 @@ public final class BluetoothSwap extends SwapType { } private BluetoothSwap(@NonNull Context context, @NonNull BluetoothAdapter adapter) { - super(context); + this.context = context; this.adapter = adapter; } - @Override public boolean isDiscoverable() { return isDiscoverable; } - @Override public boolean isConnected() { - return server != null && server.isRunning() && super.isConnected(); + return server != null && server.isRunning() && isConnected; } - @Override public synchronized void start() { if (isConnected()) { Utils.debugLog(TAG, "already running, quitting start()"); @@ -128,26 +132,10 @@ public final class BluetoothSwap extends SwapType { } } - /** - * Don't try to start BT in the background. you can only start/stop a BT server once, else new connections don't work. - */ - @Override - public void stopInBackground() { - stop(); - } - - @Override public void stop() { if (server != null && server.isAlive()) { server.close(); setConnected(false); - - /* - if (receiver != null) { - context.unregisterReceiver(receiver); - receiver = null; - } - */ } else { Log.i(TAG, "Attempting to stop Bluetooth swap, but it is not currently running."); } @@ -158,15 +146,50 @@ public final class BluetoothSwap extends SwapType { adapter.setName(deviceBluetoothName); } - @Override - public String getBroadcastAction() { + protected String getBroadcastAction() { return SwapService.BLUETOOTH_STATE_CHANGE; } - private static class NoBluetoothType extends SwapType { + protected final void setConnected(boolean connected) { + if (connected) { + isConnected = true; + sendBroadcast(SwapService.EXTRA_STARTED); + } else { + isConnected = false; + sendBroadcast(SwapService.EXTRA_STOPPED); + } + } + + /** + * Sends either a {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STARTING}, + * {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STARTED} or + * {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STOPPED} broadcast. + */ + protected final void sendBroadcast(String extra) { + if (getBroadcastAction() != null) { + Intent intent = new Intent(getBroadcastAction()); + intent.putExtra(extra, true); + Utils.debugLog(TAG, "Sending broadcast " + extra + " from " + getClass().getSimpleName()); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + } + } + + public void startInBackground() { + // TODO switch to thread which is killed if still running, like WiFiStateChangeService + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + start(); + return null; + } + }.execute(); + } + + + private static class NoBluetoothType extends BluetoothSwap { NoBluetoothType(@NonNull Context context) { - super(context); + super(context, null); } @Override diff --git a/app/src/full/java/org/fdroid/fdroid/localrepo/type/SwapType.java b/app/src/full/java/org/fdroid/fdroid/localrepo/type/SwapType.java deleted file mode 100644 index 8e45aafc8..000000000 --- a/app/src/full/java/org/fdroid/fdroid/localrepo/type/SwapType.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.fdroid.fdroid.localrepo.type; - -import android.content.Context; -import android.content.Intent; -import android.os.AsyncTask; -import android.support.annotation.NonNull; -import android.support.v4.content.LocalBroadcastManager; - -import org.fdroid.fdroid.Utils; -import org.fdroid.fdroid.localrepo.SwapService; - -/** - * There is lots of common functionality, and a common API among different communication protocols - * associated with the swap process. This includes Bluetooth visability, Bonjour visability, - * and the web server which serves info for swapping. This class provides a common API for - * starting and stopping these services. In addition, it helps with the process of sending broadcast - * intents in response to the thing starting or stopping. - */ -public abstract class SwapType { - - private static final String TAG = "SwapType"; - - private boolean isConnected; - - @NonNull - protected final Context context; - - public SwapType(@NonNull Context context) { - this.context = context; - } - - public abstract void start(); - - public abstract void stop(); - - protected abstract String getBroadcastAction(); - - public boolean isDiscoverable() { - return isConnected(); - } - - protected final void setConnected(boolean connected) { - if (connected) { - isConnected = true; - sendBroadcast(SwapService.EXTRA_STARTED); - } else { - isConnected = false; - onStopped(); - sendBroadcast(SwapService.EXTRA_STOPPED); - } - } - - protected void onStopped() { } - - /** - * Sends either a {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STARTING}, - * {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STARTED} or - * {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STOPPED} broadcast. - */ - protected final void sendBroadcast(String extra) { - if (getBroadcastAction() != null) { - Intent intent = new Intent(getBroadcastAction()); - intent.putExtra(extra, true); - Utils.debugLog(TAG, "Sending broadcast " + extra + " from " + getClass().getSimpleName()); - LocalBroadcastManager.getInstance(context).sendBroadcast(intent); - } - } - - public boolean isConnected() { - return isConnected; - } - - public void startInBackground() { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - start(); - return null; - } - }.execute(); - } - - private void ensureRunning() { - if (!isConnected()) { - start(); - } - } - - public void ensureRunningInBackground() { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - ensureRunning(); - return null; - } - }.execute(); - } - - public void stopInBackground() { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - stop(); - return null; - } - }.execute(); - } - -} diff --git a/app/src/full/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java b/app/src/full/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java deleted file mode 100644 index bca4a0f36..000000000 --- a/app/src/full/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.fdroid.fdroid.localrepo.type; - -import android.content.Context; -import android.net.wifi.WifiManager; -import org.fdroid.fdroid.FDroidApp; -import org.fdroid.fdroid.localrepo.BonjourManager; -import org.fdroid.fdroid.localrepo.LocalHTTPDManager; -import org.fdroid.fdroid.localrepo.SwapService; - -@SuppressWarnings("LineLength") -public class WifiSwap extends SwapType { - - private static final String TAG = "WifiSwap"; - - private final WifiManager wifiManager; - - public WifiSwap(Context context, WifiManager wifiManager) { - super(context); - this.wifiManager = wifiManager; - } - - protected String getBroadcastAction() { - return SwapService.WIFI_STATE_CHANGE; - } - - @Override - public void start() { - sendBroadcast(SwapService.EXTRA_STARTING); - wifiManager.setWifiEnabled(true); - LocalHTTPDManager.start(context); - BonjourManager.start(context); - BonjourManager.setVisible(context, SwapService.getWifiVisibleUserPreference()); - - if (FDroidApp.ipAddressString == null) { - setConnected(false); - } else { - setConnected(true); - } - } - - @Override - public void stop() { - sendBroadcast(SwapService.EXTRA_STOPPING); // This needs to be per-SwapType - LocalHTTPDManager.stop(context); - BonjourManager.stop(context); - setConnected(false); - } - -} diff --git a/app/src/full/java/org/fdroid/fdroid/net/WifiStateChangeService.java b/app/src/full/java/org/fdroid/fdroid/net/WifiStateChangeService.java index 4bf85b381..81f738c2a 100644 --- a/app/src/full/java/org/fdroid/fdroid/net/WifiStateChangeService.java +++ b/app/src/full/java/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -59,10 +59,12 @@ public class WifiStateChangeService extends IntentService { private static final String TAG = "WifiStateChangeService"; public static final String BROADCAST = "org.fdroid.fdroid.action.WIFI_CHANGE"; + public static final String EXTRA_STATUS = "wifiStateChangeStatus"; private WifiManager wifiManager; private static WifiInfoThread wifiInfoThread; private static int previousWifiState = Integer.MIN_VALUE; + private static int wifiState; public WifiStateChangeService() { super("WifiStateChangeService"); @@ -86,7 +88,7 @@ public class WifiStateChangeService extends IntentService { Utils.debugLog(TAG, "WiFi change service started."); NetworkInfo ni = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE); - int wifiState = wifiManager.getWifiState(); + wifiState = wifiManager.getWifiState(); if (ni == null || ni.isConnected()) { Utils.debugLog(TAG, "ni == " + ni + " wifiState == " + printWifiState(wifiState)); if (previousWifiState != wifiState && @@ -219,6 +221,7 @@ public class WifiStateChangeService extends IntentService { return; } Intent intent = new Intent(BROADCAST); + intent.putExtra(EXTRA_STATUS, wifiState); LocalBroadcastManager.getInstance(WifiStateChangeService.this).sendBroadcast(intent); } } diff --git a/app/src/full/java/org/fdroid/fdroid/views/swap/StartSwapView.java b/app/src/full/java/org/fdroid/fdroid/views/swap/StartSwapView.java index 10a0d3797..60c7db5ec 100644 --- a/app/src/full/java/org/fdroid/fdroid/views/swap/StartSwapView.java +++ b/app/src/full/java/org/fdroid/fdroid/views/swap/StartSwapView.java @@ -26,7 +26,6 @@ import cc.mvdan.accesspoint.WifiApControl; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; -import org.fdroid.fdroid.localrepo.BonjourManager; import org.fdroid.fdroid.localrepo.SwapService; import org.fdroid.fdroid.localrepo.SwapView; import org.fdroid.fdroid.localrepo.peers.Peer; @@ -82,9 +81,7 @@ public class StartSwapView extends SwapView { @Nullable /* Emulators typically don't have bluetooth adapters */ private final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); - private SwitchCompat wifiSwitch; private SwitchCompat bluetoothSwitch; - private TextView textWifiVisible; private TextView viewBluetoothId; private TextView textBluetoothVisible; private TextView viewWifiId; @@ -134,15 +131,10 @@ public class StartSwapView extends SwapView { peerFinderSubscription = null; } - if (wifiSwitch != null) { - wifiSwitch.setOnCheckedChangeListener(null); - } - if (bluetoothSwitch != null) { bluetoothSwitch.setOnCheckedChangeListener(null); } - LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(onWifiSwapStateChanged); LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(onBluetoothSwapStateChanged); LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(onWifiNetworkChanged); } @@ -159,7 +151,6 @@ public class StartSwapView extends SwapView { uiInitBluetooth(); uiInitWifi(); uiInitButtons(); - uiShowSearchingForPeers(); LocalBroadcastManager.getInstance(getActivity()).registerReceiver( onWifiNetworkChanged, new IntentFilter(WifiStateChangeService.BROADCAST)); @@ -210,11 +201,6 @@ public class StartSwapView extends SwapView { }); } - private void uiShowSearchingForPeers() { - peopleNearbyText.setText(getContext().getString(R.string.swap_scanning_for_peers)); - peopleNearbyProgress.setVisibility(View.VISIBLE); - } - private void uiShowNotSearchingForPeers() { peopleNearbyProgress.setVisibility(View.GONE); if (peopleNearbyList.getAdapter().getCount() > 0) { @@ -253,9 +239,6 @@ public class StartSwapView extends SwapView { } } - /** - * @see StartSwapView#onWifiSwapStateChanged - */ private final BroadcastReceiver onBluetoothSwapStateChanged = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -279,9 +262,6 @@ public class StartSwapView extends SwapView { } }; - /** - * @see StartSwapView#setWifiSwitchState(boolean, boolean) - */ private void setBluetoothSwitchState(boolean isChecked, boolean isEnabled) { bluetoothSwitch.setOnCheckedChangeListener(null); bluetoothSwitch.setChecked(isChecked); @@ -289,9 +269,6 @@ public class StartSwapView extends SwapView { bluetoothSwitch.setOnCheckedChangeListener(onBluetoothSwitchToggled); } - /** - * @see StartSwapView#onWifiSwitchToggled - */ private final CompoundButton.OnCheckedChangeListener onBluetoothSwitchToggled = new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -318,109 +295,9 @@ public class StartSwapView extends SwapView { viewWifiId = (TextView) findViewById(R.id.device_id_wifi); viewWifiNetwork = (TextView) findViewById(R.id.wifi_network); - wifiSwitch = (SwitchCompat) findViewById(R.id.switch_wifi); - wifiSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - BonjourManager.setVisible(getContext(), isChecked); - SwapService.putWifiVisibleUserPreference(isChecked); - } - }); - - textWifiVisible = findViewById(R.id.wifi_visible); - - // Note that this is only listening for the WifiSwap, whereas we start both the WifiSwap - // and the Bonjour service at the same time. Technically swap will work fine without - // Bonjour, and that is more of a convenience. Thus, we should show feedback once wifi - // is ready, even if Bonjour is not yet. - LocalBroadcastManager.getInstance(getContext()).registerReceiver(onWifiSwapStateChanged, - new IntentFilter(SwapService.WIFI_STATE_CHANGE)); - - viewWifiNetwork.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - getActivity().promptToSelectWifiNetwork(); - } - }); - uiUpdateWifiNetwork(); } - /** - * When the WiFi swap service is started or stopped, update the UI appropriately. - * This includes both the in-transit states of "Starting" and "Stopping". In these two cases, - * the UI should be disabled to prevent the user quickly switching back and forth - causing - * multiple start/stop actions to be sent to the swap service. - */ - private final BroadcastReceiver onWifiSwapStateChanged = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.hasExtra(SwapService.EXTRA_STARTING)) { - Utils.debugLog(TAG, "WiFi service is starting (setting toggle to checked, but disabled)."); - textWifiVisible.setText(R.string.swap_setting_up_wifi); - setWifiSwitchState(true, false); - } else if (intent.hasExtra(SwapService.EXTRA_STOPPING)) { - Utils.debugLog(TAG, "WiFi service is stopping (setting toggle to unchecked and disabled)."); - textWifiVisible.setText(R.string.swap_stopping_wifi); - setWifiSwitchState(false, false); - } else { - if (intent.hasExtra(SwapService.EXTRA_STARTED)) { - Utils.debugLog(TAG, "WiFi service has started (setting toggle to visible)."); - textWifiVisible.setText(R.string.swap_visible_wifi); - setWifiSwitchState(true, true); - } else { - Utils.debugLog(TAG, "WiFi service has stopped (setting toggle to not-visible)."); - textWifiVisible.setText(R.string.swap_not_visible_wifi); - setWifiSwitchState(false, true); - } - } - uiUpdateWifiNetwork(); - } - }; - - /** - * Helper function to set the "enable wifi" switch, but prevents the listeners from - * being notified. This enables the UI to be updated without triggering further enable/disable - * events being queued. - *

- * This is required because the SwitchCompat and its parent classes will always try to notify - * their listeners if there is one (e.g. http://stackoverflow.com/a/15523518). - *

- * The fact that this method also deals with enabling/disabling the switch is more of a convenience - * Nigh on all times this UI wants to change the state of the switch, it is also interested in - * ensuring the enabled state of the switch. - */ - private void setWifiSwitchState(boolean isChecked, boolean isEnabled) { - wifiSwitch.setOnCheckedChangeListener(null); - wifiSwitch.setChecked(isChecked); - wifiSwitch.setEnabled(isEnabled); - wifiSwitch.setOnCheckedChangeListener(onWifiSwitchToggled); - } - - /** - * When the wifi switch is: - *

- * Toggled on: Ask the swap service to ensure wifi swap is running. - * Toggled off: Ask the swap service to prevent the wifi swap service from running. - *

- * Both of these actions will be performed in a background thread which will send broadcast - * intents when they are completed. - */ - private final CompoundButton.OnCheckedChangeListener onWifiSwitchToggled = new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - Utils.debugLog(TAG, "Received onCheckChanged(true) for WiFi swap, asking in background thread to ensure WiFi swap is running."); - getActivity().getSwapService().getWifiSwap().ensureRunningInBackground(); - } else { - Utils.debugLog(TAG, "Received onCheckChanged(false) for WiFi swap, disabling WiFi swap in background thread."); - getActivity().getSwapService().getWifiSwap().stopInBackground(); - } - SwapService.putWifiVisibleUserPreference(isChecked); - uiUpdateWifiNetwork(); - } - }; - private void uiUpdateWifiNetwork() { viewWifiId.setText(FDroidApp.ipAddressString); diff --git a/app/src/full/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java b/app/src/full/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java index d7eec2af8..e63fc2b61 100644 --- a/app/src/full/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java +++ b/app/src/full/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java @@ -27,6 +27,7 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.SearchView; +import android.support.v7.widget.SwitchCompat; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.Log; @@ -61,6 +62,8 @@ import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.installer.InstallManagerService; import org.fdroid.fdroid.installer.Installer; +import org.fdroid.fdroid.localrepo.BonjourManager; +import org.fdroid.fdroid.localrepo.LocalHTTPDManager; import org.fdroid.fdroid.localrepo.LocalRepoService; import org.fdroid.fdroid.localrepo.SwapService; import org.fdroid.fdroid.localrepo.SwapView; @@ -343,6 +346,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { new IntentFilter(SwapWorkflowActivity.PrepareSwapRepo.ACTION)); localBroadcastManager.registerReceiver(repoUpdateReceiver, new IntentFilter(UpdateService.LOCAL_ACTION_STATUS)); + localBroadcastManager.registerReceiver(bonjourStatus, new IntentFilter(BonjourManager.ACTION_STATUS)); checkIncomingIntent(); @@ -359,6 +363,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { localBroadcastManager.unregisterReceiver(onWifiStateChanged); localBroadcastManager.unregisterReceiver(prepareSwapReceiver); localBroadcastManager.unregisterReceiver(repoUpdateReceiver); + localBroadcastManager.unregisterReceiver(bonjourStatus); } @Override @@ -388,17 +393,6 @@ 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) @@ -505,6 +499,9 @@ public class SwapWorkflowActivity extends AppCompatActivity { case R.layout.swap_connecting: setUpConnectingView(); break; + case R.layout.swap_start_swap: + setUpStartVisibility(); + break; } } @@ -568,7 +565,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null || Build.VERSION.SDK_INT >= 23 // TODO make Bluetooth work with content:// URIs - || (!adapter.isEnabled() && getSwapService().getWifiSwap().isConnected())) { + || (!adapter.isEnabled() && LocalHTTPDManager.isAlive())) { inflateSwapView(R.layout.swap_send_fdroid); } else { sendFDroidBluetooth(); @@ -814,8 +811,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { if (service == null) { message = "No swap service"; } else { - String bluetooth = service.getBluetoothSwap().isConnected() ? "Y" : " N"; - String wifi = service.getWifiSwap().isConnected() ? "Y" : " N"; + String bluetooth = getSwapService().getBluetoothSwap().isConnected() ? "Y" : " N"; BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); bluetooth = "N/A"; @@ -826,12 +822,11 @@ public class SwapWorkflowActivity extends AppCompatActivity { scanModes.put(BluetoothAdapter.SCAN_MODE_NONE, "NONE"); bluetooth = "\"" + adapter.getName() + "\" - " + scanModes.get(adapter.getScanMode()); } - - message += "Find { BT: " + bluetooth + ", WiFi: " + wifi + "}"; } Date now = new Date(); - Utils.debugLog("Swap Status", now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + " " + message); + Utils.debugLog("SWAP_STATUS", + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + " " + message); new Timer().schedule(new TimerTask() { @Override @@ -888,6 +883,26 @@ public class SwapWorkflowActivity extends AppCompatActivity { @Override public void onReceive(Context context, Intent intent) { setUpFromWifi(); + + int wifiStatus = -1; + TextView textWifiVisible = container.findViewById(R.id.wifi_visible); + if (textWifiVisible != null) { + intent.getIntExtra(WifiStateChangeService.EXTRA_STATUS, -1); + } + switch (wifiStatus) { + case WifiManager.WIFI_STATE_ENABLING: + textWifiVisible.setText(R.string.swap_setting_up_wifi); + break; + case WifiManager.WIFI_STATE_ENABLED: + textWifiVisible.setText(R.string.swap_not_visible_wifi); + break; + case WifiManager.WIFI_STATE_DISABLING: + case WifiManager.WIFI_STATE_DISABLED: + textWifiVisible.setText(R.string.swap_stopping_wifi); + break; + case WifiManager.WIFI_STATE_UNKNOWN: + break; + } } }; @@ -988,6 +1003,100 @@ public class SwapWorkflowActivity extends AppCompatActivity { } } + private void setUpStartVisibility() { + TextView viewWifiNetwork = findViewById(R.id.wifi_network); + + viewWifiNetwork.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + promptToSelectWifiNetwork(); + } + }); + + SwitchCompat wifiSwitch = findViewById(R.id.switch_wifi); + wifiSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + Context context = getApplicationContext(); + if (isChecked) { + wifiManager.setWifiEnabled(true); + BonjourManager.start(context); + } + BonjourManager.setVisible(context, isChecked); + SwapService.putWifiVisibleUserPreference(isChecked); + } + }); + + if (SwapService.getWifiVisibleUserPreference()) { + wifiSwitch.setChecked(true); + } else { + wifiSwitch.setChecked(false); + } + } + + private final BroadcastReceiver bonjourStatus = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + TextView textWifiVisible = container.findViewById(R.id.wifi_visible); + TextView peopleNearbyText = container.findViewById(R.id.text_people_nearby); + ProgressBar peopleNearbyProgress = container.findViewById(R.id.searching_people_nearby); + if (textWifiVisible == null || peopleNearbyText == null || peopleNearbyProgress == null + || !BonjourManager.ACTION_STATUS.equals(intent.getAction())) { + return; + } + int status = intent.getIntExtra(BonjourManager.EXTRA_STATUS, -1); + Log.i(TAG, "BonjourManager.EXTRA_STATUS: " + status); + switch (status) { + case BonjourManager.STATUS_STARTING: + textWifiVisible.setText(R.string.swap_setting_up_wifi); + peopleNearbyText.setText(R.string.swap_starting); + peopleNearbyText.setVisibility(View.VISIBLE); + peopleNearbyProgress.setVisibility(View.VISIBLE); + break; + case BonjourManager.STATUS_STARTED: + textWifiVisible.setText(R.string.swap_not_visible_wifi); + peopleNearbyText.setText(R.string.swap_scanning_for_peers); + peopleNearbyText.setVisibility(View.VISIBLE); + peopleNearbyProgress.setVisibility(View.VISIBLE); + break; + case BonjourManager.STATUS_NOT_VISIBLE: + textWifiVisible.setText(R.string.swap_not_visible_wifi); + peopleNearbyText.setText(R.string.swap_scanning_for_peers); + peopleNearbyText.setVisibility(View.VISIBLE); + peopleNearbyProgress.setVisibility(View.VISIBLE); + break; + case BonjourManager.STATUS_VISIBLE: + textWifiVisible.setText(R.string.swap_visible_wifi); + peopleNearbyText.setText(R.string.swap_scanning_for_peers); + peopleNearbyText.setVisibility(View.VISIBLE); + peopleNearbyProgress.setVisibility(View.VISIBLE); + break; + case BonjourManager.STATUS_STOPPING: + textWifiVisible.setText(R.string.swap_stopping_wifi); + if (!BluetoothManager.isAlive()) { + peopleNearbyText.setText(R.string.swap_stopping); + peopleNearbyText.setVisibility(View.VISIBLE); + peopleNearbyProgress.setVisibility(View.VISIBLE); + } + break; + case BonjourManager.STATUS_STOPPED: + textWifiVisible.setText(R.string.swap_not_visible_wifi); + if (!BluetoothManager.isAlive()) { + peopleNearbyText.setVisibility(View.GONE); + peopleNearbyProgress.setVisibility(View.GONE); + } + break; + case BonjourManager.STATUS_ERROR: + textWifiVisible.setText(R.string.swap_not_visible_wifi); + peopleNearbyText.setText(intent.getStringExtra(Intent.EXTRA_TEXT)); + peopleNearbyText.setVisibility(View.VISIBLE); + peopleNearbyProgress.setVisibility(View.GONE); + default: + throw new IllegalArgumentException("Bad intent: " + intent); + } + } + }; + private void setUpUseBluetoothButton() { Button useBluetooth = findViewById(R.id.btn_use_bluetooth); if (useBluetooth != null) { diff --git a/app/src/full/res/layout/swap_start_swap.xml b/app/src/full/res/layout/swap_start_swap.xml index 2eb22f17a..679d64feb 100644 --- a/app/src/full/res/layout/swap_start_swap.xml +++ b/app/src/full/res/layout/swap_start_swap.xml @@ -91,7 +91,7 @@ android:id="@+id/wifi_visible" android:layout_width="wrap_content" android:layout_height="wrap_content" - tools:text="@string/swap_not_visible_wifi" + tools:text="@string/swap_starting" android:textSize="18sp"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 40ee0ee11..3ba657edc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -488,6 +488,8 @@ This often occurs with apps installed via Google Play or other sources, if they Nearby Swap Connect and trade apps with people near you. + Starting… + Stopping… Visible via Bluetooth Setting up Bluetooth… Not visible via Bluetooth