diff --git a/F-Droid/res/layout/swap_connecting.xml b/F-Droid/res/layout/swap_connecting.xml index 5df0e4034..e729653db 100644 --- a/F-Droid/res/layout/swap_connecting.xml +++ b/F-Droid/res/layout/swap_connecting.xml @@ -30,4 +30,6 @@ tools:text="Downloading index from http://10.0.0.4:8888/fdroid/repo" android:padding="30dp" /> + + \ No newline at end of file diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java index c9e0eed39..42fa9c6aa 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java @@ -10,6 +10,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.Uri; +import android.net.http.AndroidHttpClient; import android.os.AsyncTask; import android.os.IBinder; import android.support.annotation.IntDef; @@ -20,11 +21,18 @@ import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.util.Log; +import org.apache.http.HttpHost; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.UpdateService; +import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.App; +import org.fdroid.fdroid.data.NewRepoConfig; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.localrepo.peers.BluetoothFinder; @@ -37,11 +45,14 @@ import org.fdroid.fdroid.localrepo.type.WebServerType; import org.fdroid.fdroid.net.WifiStateChangeService; import org.fdroid.fdroid.views.swap.SwapWorkflowActivity; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.Timer; import java.util.TimerTask; @@ -134,11 +145,11 @@ public class SwapService extends Service { @Nullable public UpdateService.UpdateReceiver refreshSwap() { - return this.peer != null ? connectTo(peer) : null; + return this.peer != null ? connectTo(peer, false) : null; } @NonNull - public UpdateService.UpdateReceiver connectTo(@NonNull Peer peer) { + public UpdateService.UpdateReceiver connectTo(@NonNull Peer peer, boolean requestSwapBack) { if (peer != this.peer) { Log.e(TAG, "Oops, got a different peer to swap with than initially planned."); } @@ -148,30 +159,34 @@ public class SwapService extends Service { // Only ask server to swap with us, if we are actually running a local repo service. // It is possible to have a swap initiated without first starting a swap, in which // case swapping back is pointless. - /*if (!newRepoConfig.preventFurtherSwaps() && isEnabled()) { - askServerToSwapWithUs(); - }*/ + if (isEnabled()) { + askServerToSwapWithUs(peerRepo); + } return UpdateService.updateRepoNow(peer.getRepoAddress(), this, false); } -/* - private void askServerToSwapWithUs() { - if (!newRepoConfig.isValidRepo()) { - return; - } + private void askServerToSwapWithUs(final Repo repo) { + askServerToSwapWithUs(repo.address); + } + + public void askServerToSwapWithUs(final NewRepoConfig config) { + askServerToSwapWithUs(config.getRepoUriString()); + } + + private void askServerToSwapWithUs(final String address) { new AsyncTask() { @Override protected Void doInBackground(Void... args) { - Uri repoUri = newRepoConfig.getRepoUri(); + Uri repoUri = Uri.parse(address); String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString(); - AndroidHttpClient client = AndroidHttpClient.newInstance("F-Droid", ConnectSwapActivity.this); + AndroidHttpClient client = AndroidHttpClient.newInstance("F-Droid", SwapService.this); HttpPost request = new HttpPost("/request-swap"); HttpHost host = new HttpHost(repoUri.getHost(), repoUri.getPort(), repoUri.getScheme()); try { - Log.d(TAG, "Asking server at " + newRepoConfig.getRepoUriString() + " to swap with us in return (by POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\")..."); + Log.d(TAG, "Asking server at " + address + " to swap with us in return (by POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\")..."); populatePostParams(swapBackUri, request); client.execute(host, request); } catch (IOException e) { @@ -191,19 +206,21 @@ public class SwapService extends Service { } private void notifyOfErrorOnUiThread() { - runOnUiThread(new Runnable() { + // TODO: Broadcast error message so that whoever wants to can display a relevant + // message in the UI. This service doesn't understand the concept of UI. + /*runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText( - ConnectSwapActivity.this, + SwapService.this, R.string.swap_reciprocate_failed, Toast.LENGTH_LONG ).show(); } - }); + });*/ } }.execute(); - }*/ + } private Repo ensureRepoExists(@NonNull Peer peer) { // TODO: newRepoConfig.getParsedUri() will include a fingerprint, which may not match with diff --git a/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java b/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java index df688998a..dc763ae1a 100644 --- a/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java +++ b/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -167,6 +167,7 @@ public class WifiStateChangeService extends Service { @Override public void onServiceConnected(ComponentName name, IBinder service) { ((SwapService.Binder)service).getService().restartIfEnabled(); + unbindService(this); } @Override diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/ConnectSwapActivity.java b/F-Droid/src/org/fdroid/fdroid/views/swap/ConnectSwapActivity.java index 76d662806..4ab1503f8 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/ConnectSwapActivity.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/ConnectSwapActivity.java @@ -6,8 +6,6 @@ import android.content.ContentValues; import android.content.Intent; import android.content.ServiceConnection; import android.net.Uri; -import android.net.http.AndroidHttpClient; -import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; import android.support.annotation.Nullable; @@ -15,32 +13,18 @@ import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.View; import android.widget.TextView; -import android.widget.Toast; -import org.apache.http.HttpHost; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.message.BasicNameValuePair; -import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.ProgressListener; import org.fdroid.fdroid.R; import org.fdroid.fdroid.UpdateService; -import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.NewRepoConfig; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.localrepo.SwapService; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - public class ConnectSwapActivity extends ActionBarActivity implements ProgressListener { - private static final String TAG = "ConnectSwapActivity"; - private static final String STATE_CONFIRM = "startSwap"; + private static final String TAG = "ConnectSwapActivity"; /** * When connecting to a swap, we then go and initiate a connection with that @@ -167,7 +151,7 @@ public class ConnectSwapActivity extends ActionBarActivity implements ProgressLi */ private void attemptSwapBack() { - if (newRepoConfig.preventFurtherSwaps()) { + if (!newRepoConfig.isValidRepo() || newRepoConfig.preventFurtherSwaps()) { return; } @@ -176,8 +160,9 @@ public class ConnectSwapActivity extends ActionBarActivity implements ProgressLi public void onServiceConnected(ComponentName name, IBinder binder) { SwapService service = ((SwapService.Binder) binder).getService(); if (service.isEnabled()) { - askServerToSwapWithUs(); + service.askServerToSwapWithUs(newRepoConfig); } + unbindService(this); } @Override @@ -187,54 +172,4 @@ public class ConnectSwapActivity extends ActionBarActivity implements ProgressLi Intent intent = new Intent(this, SwapService.class); bindService(intent, connection, BIND_AUTO_CREATE); } - - private void askServerToSwapWithUs() { - if (!newRepoConfig.isValidRepo()) { - return; - } - - new AsyncTask() { - @Override - protected Void doInBackground(Void... args) { - Uri repoUri = newRepoConfig.getRepoUri(); - String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString(); - - AndroidHttpClient client = AndroidHttpClient.newInstance("F-Droid", ConnectSwapActivity.this); - HttpPost request = new HttpPost("/request-swap"); - HttpHost host = new HttpHost(repoUri.getHost(), repoUri.getPort(), repoUri.getScheme()); - - try { - Log.d(TAG, "Asking server at " + newRepoConfig.getRepoUriString() + " to swap with us in return (by POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\")..."); - populatePostParams(swapBackUri, request); - client.execute(host, request); - } catch (IOException e) { - notifyOfErrorOnUiThread(); - Log.e(TAG, "Error while asking server to swap with us: " + e.getMessage()); - } finally { - client.close(); - } - return null; - } - - private void populatePostParams(String swapBackUri, HttpPost request) throws UnsupportedEncodingException { - List params = new ArrayList<>(); - params.add(new BasicNameValuePair("repo", swapBackUri)); - UrlEncodedFormEntity encodedParams = new UrlEncodedFormEntity(params); - request.setEntity(encodedParams); - } - - private void notifyOfErrorOnUiThread() { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText( - ConnectSwapActivity.this, - R.string.swap_reciprocate_failed, - Toast.LENGTH_LONG - ).show(); - } - }); - } - }.execute(); - } } 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 5a042378d..c5565dc27 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java @@ -167,7 +167,7 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In } }); - getContext().registerReceiver(new BroadcastReceiver() { + LocalBroadcastManager.getInstance(getContext()).registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Peer peer = intent.getParcelableExtra(SwapService.EXTRA_PEER); diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapConnecting.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapConnecting.java index ba0d34e33..a594847fa 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapConnecting.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapConnecting.java @@ -64,7 +64,7 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity String heading = getContext().getString(R.string.status_connecting_to_repo, getActivity().getState().getPeer().getName()); ((TextView) findViewById(R.id.heading)).setText(heading); - UpdateService.UpdateReceiver receiver = getManager().connectTo(peer); + UpdateService.UpdateReceiver receiver = getManager().connectTo(peer, true); receiver.hideDialog(); receiver.setListener(new ProgressListener() { @@ -117,7 +117,7 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity @ColorRes public int getToolbarColour() { - return getResources().getColor(R.color.swap_blue); + return getResources().getColor(R.color.swap_bright_blue); } @Override 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 0a73d70de..263ab4a01 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java @@ -74,6 +74,23 @@ public class SwapWorkflowActivity extends AppCompatActivity { private boolean hasPreparedLocalRepo = false; private PrepareSwapRepo updateSwappableAppsTask = null; + @NonNull + private final ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName className, IBinder binder) { + Log.d(TAG, "Swap service connected, enabling SwapManager to communicate with SwapService."); + service = ((SwapService.Binder)binder).getService(); + showRelevantView(); + } + + @Override + public void onServiceDisconnected(ComponentName className) { + Log.d(TAG, "Swap service disconnected"); + service = null; + // TODO: What to do about the UI in this instance? + } + }; + @Nullable private SwapService service = null; @@ -86,34 +103,6 @@ public class SwapWorkflowActivity extends AppCompatActivity { return service; } - private void setupService() { - - ServiceConnection serviceConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName className, IBinder binder) { - Log.d(TAG, "Swap service connected, enabling SwapManager to communicate with SwapService."); - service = ((SwapService.Binder)binder).getService(); - showRelevantView(); - } - - @Override - public void onServiceDisconnected(ComponentName className) { - Log.d(TAG, "Swap service disconnected"); - service = null; - // TODO: What to do about the UI in this instance? - } - }; - - // The server should not be doing anything or occupying any (noticeable) resources - // until we actually ask it to enable swapping. Therefore, we will start it nice and - // early so we don't have to wait until it is connected later. - Intent service = new Intent(this, SwapService.class); - if (bindService(service, serviceConnection, Context.BIND_AUTO_CREATE)) { - startService(service); - } - - } - @Override public void onBackPressed() { if (currentView.getStep() == SwapService.STEP_INTRO) { @@ -129,7 +118,13 @@ public class SwapWorkflowActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setupService(); + // The server should not be doing anything or occupying any (noticeable) resources + // until we actually ask it to enable swapping. Therefore, we will start it nice and + // early so we don't have to wait until it is connected later. + Intent service = new Intent(this, SwapService.class); + if (bindService(service, serviceConnection, Context.BIND_AUTO_CREATE)) { + startService(service); + } setContentView(R.layout.swap_activity); @@ -140,6 +135,12 @@ public class SwapWorkflowActivity extends AppCompatActivity { container = (ViewGroup) findViewById(R.id.fragment_container); } + @Override + protected void onDestroy() { + unbindService(serviceConnection); + super.onDestroy(); + } + @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear();