Skip to content

Cleanup swap code when returning to start swap view.

This change cleans up some code around how the StartSwapView attaches and detaches listeners/broadcast receivers/etc. There are two things that occured which were undesirable, one causing observable bugs, the other having the potential to.

The first is that when the swap process is stopped (e.g. by hitting the cross in the top left of the action bar) then it would trigger an event to be broadcast. This would hit the StartSwapView, and then that view would change the UI widgets to match the state of the swap process (i.e. "Stopping" == Disabled and unchecked switch, "Stopped" == Enabled and unchecked switch). When the UI was updated, it was inadvertantly sending further requests to stop swap, because Switch widgets always notify their listeners, even if they are explicitly set via setChecked(). Now it temporarily removes listeners while brining the UI in line with what the swap service is doing, then reattaches them afterwards.

The later is due to BroadcastReceivers being added each time the StartSwapView is shown, and never unregistered. Now they are unregistered when the view is detached. Note that because we are not using the convoluted but well documented Fragment API, I'm not 100% certain this is the right time to detach listeners, but it seems suitable.

FYI, here is a logcat of me starting hitting the "Cancel swap" X button on master:

            SwapManager  I  Asked to stop swapping, will stop bluetooth, wifi, and move service to BG for GC.
                         D  Moving SwapService to background so that it can be GC'ed if required.
               SwapType  D  Sending broadcast STOPPING from WifiSwap
               WifiSwap  D  Sending message to swap webserver to stop it.
       BonjourBroadcast  D  Unregistering MDNS service...
               WifiSwap  I  we've been asked to stop the webserver: Thread-622 says stop
            SwapManager  D  Remembering that Bluetooth swap is NOT connected and WiFi swap IS connected.
          StartSwapView  D  WiFi service is stopping (setting toggle to unchecked and disabled).
                         D  Received onCheckChanged(false) for WiFi swap, disabling WiFi swap in background thread.
  AvailableAppsFragment  D  Category 'What's New' selected.
         OpenGLRenderer  D  endAllStagingAnimators on 0xb8c007e8 (RippleDrawable) with handle 0xb8cef7e8
        BluetoothFinder  D  Stopping bluetooth discovery.
       BluetoothAdapter  D  235158966: getState() :  mService = null. Returning STATE_OFF
          BonjourFinder  D  Cancelling BonjourFinder, releasing multicast lock, removing jmdns service listeners
                    art  I  WaitForGcToComplete blocked for 7.385ms for cause DisableMovingGc
Manager.CallbackHandler  D  CM callback handler got msg 524290
                         D  CM callback handler got msg 524290
               SwapType  D  Sending broadcast STOPPED from BonjourBroadcast
                         D  Sending broadcast STOPPED from WifiSwap
                         D  Sending broadcast STOPPING from WifiSwap
            SwapManager  D  Moving SwapService to background so that it can be GC'ed if required.
               WifiSwap  D  Sending message to swap webserver to stop it.
           MessageQueue  W  Handler (org.fdroid.fdroid.localrepo.type.WifiSwap$5$1$1) {29eeaaee} sending message to a Handler on a dead thread
                         W  java.lang.IllegalStateException: Handler (org.fdroid.fdroid.localrepo.type.WifiSwap$5$1$1) {29eeaaee} sending message to a Handler on a dead
                             thread
                         W      at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
                         W      at android.os.Handler.enqueueMessage(Handler.java:631)
                         W      at android.os.Handler.sendMessageAtTime(Handler.java:600)
                         W      at android.os.Handler.sendMessageDelayed(Handler.java:570)
                         W      at android.os.Handler.sendMessage(Handler.java:507)
                         W      at org.fdroid.fdroid.localrepo.type.WifiSwap.stop(WifiSwap.java:167)
                         W      at org.fdroid.fdroid.localrepo.type.SwapType$3.doInBackground(SwapType.java:103)
                         W      at org.fdroid.fdroid.localrepo.type.SwapType$3.doInBackground(SwapType.java:100)
                         W      at android.os.AsyncTask$2.call(AsyncTask.java:288)
                         W      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                         W      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                         W      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                         W      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                         W      at java.lang.Thread.run(Thread.java:818)
       BonjourBroadcast  D  Unregistering MDNS service...
               SwapType  D  Sending broadcast STOPPED from BonjourBroadcast
                         D  Sending broadcast STOPPED from WifiSwap
            SwapManager  D  Remembering that Bluetooth swap is NOT connected and WiFi swap is NOT connected.
          StartSwapView  D  WiFi service has stopped (setting toggle to not-visible).
            SwapManager  D  Remembering that Bluetooth swap is NOT connected and WiFi swap is NOT connected.
          StartSwapView  D  WiFi service is stopping (setting toggle to unchecked and disabled).
            SwapManager  D  Moving SwapService to background so that it can be GC'ed if required.
                         D  Remembering that Bluetooth swap is NOT connected and WiFi swap is NOT connected.
          StartSwapView  D  WiFi service has stopped (setting toggle to not-visible).

And also on this branch:

            SwapService  I  Asked to stop swapping, will stop bluetooth, wifi, and move service to BG for GC.
                         D  Moving SwapService to background so that it can be GC'ed if required.
               SwapType  D  Sending broadcast STOPPING from WifiSwap
               WifiSwap  D  Sending message to swap webserver to stop it.
       BonjourBroadcast  D  Unregistering MDNS service...
               WifiSwap  I  we've been asked to stop the webserver: Thread-646 says stop
            SwapService  D  Remembering that Bluetooth swap is NOT connected and WiFi swap IS connected.
          StartSwapView  D  WiFi service is stopping (setting toggle to unchecked and disabled).
  AvailableAppsFragment  D  Category 'What's New' selected.
         OpenGLRenderer  D  endAllStagingAnimators on 0xb8b1bb70 (RippleDrawable) with handle 0xb8cec7c0
          BonjourFinder  D  Cancelling BonjourFinder, releasing multicast lock, removing jmdns service listeners
        BluetoothFinder  D  Stopping bluetooth discovery.
       BluetoothAdapter  D  93224770: getState() :  mService = null. Returning STATE_OFF
Manager.CallbackHandler  D  CM callback handler got msg 524290
                         D  CM callback handler got msg 524290
               SwapType  D  Sending broadcast STOPPED from BonjourBroadcast
                         D  Sending broadcast STOPPED from WifiSwap
            SwapService  D  Moving SwapService to background so that it can be GC'ed if required.
                         D  Remembering that Bluetooth swap is NOT connected and WiFi swap is NOT connected.
          StartSwapView  D  WiFi service has stopped (setting toggle to not-visible).
Manager.CallbackHandler  D  CM callback handler got msg 524290

One of the most notable things that can be seen is the lack of the following message in the second (fixed) logcat.

Received onCheckChanged(false) for WiFi swap, disabling WiFi swap in background thread.

Merge request reports