From 09c96c620f4280d83a7764404a275699ce0f59c5 Mon Sep 17 00:00:00 2001 From: Thuy Trinh Date: Fri, 8 Jun 2018 09:48:04 +0200 Subject: [PATCH] Use `Observable.create()` to construct LocationServicesOkObservable (#438) * Use `Observable.create()` to construct LocationServicesOkObservable * Move setCancellable to the bottom * Remove try-catch block --- .../rxandroidble2/ClientComponent.java | 6 +- .../LocationServicesOkObservableApi23.java | 56 ------------------- ...ationServicesOkObservableApi23Factory.java | 53 ++++++++++++++++++ ...rvicesOkObservableApi23FactoryTest.groovy} | 16 +++--- 4 files changed, 64 insertions(+), 67 deletions(-) delete mode 100644 rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23.java create mode 100644 rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Factory.java rename rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/{LocationServicesOkObservableApi23Test.groovy => LocationServicesOkObservableApi23FactoryTest.groovy} (86%) diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/ClientComponent.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/ClientComponent.java index 8b5c72d0f..6aa43945a 100644 --- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/ClientComponent.java +++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/ClientComponent.java @@ -26,7 +26,7 @@ import com.polidea.rxandroidble2.internal.scan.ScanSetupBuilderImplApi23; import com.polidea.rxandroidble2.internal.serialization.ClientOperationQueue; import com.polidea.rxandroidble2.internal.serialization.ClientOperationQueueImpl; -import com.polidea.rxandroidble2.internal.util.LocationServicesOkObservableApi23; +import com.polidea.rxandroidble2.internal.util.LocationServicesOkObservableApi23Factory; import com.polidea.rxandroidble2.internal.util.LocationServicesStatus; import com.polidea.rxandroidble2.internal.util.LocationServicesStatusApi18; import com.polidea.rxandroidble2.internal.util.LocationServicesStatusApi23; @@ -163,11 +163,11 @@ LocationServicesStatus provideLocationServicesStatus( @Named(NamedBooleanObservables.LOCATION_SERVICES_OK) Observable provideLocationServicesOkObservable( @Named(PlatformConstants.INT_DEVICE_SDK) int deviceSdk, - Provider locationServicesOkObservableApi23Provider + LocationServicesOkObservableApi23Factory locationServicesOkObservableApi23Factory ) { return deviceSdk < Build.VERSION_CODES.M ? ObservableUtil.justOnNext(true) // there is no need for one before Marshmallow - : locationServicesOkObservableApi23Provider.get(); + : locationServicesOkObservableApi23Factory.get(); } @Provides diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23.java deleted file mode 100644 index 56a830135..000000000 --- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.polidea.rxandroidble2.internal.util; - -import android.annotation.TargetApi; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.location.LocationManager; -import android.os.Build; - -import java.util.concurrent.atomic.AtomicBoolean; - -import bleshadow.javax.inject.Inject; -import io.reactivex.Observable; -import io.reactivex.Observer; -import io.reactivex.disposables.Disposables; -import io.reactivex.functions.Action; - -@TargetApi(Build.VERSION_CODES.KITKAT) -public class LocationServicesOkObservableApi23 extends Observable { - - private final Context context; - private final LocationServicesStatus locationServicesStatus; - - @Inject - LocationServicesOkObservableApi23(final Context context, final LocationServicesStatus locationServicesStatus) { - this.context = context; - this.locationServicesStatus = locationServicesStatus; - } - - @Override - protected void subscribeActual(final Observer observer) { - final boolean locationProviderOk = locationServicesStatus.isLocationProviderOk(); - final AtomicBoolean locationProviderOkAtomicBoolean = new AtomicBoolean(locationProviderOk); - final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final boolean newLocationProviderOkValue = locationServicesStatus.isLocationProviderOk(); - final boolean valueChanged = locationProviderOkAtomicBoolean - .compareAndSet(!newLocationProviderOkValue, newLocationProviderOkValue); - if (valueChanged) { - observer.onNext(newLocationProviderOkValue); - } - } - }; - - context.registerReceiver(broadcastReceiver, new IntentFilter(LocationManager.MODE_CHANGED_ACTION)); - observer.onSubscribe(Disposables.fromAction(new Action() { - @Override - public void run() throws Exception { - context.unregisterReceiver(broadcastReceiver); - } - })); - observer.onNext(locationProviderOk); - } -} diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Factory.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Factory.java new file mode 100644 index 000000000..6c6455122 --- /dev/null +++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Factory.java @@ -0,0 +1,53 @@ +package com.polidea.rxandroidble2.internal.util; + +import android.annotation.TargetApi; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.location.LocationManager; +import android.os.Build; + +import bleshadow.javax.inject.Inject; +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.functions.Cancellable; + +@TargetApi(Build.VERSION_CODES.KITKAT) +public class LocationServicesOkObservableApi23Factory { + private final Context context; + private final LocationServicesStatus locationServicesStatus; + + @Inject + LocationServicesOkObservableApi23Factory( + final Context context, + final LocationServicesStatus locationServicesStatus) { + this.context = context; + this.locationServicesStatus = locationServicesStatus; + } + + public Observable get() { + return Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(final ObservableEmitter emitter) throws Exception { + final boolean initialValue = locationServicesStatus.isLocationProviderOk(); + final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final boolean newValue = locationServicesStatus.isLocationProviderOk(); + emitter.onNext(newValue); + } + }; + emitter.onNext(initialValue); + context.registerReceiver(broadcastReceiver, new IntentFilter(LocationManager.MODE_CHANGED_ACTION)); + emitter.setCancellable(new Cancellable() { + @Override + public void cancel() throws Exception { + context.unregisterReceiver(broadcastReceiver); + } + }); + } + }).distinctUntilChanged(); + } +} diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Test.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy similarity index 86% rename from rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Test.groovy rename to rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy index aeeffed49..688d83d10 100644 --- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23Test.groovy +++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy @@ -8,10 +8,10 @@ import hkhc.electricspock.ElectricSpecification import org.robolectric.annotation.Config @Config(manifest = Config.NONE) -class LocationServicesOkObservableApi23Test extends ElectricSpecification { +class LocationServicesOkObservableApi23FactoryTest extends ElectricSpecification { def contextMock = Mock Context def mockLocationServicesStatus = Mock LocationServicesStatus - def objectUnderTest = new LocationServicesOkObservableApi23(contextMock, mockLocationServicesStatus) + def objectUnderTest = new LocationServicesOkObservableApi23Factory(contextMock, mockLocationServicesStatus) BroadcastReceiver registeredReceiver def setup() { @@ -24,7 +24,7 @@ class LocationServicesOkObservableApi23Test extends ElectricSpecification { mockLocationServicesStatus.isLocationProviderOk() >> true when: - objectUnderTest.subscribe() + objectUnderTest.get().subscribe() then: 1 * contextMock.registerReceiver(!null, { @@ -37,7 +37,7 @@ class LocationServicesOkObservableApi23Test extends ElectricSpecification { given: mockLocationServicesStatus.isLocationProviderOk() >> true shouldCaptureRegisteredReceiver() - def disposable = objectUnderTest.test() + def disposable = objectUnderTest.get().test() when: disposable.dispose() @@ -46,12 +46,12 @@ class LocationServicesOkObservableApi23Test extends ElectricSpecification { 1 * contextMock.unregisterReceiver(registeredReceiver) } - def "should register and unregister broadcast listeners in correct order if unsubscribed on the first emission"() { + def "should still register and unregister in correct order"() { given: mockLocationServicesStatus.isLocationProviderOk() >> isLocationProviderOkResult when: - objectUnderTest.take(1).test() + objectUnderTest.get().take(1).test() then: 1 * contextMock.registerReceiver(_, _) @@ -70,7 +70,7 @@ class LocationServicesOkObservableApi23Test extends ElectricSpecification { mockLocationServicesStatus.isLocationProviderOk() >>> [true, false, true] when: - def testObserver = objectUnderTest.test() + def testObserver = objectUnderTest.get().test() then: testObserver.assertValue(true) @@ -95,7 +95,7 @@ class LocationServicesOkObservableApi23Test extends ElectricSpecification { mockLocationServicesStatus.isLocationProviderOk() >>> [false, false, true, true, false, false] when: - def testObserver = objectUnderTest.test() + def testObserver = objectUnderTest.get().test() then: testObserver.assertValue(false)