diff --git a/res/layout/swap_wifi_qr.xml b/res/layout/swap_wifi_qr.xml index b916b0332..ae9af93b1 100644 --- a/res/layout/swap_wifi_qr.xml +++ b/res/layout/swap_wifi_qr.xml @@ -1,50 +1,53 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - xmlns:tools="http://schemas.android.com/tools"> +<ScrollView + xmlns:tools="http://schemas.android.com/tools" + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="match_parent" + android:layout_width="wrap_content"> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/textView" - android:layout_gravity="center_horizontal" - android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" - android:text="One person needs to scan the code, or type the URL of the other swapper into a browser." - style="@style/SwapTheme.Wizard.MainText"/> - <ImageView - android:layout_width="match_parent" - android:layout_height="match_parent" - android:id="@+id/wifi_qr_code" - tools:src="@drawable/swap_qr_example" - android:layout_below="@+id/textView" - android:layout_above="@+id/device_ip_address"/> + <LinearLayout android:orientation="vertical" + android:gravity="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> - <!-- - <Button style="@style/SwapTheme.Wizard.OptionButton" - android:id="@+id/btn_not_working" - android:text="@string/swap_wifi_qr_not_working" - android:layout_alignParentBottom="true" /> - --> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/textView" + android:text="One person needs to scan the code, or type the URL of the other swapper into a browser." + style="@style/SwapTheme.Wizard.MainText"/> - <Button style="@style/SwapTheme.Wizard.OptionButton" - android:text="@string/open_qr_code_scanner" - android:layout_gravity="center" - android:layout_alignParentBottom="true" - android:id="@+id/btn_qr_scanner"/> - <!-- android:layout_above="@id/btn_not_working" --> + <ImageView + android:layout_width="250dp" + android:layout_height="250dp" + android:maxHeight="20dp" + android:id="@+id/wifi_qr_code" + tools:src="@drawable/swap_qr_example"/> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/device_ip_address" - tools:text="192.168.1.1:8888" - android:layout_above="@+id/btn_qr_scanner" - android:layout_centerHorizontal="true" - style="@style/SwapTheme.Wizard.LocalIpAddress"/> + <!-- + <Button style="@style/SwapTheme.Wizard.OptionButton" + android:id="@+id/btn_not_working" + android:text="@string/swap_wifi_qr_not_working" + android:layout_alignParentBottom="true" /> + --> -</RelativeLayout> \ No newline at end of file + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/device_ip_address" + tools:text="http://255.255.255.255:8888" + style="@style/SwapTheme.Wizard.LocalIpAddress"/> + + <Button style="@style/SwapTheme.Wizard.OptionButton" + android:text="@string/open_qr_code_scanner" + android:layout_gravity="center" + android:id="@+id/btn_qr_scanner"/> + + <Button style="@style/SwapTheme.Wizard.OptionButton" + android:id="@+id/btn_cancel_swap" + android:text="@string/cancel" /> + + </LinearLayout> + +</ScrollView> \ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml index fa3512fe8..1d34a71d8 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -113,7 +113,7 @@ </style> <style name="SwapTheme.Wizard.LocalIpAddress" parent="@style/SwapTheme.Wizard.Text"> - <item name="android:textSize">32.5sp</item> <!-- 58px * 96dpi / 160dpi --> + <item name="android:textSize">26.5sp</item> <!-- 58px * 96dpi / 160dpi = 32.5sp (ended up making a bit smaller, because longer addresses didn't fit well) --> <item name="android:paddingLeft">40dp</item> <item name="android:paddingRight">40dp</item> <item name="android:paddingTop">22.5dp</item> <!-- 40px * 96dpi / 160dpi --> diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java index 249e32d94..e16a5728c 100644 --- a/src/org/fdroid/fdroid/FDroidApp.java +++ b/src/org/fdroid/fdroid/FDroidApp.java @@ -41,13 +41,11 @@ import android.os.Messenger; import android.os.RemoteException; import android.preference.PreferenceManager; import android.widget.Toast; - import com.nostra13.universalimageloader.cache.disc.impl.LimitedAgeDiscCache; import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.utils.StorageUtils; - import org.fdroid.fdroid.Preferences.ChangeListener; import org.fdroid.fdroid.compat.PRNGFixes; import org.fdroid.fdroid.data.AppProvider; @@ -57,6 +55,9 @@ import org.fdroid.fdroid.localrepo.LocalRepoService; import org.fdroid.fdroid.net.IconDownloader; import org.fdroid.fdroid.net.WifiStateChangeService; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; import java.io.File; import java.util.Set; @@ -73,6 +74,8 @@ public class FDroidApp extends Application { private static Messenger localRepoServiceMessenger = null; private static boolean localRepoServiceIsBound = false; + private static final String TAG = "org.fdroid.fdroid.FDroidApp"; + BluetoothAdapter bluetoothAdapter = null; public static enum Theme { @@ -266,8 +269,7 @@ public class FDroidApp extends Application { if (!localRepoServiceIsBound) { Context app = context.getApplicationContext(); Intent service = new Intent(app, LocalRepoService.class); - localRepoServiceIsBound = app.bindService(service, serviceConnection, - Context.BIND_AUTO_CREATE); + localRepoServiceIsBound = app.bindService(service, serviceConnection, Context.BIND_AUTO_CREATE); if (localRepoServiceIsBound) app.startService(service); } @@ -285,8 +287,7 @@ public class FDroidApp extends Application { public static void restartLocalRepoService() { if (localRepoServiceMessenger != null) { try { - Message msg = Message.obtain(null, - LocalRepoService.RESTART, LocalRepoService.RESTART, 0); + Message msg = Message.obtain(null, LocalRepoService.RESTART, LocalRepoService.RESTART, 0); localRepoServiceMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); @@ -294,7 +295,7 @@ public class FDroidApp extends Application { } } - public static boolean isLocalRepoServiceRunnig() { + public static boolean isLocalRepoServiceRunning() { return localRepoServiceIsBound; } } diff --git a/src/org/fdroid/fdroid/QrGenAsyncTask.java b/src/org/fdroid/fdroid/QrGenAsyncTask.java index ebfc0fc19..e3a167e1f 100644 --- a/src/org/fdroid/fdroid/QrGenAsyncTask.java +++ b/src/org/fdroid/fdroid/QrGenAsyncTask.java @@ -70,6 +70,11 @@ public class QrGenAsyncTask extends AsyncTask<String, Void, Void> { @Override protected void onPostExecute(Void v) { ImageView qrCodeImageView = (ImageView) activity.findViewById(viewId); - qrCodeImageView.setImageBitmap(qrBitmap); + + // If the generation takes too long for whatever reason, then this view, and indeed the entire + // activity may not be around any more. + if (qrCodeImageView != null) { + qrCodeImageView.setImageBitmap(qrBitmap); + } } } diff --git a/src/org/fdroid/fdroid/localrepo/LocalRepoService.java b/src/org/fdroid/fdroid/localrepo/LocalRepoService.java index 6b9152d08..a8ed9f59b 100644 --- a/src/org/fdroid/fdroid/localrepo/LocalRepoService.java +++ b/src/org/fdroid/fdroid/localrepo/LocalRepoService.java @@ -58,25 +58,35 @@ public class LocalRepoService extends Service { final Messenger messenger = new Messenger(new StartStopHandler(this)); + /** + * This is most likely going to be created on the UI thread, hence all of + * the message handling will take place on a new thread to prevent blocking + * the UI. + */ static class StartStopHandler extends Handler { - private static LocalRepoService service; + + private final LocalRepoService service; public StartStopHandler(LocalRepoService service) { - StartStopHandler.service = service; + this.service = service; } @Override - public void handleMessage(Message msg) { - if (msg.arg1 == START) { - service.startNetworkServices(); - } else if (msg.arg1 == STOP) { - service.stopNetworkServices(); - } else if (msg.arg1 == RESTART) { - service.stopNetworkServices(); - service.startNetworkServices(); - } else { - Log.e(TAG, "unsupported msg.arg1, ignored"); - } + public void handleMessage(final Message msg) { + new Thread() { + public void run() { + if (msg.arg1 == START) { + service.startNetworkServices(); + } else if (msg.arg1 == STOP) { + service.stopNetworkServices(); + } else if (msg.arg1 == RESTART) { + service.stopNetworkServices(); + service.startNetworkServices(); + } else { + Log.e(TAG, "Unsupported msg.arg1 (" + msg.arg1 + "), ignored"); + } + } + }.start(); } } @@ -116,14 +126,12 @@ public class LocalRepoService extends Service { } }; - @Override - public void onCreate() { + private void showNotification() { notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // launch LocalRepoActivity if the user selects this notification Intent intent = new Intent(this, SwapActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, - PendingIntent.FLAG_CANCEL_CURRENT); + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); notification = new NotificationCompat.Builder(this) .setContentTitle(getText(R.string.local_repo_running)) .setContentText(getText(R.string.touch_to_configure_local_repo)) @@ -131,6 +139,11 @@ public class LocalRepoService extends Service { .setContentIntent(contentIntent) .build(); startForeground(NOTIFICATION, notification); + } + + @Override + public void onCreate() { + showNotification(); startNetworkServices(); Preferences.get().registerLocalRepoBonjourListeners(localRepoBonjourChangeListener); @@ -147,7 +160,12 @@ public class LocalRepoService extends Service { @Override public void onDestroy() { - stopNetworkServices(); + new Thread() { + public void run() { + stopNetworkServices(); + } + }.start(); + notificationManager.cancel(NOTIFICATION); LocalBroadcastManager.getInstance(this).unregisterReceiver(onWifiChange); Preferences.get().unregisterLocalRepoBonjourListeners(localRepoBonjourChangeListener); @@ -159,6 +177,7 @@ public class LocalRepoService extends Service { } private void startNetworkServices() { + Log.d(TAG, "Starting local repo network services"); startWebServer(); if (Preferences.get().isLocalRepoBonjourEnabled()) registerMDNSService(); @@ -166,8 +185,13 @@ public class LocalRepoService extends Service { } private void stopNetworkServices() { + Log.d(TAG, "Stopping local repo network services"); Preferences.get().unregisterLocalRepoHttpsListeners(localRepoHttpsChangeListener); + + Log.d(TAG, "Unregistering MDNS service..."); unregisterMDNSService(); + + Log.d(TAG, "Stopping web server..."); stopWebServer(); } diff --git a/src/org/fdroid/fdroid/views/LocalRepoActivity.java b/src/org/fdroid/fdroid/views/LocalRepoActivity.java index 67ef20e07..0005245f3 100644 --- a/src/org/fdroid/fdroid/views/LocalRepoActivity.java +++ b/src/org/fdroid/fdroid/views/LocalRepoActivity.java @@ -74,7 +74,7 @@ public class LocalRepoActivity extends ActionBarActivity { public void onResume() { super.onResume(); resetNetworkInfo(); - setRepoSwitchChecked(FDroidApp.isLocalRepoServiceRunnig()); + setRepoSwitchChecked(FDroidApp.isLocalRepoServiceRunning()); LocalBroadcastManager.getInstance(this).registerReceiver(onWifiChange, new IntentFilter(WifiStateChangeService.BROADCAST)); diff --git a/src/org/fdroid/fdroid/views/swap/SwapActivity.java b/src/org/fdroid/fdroid/views/swap/SwapActivity.java index 3359db011..f9ba06dea 100644 --- a/src/org/fdroid/fdroid/views/swap/SwapActivity.java +++ b/src/org/fdroid/fdroid/views/swap/SwapActivity.java @@ -121,7 +121,7 @@ public class SwapActivity extends ActionBarActivity implements SwapProcessManage if (savedInstanceState == null) { - if (FDroidApp.isLocalRepoServiceRunnig()) { + if (FDroidApp.isLocalRepoServiceRunning()) { onWifiQr(); } else { @@ -218,9 +218,13 @@ public class SwapActivity extends ActionBarActivity implements SwapProcessManage } private void startLocalRepo() { - if (!FDroidApp.isLocalRepoServiceRunnig()) { + if (!FDroidApp.isLocalRepoServiceRunning()) { FDroidApp.startLocalRepoService(this); + initLocalRepoTimer(900000); // 15 mins } + } + + private void initLocalRepoTimer(long timeoutMilliseconds) { // reset the timer if viewing this Activity again if (shutdownLocalRepoTimer != null) @@ -233,7 +237,19 @@ public class SwapActivity extends ActionBarActivity implements SwapProcessManage public void run() { FDroidApp.stopLocalRepoService(SwapActivity.this); } - }, 900000); // 15 minutes + }, timeoutMilliseconds); + + } + + @Override + public void stopSwapping() { + if (FDroidApp.isLocalRepoServiceRunning()) { + if (shutdownLocalRepoTimer != null) { + shutdownLocalRepoTimer.cancel(); + } + FDroidApp.stopLocalRepoService(SwapActivity.this); + } + finish(); } class UpdateAsyncTask extends AsyncTask<Void, String, Void> { diff --git a/src/org/fdroid/fdroid/views/swap/SwapProcessManager.java b/src/org/fdroid/fdroid/views/swap/SwapProcessManager.java index fcf9aebc5..0153fc578 100644 --- a/src/org/fdroid/fdroid/views/swap/SwapProcessManager.java +++ b/src/org/fdroid/fdroid/views/swap/SwapProcessManager.java @@ -2,4 +2,5 @@ package org.fdroid.fdroid.views.swap; public interface SwapProcessManager { public void nextStep(); + public void stopSwapping(); } diff --git a/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java b/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java index 1f9b296ea..4349382aa 100644 --- a/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java +++ b/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java @@ -45,6 +45,8 @@ public class WifiQrFragment extends Fragment { } }; + private SwapProcessManager swapManager; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.swap_wifi_qr, container, false); @@ -62,9 +64,22 @@ public class WifiQrFragment extends Fragment { } }); + Button cancel = (Button)view.findViewById(R.id.btn_cancel_swap); + cancel.setOnClickListener(new Button.OnClickListener() { + @Override + public void onClick(View v) { + swapManager.stopSwapping(); + } + }); return view; } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + swapManager = (SwapProcessManager)activity; + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);