scanPreconditionVerifierForApi31
) {
if (deviceSdk < Build.VERSION_CODES.N) {
return scanPreconditionVerifierForApi18.get();
- } else {
+ } else if (deviceSdk < Build.VERSION_CODES.S) {
return scanPreconditionVerifierForApi24.get();
+ } else {
+ return scanPreconditionVerifierForApi31.get();
}
}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClient.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClient.java
index 3206b5028..1e8ec9ee1 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClient.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClient.java
@@ -25,10 +25,15 @@ public enum State {
*/
BLUETOOTH_NOT_AVAILABLE,
/**
- * Runtime location permission is not given. Scanning will not work. Used on API >=23.
+ * Runtime Bluetooth scan permission is not granted. Scanning will not work. Used on API >=31.
+ * APIs 31+ - BLUETOOTH_SCAN
+ */
+ BLUETOOTH_SCAN_PERMISSION_NOT_GRANTED,
+ /**
+ * Runtime location permission is not given. Scanning will not work. Used on API 23-30 inclusive.
*
APIs 23-28 – ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
*
APIs 29-30 - ACCESS_FINE_LOCATION
- *
APIs 31+ - BLUETOOTH_SCAN and ACCESS_FINE_LOCATION (if BLUETOOTH_SCAN does not have neverForLocation flag)
+ *
APIs 31+ - BLUETOOTH_SCAN and ACCESS_FINE_LOCATION if BLUETOOTH_SCAN does not have neverForLocation flag
*/
LOCATION_PERMISSION_NOT_GRANTED,
/**
@@ -222,4 +227,27 @@ public static void updateLogOptions(LogOptions logOptions) {
* @return an ordered array of possible scan permissions
*/
public abstract String[] getRecommendedScanRuntimePermissions();
+
+ /**
+ * Returns whether runtime permissions needed to establish BLE connection are granted. If permissions are not granted then one may check
+ * {@link #getRecommendedConnectRuntimePermissions()} to get Android runtime permission strings needed to establish a connection.
+ *
+ * @return true if needed permissions are granted, false otherwise
+ */
+ public abstract boolean isConnectRuntimePermissionGranted();
+
+ /**
+ * Returns permission strings needed by the application to connect to Bluetooth devices or retrieve bonded devices, or an empty array
+ * if no runtime permissions are needed.
+ *
+ * Returned values:
+ *
+ * case: API < 31
+ * Empty array. No runtime permissions needed.
+ *
+ * case: 31 <= API
+ * {@link android.Manifest.permission#BLUETOOTH_CONNECT}
+ * @return an ordered array of possible connect permissions
+ */
+ public abstract String[] getRecommendedConnectRuntimePermissions();
}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClientImpl.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClientImpl.java
index 838bed9ec..7e921023b 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClientImpl.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/RxBleClientImpl.java
@@ -1,10 +1,15 @@
package com.polidea.rxandroidble2;
+import android.Manifest;
import android.bluetooth.BluetoothDevice;
+import android.os.Build;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.polidea.rxandroidble2.RxBleAdapterStateObservable.BleAdapterState;
+import com.polidea.rxandroidble2.exceptions.BleException;
+import com.polidea.rxandroidble2.exceptions.BlePermissionException;
import com.polidea.rxandroidble2.exceptions.BleScanException;
import com.polidea.rxandroidble2.internal.RxBleDeviceProvider;
import com.polidea.rxandroidble2.internal.RxBleLog;
@@ -113,6 +118,12 @@ public RxBleDevice getBleDevice(@NonNull String macAddress) {
@Override
public Set getBondedDevices() {
+ if (!locationServicesStatus.isConnectPermissionOk()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ throw new BlePermissionException(Manifest.permission.BLUETOOTH_CONNECT);
+ }
+ throw new BleException("Unexpected connect permission not OK");
+ }
guardBluetoothAdapterAvailable();
Set rxBleDevices = new HashSet<>();
Set bluetoothDevices = rxBleAdapterWrapper.getBondedDevices();
@@ -257,6 +268,9 @@ public State getState() {
if (!rxBleAdapterWrapper.hasBluetoothAdapter()) {
return State.BLUETOOTH_NOT_AVAILABLE;
}
+ if (!locationServicesStatus.isScanPermissionOk()) {
+ return State.BLUETOOTH_SCAN_PERMISSION_NOT_GRANTED;
+ }
if (!locationServicesStatus.isLocationPermissionOk()) {
return State.LOCATION_PERMISSION_NOT_GRANTED;
}
@@ -279,4 +293,14 @@ public boolean isScanRuntimePermissionGranted() {
public String[] getRecommendedScanRuntimePermissions() {
return checkerScanPermission.getRecommendedScanRuntimePermissions();
}
+
+ @Override
+ public boolean isConnectRuntimePermissionGranted() {
+ return checkerScanPermission.isConnectRuntimePermissionGranted();
+ }
+
+ @Override
+ public String[] getRecommendedConnectRuntimePermissions() {
+ return checkerScanPermission.getRecommendedConnectRuntimePermissions();
+ }
}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BlePermissionException.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BlePermissionException.java
new file mode 100644
index 000000000..e1d42c0ea
--- /dev/null
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BlePermissionException.java
@@ -0,0 +1,28 @@
+package com.polidea.rxandroidble2.exceptions;
+
+
+import android.Manifest;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+import androidx.annotation.StringDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class BlePermissionException extends BleException {
+
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ @StringDef({Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Permission {
+ }
+
+ public BlePermissionException(@Permission String permission) {
+ super(createMessage(permission));
+ }
+
+ private static String createMessage(@Permission String permission) {
+ return "BLE permission exception: " + permission;
+ }
+}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BleScanException.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BleScanException.java
index 82c9f957c..d72d0dc93 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BleScanException.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/exceptions/BleScanException.java
@@ -15,7 +15,8 @@ public class BleScanException extends BleException {
@IntDef({BLUETOOTH_CANNOT_START, BLUETOOTH_DISABLED, BLUETOOTH_NOT_AVAILABLE, LOCATION_PERMISSION_MISSING, LOCATION_SERVICES_DISABLED,
SCAN_FAILED_ALREADY_STARTED, SCAN_FAILED_APPLICATION_REGISTRATION_FAILED, SCAN_FAILED_INTERNAL_ERROR,
- SCAN_FAILED_FEATURE_UNSUPPORTED, SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES, UNDOCUMENTED_SCAN_THROTTLE, UNKNOWN_ERROR_CODE})
+ SCAN_FAILED_FEATURE_UNSUPPORTED, SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES, SCAN_PERMISSION_MISSING, UNDOCUMENTED_SCAN_THROTTLE,
+ UNKNOWN_ERROR_CODE})
@Retention(RetentionPolicy.SOURCE)
public @interface Reason {
@@ -76,6 +77,11 @@ public class BleScanException extends BleException {
*/
public static final int SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES = 9;
+ /**
+ * The BLUETOOTH_SCAN permission has not been granted. Only on API >=31.
+ */
+ public static final int SCAN_PERMISSION_MISSING = 10;
+
/**
* On API >=25 there is an undocumented scan throttling mechanism. If 5 scans were started by the app during a 30 second window
* the next scan in that window will be silently skipped with only a log warning. In this situation there should be
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/RxBleDeviceImpl.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/RxBleDeviceImpl.java
index 0b8aa421d..880c5b8a6 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/RxBleDeviceImpl.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/RxBleDeviceImpl.java
@@ -1,6 +1,9 @@
package com.polidea.rxandroidble2.internal;
+import android.Manifest;
import android.bluetooth.BluetoothDevice;
+import android.os.Build;
+
import androidx.annotation.Nullable;
import com.jakewharton.rxrelay2.BehaviorRelay;
@@ -9,9 +12,13 @@
import com.polidea.rxandroidble2.RxBleDevice;
import com.polidea.rxandroidble2.Timeout;
import com.polidea.rxandroidble2.exceptions.BleAlreadyConnectedException;
+import com.polidea.rxandroidble2.exceptions.BleException;
+import com.polidea.rxandroidble2.exceptions.BlePermissionException;
import com.polidea.rxandroidble2.internal.connection.Connector;
import com.polidea.rxandroidble2.internal.logger.LoggerUtil;
+import com.polidea.rxandroidble2.internal.util.LocationServicesStatus;
+
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -26,17 +33,20 @@ class RxBleDeviceImpl implements RxBleDevice {
final BluetoothDevice bluetoothDevice;
final Connector connector;
private final BehaviorRelay connectionStateRelay;
+ private final LocationServicesStatus locationServicesStatus;
final AtomicBoolean isConnected = new AtomicBoolean(false);
@Inject
RxBleDeviceImpl(
BluetoothDevice bluetoothDevice,
Connector connector,
- BehaviorRelay connectionStateRelay
+ BehaviorRelay connectionStateRelay,
+ LocationServicesStatus locationServicesStatus
) {
this.bluetoothDevice = bluetoothDevice;
this.connector = connector;
this.connectionStateRelay = connectionStateRelay;
+ this.locationServicesStatus = locationServicesStatus;
}
@Override
@@ -72,6 +82,12 @@ public Observable establishConnection(final ConnectionSetup opt
return Observable.defer(new Callable>() {
@Override
public ObservableSource call() {
+ if (!locationServicesStatus.isConnectPermissionOk()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ return Observable.error(new BlePermissionException(Manifest.permission.BLUETOOTH_CONNECT));
+ }
+ return Observable.error(new BleException("Unexpected connect permission not OK"));
+ }
if (isConnected.compareAndSet(false, true)) {
return connector.prepareConnection(options)
.doFinally(new Action() {
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi31.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi31.java
new file mode 100644
index 000000000..a5f617702
--- /dev/null
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi31.java
@@ -0,0 +1,108 @@
+package com.polidea.rxandroidble2.internal.scan;
+
+
+import android.Manifest;
+import android.content.pm.PackageInfo;
+
+import com.polidea.rxandroidble2.ClientComponent;
+import com.polidea.rxandroidble2.exceptions.BleScanException;
+import com.polidea.rxandroidble2.internal.util.LocationServicesStatus;
+import com.polidea.rxandroidble2.internal.util.RxBleAdapterWrapper;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import bleshadow.javax.inject.Inject;
+import bleshadow.javax.inject.Named;
+import io.reactivex.Scheduler;
+
+public class ScanPreconditionsVerifierApi31 implements ScanPreconditionsVerifier {
+
+ /*
+ * default values taken from
+ * https://android.googlesource.com/platform/packages/apps/Bluetooth/+/android-7.0.0_r1/src/com/android/bluetooth/gatt/AppScanStats.java
+ */
+ private static final int SCANS_LENGTH = 5;
+ private static final long EXCESSIVE_SCANNING_PERIOD = TimeUnit.SECONDS.toMillis(30);
+ private final long[] previousChecks = new long[SCANS_LENGTH];
+ private final RxBleAdapterWrapper rxBleAdapterWrapper;
+ private final LocationServicesStatus locationServicesStatus;
+ private final Scheduler timeScheduler;
+ private final PackageInfo packageInfo;
+
+ @Inject
+ public ScanPreconditionsVerifierApi31(
+ RxBleAdapterWrapper rxBleAdapterWrapper,
+ LocationServicesStatus locationServicesStatus,
+ @Named(ClientComponent.NamedSchedulers.COMPUTATION) Scheduler timeScheduler,
+ @Named(ClientComponent.PlatformConstants.PACKAGE_INFO) PackageInfo packageInfo
+ ) {
+ this.rxBleAdapterWrapper = rxBleAdapterWrapper;
+ this.locationServicesStatus = locationServicesStatus;
+ this.timeScheduler = timeScheduler;
+ this.packageInfo = packageInfo;
+ }
+
+ @Override
+ public void verify(boolean checkLocationProviderState) {
+ // determine if we really need to check location
+ if (checkLocationProviderState
+ && this.packageInfo != null
+ && this.packageInfo.requestedPermissions != null
+ && this.packageInfo.requestedPermissionsFlags != null) {
+ // On API 31 we only need to check location here if the scan permission requests it
+ for (int i = 0; i < this.packageInfo.requestedPermissions.length; i++) {
+ if (Manifest.permission.BLUETOOTH_SCAN.equals(this.packageInfo.requestedPermissions[i])) {
+ if ((this.packageInfo.requestedPermissionsFlags[i] & PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION) != 0) {
+ // BLUETOOTH_SCAN is neverForLocation
+ checkLocationProviderState = false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (!rxBleAdapterWrapper.hasBluetoothAdapter()) {
+ throw new BleScanException(BleScanException.BLUETOOTH_NOT_AVAILABLE);
+ } else if (!rxBleAdapterWrapper.isBluetoothEnabled()) {
+ throw new BleScanException(BleScanException.BLUETOOTH_DISABLED);
+ } else if (checkLocationProviderState && !locationServicesStatus.isLocationPermissionOk()) {
+ throw new BleScanException(BleScanException.LOCATION_PERMISSION_MISSING);
+ } else if (checkLocationProviderState && !locationServicesStatus.isLocationProviderOk()) {
+ throw new BleScanException(BleScanException.LOCATION_SERVICES_DISABLED);
+ } else if (!locationServicesStatus.isScanPermissionOk()) {
+ throw new BleScanException(BleScanException.SCAN_PERMISSION_MISSING);
+ }
+
+ /*
+ * Android 7.0 (API 24) introduces an undocumented scan throttle for applications that try to scan more than 5 times during
+ * a 30 second window. More on the topic: https://blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983
+ */
+
+ // TODO: [DS] 27.06.2017 Think if persisting this information through Application close is needed
+ final int oldestCheckTimestampIndex = getOldestCheckTimestampIndex();
+ final long oldestCheckTimestamp = previousChecks[oldestCheckTimestampIndex];
+ final long currentCheckTimestamp = timeScheduler.now(TimeUnit.MILLISECONDS);
+
+ if (currentCheckTimestamp - oldestCheckTimestamp < EXCESSIVE_SCANNING_PERIOD) {
+ throw new BleScanException(
+ BleScanException.UNDOCUMENTED_SCAN_THROTTLE,
+ new Date(oldestCheckTimestamp + EXCESSIVE_SCANNING_PERIOD)
+ );
+ }
+ previousChecks[oldestCheckTimestampIndex] = currentCheckTimestamp;
+ }
+
+ private int getOldestCheckTimestampIndex() {
+ long oldestTimestamp = Long.MAX_VALUE;
+ int index = -1;
+ for (int i = 0; i < SCANS_LENGTH; i++) {
+ final long previousCheckTimestamp = previousChecks[i];
+ if (previousCheckTimestamp < oldestTimestamp) {
+ index = i;
+ oldestTimestamp = previousCheckTimestamp;
+ }
+ }
+ return index;
+ }
+}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/CheckerScanPermission.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/CheckerScanPermission.java
index 9d58509ce..f20a0fa46 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/CheckerScanPermission.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/CheckerScanPermission.java
@@ -1,6 +1,7 @@
package com.polidea.rxandroidble2.internal.util;
+import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Process;
@@ -16,20 +17,40 @@ public class CheckerScanPermission {
private final Context context;
private final String[][] scanPermissions;
+ private final String[][] connectPermissions;
@Inject
CheckerScanPermission(
Context context,
- @Named(ClientComponent.PlatformConstants.STRING_ARRAY_SCAN_PERMISSIONS) String[][] scanPermissions
+ @Named(ClientComponent.PlatformConstants.STRING_ARRAY_SCAN_PERMISSIONS) String[][] scanPermissions,
+ @Named(ClientComponent.PlatformConstants.STRING_ARRAY_CONNECT_PERMISSIONS) String[][] connectPermissions
) {
this.context = context;
this.scanPermissions = scanPermissions;
+ this.connectPermissions = connectPermissions;
}
public boolean isScanRuntimePermissionGranted() {
+ return isAllPermissionsGranted(scanPermissions);
+ }
+
+ public boolean isConnectRuntimePermissionGranted() {
+ return isAllPermissionsGranted(connectPermissions);
+ }
+
+ public boolean isLocationRuntimePermissionGranted() {
+ return isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)
+ || isPermissionGranted(Manifest.permission.ACCESS_FINE_LOCATION);
+ }
+
+ public boolean isFineLocationRuntimePermissionGranted() {
+ return isPermissionGranted(Manifest.permission.ACCESS_FINE_LOCATION);
+ }
+
+ private boolean isAllPermissionsGranted(String[][] neededPermissions) {
boolean allNeededPermissionsGranted = true;
- for (String[] neededPermissions : scanPermissions) {
- allNeededPermissionsGranted &= isAnyPermissionGranted(neededPermissions);
+ for (String[] permissions : neededPermissions) {
+ allNeededPermissionsGranted &= isAnyPermissionGranted(permissions);
}
return allNeededPermissionsGranted;
}
@@ -44,13 +65,21 @@ private boolean isAnyPermissionGranted(String[] acceptablePermissions) {
}
public String[] getRecommendedScanRuntimePermissions() {
+ return getRecommendedRuntimePermissions(scanPermissions);
+ }
+
+ public String[] getRecommendedConnectRuntimePermissions() {
+ return getRecommendedRuntimePermissions(connectPermissions);
+ }
+
+ private String[] getRecommendedRuntimePermissions(String[][] permissions) {
int allPermissionsCount = 0;
- for (String[] permissionsArray : scanPermissions) {
+ for (String[] permissionsArray : permissions) {
allPermissionsCount += permissionsArray.length;
}
String[] resultPermissions = new String[allPermissionsCount];
int i = 0;
- for (String[] permissionsArray : scanPermissions) {
+ for (String[] permissionsArray : permissions) {
for (String permission : permissionsArray) {
resultPermissions[i++] = permission;
}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatus.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatus.java
index e1da71da3..bbf8ff6d5 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatus.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatus.java
@@ -5,4 +5,6 @@ public interface LocationServicesStatus {
boolean isLocationPermissionOk();
boolean isLocationProviderOk();
+ boolean isScanPermissionOk();
+ boolean isConnectPermissionOk();
}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi18.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi18.java
index 413e22e06..c32545544 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi18.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi18.java
@@ -16,4 +16,12 @@ public boolean isLocationPermissionOk() {
public boolean isLocationProviderOk() {
return true;
}
+
+ public boolean isScanPermissionOk() {
+ return true;
+ }
+
+ public boolean isConnectPermissionOk() {
+ return true;
+ }
}
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi23.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi23.java
index 21e13ed41..6193f737f 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi23.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi23.java
@@ -36,6 +36,14 @@ public boolean isLocationProviderOk() {
return !isLocationProviderEnabledRequired() || checkerLocationProvider.isLocationProviderEnabled();
}
+ public boolean isScanPermissionOk() {
+ return true;
+ }
+
+ public boolean isConnectPermissionOk() {
+ return true;
+ }
+
/**
* A function that returns true if the location services may be needed to be turned ON. Since there are no official guidelines
* for Android Wear check is disabled.
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi31.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi31.java
index a94c23d0d..9b9fcfd19 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi31.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/LocationServicesStatusApi31.java
@@ -29,13 +29,22 @@ public class LocationServicesStatusApi31 implements LocationServicesStatus {
}
public boolean isLocationPermissionOk() {
- return checkerScanPermission.isScanRuntimePermissionGranted();
+ return isNearbyPermissionNeverForLoc || checkerScanPermission.isFineLocationRuntimePermissionGranted();
}
public boolean isLocationProviderOk() {
return !isLocationProviderEnabledRequired() || checkerLocationProvider.isLocationProviderEnabled();
}
+ @Override
+ public boolean isScanPermissionOk() {
+ return checkerScanPermission.isScanRuntimePermissionGranted();
+ }
+
+ public boolean isConnectPermissionOk() {
+ return checkerScanPermission.isConnectRuntimePermissionGranted();
+ }
+
/**
* A function that returns true if the location services may be needed to be turned ON. Since there are no official guidelines
* for Android Wear check is disabled.
diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/RxBleAdapterWrapper.java b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/RxBleAdapterWrapper.java
index c8217379f..38d119260 100644
--- a/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/RxBleAdapterWrapper.java
+++ b/rxandroidble/src/main/java/com/polidea/rxandroidble2/internal/util/RxBleAdapterWrapper.java
@@ -111,7 +111,7 @@ public void stopLeScan(ScanCallback scanCallback) {
bluetoothLeScanner.stopScan(scanCallback);
}
- public Set getBondedDevices() {
+ public Set getBondedDevices() throws SecurityException {
if (bluetoothAdapter == null) {
throw nullBluetoothAdapter;
}
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockLocationServicesStatus.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockLocationServicesStatus.groovy
index 463122174..53bf83643 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockLocationServicesStatus.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockLocationServicesStatus.groovy
@@ -5,6 +5,8 @@ import com.polidea.rxandroidble2.internal.util.LocationServicesStatus
class MockLocationServicesStatus implements LocationServicesStatus {
boolean isLocationPermissionOk = true
boolean isLocationProviderOk = true
+ boolean isConnectPermissionOk = true
+ boolean isScanPermissionOk = true
MockLocationServicesStatus() {
}
@@ -18,4 +20,14 @@ class MockLocationServicesStatus implements LocationServicesStatus {
boolean isLocationProviderOk() {
return isLocationProviderOk
}
+
+ @Override
+ boolean isConnectPermissionOk() {
+ return isConnectPermissionOk
+ }
+
+ @Override
+ boolean isScanPermissionOk() {
+ return isScanPermissionOk
+ }
}
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterStateObservable.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterStateObservable.groovy
index b060450da..8bde0e7d4 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterStateObservable.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterStateObservable.groovy
@@ -11,6 +11,10 @@ class MockRxBleAdapterStateObservable {
public final ReplaySubject relay = ReplaySubject.create()
+ public final ReplaySubject getRelay() {
+ return relay
+ }
+
public Observable asObservable() {
Observable.create(new ObservableOnSubscribe() {
@Override
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterWrapper.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterWrapper.groovy
index e4c9ab82e..d935b0636 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterWrapper.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/MockRxBleAdapterWrapper.groovy
@@ -5,7 +5,6 @@ import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanSettings
-import android.os.Build
import androidx.annotation.RequiresApi
import com.polidea.rxandroidble2.internal.util.RxBleAdapterWrapper
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleAdapterStateObservableTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleAdapterStateObservableTest.groovy
index e9e5d71aa..e1ee0a7e5 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleAdapterStateObservableTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleAdapterStateObservableTest.groovy
@@ -4,14 +4,13 @@ import android.bluetooth.BluetoothAdapter
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import hkhc.electricspock.ElectricSpecification
+import android.content.IntentFilter
import io.reactivex.disposables.Disposable
-import org.robolectric.annotation.Config
+import spock.lang.Specification
import static com.polidea.rxandroidble2.RxBleAdapterStateObservable.BleAdapterState.*
-@Config(manifest = Config.NONE)
-class RxBleAdapterStateObservableTest extends ElectricSpecification {
+class RxBleAdapterStateObservableTest extends Specification {
def contextMock = Mock Context
def objectUnderTest = new RxBleAdapterStateObservable(contextMock)
BroadcastReceiver registeredReceiver
@@ -77,16 +76,16 @@ class RxBleAdapterStateObservableTest extends ElectricSpecification {
STATE_TURNING_ON | false
}
- public postStateChangeBroadcast(int bluetoothChange) {
- def intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED)
- intent.putExtra(BluetoothAdapter.EXTRA_STATE, bluetoothChange)
+ def postStateChangeBroadcast(int bluetoothChange) {
+ def intent = Mock Intent
+ intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, _) >> bluetoothChange
registeredReceiver.onReceive(contextMock, intent)
}
- public BroadcastReceiver shouldCaptureRegisteredReceiver() {
- _ * contextMock.registerReceiver({
- BroadcastReceiver receiver ->
- this.registeredReceiver = receiver
- }, _)
+ def shouldCaptureRegisteredReceiver() {
+ _ * contextMock.registerReceiver(*_) >> {
+ this.registeredReceiver = it[0]
+ return Mock(Intent)
+ }
}
}
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleClientTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleClientTest.groovy
index c9f4dfdd7..dd8ab20be 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleClientTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/RxBleClientTest.groovy
@@ -2,7 +2,6 @@ package com.polidea.rxandroidble2
import android.bluetooth.BluetoothDevice
import android.content.Context
-import android.os.Build
import com.polidea.rxandroidble2.exceptions.BleScanException
import com.polidea.rxandroidble2.internal.RxBleDeviceProvider
@@ -14,21 +13,19 @@ import com.polidea.rxandroidble2.internal.util.ClientStateObservable
import com.polidea.rxandroidble2.internal.util.ScanRecordParser
import com.polidea.rxandroidble2.scan.BackgroundScanner
import com.polidea.rxandroidble2.scan.ScanSettings
-import hkhc.electricspock.ElectricSpecification
+import spock.lang.Specification
import io.reactivex.Observable
import io.reactivex.ObservableSource
import io.reactivex.ObservableTransformer
import io.reactivex.annotations.NonNull
import io.reactivex.observers.TestObserver
import io.reactivex.schedulers.TestScheduler
-import org.robolectric.annotation.Config
import spock.lang.Unroll
import static com.polidea.rxandroidble2.exceptions.BleScanException.*
@SuppressWarnings("GrDeprecatedAPIUsage")
-@Config(manifest = Config.NONE, constants = BuildConfig, sdk = Build.VERSION_CODES.LOLLIPOP)
-class RxBleClientTest extends ElectricSpecification {
+class RxBleClientTest extends Specification {
BackgroundScanner backgroundScanner = Mock(BackgroundScanner)
DummyOperationQueue dummyQueue = new DummyOperationQueue()
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/RxBleDeviceTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/RxBleDeviceTest.groovy
index cd136fe5f..edd350960 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/RxBleDeviceTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/RxBleDeviceTest.groovy
@@ -9,7 +9,9 @@ import com.polidea.rxandroidble2.RxBleDevice
import com.polidea.rxandroidble2.exceptions.BleAlreadyConnectedException
import com.polidea.rxandroidble2.exceptions.BleGattException
import com.polidea.rxandroidble2.exceptions.BleGattOperationType
+import com.polidea.rxandroidble2.exceptions.BlePermissionException
import com.polidea.rxandroidble2.internal.connection.Connector
+import com.polidea.rxandroidble2.internal.util.LocationServicesStatus
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
import spock.lang.Shared
@@ -26,7 +28,8 @@ class RxBleDeviceTest extends Specification {
PublishSubject mockConnectorEstablishConnectionPublishSubject = PublishSubject.create()
BehaviorRelay connectionStateBehaviorRelay = BehaviorRelay.createDefault(DISCONNECTED)
@Shared BluetoothGatt mockBluetoothGatt = Mock BluetoothGatt
- RxBleDevice rxBleDevice = new RxBleDeviceImpl(mockBluetoothDevice, mockConnector, connectionStateBehaviorRelay)
+ LocationServicesStatus mockLocationServicesStatus = Mock LocationServicesStatus
+ RxBleDevice rxBleDevice = new RxBleDeviceImpl(mockBluetoothDevice, mockConnector, connectionStateBehaviorRelay, mockLocationServicesStatus)
static List establishConnectionCallers = []
static List establishConnectionTestSetups = []
@@ -96,7 +99,7 @@ class RxBleDeviceTest extends Specification {
def "equals() should return true when compared to a different RxBleDevice instance with the same underlying BluetoothDevice"() {
given:
- def differentRxBleDeviceWithSameBluetoothDevice = new RxBleDeviceImpl(mockBluetoothDevice, null, BehaviorRelay.create())
+ def differentRxBleDeviceWithSameBluetoothDevice = new RxBleDeviceImpl(mockBluetoothDevice, null, BehaviorRelay.create(), mockLocationServicesStatus)
expect:
rxBleDevice == differentRxBleDeviceWithSameBluetoothDevice
@@ -105,7 +108,7 @@ class RxBleDeviceTest extends Specification {
def "hashCode() should return the same value as a different RxBleDevice instance hashCode() with the same underlying BluetoothDevice"() {
given:
- def differentRxBleDevice = new RxBleDeviceImpl(mockBluetoothDevice, null, BehaviorRelay.create())
+ def differentRxBleDevice = new RxBleDeviceImpl(mockBluetoothDevice, null, BehaviorRelay.create(), mockLocationServicesStatus)
expect:
rxBleDevice.hashCode() == differentRxBleDevice.hashCode()
@@ -115,6 +118,7 @@ class RxBleDeviceTest extends Specification {
def "establishConnection() should call RxBleConnection.Connector.prepareConnection() => autoConnect:#autoConnectValue #establishConnectionCaller"() {
given:
+ mockLocationServicesStatus.isConnectPermissionOk() >> true
ConnectionSetup connectionSetup = new ConnectionSetup.Builder()
.setAutoConnect(autoConnectValue)
.setSuppressIllegalOperationCheck(suppressIllegalOperationCheckValue)
@@ -174,6 +178,7 @@ class RxBleDeviceTest extends Specification {
def "should emit connection and stay subscribed after it was established => call:#establishConnectionSetup"() {
given:
+ mockLocationServicesStatus.isConnectPermissionOk() >> true
def connectionObservable = establishConnectionSetup.establishConnection(rxBleDevice)
when:
@@ -192,6 +197,7 @@ class RxBleDeviceTest extends Specification {
def "should emit BleAlreadyConnectedException if already connected => firstCall:#establishConnectionSetup0 secondCall:#establishConnectionSetup1\""() {
given:
+ mockLocationServicesStatus.isConnectPermissionOk() >> true
def connectionObs0 = establishConnectionSetup0.establishConnection(rxBleDevice)
def connectionObs1 = establishConnectionSetup1.establishConnection(rxBleDevice)
connectionObs0.subscribe()
@@ -214,6 +220,7 @@ class RxBleDeviceTest extends Specification {
def "should emit BleAlreadyConnectedException if there is already one subscriber to .establishConnection() => firstCall:#establishConnectionSetup0 secondCall:#establishConnectionSetup1"() {
given:
+ mockLocationServicesStatus.isConnectPermissionOk() >> true
def connectionObs0 = establishConnectionSetup0.establishConnection(rxBleDevice)
def connectionObs1 = establishConnectionSetup1.establishConnection(rxBleDevice)
connectionObs0.test()
@@ -235,6 +242,7 @@ class RxBleDeviceTest extends Specification {
def "should create new connection if previous connection was established and released before second subscriber has subscribed => firstCall:#establishConnectionSetup0 secondCall:#establishConnectionSetup1"() {
given:
+ mockLocationServicesStatus.isConnectPermissionOk() >> true
def connectionObs0 = establishConnectionSetup0.establishConnection(rxBleDevice)
def connectionObs1 = establishConnectionSetup1.establishConnection(rxBleDevice)
def firstSubscriber = connectionObs0.test()
@@ -259,6 +267,7 @@ class RxBleDeviceTest extends Specification {
def "should not emit BleAlreadyConnectedException if there is already was subscriber to .establishConnection() but it unsubscribed => firstCall:#establishConnectionSetup0 secondCall:#establishConnectionSetup1"() {
given:
+ mockLocationServicesStatus.isConnectPermissionOk() >> true
def connectionObs0 = establishConnectionSetup0.establishConnection(rxBleDevice)
def connectionObs1 = establishConnectionSetup1.establishConnection(rxBleDevice)
def testSubscriber = connectionObs0.test()
@@ -277,6 +286,30 @@ class RxBleDeviceTest extends Specification {
].combinations()
}
+ @Unroll
+ def "should emit permission error but only once => firstCall:#establishConnectionSetup0 secondCall:#establishConnectionSetup1"() {
+
+ given:
+ 1 * mockLocationServicesStatus.isConnectPermissionOk() >> false
+ 1 * mockLocationServicesStatus.isConnectPermissionOk() >> true
+ def connectionObs0 = establishConnectionSetup0.establishConnection(rxBleDevice)
+ def connectionObs1 = establishConnectionSetup1.establishConnection(rxBleDevice)
+
+ when:
+ def testSubscriber0 = connectionObs0.test()
+ def testSubscriber1 = connectionObs1.test()
+
+ then:
+ testSubscriber0.assertError(BlePermissionException)
+ testSubscriber1.assertNoErrors()
+
+ where:
+ [establishConnectionSetup0, establishConnectionSetup1] << [
+ establishConnectionTestSetups,
+ establishConnectionTestSetups
+ ].combinations()
+ }
+
@Unroll
def "should unsubscribe from connection if it was dropped => call:#establishConnectionSetup"() {
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/DisconnectionRouterTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/DisconnectionRouterTest.groovy
index 445563339..7294ac88c 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/DisconnectionRouterTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/DisconnectionRouterTest.groovy
@@ -7,16 +7,14 @@ import com.polidea.rxandroidble2.exceptions.BleDisconnectedException
import com.polidea.rxandroidble2.exceptions.BleGattException
import com.polidea.rxandroidble2.exceptions.BleGattOperationType
import com.polidea.rxandroidble2.internal.util.RxBleAdapterWrapper
-import hkhc.electricspock.ElectricSpecification
+import spock.lang.Specification
import io.reactivex.subjects.PublishSubject
-import org.robolectric.annotation.Config
import spock.lang.Shared
import spock.lang.Unroll
import static com.polidea.rxandroidble2.RxBleAdapterStateObservable.BleAdapterState.*
-@Config(manifest = Config.NONE)
-class DisconnectionRouterTest extends ElectricSpecification {
+class DisconnectionRouterTest extends Specification {
String mockMacAddress = "1234"
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/NotificationAndIndicationManagerTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/NotificationAndIndicationManagerTest.groovy
index 3cd4aea82..a9c253e0f 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/NotificationAndIndicationManagerTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/NotificationAndIndicationManagerTest.groovy
@@ -7,18 +7,16 @@ import com.polidea.rxandroidble2.NotificationSetupMode
import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException
import com.polidea.rxandroidble2.exceptions.BleConflictingNotificationAlreadySetException
import com.polidea.rxandroidble2.internal.util.CharacteristicChangedEvent
-import hkhc.electricspock.ElectricSpecification
+import spock.lang.Specification
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
-import org.robolectric.annotation.Config
import spock.lang.Unroll
import static io.reactivex.Observable.just
-@Config(manifest = Config.NONE)
-class NotificationAndIndicationManagerTest extends ElectricSpecification {
+class NotificationAndIndicationManagerTest extends Specification {
public static final CHARACTERISTIC_UUID = UUID.fromString("f301f518-5414-471c-8a7b-2ef6d1b7373d")
public static final CHARACTERISTIC_INSTANCE_ID = 1
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleConnectionTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleConnectionTest.groovy
index 833b377bb..c13c76aed 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleConnectionTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleConnectionTest.groovy
@@ -1,6 +1,9 @@
package com.polidea.rxandroidble2.internal.connection
-import android.bluetooth.*
+import android.bluetooth.BluetoothGatt
+import android.bluetooth.BluetoothGattCharacteristic
+import android.bluetooth.BluetoothGattService
+import android.bluetooth.BluetoothGattCallback
import androidx.annotation.NonNull
import com.polidea.rxandroidble2.*
import com.polidea.rxandroidble2.exceptions.BleCharacteristicNotFoundException
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleGattCallbackTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleGattCallbackTest.groovy
index 81a97fd07..ef29ee4ca 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleGattCallbackTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/connection/RxBleGattCallbackTest.groovy
@@ -10,7 +10,7 @@ import com.polidea.rxandroidble2.RxBleDeviceServices
import com.polidea.rxandroidble2.exceptions.*
import com.polidea.rxandroidble2.internal.util.ByteAssociation
import com.polidea.rxandroidble2.internal.util.CharacteristicChangedEvent
-import hkhc.electricspock.ElectricSpecification
+import spock.lang.Specification
import io.reactivex.Observable
import io.reactivex.annotations.NonNull
import io.reactivex.functions.Predicate
@@ -20,7 +20,6 @@ import io.reactivex.schedulers.Schedulers
import io.reactivex.schedulers.TestScheduler
import io.reactivex.subjects.PublishSubject
import java.util.function.Consumer
-import org.robolectric.annotation.Config
import spock.lang.Shared
import spock.lang.Unroll
@@ -29,8 +28,7 @@ import static android.bluetooth.BluetoothGatt.GATT_SUCCESS
import static android.bluetooth.BluetoothProfile.*
import static com.polidea.rxandroidble2.RxBleConnection.RxBleConnectionState.DISCONNECTED
-@Config(manifest = Config.NONE)
-class RxBleGattCallbackTest extends ElectricSpecification {
+class RxBleGattCallbackTest extends Specification {
DisconnectionRouter mockDisconnectionRouter
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/BackgroundScannerTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/BackgroundScannerTest.groovy
index c38cb4670..e6a16d683 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/BackgroundScannerTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/BackgroundScannerTest.groovy
@@ -5,18 +5,15 @@ import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.content.Intent
-import android.os.Build
import com.polidea.rxandroidble2.exceptions.BleScanException
import com.polidea.rxandroidble2.internal.util.RxBleAdapterWrapper
import com.polidea.rxandroidble2.scan.ScanFilter
import com.polidea.rxandroidble2.scan.ScanSettings
-import hkhc.electricspock.ElectricSpecification
-import org.robolectric.annotation.Config
+import spock.lang.Specification
import static com.polidea.rxandroidble2.scan.ScanCallbackType.CALLBACK_TYPE_ALL_MATCHES
-@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.O)
-class BackgroundScannerTest extends ElectricSpecification {
+class BackgroundScannerTest extends Specification {
public static final int SUCCESS_CODE = 0
BackgroundScannerImpl objectUnderTest
RxBleAdapterWrapper adapterWrapper
@@ -176,25 +173,25 @@ class BackgroundScannerTest extends ElectricSpecification {
}
- private static Intent prepareIntentWithScanResultError(int errorCode) {
- def intent = new Intent()
- intent.putExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, errorCode)
+ private Intent prepareIntentWithScanResultError(int errorCode) {
+ def intent = Mock Intent
+ intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, _) >> errorCode
return intent
}
- private static Intent prepareIntentWithEmptyResult() {
- def intent = new Intent()
- intent.putExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, BackgroundScannerImpl.NO_ERROR)
- intent.putExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, CALLBACK_TYPE_ALL_MATCHES)
- intent.putExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT, [])
+ private Intent prepareIntentWithEmptyResult() {
+ def intent = Mock Intent
+ intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, _) >> BackgroundScannerImpl.NO_ERROR
+ intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, _) >> CALLBACK_TYPE_ALL_MATCHES.ordinal()
+ intent.getSerializableExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT) >> []
return intent
}
- private static Intent prepareIntentWithResults(ScanResult... scanResults) {
- def intent = new Intent()
- intent.putExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, BackgroundScannerImpl.NO_ERROR)
- intent.putExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, CALLBACK_TYPE_ALL_MATCHES)
- intent.putExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT, scanResults.toList())
+ private Intent prepareIntentWithResults(ScanResult... scanResults) {
+ def intent = Mock Intent
+ intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, _) >> BackgroundScannerImpl.NO_ERROR
+ intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, _) >> CALLBACK_TYPE_ALL_MATCHES.ordinal()
+ intent.getSerializableExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT) >> scanResults.toList()
return intent
}
}
\ No newline at end of file
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi24Test.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi24Test.groovy
index 13cb8083d..e94a33294 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi24Test.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/scan/ScanPreconditionsVerifierApi24Test.groovy
@@ -4,9 +4,9 @@ import com.polidea.rxandroidble2.exceptions.BleScanException
import io.reactivex.Scheduler
import io.reactivex.schedulers.TestScheduler
import spock.lang.Specification
+import spock.lang.Unroll
import java.util.concurrent.TimeUnit
-import spock.lang.Unroll
class ScanPreconditionsVerifierApi24Test extends Specification {
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy
index 688d83d10..0d0e95c90 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/LocationServicesOkObservableApi23FactoryTest.groovy
@@ -3,12 +3,11 @@ package com.polidea.rxandroidble2.internal.util
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
+import android.content.IntentFilter
import android.location.LocationManager
-import hkhc.electricspock.ElectricSpecification
-import org.robolectric.annotation.Config
+import spock.lang.Specification
-@Config(manifest = Config.NONE)
-class LocationServicesOkObservableApi23FactoryTest extends ElectricSpecification {
+class LocationServicesOkObservableApi23FactoryTest extends Specification {
def contextMock = Mock Context
def mockLocationServicesStatus = Mock LocationServicesStatus
def objectUnderTest = new LocationServicesOkObservableApi23Factory(contextMock, mockLocationServicesStatus)
@@ -137,9 +136,10 @@ class LocationServicesOkObservableApi23FactoryTest extends ElectricSpecification
}
BroadcastReceiver shouldCaptureRegisteredReceiver() {
- _ * contextMock.registerReceiver({
- BroadcastReceiver receiver ->
+ _ * contextMock.registerReceiver(*_) >> {
+ BroadcastReceiver receiver, IntentFilter filter ->
this.registeredReceiver = receiver
- }, _)
+ return Mock(Intent)
+ }
}
}
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/ScanRecordParserTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/ScanRecordParserTest.groovy
index ee1a242e3..ccda979f0 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/ScanRecordParserTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/ScanRecordParserTest.groovy
@@ -1,12 +1,8 @@
package com.polidea.rxandroidble2.internal.util
-import android.os.Build
-import com.polidea.rxandroidble2.BuildConfig
-import hkhc.electricspock.ElectricSpecification
-import org.robolectric.annotation.Config
+import spock.lang.Specification
-@Config(manifest = Config.NONE, constants = BuildConfig, sdk = Build.VERSION_CODES.LOLLIPOP)
-class ScanRecordParserTest extends ElectricSpecification {
+class ScanRecordParserTest extends Specification {
static final UNKNOWN_DATA_TYPE = 0xfa
ScanRecordParser objectUnderTest = new ScanRecordParser()
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/UUIDUtilTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/UUIDUtilTest.groovy
index 724efcb52..68d810764 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/UUIDUtilTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/internal/util/UUIDUtilTest.groovy
@@ -1,12 +1,8 @@
package com.polidea.rxandroidble2.internal.util
-import android.os.Build
-import com.polidea.rxandroidble2.BuildConfig
-import hkhc.electricspock.ElectricSpecification
-import org.robolectric.annotation.Config
+import spock.lang.Specification
-@Config(manifest = Config.NONE, constants = BuildConfig, sdk = Build.VERSION_CODES.LOLLIPOP)
-class UUIDUtilTest extends ElectricSpecification {
+class UUIDUtilTest extends Specification {
static final UNKNOWN_DATA_TYPE = 0xfa
UUIDUtil objectUnderTest = new UUIDUtil()
diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/scan/ScanFilterTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/scan/ScanFilterTest.groovy
index be5c6eb2f..ae5965efd 100644
--- a/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/scan/ScanFilterTest.groovy
+++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble2/scan/ScanFilterTest.groovy
@@ -1,14 +1,10 @@
package com.polidea.rxandroidble2.scan
-import android.os.Build
import android.os.ParcelUuid
-import com.polidea.rxandroidble2.BuildConfig
import com.polidea.rxandroidble2.internal.scan.RxBleInternalScanResult
-import hkhc.electricspock.ElectricSpecification
-import org.robolectric.annotation.Config
+import spock.lang.Specification
-@Config(manifest = Config.NONE, constants = BuildConfig, sdk = Build.VERSION_CODES.LOLLIPOP)
-public class ScanFilterTest extends ElectricSpecification {
+public class ScanFilterTest extends Specification {
RxBleInternalScanResult mockInternalScanResult = Mock RxBleInternalScanResult
diff --git a/rxandroidble/src/test/java/android/app/Activity.java b/rxandroidble/src/test/java/android/app/Activity.java
new file mode 100644
index 000000000..0e12b37b0
--- /dev/null
+++ b/rxandroidble/src/test/java/android/app/Activity.java
@@ -0,0 +1,333 @@
+package android.app;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.MemorySharedPreferences;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.DatabaseErrorHandler;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.view.Display;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+@SuppressWarnings("deprecation")
+public class Activity {
+ public static final int RESULT_CANCELED = 0;
+ public static final int RESULT_OK = -1;
+ public static final int RESULT_FIRST_USER = 1;
+ public Activity() {
+ this.resources = null;
+ }
+ public Activity(Resources resources) {
+ this.resources = resources;
+ }
+ public void requestPermissions(String[] permissions, int requestCode) {
+ }
+ public void startActivityForResult(Intent intent, int requestCode) {
+ }
+ public void startActivityForResult(Intent intent, int requestCode,
+ Bundle options) {
+ }
+ public AssetManager getAssets() {
+ return null;
+ }
+ private final Resources resources;
+ public Resources getResources() {
+ return resources;
+ }
+ public PackageManager getPackageManager() {
+ return null;
+ }
+ public ContentResolver getContentResolver() {
+ return null;
+ }
+ public Looper getMainLooper() {
+ return null;
+ }
+ public Context getApplicationContext() {
+ return null;
+ }
+ public void setTheme(int resid) {
+ }
+ public Resources.Theme getTheme() {
+ return null;
+ }
+ public ClassLoader getClassLoader() {
+ return null;
+ }
+ public String getPackageName() {
+ return null;
+ }
+ public ApplicationInfo getApplicationInfo() {
+ return null;
+ }
+ public String getPackageResourcePath() {
+ return null;
+ }
+ public String getPackageCodePath() {
+ return null;
+ }
+ public SharedPreferences getSharedPreferences(String name, int mode) {
+ return new MemorySharedPreferences();
+ }
+ public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
+ return false;
+ }
+ public boolean deleteSharedPreferences(String name) {
+ return false;
+ }
+ public FileInputStream openFileInput(String name) throws FileNotFoundException {
+ return null;
+ }
+ public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
+ return null;
+ }
+ public boolean deleteFile(String name) {
+ return false;
+ }
+ public File getFileStreamPath(String name) {
+ return null;
+ }
+ public File getDataDir() {
+ return null;
+ }
+ public File getFilesDir() {
+ return null;
+ }
+ public File getNoBackupFilesDir() {
+ return null;
+ }
+ public File getExternalFilesDir(String type) {
+ return null;
+ }
+ public File[] getExternalFilesDirs(String type) {
+ return new File[0];
+ }
+ public File getObbDir() {
+ return null;
+ }
+ public File[] getObbDirs() {
+ return new File[0];
+ }
+ public File getCacheDir() {
+ return null;
+ }
+ public File getCodeCacheDir() {
+ return null;
+ }
+ public File getExternalCacheDir() {
+ return null;
+ }
+ public File[] getExternalCacheDirs() {
+ return new File[0];
+ }
+ public File[] getExternalMediaDirs() {
+ return new File[0];
+ }
+ public String[] fileList() {
+ return new String[0];
+ }
+ public File getDir(String name, int mode) {
+ return null;
+ }
+ public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
+ return null;
+ }
+ public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
+ return null;
+ }
+ public boolean moveDatabaseFrom(Context sourceContext, String name) {
+ return false;
+ }
+ public boolean deleteDatabase(String name) {
+ return false;
+ }
+ public File getDatabasePath(String name) {
+ return null;
+ }
+ public String[] databaseList() {
+ return new String[0];
+ }
+ public Drawable getWallpaper() {
+ return null;
+ }
+ public Drawable peekWallpaper() {
+ return null;
+ }
+ public int getWallpaperDesiredMinimumWidth() {
+ return 0;
+ }
+ public int getWallpaperDesiredMinimumHeight() {
+ return 0;
+ }
+ public void setWallpaper(Bitmap bitmap) throws IOException {
+ }
+ public void setWallpaper(InputStream data) throws IOException {
+ }
+ public void clearWallpaper() throws IOException {
+ }
+ public void startActivity(Intent intent) {
+ }
+ public void startActivity(Intent intent, Bundle options) {
+ }
+ public void startActivities(Intent[] intents) {
+ }
+ public void startActivities(Intent[] intents, Bundle options) {
+ }
+ public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) throws IntentSender.SendIntentException {
+ }
+ public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) throws IntentSender.SendIntentException {
+ }
+ public void sendBroadcast(Intent intent) {
+ }
+ public void sendBroadcast(Intent intent, String receiverPermission) {
+ }
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
+ }
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ }
+ public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+ }
+ public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
+ }
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ }
+ public void sendStickyBroadcast(Intent intent) {
+ }
+ public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ }
+ public void removeStickyBroadcast(Intent intent) {
+ }
+ public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
+ }
+ public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ }
+ public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
+ }
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ return null;
+ }
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
+ return null;
+ }
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission,
+ Handler scheduler) {
+ return null;
+ }
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission,
+ Handler scheduler, int flags) {
+ return null;
+ }
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ }
+ public ComponentName startService(Intent service) {
+ return null;
+ }
+ public ComponentName startForegroundService(Intent service) {
+ return null;
+ }
+ public boolean stopService(Intent service) {
+ return false;
+ }
+ public boolean bindService(Intent service, ServiceConnection conn, int flags) {
+ return false;
+ }
+ public void unbindService(ServiceConnection conn) {
+ }
+ public boolean startInstrumentation(ComponentName className, String profileFile, Bundle arguments) {
+ return false;
+ }
+ public Object getSystemService(String name) {
+ return null;
+ }
+ public String getSystemServiceName(Class> serviceClass) {
+ return null;
+ }
+ public int checkPermission(String permission, int pid, int uid) {
+ return 0;
+ }
+ public int checkCallingPermission(String permission) {
+ return 0;
+ }
+ public int checkCallingOrSelfPermission(String permission) {
+ return 0;
+ }
+ public int checkSelfPermission(String permission) {
+ return 0;
+ }
+ public void enforcePermission(String permission, int pid, int uid, String message) {
+ }
+ public void enforceCallingPermission(String permission, String message) {
+ }
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ }
+ public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
+ }
+ public void revokeUriPermission(Uri uri, int modeFlags) {
+ }
+ public void revokeUriPermission(String toPackage, Uri uri, int modeFlags) {
+ }
+ public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
+ return 0;
+ }
+ public int checkCallingUriPermission(Uri uri, int modeFlags) {
+ return 0;
+ }
+ public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
+ return 0;
+ }
+ public int checkUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid,
+ int modeFlags) {
+ return 0;
+ }
+ public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message) {
+ }
+ public void enforceCallingUriPermission(Uri uri, int modeFlags, String message) {
+ }
+ public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message) {
+ }
+ public void enforceUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags, String message) {
+ }
+ public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException {
+ return null;
+ }
+ public Context createContextForSplit(String splitName) throws PackageManager.NameNotFoundException {
+ return null;
+ }
+ public Context createConfigurationContext(Configuration overrideConfiguration) {
+ return null;
+ }
+ public Context createDisplayContext(Display display) {
+ return null;
+ }
+ public Context createDeviceProtectedStorageContext() {
+ return null;
+ }
+ public boolean isDeviceProtectedStorage() {
+ return false;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/app/PendingIntent.java b/rxandroidble/src/test/java/android/app/PendingIntent.java
new file mode 100644
index 000000000..36192bec1
--- /dev/null
+++ b/rxandroidble/src/test/java/android/app/PendingIntent.java
@@ -0,0 +1,14 @@
+package android.app;
+import android.os.Parcel;
+import android.os.Parcelable;
+public class PendingIntent implements Parcelable {
+ public PendingIntent() {
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothAdapter.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothAdapter.java
new file mode 100644
index 000000000..799286a31
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothAdapter.java
@@ -0,0 +1,163 @@
+package android.bluetooth;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.os.RemoteException;
+import android.util.Log;
+import androidx.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.UUID;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+public class BluetoothAdapter {
+ private static final String TAG = "BluetoothAdapter";
+ private static final boolean VDBG = false;
+ public static final String
+ ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
+ public static final String EXTRA_STATE = "android.bluetooth.adapter.extra.STATE";
+ @IntDef(value = {
+ STATE_OFF,
+ STATE_TURNING_ON,
+ STATE_ON,
+ STATE_TURNING_OFF,
+ STATE_BLE_TURNING_ON,
+ STATE_BLE_ON,
+ STATE_BLE_TURNING_OFF
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AdapterState {}
+ public static final int STATE_OFF = 10;
+ public static final int STATE_TURNING_ON = 11;
+ public static final int STATE_ON = 12;
+ public static final int STATE_TURNING_OFF = 13;
+ public static final int STATE_BLE_TURNING_ON = 14;
+ public static final int STATE_BLE_ON = 15;
+ public static final int STATE_BLE_TURNING_OFF = 16;
+ public static final UUID LE_PSM_CHARACTERISTIC_UUID =
+ UUID.fromString("2d410339-82b6-42aa-b34e-e2e01df8cc1a");
+ public static String nameForState(@AdapterState int state) {
+ switch (state) {
+ case STATE_OFF:
+ return "OFF";
+ case STATE_TURNING_ON:
+ return "TURNING_ON";
+ case STATE_ON:
+ return "ON";
+ case STATE_TURNING_OFF:
+ return "TURNING_OFF";
+ case STATE_BLE_TURNING_ON:
+ return "BLE_TURNING_ON";
+ case STATE_BLE_ON:
+ return "BLE_ON";
+ case STATE_BLE_TURNING_OFF:
+ return "BLE_TURNING_OFF";
+ default:
+ return "?!?!? (" + state + ")";
+ }
+ }
+ @IntDef(value = {
+ SCAN_MODE_NONE,
+ SCAN_MODE_CONNECTABLE,
+ SCAN_MODE_CONNECTABLE_DISCOVERABLE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ScanMode {}
+ public static final int SCAN_MODE_NONE = 20;
+ public static final int SCAN_MODE_CONNECTABLE = 21;
+ public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;
+ public static final int IO_CAPABILITY_OUT = 0;
+ public static final int IO_CAPABILITY_IO = 1;
+ public static final int IO_CAPABILITY_IN = 2;
+ public static final int IO_CAPABILITY_NONE = 3;
+ public static final int IO_CAPABILITY_KBDISP = 4;
+ public static final int IO_CAPABILITY_MAX = 5;
+ public static final int IO_CAPABILITY_UNKNOWN = 255;
+ @IntDef({IO_CAPABILITY_OUT, IO_CAPABILITY_IO, IO_CAPABILITY_IN, IO_CAPABILITY_NONE,
+ IO_CAPABILITY_KBDISP})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IoCapability {}
+ @IntDef(value = {ACTIVE_DEVICE_AUDIO,
+ ACTIVE_DEVICE_PHONE_CALL, ACTIVE_DEVICE_ALL})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ActiveDeviceUse {}
+ public static final int ACTIVE_DEVICE_AUDIO = 0;
+ public static final int ACTIVE_DEVICE_PHONE_CALL = 1;
+ public static final int ACTIVE_DEVICE_ALL = 2;
+ private BluetoothLeScanner mBluetoothLeScanner;
+ // Yeah, keeping both mService and sService isn't pretty, but it's too late
+ // in the current release for a major refactoring, so we leave them both
+ // intact until this can be cleaned up in a future release
+ private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
+ private final Object mLock = new Object();
+ public BluetoothDevice getRemoteDevice(String address) {
+ return null;
+ }
+ public BluetoothLeScanner getBluetoothLeScanner() {
+ return null;
+ }
+ public boolean isEnabled() {
+ return getState() == BluetoothAdapter.STATE_ON;
+ }
+ @AdapterState
+ private int getStateInternal() {
+ int state = BluetoothAdapter.STATE_OFF;
+ try {
+ mServiceLock.readLock().lock();
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof RemoteException) {
+ Log.e(TAG, "", e.getCause());
+ } else {
+ throw e;
+ }
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return state;
+ }
+ public int getState() {
+ int state = getStateInternal();
+ // Consider all internal states as OFF
+ if (state == BluetoothAdapter.STATE_BLE_ON || state == BluetoothAdapter.STATE_BLE_TURNING_ON
+ || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
+ if (VDBG) {
+ Log.d(TAG, "Consider " + BluetoothAdapter.nameForState(state) + " state as OFF");
+ }
+ state = BluetoothAdapter.STATE_OFF;
+ }
+ if (VDBG) {
+ Log.d(TAG, "" + hashCode() + ": getState(). Returning " + BluetoothAdapter.nameForState(
+ state));
+ }
+ return state;
+ }
+ public int getLeState() {
+ int state = getStateInternal();
+ if (VDBG) {
+ Log.d(TAG, "getLeState() returning " + BluetoothAdapter.nameForState(state));
+ }
+ return state;
+ }
+ boolean getLeAccess() {
+ if (getLeState() == STATE_ON) {
+ return true;
+ } else if (getLeState() == STATE_BLE_ON) {
+ return true; // TODO: FILTER SYSTEM APPS HERE <--
+ }
+ return false;
+ }
+ public String getName() {
+ return null;
+ }
+ public interface LeScanCallback {
+ void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
+ }
+
+ public static synchronized BluetoothAdapter getDefaultAdapter() {
+ return null;
+ }
+
+ public boolean startLeScan(LeScanCallback callback) {
+ return false;
+ }
+
+ public void stopLeScan(LeScanCallback callback) {
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothDevice.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothDevice.java
new file mode 100644
index 000000000..3d13ac77b
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothDevice.java
@@ -0,0 +1,332 @@
+package android.bluetooth;
+import android.annotation.SuppressLint;
+import android.content.AttributionSource;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+import androidx.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+public class BluetoothDevice implements Parcelable {
+ private static final String TAG = "BluetoothDevice";
+ private static final boolean DBG = false;
+ private static final int CONNECTION_STATE_DISCONNECTED = 0;
+ private static final int CONNECTION_STATE_CONNECTED = 1;
+ private static final int CONNECTION_STATE_ENCRYPTED_BREDR = 2;
+ private static final int CONNECTION_STATE_ENCRYPTED_LE = 4;
+ public static final int ERROR = Integer.MIN_VALUE;
+ public static final String ACTION_FOUND =
+ "android.bluetooth.device.action.FOUND";
+ public static final String ACTION_CLASS_CHANGED =
+ "android.bluetooth.device.action.CLASS_CHANGED";
+ public static final String ACTION_ACL_CONNECTED =
+ "android.bluetooth.device.action.ACL_CONNECTED";
+ public static final String ACTION_ACL_DISCONNECT_REQUESTED =
+ "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
+ public static final String ACTION_ACL_DISCONNECTED =
+ "android.bluetooth.device.action.ACL_DISCONNECTED";
+ public static final String ACTION_NAME_CHANGED =
+ "android.bluetooth.device.action.NAME_CHANGED";
+ @SuppressLint("ActionValue")
+ public static final String ACTION_ALIAS_CHANGED =
+ "android.bluetooth.device.action.ALIAS_CHANGED";
+ // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
+ // contain a hidden extra field EXTRA_REASON with the result code.
+ public static final String ACTION_BOND_STATE_CHANGED =
+ "android.bluetooth.device.action.BOND_STATE_CHANGED";
+ public static final String ACTION_BATTERY_LEVEL_CHANGED =
+ "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
+ public static final String EXTRA_BATTERY_LEVEL =
+ "android.bluetooth.device.extra.BATTERY_LEVEL";
+ public static final int BATTERY_LEVEL_UNKNOWN = -1;
+ public static final int BATTERY_LEVEL_BLUETOOTH_OFF = -100;
+ public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
+ public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
+ public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
+ public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
+ public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
+ public static final String EXTRA_PREVIOUS_BOND_STATE =
+ "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
+ public static final int BOND_NONE = 10;
+ public static final int BOND_BONDING = 11;
+ public static final int BOND_BONDED = 12;
+ public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
+ public static final String EXTRA_PAIRING_VARIANT =
+ "android.bluetooth.device.extra.PAIRING_VARIANT";
+ public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
+ public static final String EXTRA_PAIRING_INITIATOR =
+ "android.bluetooth.device.extra.PAIRING_INITIATOR";
+ public static final int EXTRA_PAIRING_INITIATOR_FOREGROUND = 1;
+ public static final int EXTRA_PAIRING_INITIATOR_BACKGROUND = 2;
+ public static final int DEVICE_TYPE_UNKNOWN = 0;
+ public static final int DEVICE_TYPE_CLASSIC = 1;
+ public static final int DEVICE_TYPE_LE = 2;
+ public static final int DEVICE_TYPE_DUAL = 3;
+ public static final String ACTION_SDP_RECORD =
+ "android.bluetooth.device.action.SDP_RECORD";
+ @IntDef(value = {
+ METADATA_MANUFACTURER_NAME,
+ METADATA_MODEL_NAME,
+ METADATA_SOFTWARE_VERSION,
+ METADATA_HARDWARE_VERSION,
+ METADATA_COMPANION_APP,
+ METADATA_MAIN_ICON,
+ METADATA_IS_UNTETHERED_HEADSET,
+ METADATA_UNTETHERED_LEFT_ICON,
+ METADATA_UNTETHERED_RIGHT_ICON,
+ METADATA_UNTETHERED_CASE_ICON,
+ METADATA_UNTETHERED_LEFT_BATTERY,
+ METADATA_UNTETHERED_RIGHT_BATTERY,
+ METADATA_UNTETHERED_CASE_BATTERY,
+ METADATA_UNTETHERED_LEFT_CHARGING,
+ METADATA_UNTETHERED_RIGHT_CHARGING,
+ METADATA_UNTETHERED_CASE_CHARGING,
+ METADATA_ENHANCED_SETTINGS_UI_URI,
+ METADATA_DEVICE_TYPE,
+ METADATA_MAIN_BATTERY,
+ METADATA_MAIN_CHARGING,
+ METADATA_MAIN_LOW_BATTERY_THRESHOLD,
+ METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
+ METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
+ METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MetadataKey{}
+ public static final int METADATA_MAX_LENGTH = 2048;
+ public static final int METADATA_MANUFACTURER_NAME = 0;
+ public static final int METADATA_MODEL_NAME = 1;
+ public static final int METADATA_SOFTWARE_VERSION = 2;
+ public static final int METADATA_HARDWARE_VERSION = 3;
+ public static final int METADATA_COMPANION_APP = 4;
+ public static final int METADATA_MAIN_ICON = 5;
+ public static final int METADATA_IS_UNTETHERED_HEADSET = 6;
+ public static final int METADATA_UNTETHERED_LEFT_ICON = 7;
+ public static final int METADATA_UNTETHERED_RIGHT_ICON = 8;
+ public static final int METADATA_UNTETHERED_CASE_ICON = 9;
+ public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10;
+ public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11;
+ public static final int METADATA_UNTETHERED_CASE_BATTERY = 12;
+ public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13;
+ public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14;
+ public static final int METADATA_UNTETHERED_CASE_CHARGING = 15;
+ public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16;
+ public static final int METADATA_DEVICE_TYPE = 17;
+ public static final int METADATA_MAIN_BATTERY = 18;
+ public static final int METADATA_MAIN_CHARGING = 19;
+ public static final int METADATA_MAIN_LOW_BATTERY_THRESHOLD = 20;
+ public static final int METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD = 21;
+ public static final int METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD = 22;
+ public static final int METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD = 23;
+ public static final String DEVICE_TYPE_DEFAULT = "Default";
+ public static final String DEVICE_TYPE_WATCH = "Watch";
+ public static final String DEVICE_TYPE_UNTETHERED_HEADSET = "Untethered Headset";
+ public static final String ACTION_UUID =
+ "android.bluetooth.device.action.UUID";
+ public static final String ACTION_MAS_INSTANCE =
+ "android.bluetooth.device.action.MAS_INSTANCE";
+ public static final String ACTION_NAME_FAILED =
+ "android.bluetooth.device.action.NAME_FAILED";
+ public static final String ACTION_PAIRING_REQUEST =
+ "android.bluetooth.device.action.PAIRING_REQUEST";
+ public static final String ACTION_PAIRING_CANCEL =
+ "android.bluetooth.device.action.PAIRING_CANCEL";
+ public static final String ACTION_CONNECTION_ACCESS_REQUEST =
+ "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST";
+ public static final String ACTION_CONNECTION_ACCESS_REPLY =
+ "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY";
+ public static final String ACTION_CONNECTION_ACCESS_CANCEL =
+ "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL";
+ public static final String ACTION_SILENCE_MODE_CHANGED =
+ "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
+ public static final String EXTRA_ACCESS_REQUEST_TYPE =
+ "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
+ public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1;
+ public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
+ public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
+ public static final int REQUEST_TYPE_SIM_ACCESS = 4;
+ public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME";
+ public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME";
+ public static final String EXTRA_CONNECTION_ACCESS_RESULT =
+ "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
+ public static final int CONNECTION_ACCESS_YES = 1;
+ public static final int CONNECTION_ACCESS_NO = 2;
+ public static final String EXTRA_ALWAYS_ALLOWED =
+ "android.bluetooth.device.extra.ALWAYS_ALLOWED";
+ public static final int BOND_SUCCESS = 0;
+ public static final int UNBOND_REASON_AUTH_FAILED = 1;
+ public static final int UNBOND_REASON_AUTH_REJECTED = 2;
+ public static final int UNBOND_REASON_AUTH_CANCELED = 3;
+ public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
+ public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
+ public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
+ public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
+ public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
+ public static final int UNBOND_REASON_REMOVED = 9;
+ public static final int PAIRING_VARIANT_PIN = 0;
+ public static final int PAIRING_VARIANT_PASSKEY = 1;
+ public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
+ public static final int PAIRING_VARIANT_CONSENT = 3;
+ public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
+ public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
+ public static final int PAIRING_VARIANT_OOB_CONSENT = 6;
+ public static final int PAIRING_VARIANT_PIN_16_DIGITS = 7;
+ public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
+ public static final String EXTRA_SDP_RECORD =
+ "android.bluetooth.device.extra.SDP_RECORD";
+ public static final String EXTRA_SDP_SEARCH_STATUS =
+ "android.bluetooth.device.extra.SDP_SEARCH_STATUS";
+ @IntDef( value = {ACCESS_UNKNOWN,
+ ACCESS_ALLOWED, ACCESS_REJECTED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AccessPermission{}
+ public static final int ACCESS_UNKNOWN = 0;
+ public static final int ACCESS_ALLOWED = 1;
+ public static final int ACCESS_REJECTED = 2;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ value = {
+ TRANSPORT_AUTO,
+ TRANSPORT_BREDR,
+ TRANSPORT_LE,
+ }
+ )
+ public @interface Transport {}
+ public static final int TRANSPORT_AUTO = 0;
+ public static final int TRANSPORT_BREDR = 1;
+ public static final int TRANSPORT_LE = 2;
+ public static final int PHY_LE_1M = 1;
+ public static final int PHY_LE_2M = 2;
+ public static final int PHY_LE_CODED = 3;
+ public static final int PHY_LE_1M_MASK = 1;
+ public static final int PHY_LE_2M_MASK = 2;
+ public static final int PHY_LE_CODED_MASK = 4;
+ public static final int PHY_OPTION_NO_PREFERRED = 0;
+ public static final int PHY_OPTION_S2 = 1;
+ public static final int PHY_OPTION_S8 = 2;
+ public static final String EXTRA_MAS_INSTANCE =
+ "android.bluetooth.device.extra.MAS_INSTANCE";
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ value = {
+ ADDRESS_TYPE_PUBLIC,
+ ADDRESS_TYPE_RANDOM,
+ }
+ )
+ public @interface AddressType {}
+ public static final int ADDRESS_TYPE_PUBLIC = 0;
+ public static final int ADDRESS_TYPE_RANDOM = 1;
+ private AttributionSource mAttributionSource;
+ BluetoothDevice(String address) {
+ }
+ public void setAttributionSource(AttributionSource attributionSource) {
+ mAttributionSource = attributionSource;
+ }
+ public void prepareToEnterProcess(AttributionSource attributionSource) {
+ setAttributionSource(attributionSource);
+ }
+ @Override
+ public boolean equals(Object o) {
+ return false;
+ }
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+ @Override
+ public String toString() {
+ return "";
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public BluetoothDevice createFromParcel(Parcel in) {
+ return new BluetoothDevice(in.readString());
+ }
+ public BluetoothDevice[] newArray(int size) {
+ return new BluetoothDevice[size];
+ }
+ };
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ }
+ public String getAddress() {
+ return null;
+ }
+ public String getAnonymizedAddress() {
+ return "XX:XX:XX" + getAddress().substring(8);
+ }
+ public String getName() {
+ return null;
+ }
+ public int getType() {
+ return DEVICE_TYPE_UNKNOWN;
+ }
+ public String getAlias() {
+ return null;
+ }
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ BluetoothStatusCodes.SUCCESS,
+ BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
+ BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED,
+ BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
+ BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED
+ })
+ public @interface SetAliasReturnValues{}
+ public @SetAliasReturnValues int setAlias(String alias) {
+ return 0;
+ }
+ public int getBatteryLevel() {
+ return BATTERY_LEVEL_UNKNOWN;
+ }
+ public boolean createBond() {
+ return createBond(TRANSPORT_AUTO);
+ }
+ public boolean createBond(int transport) {
+ return false;
+ }
+ public boolean isBondingInitiatedLocally() {
+ return false;
+ }
+ public boolean cancelBondProcess() {
+ return false;
+ }
+ public boolean removeBond() {
+ return false;
+ }
+ private static final String BLUETOOTH_BONDING_CACHE_PROPERTY =
+ "cache_key.bluetooth.get_bond_state";
+ boolean isBluetoothEnabled() {
+ boolean ret = false;
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ if (adapter != null && adapter.isEnabled()) {
+ ret = true;
+ }
+ return ret;
+ }
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback) {
+ return (connectGatt(context, autoConnect, callback, TRANSPORT_AUTO));
+ }
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback, int transport) {
+ return (connectGatt(context, autoConnect, callback, transport, PHY_LE_1M_MASK));
+ }
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback, int transport, int phy) {
+ return connectGatt(context, autoConnect, callback, transport, phy, null);
+ }
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback, int transport, int phy,
+ Handler handler) {
+ return connectGatt(context, autoConnect, callback, transport, false, phy, handler);
+ }
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback, int transport,
+ boolean opportunistic, int phy, Handler handler) {
+ return null;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothGatt.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothGatt.java
new file mode 100644
index 000000000..ee93ac6e8
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothGatt.java
@@ -0,0 +1,118 @@
+package android.bluetooth;
+import android.os.Handler;
+import java.util.List;
+import java.util.UUID;
+public class BluetoothGatt implements BluetoothProfile {
+ public static final int GATT_SUCCESS = 0;
+ public static final int GATT_READ_NOT_PERMITTED = 0x2;
+ public static final int GATT_WRITE_NOT_PERMITTED = 0x3;
+ public static final int GATT_INSUFFICIENT_AUTHENTICATION = 0x5;
+ public static final int GATT_REQUEST_NOT_SUPPORTED = 0x6;
+ public static final int GATT_INSUFFICIENT_ENCRYPTION = 0xf;
+ public static final int GATT_INVALID_OFFSET = 0x7;
+ public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd;
+ public static final int GATT_CONNECTION_CONGESTED = 0x8f;
+ public static final int GATT_FAILURE = 0x101;
+ public static final int CONNECTION_PRIORITY_BALANCED = 0;
+ public static final int CONNECTION_PRIORITY_HIGH = 1;
+ public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
+ static final int AUTHENTICATION_NONE = 0;
+ static final int AUTHENTICATION_NO_MITM = 1;
+ static final int AUTHENTICATION_MITM = 2;
+ public void close() {
+ }
+ BluetoothGattService getService(BluetoothDevice device, UUID uuid,
+ int instanceId) {
+ return null;
+ }
+ BluetoothGattCharacteristic getCharacteristicById(BluetoothDevice device,
+ int instanceId) {
+ return null;
+ }
+ BluetoothGattDescriptor getDescriptorById(BluetoothDevice device, int instanceId) {
+ return null;
+ }
+
+ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
+ Handler handler) {
+ return true;
+ }
+ public void disconnect() {
+ }
+ public boolean connect() {
+ return false;
+ }
+ public void setPreferredPhy(int txPhy, int rxPhy, int phyOptions) {
+ }
+ public void readPhy() {
+ }
+ public BluetoothDevice getDevice() {
+ return null;
+ }
+ public boolean discoverServices() {
+ return true;
+ }
+ public boolean discoverServiceByUuid(UUID uuid) {
+ return true;
+ }
+ public List getServices() {
+ return null;
+ }
+ public BluetoothGattService getService(UUID uuid) {
+ return null;
+ }
+ public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
+ return true;
+ }
+ public boolean readUsingCharacteristicUuid(UUID uuid, int startHandle, int endHandle) {
+ return true;
+ }
+ public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
+ return true;
+ }
+ public boolean readDescriptor(BluetoothGattDescriptor descriptor) {
+ return true;
+ }
+ public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
+ return true;
+ }
+ public boolean beginReliableWrite() {
+ return true;
+ }
+ public boolean executeReliableWrite() {
+ return true;
+ }
+ public void abortReliableWrite() {
+ }
+ @Deprecated
+ public void abortReliableWrite(BluetoothDevice mDevice) {
+ abortReliableWrite();
+ }
+ public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
+ boolean enable) {
+ return true;
+ }
+ public boolean readRemoteRssi() {
+ return true;
+ }
+ public boolean requestMtu(int mtu) {
+ return true;
+ }
+ public boolean requestConnectionPriority(int connectionPriority) {
+ return true;
+ }
+ @Override
+ public int getConnectionState(BluetoothDevice device) {
+ throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
+ }
+ @Override
+ public List getConnectedDevices() {
+ throw new UnsupportedOperationException(
+ "Use BluetoothManager#getConnectedDevices instead.");
+ }
+ @Override
+ public List getDevicesMatchingConnectionStates(int[] states) {
+ throw new UnsupportedOperationException(
+ "Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothGattCallback.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattCallback.java
new file mode 100644
index 000000000..f0d290165
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattCallback.java
@@ -0,0 +1,38 @@
+package android.bluetooth;
+public abstract class BluetoothGattCallback {
+ public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
+ }
+ public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
+ }
+ public void onConnectionStateChange(BluetoothGatt gatt, int status,
+ int newState) {
+ }
+ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+ }
+ public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+ int status) {
+ }
+ public void onCharacteristicWrite(BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic, int status) {
+ }
+ public void onCharacteristicChanged(BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic) {
+ }
+ public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+ int status) {
+ }
+ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+ int status) {
+ }
+ public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+ }
+ public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+ }
+ public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+ }
+ public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,
+ int status) {
+ }
+ public void onServiceChanged(BluetoothGatt gatt) {
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothGattCharacteristic.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattCharacteristic.java
new file mode 100644
index 000000000..5f087b1e9
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -0,0 +1,294 @@
+package android.bluetooth;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+public class BluetoothGattCharacteristic implements Parcelable {
+ public static final int PROPERTY_BROADCAST = 0x01;
+ public static final int PROPERTY_READ = 0x02;
+ public static final int PROPERTY_WRITE_NO_RESPONSE = 0x04;
+ public static final int PROPERTY_WRITE = 0x08;
+ public static final int PROPERTY_NOTIFY = 0x10;
+ public static final int PROPERTY_INDICATE = 0x20;
+ public static final int PROPERTY_SIGNED_WRITE = 0x40;
+ public static final int PROPERTY_EXTENDED_PROPS = 0x80;
+ public static final int PERMISSION_READ = 0x01;
+ public static final int PERMISSION_READ_ENCRYPTED = 0x02;
+ public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
+ public static final int PERMISSION_WRITE = 0x10;
+ public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
+ public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
+ public static final int PERMISSION_WRITE_SIGNED = 0x80;
+ public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
+ public static final int WRITE_TYPE_DEFAULT = 0x02;
+ public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
+ public static final int WRITE_TYPE_SIGNED = 0x04;
+ public static final int FORMAT_UINT8 = 0x11;
+ public static final int FORMAT_UINT16 = 0x12;
+ public static final int FORMAT_UINT32 = 0x14;
+ public static final int FORMAT_SINT8 = 0x21;
+ public static final int FORMAT_SINT16 = 0x22;
+ public static final int FORMAT_SINT32 = 0x24;
+ public static final int FORMAT_SFLOAT = 0x32;
+ public static final int FORMAT_FLOAT = 0x34;
+ protected UUID mUuid;
+ protected int mInstance;
+ protected int mProperties;
+ protected int mPermissions;
+ protected int mKeySize = 16;
+ protected int mWriteType;
+ protected BluetoothGattService mService;
+ protected byte[] mValue;
+ protected List mDescriptors;
+ public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
+ initCharacteristic(null, uuid, 0, properties, permissions);
+ }
+ BluetoothGattCharacteristic(BluetoothGattService service,
+ UUID uuid, int instanceId,
+ int properties, int permissions) {
+ initCharacteristic(service, uuid, instanceId, properties, permissions);
+ }
+ public BluetoothGattCharacteristic(UUID uuid, int instanceId,
+ int properties, int permissions) {
+ initCharacteristic(null, uuid, instanceId, properties, permissions);
+ }
+ private void initCharacteristic(BluetoothGattService service,
+ UUID uuid, int instanceId,
+ int properties, int permissions) {
+ mUuid = uuid;
+ mInstance = instanceId;
+ mProperties = properties;
+ mPermissions = permissions;
+ mService = service;
+ mValue = null;
+ mDescriptors = new ArrayList();
+ if ((mProperties & PROPERTY_WRITE_NO_RESPONSE) != 0) {
+ mWriteType = WRITE_TYPE_NO_RESPONSE;
+ } else {
+ mWriteType = WRITE_TYPE_DEFAULT;
+ }
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public BluetoothGattCharacteristic createFromParcel(Parcel in) {
+ return new BluetoothGattCharacteristic(in);
+ }
+ public BluetoothGattCharacteristic[] newArray(int size) {
+ return new BluetoothGattCharacteristic[size];
+ }
+ };
+ private BluetoothGattCharacteristic(Parcel in) {
+
+ }
+ public int getKeySize() {
+ return mKeySize;
+ }
+ public boolean addDescriptor(BluetoothGattDescriptor descriptor) {
+ mDescriptors.add(descriptor);
+ descriptor.setCharacteristic(this);
+ return true;
+ }
+ BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
+ for (BluetoothGattDescriptor descriptor : mDescriptors) {
+ if (descriptor.getUuid().equals(uuid)
+ && descriptor.getInstanceId() == instanceId) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+ public BluetoothGattService getService() {
+ return mService;
+ }
+ void setService(BluetoothGattService service) {
+ mService = service;
+ }
+ public UUID getUuid() {
+ return mUuid;
+ }
+ public int getInstanceId() {
+ return mInstance;
+ }
+ public void setInstanceId(int instanceId) {
+ mInstance = instanceId;
+ }
+ public int getProperties() {
+ return mProperties;
+ }
+ public int getPermissions() {
+ return mPermissions;
+ }
+ public int getWriteType() {
+ return mWriteType;
+ }
+ public void setWriteType(int writeType) {
+ mWriteType = writeType;
+ }
+ public void setKeySize(int keySize) {
+ mKeySize = keySize;
+ }
+ public List getDescriptors() {
+ return mDescriptors;
+ }
+ public BluetoothGattDescriptor getDescriptor(UUID uuid) {
+ for (BluetoothGattDescriptor descriptor : mDescriptors) {
+ if (descriptor.getUuid().equals(uuid)) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+ public byte[] getValue() {
+ return mValue;
+ }
+ public Integer getIntValue(int formatType, int offset) {
+ if ((offset + getTypeLen(formatType)) > mValue.length) return null;
+ switch (formatType) {
+ case FORMAT_UINT8:
+ return unsignedByteToInt(mValue[offset]);
+ case FORMAT_UINT16:
+ return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
+ case FORMAT_UINT32:
+ return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
+ mValue[offset + 2], mValue[offset + 3]);
+ case FORMAT_SINT8:
+ return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
+ case FORMAT_SINT16:
+ return unsignedToSigned(unsignedBytesToInt(mValue[offset],
+ mValue[offset + 1]), 16);
+ case FORMAT_SINT32:
+ return unsignedToSigned(unsignedBytesToInt(mValue[offset],
+ mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
+ }
+ return null;
+ }
+ public Float getFloatValue(int formatType, int offset) {
+ if ((offset + getTypeLen(formatType)) > mValue.length) return null;
+ switch (formatType) {
+ case FORMAT_SFLOAT:
+ return bytesToFloat(mValue[offset], mValue[offset + 1]);
+ case FORMAT_FLOAT:
+ return bytesToFloat(mValue[offset], mValue[offset + 1],
+ mValue[offset + 2], mValue[offset + 3]);
+ }
+ return null;
+ }
+ public String getStringValue(int offset) {
+ if (mValue == null || offset > mValue.length) return null;
+ byte[] strBytes = new byte[mValue.length - offset];
+ for (int i = 0; i != (mValue.length - offset); ++i) strBytes[i] = mValue[offset + i];
+ return new String(strBytes);
+ }
+ public boolean setValue(byte[] value) {
+ mValue = value;
+ return true;
+ }
+ public boolean setValue(int value, int formatType, int offset) {
+ int len = offset + getTypeLen(formatType);
+ if (mValue == null) mValue = new byte[len];
+ if (len > mValue.length) return false;
+ switch (formatType) {
+ case FORMAT_SINT8:
+ value = intToSignedBits(value, 8);
+ // Fall-through intended
+ case FORMAT_UINT8:
+ mValue[offset] = (byte) (value & 0xFF);
+ break;
+ case FORMAT_SINT16:
+ value = intToSignedBits(value, 16);
+ // Fall-through intended
+ case FORMAT_UINT16:
+ mValue[offset++] = (byte) (value & 0xFF);
+ mValue[offset] = (byte) ((value >> 8) & 0xFF);
+ break;
+ case FORMAT_SINT32:
+ value = intToSignedBits(value, 32);
+ // Fall-through intended
+ case FORMAT_UINT32:
+ mValue[offset++] = (byte) (value & 0xFF);
+ mValue[offset++] = (byte) ((value >> 8) & 0xFF);
+ mValue[offset++] = (byte) ((value >> 16) & 0xFF);
+ mValue[offset] = (byte) ((value >> 24) & 0xFF);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ public boolean setValue(int mantissa, int exponent, int formatType, int offset) {
+ int len = offset + getTypeLen(formatType);
+ if (mValue == null) mValue = new byte[len];
+ if (len > mValue.length) return false;
+ switch (formatType) {
+ case FORMAT_SFLOAT:
+ mantissa = intToSignedBits(mantissa, 12);
+ exponent = intToSignedBits(exponent, 4);
+ mValue[offset++] = (byte) (mantissa & 0xFF);
+ mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
+ mValue[offset] += (byte) ((exponent & 0x0F) << 4);
+ break;
+ case FORMAT_FLOAT:
+ mantissa = intToSignedBits(mantissa, 24);
+ exponent = intToSignedBits(exponent, 8);
+ mValue[offset++] = (byte) (mantissa & 0xFF);
+ mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
+ mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
+ mValue[offset] += (byte) (exponent & 0xFF);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ public boolean setValue(String value) {
+ mValue = value.getBytes();
+ return true;
+ }
+ private int getTypeLen(int formatType) {
+ return formatType & 0xF;
+ }
+ private int unsignedByteToInt(byte b) {
+ return b & 0xFF;
+ }
+ private int unsignedBytesToInt(byte b0, byte b1) {
+ return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
+ }
+ private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
+ return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
+ + (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
+ }
+ private float bytesToFloat(byte b0, byte b1) {
+ int mantissa = unsignedToSigned(unsignedByteToInt(b0)
+ + ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
+ int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
+ return (float) (mantissa * Math.pow(10, exponent));
+ }
+ private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
+ int mantissa = unsignedToSigned(unsignedByteToInt(b0)
+ + (unsignedByteToInt(b1) << 8)
+ + (unsignedByteToInt(b2) << 16), 24);
+ return (float) (mantissa * Math.pow(10, b3));
+ }
+ private int unsignedToSigned(int unsigned, int size) {
+ if ((unsigned & (1 << size - 1)) != 0) {
+ unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
+ }
+ return unsigned;
+ }
+ private int intToSignedBits(int i, int size) {
+ if (i < 0) {
+ i = (1 << size - 1) + (i & ((1 << size - 1) - 1));
+ }
+ return i;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothGattDescriptor.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattDescriptor.java
new file mode 100644
index 000000000..709e11989
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -0,0 +1,89 @@
+package android.bluetooth;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import java.util.UUID;
+public class BluetoothGattDescriptor implements Parcelable {
+ public static final byte[] ENABLE_NOTIFICATION_VALUE = {0x01, 0x00};
+ public static final byte[] ENABLE_INDICATION_VALUE = {0x02, 0x00};
+ public static final byte[] DISABLE_NOTIFICATION_VALUE = {0x00, 0x00};
+ public static final int PERMISSION_READ = 0x01;
+ public static final int PERMISSION_READ_ENCRYPTED = 0x02;
+ public static final int PERMISSION_READ_ENCRYPTED_MITM = 0x04;
+ public static final int PERMISSION_WRITE = 0x10;
+ public static final int PERMISSION_WRITE_ENCRYPTED = 0x20;
+ public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 0x40;
+ public static final int PERMISSION_WRITE_SIGNED = 0x80;
+ public static final int PERMISSION_WRITE_SIGNED_MITM = 0x100;
+ protected UUID mUuid;
+ protected int mInstance;
+ protected int mPermissions;
+ protected BluetoothGattCharacteristic mCharacteristic;
+ protected byte[] mValue;
+ public BluetoothGattDescriptor(UUID uuid, int permissions) {
+ initDescriptor(null, uuid, 0, permissions);
+ }
+ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
+ int instance, int permissions) {
+ initDescriptor(characteristic, uuid, instance, permissions);
+ }
+ public BluetoothGattDescriptor(UUID uuid, int instance, int permissions) {
+ initDescriptor(null, uuid, instance, permissions);
+ }
+ private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
+ int instance, int permissions) {
+ mCharacteristic = characteristic;
+ mUuid = uuid;
+ mInstance = instance;
+ mPermissions = permissions;
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(new ParcelUuid(mUuid), 0);
+ out.writeInt(mInstance);
+ out.writeInt(mPermissions);
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public BluetoothGattDescriptor createFromParcel(Parcel in) {
+ return new BluetoothGattDescriptor(in);
+ }
+ public BluetoothGattDescriptor[] newArray(int size) {
+ return new BluetoothGattDescriptor[size];
+ }
+ };
+ private BluetoothGattDescriptor(Parcel in) {
+ mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid();
+ mInstance = in.readInt();
+ mPermissions = in.readInt();
+ }
+ public BluetoothGattCharacteristic getCharacteristic() {
+ return mCharacteristic;
+ }
+ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
+ mCharacteristic = characteristic;
+ }
+ public UUID getUuid() {
+ return mUuid;
+ }
+ public int getInstanceId() {
+ return mInstance;
+ }
+ public void setInstanceId(int instanceId) {
+ mInstance = instanceId;
+ }
+ public int getPermissions() {
+ return mPermissions;
+ }
+ public byte[] getValue() {
+ return mValue;
+ }
+ public boolean setValue(byte[] value) {
+ mValue = value;
+ return true;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothGattIncludedService.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattIncludedService.java
new file mode 100644
index 000000000..89a4dea4d
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattIncludedService.java
@@ -0,0 +1,36 @@
+package android.bluetooth;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import java.util.UUID;
+public class BluetoothGattIncludedService implements Parcelable {
+ public BluetoothGattIncludedService(UUID uuid, int instanceId, int serviceType) {
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public BluetoothGattIncludedService createFromParcel(Parcel in) {
+ return new BluetoothGattIncludedService(in);
+ }
+ public BluetoothGattIncludedService[] newArray(int size) {
+ return new BluetoothGattIncludedService[size];
+ }
+ };
+ private BluetoothGattIncludedService(Parcel in) {
+ }
+ public UUID getUuid() {
+ return null;
+ }
+ public int getInstanceId() {
+ return 0;
+ }
+ public int getType() {
+ return 0;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/BluetoothGattService.java b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattService.java
new file mode 100644
index 000000000..23c1d6701
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/BluetoothGattService.java
@@ -0,0 +1,126 @@
+package android.bluetooth;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+public class BluetoothGattService implements Parcelable {
+ public static final int SERVICE_TYPE_PRIMARY = 0;
+ public static final int SERVICE_TYPE_SECONDARY = 1;
+ protected BluetoothDevice mDevice;
+ protected UUID mUuid;
+ protected int mInstanceId;
+ protected int mHandles = 0;
+ protected int mServiceType;
+ protected List mCharacteristics;
+ protected List mIncludedServices;
+ private boolean mAdvertisePreferred;
+ public BluetoothGattService(UUID uuid, int serviceType) {
+ mDevice = null;
+ mUuid = uuid;
+ mInstanceId = 0;
+ mServiceType = serviceType;
+ mCharacteristics = new ArrayList();
+ mIncludedServices = new ArrayList();
+ }
+ BluetoothGattService(BluetoothDevice device, UUID uuid,
+ int instanceId, int serviceType) {
+ mDevice = device;
+ mUuid = uuid;
+ mInstanceId = instanceId;
+ mServiceType = serviceType;
+ mCharacteristics = new ArrayList();
+ mIncludedServices = new ArrayList();
+ }
+ public BluetoothGattService(UUID uuid, int instanceId, int serviceType) {
+ mDevice = null;
+ mUuid = uuid;
+ mInstanceId = instanceId;
+ mServiceType = serviceType;
+ mCharacteristics = new ArrayList();
+ mIncludedServices = new ArrayList();
+ }
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public BluetoothGattService createFromParcel(Parcel in) {
+ return new BluetoothGattService(in);
+ }
+ public BluetoothGattService[] newArray(int size) {
+ return new BluetoothGattService[size];
+ }
+ };
+ private BluetoothGattService(Parcel in) {
+ }
+ BluetoothDevice getDevice() {
+ return mDevice;
+ }
+ void setDevice(BluetoothDevice device) {
+ mDevice = device;
+ }
+ public boolean addService(BluetoothGattService service) {
+ mIncludedServices.add(service);
+ return true;
+ }
+ public boolean addCharacteristic(BluetoothGattCharacteristic characteristic) {
+ mCharacteristics.add(characteristic);
+ characteristic.setService(this);
+ return true;
+ }
+ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
+ for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
+ if (uuid.equals(characteristic.getUuid())
+ && characteristic.getInstanceId() == instanceId) {
+ return characteristic;
+ }
+ }
+ return null;
+ }
+ public void setInstanceId(int instanceId) {
+ mInstanceId = instanceId;
+ }
+ int getHandles() {
+ return mHandles;
+ }
+ public void setHandles(int handles) {
+ mHandles = handles;
+ }
+ public void addIncludedService(BluetoothGattService includedService) {
+ mIncludedServices.add(includedService);
+ }
+ public UUID getUuid() {
+ return mUuid;
+ }
+ public int getInstanceId() {
+ return mInstanceId;
+ }
+ public int getType() {
+ return mServiceType;
+ }
+ public List getIncludedServices() {
+ return mIncludedServices;
+ }
+ public List getCharacteristics() {
+ return mCharacteristics;
+ }
+ public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
+ for (BluetoothGattCharacteristic characteristic : mCharacteristics) {
+ if (uuid.equals(characteristic.getUuid())) {
+ return characteristic;
+ }
+ }
+ return null;
+ }
+ public boolean isAdvertisePreferred() {
+ return mAdvertisePreferred;
+ }
+ public void setAdvertisePreferred(boolean advertisePreferred) {
+ mAdvertisePreferred = advertisePreferred;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/le/BluetoothLeScanner.java b/rxandroidble/src/test/java/android/bluetooth/le/BluetoothLeScanner.java
new file mode 100644
index 000000000..fbc3912ac
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -0,0 +1,12 @@
+package android.bluetooth.le;
+import android.bluetooth.BluetoothAdapter;
+public class BluetoothLeScanner {
+ public static final String EXTRA_LIST_SCAN_RESULT =
+ "android.bluetooth.le.extra.LIST_SCAN_RESULT";
+ public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
+ public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
+ public BluetoothLeScanner(BluetoothAdapter bluetoothAdapter) {
+
+ }
+
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/le/ScanCallback.java b/rxandroidble/src/test/java/android/bluetooth/le/ScanCallback.java
new file mode 100644
index 000000000..2a49d3190
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/le/ScanCallback.java
@@ -0,0 +1,12 @@
+package android.bluetooth.le;
+import java.util.List;
+public abstract class ScanCallback {
+ public static final int SCAN_FAILED_ALREADY_STARTED = 1;
+ public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2;
+ public void onScanResult(int callbackType, ScanResult result) {
+ }
+ public void onBatchScanResults(List results) {
+ }
+ public void onScanFailed(int errorCode) {
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/le/ScanFilter.java b/rxandroidble/src/test/java/android/bluetooth/le/ScanFilter.java
new file mode 100644
index 000000000..292fb5f59
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/le/ScanFilter.java
@@ -0,0 +1,137 @@
+package android.bluetooth.le;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothDevice.AddressType;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import java.util.List;
+public class ScanFilter implements Parcelable {
+ public static final ScanFilter EMPTY = new Builder().build();
+ private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
+ ParcelUuid uuidMask, ParcelUuid solicitationUuid,
+ ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
+ byte[] serviceData, byte[] serviceDataMask,
+ int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
+ @AddressType int addressType, byte[] irk) {
+ }
+ public int describeContents() {
+ return 0;
+ }
+ public void writeToParcel(Parcel dest, int flags) {
+
+ }
+ public ScanFilter[] newArray(int size) {
+ return new ScanFilter[size];
+ }
+ public ScanFilter createFromParcel(Parcel in) {
+ return null;
+ }
+ public String getDeviceName() {
+ return null;
+ }
+ public ParcelUuid getServiceUuid() {
+ return null;
+ }
+ public ParcelUuid getServiceUuidMask() {
+ return null;
+ }
+ public ParcelUuid getServiceSolicitationUuid() {
+ return null;
+ }
+ public ParcelUuid getServiceSolicitationUuidMask() {
+ return null;
+ }
+ public String getDeviceAddress() {
+ return null;
+ }
+ public @AddressType int getAddressType() {
+ return 0;
+ }
+ public byte[] getIrk() {
+ return null;
+ }
+ public byte[] getServiceData() {
+ return null;
+ }
+ public byte[] getServiceDataMask() {
+ return null;
+ }
+ public ParcelUuid getServiceDataUuid() {
+ return null;
+ }
+ public int getManufacturerId() {
+ return 0;
+ }
+ public byte[] getManufacturerData() {
+ return null;
+ }
+ public byte[] getManufacturerDataMask() {
+ return null;
+ }
+ public boolean matches(ScanResult scanResult) {
+
+ return true;
+ }
+ public static boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
+ List uuids) {
+
+ return false;
+ }
+ public String toString() {
+ return "";
+ }
+ public int hashCode() {
+ return 0;
+ }
+ public boolean equals(Object obj) {
+ return false;
+ }
+ public boolean isAllFieldsEmpty() {
+ return EMPTY.equals(this);
+ }
+ public static final class Builder {
+ public static final int LEN_IRK_OCTETS = 16;
+ public Builder setDeviceName(String deviceName) {
+ return this;
+ }
+ public Builder setDeviceAddress(String deviceAddress) {
+ return setDeviceAddress(deviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
+ }
+ public Builder setDeviceAddress(String deviceAddress,
+ @AddressType int addressType) {
+ return this;
+ }
+ public Builder setServiceUuid(ParcelUuid serviceUuid) {
+ return this;
+ }
+ public Builder setServiceUuid(ParcelUuid serviceUuid, ParcelUuid uuidMask) {
+ return this;
+ }
+ public Builder setServiceSolicitationUuid(
+ ParcelUuid serviceSolicitationUuid) {
+ return this;
+ }
+ public Builder setServiceSolicitationUuid(
+ ParcelUuid serviceSolicitationUuid,
+ ParcelUuid solicitationUuidMask) {
+ return this;
+ }
+ public Builder setServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
+ return this;
+ }
+ public Builder setServiceData(ParcelUuid serviceDataUuid,
+ byte[] serviceData, byte[] serviceDataMask) {
+ return this;
+ }
+ public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData) {
+ return this;
+ }
+ public Builder setManufacturerData(int manufacturerId, byte[] manufacturerData,
+ byte[] manufacturerDataMask) {
+ return this;
+ }
+ public ScanFilter build() {
+ return new ScanFilter(null, null, null, null, null, null, null, null, null, 0, null, null, 0, null);
+ }
+ }
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/le/ScanResult.java b/rxandroidble/src/test/java/android/bluetooth/le/ScanResult.java
new file mode 100644
index 000000000..a7fa85020
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/le/ScanResult.java
@@ -0,0 +1,69 @@
+package android.bluetooth.le;
+import android.bluetooth.BluetoothDevice;
+import android.os.Parcel;
+import android.os.Parcelable;
+import java.util.Objects;
+public class ScanResult implements Parcelable {
+ public static final int DATA_COMPLETE = 0x00;
+ public static final int DATA_TRUNCATED = 0x02;
+ public static final int PHY_UNUSED = 0x00;
+ public static final int SID_NOT_PRESENT = 0xFF;
+ public static final int TX_POWER_NOT_PRESENT = 0x7F;
+ public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0x00;
+ private static final int ET_LEGACY_MASK = 0x10;
+ private static final int ET_CONNECTABLE_MASK = 0x01;
+ @Deprecated
+ public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
+ long timestampNanos) {
+
+ }
+ public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
+ int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
+ ScanRecord scanRecord, long timestampNanos) {
+
+ }
+ private ScanResult(Parcel in) {
+ readFromParcel(in);
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+
+ }
+ private void readFromParcel(Parcel in) {
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ public BluetoothDevice getDevice() {
+ return null;
+ }
+ public ScanRecord getScanRecord() {
+ return null;
+ }
+ public int getRssi() {
+ return 0;
+ }
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return false;
+ }
+ @Override
+ public String toString() {
+ return "ScanResult";
+ }
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public ScanResult createFromParcel(Parcel source) {
+ return new ScanResult(source);
+ }
+ @Override
+ public ScanResult[] newArray(int size) {
+ return new ScanResult[size];
+ }
+ };
+}
diff --git a/rxandroidble/src/test/java/android/bluetooth/le/ScanSettings.java b/rxandroidble/src/test/java/android/bluetooth/le/ScanSettings.java
new file mode 100644
index 000000000..6596193dd
--- /dev/null
+++ b/rxandroidble/src/test/java/android/bluetooth/le/ScanSettings.java
@@ -0,0 +1,107 @@
+package android.bluetooth.le;
+import android.os.Parcel;
+import android.os.Parcelable;
+public class ScanSettings implements Parcelable {
+ public static final int SCAN_MODE_OPPORTUNISTIC = -1;
+ public static final int SCAN_MODE_LOW_POWER = 0;
+ public static final int SCAN_MODE_BALANCED = 1;
+ public static final int SCAN_MODE_LOW_LATENCY = 2;
+ public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3;
+ public static final int CALLBACK_TYPE_ALL_MATCHES = 1;
+ public static final int CALLBACK_TYPE_FIRST_MATCH = 2;
+ public static final int CALLBACK_TYPE_MATCH_LOST = 4;
+ public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1;
+ public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2;
+ public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3;
+ public static final int MATCH_MODE_AGGRESSIVE = 1;
+ public static final int MATCH_MODE_STICKY = 2;
+ public static final int SCAN_RESULT_TYPE_FULL = 0;
+ public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1;
+ public static final int PHY_LE_ALL_SUPPORTED = 255;
+
+ public int getScanMode() {
+ return 0;
+ }
+ public int getCallbackType() {
+ return 0;
+ }
+ public int getScanResultType() {
+ return 0;
+ }
+ public int getMatchMode() {
+ return 0;
+}
+ public int getNumOfMatches() {
+ return 0;
+}
+ public boolean getLegacy() {
+ return false;
+}
+ public int getPhy() {
+ return 0;
+}
+ public long getReportDelayMillis() {
+ return 0;
+ }
+ private ScanSettings(int scanMode, int callbackType, int scanResultType,
+ long reportDelayMillis, int matchMode,
+ int numOfMatchesPerFilter, boolean legacy, int phy) {
+
+ }
+ private ScanSettings(Parcel in) {
+
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ @Override
+ public ScanSettings[] newArray(int size) {
+ return new ScanSettings[size];
+ }
+ @Override
+ public ScanSettings createFromParcel(Parcel in) {
+ return new ScanSettings(in);
+ }
+ };
+ public static final class Builder {
+
+ public Builder setScanMode(int scanMode) {
+ return this;
+ }
+ public Builder setCallbackType(int callbackType) {
+ return this;
+ }
+ // Returns true if the callbackType is valid.
+ private boolean isValidCallbackType(int callbackType) {
+ return false;
+ }
+ public Builder setScanResultType(int scanResultType) {
+ return this;
+ }
+ public Builder setReportDelay(long reportDelayMillis) {
+ return this;
+ }
+ public Builder setNumOfMatches(int numOfMatches) {
+ return this;
+ }
+ public Builder setMatchMode(int matchMode) {
+ return this;
+ }
+ public Builder setLegacy(boolean legacy) {
+ return this;
+ }
+ public Builder setPhy(int phy) {
+ return this;
+ }
+ public ScanSettings build() {
+ return new ScanSettings(0, 0, 0, 0, 0, 0, false, 0);
+ }
+ }
+}
diff --git a/rxandroidble/src/test/java/android/content/BroadcastReceiver.java b/rxandroidble/src/test/java/android/content/BroadcastReceiver.java
new file mode 100644
index 000000000..bbf79a1ed
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/BroadcastReceiver.java
@@ -0,0 +1,7 @@
+package android.content;
+public abstract class BroadcastReceiver {
+ public BroadcastReceiver() {
+ }
+ public void onReceive(Context context, Intent intent) {
+ }
+}
diff --git a/rxandroidble/src/test/java/android/content/Context.java b/rxandroidble/src/test/java/android/content/Context.java
new file mode 100644
index 000000000..5a992a94e
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/Context.java
@@ -0,0 +1,14 @@
+package android.content;
+
+import android.content.res.Resources;
+
+public abstract class Context {
+
+ public abstract String getPackageName();
+
+ public abstract Resources getResources();
+ public abstract ContentResolver getContentResolver();
+ public abstract Intent registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter);
+ public abstract void unregisterReceiver(BroadcastReceiver receiver);
+
+}
diff --git a/rxandroidble/src/test/java/android/content/Intent.java b/rxandroidble/src/test/java/android/content/Intent.java
new file mode 100644
index 000000000..bb9cbbd9e
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/Intent.java
@@ -0,0 +1,1580 @@
+package android.content;
+import android.accessibilityservice.AccessibilityService;
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothDevice;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+import android.os.Process;
+import android.os.ResultReceiver;
+import android.os.StrictMode;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.provider.ContactsContract.QuickContact;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsProvider;
+import android.provider.MediaStore;
+import android.provider.OpenableColumns;
+import android.telecom.PhoneAccount;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+import androidx.annotation.IntDef;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TimeZone;
+public class Intent implements Parcelable, Cloneable {
+ private static final String TAG = "Intent";
+ private static final String ATTR_ACTION = "action";
+ private static final String TAG_CATEGORIES = "categories";
+ private static final String ATTR_CATEGORY = "category";
+ private static final String TAG_EXTRA = "extra";
+ private static final String ATTR_TYPE = "type";
+ private static final String ATTR_IDENTIFIER = "ident";
+ private static final String ATTR_COMPONENT = "component";
+ private static final String ATTR_DATA = "data";
+ private static final String ATTR_FLAGS = "flags";
+ public static final String ACTION_MAIN = "android.intent.action.MAIN";
+ public static final String ACTION_VIEW = "android.intent.action.VIEW";
+ public static final String EXTRA_FROM_STORAGE = "android.intent.extra.FROM_STORAGE";
+ public static final String ACTION_DEFAULT = ACTION_VIEW;
+ public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
+ public static final String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
+ public static final String ACTION_EDIT = "android.intent.action.EDIT";
+ public static final String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
+ public static final String ACTION_PICK = "android.intent.action.PICK";
+ public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
+ public static final String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
+ @Deprecated
+ public static final String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
+ @Deprecated
+ public static final String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
+ @Deprecated
+ public static final String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON";
+ @Deprecated
+ public static final String EXTRA_SHORTCUT_ICON_RESOURCE =
+ "android.intent.extra.shortcut.ICON_RESOURCE";
+ public static final String ACTION_APPLICATION_PREFERENCES
+ = "android.intent.action.APPLICATION_PREFERENCES";
+ public static final String ACTION_SHOW_APP_INFO
+ = "android.intent.action.SHOW_APP_INFO";
+ public static final String ACTION_ACTIVITY_RECOGNIZER =
+ "android.intent.action.ACTIVITY_RECOGNIZER";
+ public static class ShortcutIconResource implements Parcelable {
+ public String packageName;
+ public String resourceName;
+ public static ShortcutIconResource fromContext(Context context, int resourceId) {
+ return null;
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public ShortcutIconResource createFromParcel(Parcel source) {
+ ShortcutIconResource icon = new ShortcutIconResource();
+ return null;
+ }
+ public ShortcutIconResource[] newArray(int size) {
+ return null;
+ }
+ };
+ public int describeContents() {
+ return 0;
+ }
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+ @Override
+ public String toString() {
+ return null;
+ }
+ }
+ public static final String ACTION_CHOOSER = "android.intent.action.CHOOSER";
+ public static final String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT";
+ public static final String ACTION_DIAL = "android.intent.action.DIAL";
+ public static final String ACTION_CALL = "android.intent.action.CALL";
+ public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
+ public static final String ACTION_DIAL_EMERGENCY = "android.intent.action.DIAL_EMERGENCY";
+ public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
+ public static final String ACTION_CARRIER_SETUP = "android.intent.action.CARRIER_SETUP";
+ public static final String ACTION_SENDTO = "android.intent.action.SENDTO";
+ public static final String ACTION_SEND = "android.intent.action.SEND";
+ public static final String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE";
+ public static final String ACTION_ANSWER = "android.intent.action.ANSWER";
+ public static final String ACTION_INSERT = "android.intent.action.INSERT";
+ public static final String ACTION_PASTE = "android.intent.action.PASTE";
+ public static final String ACTION_DELETE = "android.intent.action.DELETE";
+ public static final String ACTION_RUN = "android.intent.action.RUN";
+ public static final String ACTION_SYNC = "android.intent.action.SYNC";
+ public static final String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY";
+ public static final String ACTION_SEARCH = "android.intent.action.SEARCH";
+ public static final String ACTION_SYSTEM_TUTORIAL = "android.intent.action.SYSTEM_TUTORIAL";
+ public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
+ public static final String ACTION_ASSIST = "android.intent.action.ASSIST";
+ public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
+ public static final String EXTRA_ASSIST_PACKAGE
+ = "android.intent.extra.ASSIST_PACKAGE";
+ public static final String EXTRA_ASSIST_UID
+ = "android.intent.extra.ASSIST_UID";
+ public static final String EXTRA_ASSIST_CONTEXT
+ = "android.intent.extra.ASSIST_CONTEXT";
+ public static final String EXTRA_ASSIST_INPUT_HINT_KEYBOARD =
+ "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
+ public static final String EXTRA_ASSIST_INPUT_DEVICE_ID =
+ "android.intent.extra.ASSIST_INPUT_DEVICE_ID";
+ public static final String ACTION_ALL_APPS = "android.intent.action.ALL_APPS";
+ public static final String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER";
+ public static final String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT";
+ public static final String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST";
+ public static final String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON";
+ public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
+ public static final String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS";
+ public static final String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
+ public static final String ACTION_PENDING_INCIDENT_REPORTS_CHANGED =
+ "android.intent.action.PENDING_INCIDENT_REPORTS_CHANGED";
+ public static final String ACTION_INCIDENT_REPORT_READY =
+ "android.intent.action.INCIDENT_REPORT_READY";
+ public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY";
+ @Deprecated
+ public static final String ACTION_DEVICE_INITIALIZATION_WIZARD =
+ "android.intent.action.DEVICE_INITIALIZATION_WIZARD";
+ public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
+ public static final String ACTION_SHOW_KEYBOARD_SHORTCUTS =
+ "com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS";
+ public static final String ACTION_DISMISS_KEYBOARD_SHORTCUTS =
+ "com.android.intent.action.DISMISS_KEYBOARD_SHORTCUTS";
+ public static final String ACTION_MANAGE_NETWORK_USAGE =
+ "android.intent.action.MANAGE_NETWORK_USAGE";
+ @Deprecated
+ public static final String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
+ public static final String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
+ public static final String ACTION_INSTALL_INSTANT_APP_PACKAGE
+ = "android.intent.action.INSTALL_INSTANT_APP_PACKAGE";
+ public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE
+ = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
+ public static final String ACTION_INSTANT_APP_RESOLVER_SETTINGS
+ = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS";
+ public static final String EXTRA_INSTALLER_PACKAGE_NAME
+ = "android.intent.extra.INSTALLER_PACKAGE_NAME";
+ public static final String EXTRA_NOT_UNKNOWN_SOURCE
+ = "android.intent.extra.NOT_UNKNOWN_SOURCE";
+ public static final String EXTRA_ORIGINATING_URI
+ = "android.intent.extra.ORIGINATING_URI";
+ public static final String EXTRA_REFERRER
+ = "android.intent.extra.REFERRER";
+ public static final String EXTRA_REFERRER_NAME
+ = "android.intent.extra.REFERRER_NAME";
+ public static final String EXTRA_ORIGINATING_UID
+ = "android.intent.extra.ORIGINATING_UID";
+ @Deprecated
+ public static final String EXTRA_ALLOW_REPLACE
+ = "android.intent.extra.ALLOW_REPLACE";
+ public static final String EXTRA_RETURN_RESULT
+ = "android.intent.extra.RETURN_RESULT";
+ public static final String EXTRA_INSTALL_RESULT
+ = "android.intent.extra.INSTALL_RESULT";
+ @Deprecated
+ public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
+ public static final String EXTRA_UNINSTALL_ALL_USERS
+ = "android.intent.extra.UNINSTALL_ALL_USERS";
+ public static final String METADATA_SETUP_VERSION = "android.SETUP_VERSION";
+ public static final String ACTION_MANAGE_APP_PERMISSIONS =
+ "android.intent.action.MANAGE_APP_PERMISSIONS";
+ public static final String ACTION_MANAGE_APP_PERMISSION =
+ "android.intent.action.MANAGE_APP_PERMISSION";
+ public static final String ACTION_MANAGE_PERMISSIONS =
+ "android.intent.action.MANAGE_PERMISSIONS";
+ public static final String ACTION_AUTO_REVOKE_PERMISSIONS =
+ "android.intent.action.AUTO_REVOKE_PERMISSIONS";
+ public static final String ACTION_MANAGE_UNUSED_APPS =
+ "android.intent.action.MANAGE_UNUSED_APPS";
+ public static final String ACTION_REVIEW_PERMISSIONS =
+ "android.intent.action.REVIEW_PERMISSIONS";
+ public static final String ACTION_VIEW_PERMISSION_USAGE =
+ "android.intent.action.VIEW_PERMISSION_USAGE";
+ public static final String ACTION_VIEW_PERMISSION_USAGE_FOR_PERIOD =
+ "android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD";
+ public static final String ACTION_MANAGE_DEFAULT_APP =
+ "android.intent.action.MANAGE_DEFAULT_APP";
+ public static final String EXTRA_ROLE_NAME = "android.intent.extra.ROLE_NAME";
+ public static final String ACTION_MANAGE_SPECIAL_APP_ACCESSES =
+ "android.intent.action.MANAGE_SPECIAL_APP_ACCESSES";
+ public static final String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
+ public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";
+ public static final String EXTRA_SUSPENDED_PACKAGE_EXTRAS = "android.intent.extra.SUSPENDED_PACKAGE_EXTRAS";
+ public static final String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
+ public static final String EXTRA_COMPONENT_NAME = "android.intent.extra.COMPONENT_NAME";
+ public static final String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
+ public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
+ public static final String ACTION_MANAGE_PERMISSION_APPS =
+ "android.intent.action.MANAGE_PERMISSION_APPS";
+ public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
+ public static final String EXTRA_PERMISSION_GROUP_NAME =
+ "android.intent.extra.PERMISSION_GROUP_NAME";
+ public static final String EXTRA_DURATION_MILLIS =
+ "android.intent.extra.DURATION_MILLIS";
+ public static final String ACTION_REVIEW_PERMISSION_USAGE =
+ "android.intent.action.REVIEW_PERMISSION_USAGE";
+ public static final String ACTION_REVIEW_PERMISSION_HISTORY =
+ "android.intent.action.REVIEW_PERMISSION_HISTORY";
+ public static final String ACTION_REVIEW_ONGOING_PERMISSION_USAGE =
+ "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE";
+ public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES =
+ "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
+ public static final String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
+ public static final String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON";
+ public static final String ACTION_DREAMING_STOPPED = "android.intent.action.DREAMING_STOPPED";
+ public static final String ACTION_DREAMING_STARTED = "android.intent.action.DREAMING_STARTED";
+ public static final String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT";
+ public static final String ACTION_TIME_TICK = "android.intent.action.TIME_TICK";
+ public static final String ACTION_TIME_CHANGED = "android.intent.action.TIME_SET";
+ public static final String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
+ public static final String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED";
+ public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
+ public static final String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
+ public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
+ @Deprecated
+ public static final String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS";
+ @Deprecated
+ public static final String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
+ public static final String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
+ public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
+ public static final String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED";
+ public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
+ public static final String ACTION_PACKAGE_REMOVED_INTERNAL =
+ "android.intent.action.PACKAGE_REMOVED_INTERNAL";
+ public static final String ACTION_PACKAGE_FULLY_REMOVED
+ = "android.intent.action.PACKAGE_FULLY_REMOVED";
+ public static final String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
+ public static final String ACTION_PACKAGE_ENABLE_ROLLBACK =
+ "android.intent.action.PACKAGE_ENABLE_ROLLBACK";
+ public static final String ACTION_CANCEL_ENABLE_ROLLBACK =
+ "android.intent.action.CANCEL_ENABLE_ROLLBACK";
+ public static final String ACTION_ROLLBACK_COMMITTED =
+ "android.intent.action.ROLLBACK_COMMITTED";
+ public static final String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
+ public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
+ public static final String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
+ public static final String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
+ public static final String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
+ public static final String ACTION_DISTRACTING_PACKAGES_CHANGED =
+ "android.intent.action.DISTRACTING_PACKAGES_CHANGED";
+ public static final String ACTION_MY_PACKAGE_SUSPENDED = "android.intent.action.MY_PACKAGE_SUSPENDED";
+ public static final String ACTION_SHOW_SUSPENDED_APP_DETAILS =
+ "android.intent.action.SHOW_SUSPENDED_APP_DETAILS";
+ public static final String ACTION_PACKAGE_UNSUSPENDED_MANUALLY =
+ "android.intent.action.PACKAGE_UNSUSPENDED_MANUALLY";
+ public static final String ACTION_MY_PACKAGE_UNSUSPENDED = "android.intent.action.MY_PACKAGE_UNSUSPENDED";
+ public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED";
+ public static final String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH";
+ public static final String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION";
+ public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
+ @Deprecated
+ public static final String ACTION_INTENT_FILTER_NEEDS_VERIFICATION =
+ "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION";
+ public static final String ACTION_DOMAINS_NEED_VERIFICATION =
+ "android.intent.action.DOMAINS_NEED_VERIFICATION";
+ public static final String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE =
+ "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
+ public static final String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE =
+ "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
+ public static final String ACTION_PREFERRED_ACTIVITY_CHANGED =
+ "android.intent.action.ACTION_PREFERRED_ACTIVITY_CHANGED";
+ public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
+ public static final String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
+ public static final String ACTION_SPLIT_CONFIGURATION_CHANGED =
+ "android.intent.action.SPLIT_CONFIGURATION_CHANGED";
+ public static final String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
+ public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
+ public static final String ACTION_BATTERY_LEVEL_CHANGED =
+ "android.intent.action.BATTERY_LEVEL_CHANGED";
+ public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
+ public static final String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
+ public static final String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED";
+ public static final String ACTION_POWER_DISCONNECTED =
+ "android.intent.action.ACTION_POWER_DISCONNECTED";
+ public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
+ public static final String ACTION_REQUEST_SHUTDOWN
+ = "com.android.internal.intent.action.REQUEST_SHUTDOWN";
+ @Deprecated
+ public static final String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";
+ @Deprecated
+ public static final String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
+ @Deprecated
+ public static final String ACTION_DEVICE_STORAGE_FULL = "android.intent.action.DEVICE_STORAGE_FULL";
+ @Deprecated
+ public static final String ACTION_DEVICE_STORAGE_NOT_FULL = "android.intent.action.DEVICE_STORAGE_NOT_FULL";
+ public static final String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
+ @Deprecated
+ public static final String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
+ @Deprecated
+ public static final String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
+ public static final String ACTION_MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED";
+ public static final String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
+ public static final String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING";
+ public static final String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS";
+ public static final String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED";
+ public static final String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED";
+ public static final String ACTION_MEDIA_UNSHARED = "android.intent.action.MEDIA_UNSHARED";
+ public static final String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
+ public static final String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE";
+ public static final String ACTION_MEDIA_EJECT = "android.intent.action.MEDIA_EJECT";
+ public static final String ACTION_MEDIA_SCANNER_STARTED = "android.intent.action.MEDIA_SCANNER_STARTED";
+ public static final String ACTION_MEDIA_SCANNER_FINISHED = "android.intent.action.MEDIA_SCANNER_FINISHED";
+ @Deprecated
+ public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE";
+ public static final String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON";
+ public static final String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON";
+ public static final String ACTION_GTALK_SERVICE_CONNECTED =
+ "android.intent.action.GTALK_CONNECTED";
+ public static final String ACTION_GTALK_SERVICE_DISCONNECTED =
+ "android.intent.action.GTALK_DISCONNECTED";
+ public static final String ACTION_INPUT_METHOD_CHANGED =
+ "android.intent.action.INPUT_METHOD_CHANGED";
+ public static final String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE";
+ public static final String ACTION_PROVIDER_CHANGED =
+ "android.intent.action.PROVIDER_CHANGED";
+ public static final String ACTION_HEADSET_PLUG = android.media.AudioManager.ACTION_HEADSET_PLUG;
+ //@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_ADVANCED_SETTINGS_CHANGED
+ = "android.intent.action.ADVANCED_SETTINGS";
+ public static final String ACTION_APPLICATION_RESTRICTIONS_CHANGED =
+ "android.intent.action.APPLICATION_RESTRICTIONS_CHANGED";
+ @Deprecated
+ public static final String ACTION_NEW_OUTGOING_CALL =
+ "android.intent.action.NEW_OUTGOING_CALL";
+ public static final String ACTION_REBOOT =
+ "android.intent.action.REBOOT";
+ public static final String ACTION_DOCK_EVENT =
+ "android.intent.action.DOCK_EVENT";
+ public static final String ACTION_IDLE_MAINTENANCE_START =
+ "android.intent.action.ACTION_IDLE_MAINTENANCE_START";
+ public static final String ACTION_IDLE_MAINTENANCE_END =
+ "android.intent.action.ACTION_IDLE_MAINTENANCE_END";
+ public static final String ACTION_REMOTE_INTENT =
+ "com.google.android.c2dm.intent.RECEIVE";
+ public static final String ACTION_PRE_BOOT_COMPLETED =
+ "android.intent.action.PRE_BOOT_COMPLETED";
+ public static final String ACTION_GET_RESTRICTION_ENTRIES =
+ "android.intent.action.GET_RESTRICTION_ENTRIES";
+ public static final String ACTION_USER_INITIALIZE =
+ "android.intent.action.USER_INITIALIZE";
+ public static final String ACTION_USER_FOREGROUND =
+ "android.intent.action.USER_FOREGROUND";
+ public static final String ACTION_USER_BACKGROUND =
+ "android.intent.action.USER_BACKGROUND";
+ public static final String ACTION_USER_ADDED =
+ "android.intent.action.USER_ADDED";
+ public static final String ACTION_USER_STARTED =
+ "android.intent.action.USER_STARTED";
+ public static final String ACTION_USER_STARTING =
+ "android.intent.action.USER_STARTING";
+ public static final String ACTION_USER_STOPPING =
+ "android.intent.action.USER_STOPPING";
+ public static final String ACTION_USER_STOPPED =
+ "android.intent.action.USER_STOPPED";
+ public static final String ACTION_USER_REMOVED =
+ "android.intent.action.USER_REMOVED";
+ public static final String ACTION_USER_SWITCHED =
+ "android.intent.action.USER_SWITCHED";
+ public static final String ACTION_USER_UNLOCKED = "android.intent.action.USER_UNLOCKED";
+ public static final String ACTION_USER_INFO_CHANGED =
+ "android.intent.action.USER_INFO_CHANGED";
+ public static final String ACTION_MANAGED_PROFILE_ADDED =
+ "android.intent.action.MANAGED_PROFILE_ADDED";
+ public static final String ACTION_MANAGED_PROFILE_REMOVED =
+ "android.intent.action.MANAGED_PROFILE_REMOVED";
+ public static final String ACTION_MANAGED_PROFILE_UNLOCKED =
+ "android.intent.action.MANAGED_PROFILE_UNLOCKED";
+ public static final String ACTION_MANAGED_PROFILE_AVAILABLE =
+ "android.intent.action.MANAGED_PROFILE_AVAILABLE";
+ public static final String ACTION_MANAGED_PROFILE_UNAVAILABLE =
+ "android.intent.action.MANAGED_PROFILE_UNAVAILABLE";
+ public static final String ACTION_PROFILE_ACCESSIBLE =
+ "android.intent.action.PROFILE_ACCESSIBLE";
+ public static final String ACTION_PROFILE_INACCESSIBLE =
+ "android.intent.action.PROFILE_INACCESSIBLE";
+ public static final String ACTION_DEVICE_LOCKED_CHANGED =
+ "android.intent.action.DEVICE_LOCKED_CHANGED";
+ public static final String ACTION_QUICK_CLOCK =
+ "android.intent.action.QUICK_CLOCK";
+ public static final String ACTION_SHOW_BRIGHTNESS_DIALOG =
+ "com.android.intent.action.SHOW_BRIGHTNESS_DIALOG";
+ public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
+ public static final String ACTION_MEDIA_RESOURCE_GRANTED =
+ "android.intent.action.MEDIA_RESOURCE_GRANTED";
+ public static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+ public static final String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
+ public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";
+ public static final String
+ ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+ public static final String ACTION_TRANSLATE = "android.intent.action.TRANSLATE";
+ public static final String ACTION_DEFINE = "android.intent.action.DEFINE";
+ public static final String
+ ACTION_DYNAMIC_SENSOR_CHANGED = "android.intent.action.DYNAMIC_SENSOR_CHANGED";
+ @Deprecated
+ public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
+ public static final String ACTION_MASTER_CLEAR_NOTIFICATION
+ = "android.intent.action.MASTER_CLEAR_NOTIFICATION";
+ @Deprecated
+ public static final String EXTRA_FORCE_MASTER_CLEAR =
+ "android.intent.extra.FORCE_MASTER_CLEAR";
+ public static final String ACTION_FACTORY_RESET = "android.intent.action.FACTORY_RESET";
+ public static final String EXTRA_FORCE_FACTORY_RESET =
+ "android.intent.extra.FORCE_FACTORY_RESET";
+ public static final String ACTION_SETTING_RESTORED = "android.os.action.SETTING_RESTORED";
+ public static final String EXTRA_SETTING_NAME = "setting_name";
+ public static final String EXTRA_SETTING_PREVIOUS_VALUE = "previous_value";
+ public static final String EXTRA_SETTING_NEW_VALUE = "new_value";
+ public static final String EXTRA_SETTING_RESTORED_FROM_SDK_INT = "restored_from_sdk_int";
+ public static final String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT";
+ @Deprecated
+ public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
+ public static final String EXTRA_SIM_STATE = "ss";
+ public static final String SIM_STATE_UNKNOWN = "UNKNOWN";
+ public static final String SIM_STATE_NOT_READY = "NOT_READY";
+ public static final String SIM_STATE_ABSENT = "ABSENT";
+ public static final String SIM_STATE_PRESENT = "PRESENT";
+ static public final String SIM_STATE_CARD_IO_ERROR = "CARD_IO_ERROR";
+ static public final String SIM_STATE_CARD_RESTRICTED = "CARD_RESTRICTED";
+ public static final String SIM_STATE_LOCKED = "LOCKED";
+ public static final String SIM_STATE_READY = "READY";
+ public static final String SIM_STATE_IMSI = "IMSI";
+ public static final String SIM_STATE_LOADED = "LOADED";
+ public static final String EXTRA_SIM_LOCKED_REASON = "reason";
+ public static final String SIM_LOCKED_ON_PIN = "PIN";
+ public static final String SIM_LOCKED_ON_PUK = "PUK";
+ public static final String SIM_LOCKED_NETWORK = "NETWORK";
+ public static final String SIM_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
+ public static final String EXTRA_REBROADCAST_ON_UNLOCK = "rebroadcastOnUnlock";
+ @Deprecated
+ public static final String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE";
+ public static final String ACTION_LOAD_DATA = "android.intent.action.LOAD_DATA";
+ @Deprecated
+ public static final String EXTRA_VOICE_REG_STATE = "voiceRegState";
+ @Deprecated
+ public static final String EXTRA_DATA_REG_STATE = "dataRegState";
+ @Deprecated
+ public static final String EXTRA_VOICE_ROAMING_TYPE = "voiceRoamingType";
+ @Deprecated
+ public static final String EXTRA_DATA_ROAMING_TYPE = "dataRoamingType";
+ @Deprecated
+ public static final String EXTRA_OPERATOR_ALPHA_LONG = "operator-alpha-long";
+ @Deprecated
+ public static final String EXTRA_OPERATOR_ALPHA_SHORT = "operator-alpha-short";
+ @Deprecated
+ public static final String EXTRA_OPERATOR_NUMERIC = "operator-numeric";
+ @Deprecated
+ public static final String EXTRA_DATA_OPERATOR_ALPHA_LONG = "data-operator-alpha-long";
+ @Deprecated
+ public static final String EXTRA_DATA_OPERATOR_ALPHA_SHORT = "data-operator-alpha-short";
+ @Deprecated
+ public static final String EXTRA_DATA_OPERATOR_NUMERIC = "data-operator-numeric";
+ @Deprecated
+ public static final String EXTRA_MANUAL = "manual";
+ @Deprecated
+ public static final String EXTRA_VOICE_RADIO_TECH = "radioTechnology";
+ @Deprecated
+ public static final String EXTRA_DATA_RADIO_TECH = "dataRadioTechnology";
+ @Deprecated
+ public static final String EXTRA_CSS_INDICATOR = "cssIndicator";
+ @Deprecated
+ public static final String EXTRA_NETWORK_ID = "networkId";
+ @Deprecated
+ public static final String EXTRA_SYSTEM_ID = "systemId";
+ @Deprecated
+ public static final String EXTRA_CDMA_ROAMING_INDICATOR = "cdmaRoamingIndicator";
+ @Deprecated
+ public static final String EXTRA_CDMA_DEFAULT_ROAMING_INDICATOR = "cdmaDefaultRoamingIndicator";
+ @Deprecated
+ public static final String EXTRA_EMERGENCY_ONLY = "emergencyOnly";
+ @Deprecated
+ public static final String EXTRA_IS_DATA_ROAMING_FROM_REGISTRATION =
+ "isDataRoamingFromRegistration";
+ @Deprecated
+ public static final String EXTRA_IS_USING_CARRIER_AGGREGATION = "isUsingCarrierAggregation";
+ @Deprecated
+ public static final String EXTRA_LTE_EARFCN_RSRP_BOOST = "LteEarfcnRsrpBoost";
+ public static final String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
+ public static final String EXTRA_PROCESS_TEXT_READONLY =
+ "android.intent.extra.PROCESS_TEXT_READONLY";
+ public static final String ACTION_THERMAL_EVENT = "android.intent.action.THERMAL_EVENT";
+ public static final String EXTRA_THERMAL_STATE = "android.intent.extra.THERMAL_STATE";
+ public static final int EXTRA_THERMAL_STATE_NORMAL = 0;
+ public static final int EXTRA_THERMAL_STATE_WARNING = 1;
+ public static final int EXTRA_THERMAL_STATE_EXCEEDED = 2;
+ public static final String ACTION_DOCK_IDLE = "android.intent.action.DOCK_IDLE";
+ public static final String ACTION_DOCK_ACTIVE = "android.intent.action.DOCK_ACTIVE";
+ public static final String ACTION_DEVICE_CUSTOMIZATION_READY =
+ "android.intent.action.DEVICE_CUSTOMIZATION_READY";
+ public static final String ACTION_VIEW_LOCUS = "android.intent.action.VIEW_LOCUS";
+ public static final String ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION =
+ "android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION";
+ public static final String CATEGORY_DEFAULT = "android.intent.category.DEFAULT";
+ public static final String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE";
+ public static final String CATEGORY_VOICE = "android.intent.category.VOICE";
+ public static final String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE";
+ public static final String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE";
+ public static final String CATEGORY_TAB = "android.intent.category.TAB";
+ public static final String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
+ public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+ public static final String CATEGORY_CAR_LAUNCHER = "android.intent.category.CAR_LAUNCHER";
+ public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
+ public static final String CATEGORY_INFO = "android.intent.category.INFO";
+ public static final String CATEGORY_HOME = "android.intent.category.HOME";
+ public static final String CATEGORY_HOME_MAIN = "android.intent.category.HOME_MAIN";
+ public static final String CATEGORY_SECONDARY_HOME = "android.intent.category.SECONDARY_HOME";
+ public static final String CATEGORY_SETUP_WIZARD = "android.intent.category.SETUP_WIZARD";
+ public static final String CATEGORY_LAUNCHER_APP = "android.intent.category.LAUNCHER_APP";
+ public static final String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE";
+ public static final String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE";
+ public static final String CATEGORY_EMBED = "android.intent.category.EMBED";
+ public static final String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET";
+ public static final String CATEGORY_MONKEY = "android.intent.category.MONKEY";
+ public static final String CATEGORY_TEST = "android.intent.category.TEST";
+ public static final String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
+ public static final String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE";
+ public static final String CATEGORY_OPENABLE = "android.intent.category.OPENABLE";
+ public static final String CATEGORY_TYPED_OPENABLE =
+ "android.intent.category.TYPED_OPENABLE";
+ public static final String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST =
+ "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST";
+ public static final String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK";
+ public static final String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK";
+ public static final String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK";
+ public static final String CATEGORY_HE_DESK_DOCK = "android.intent.category.HE_DESK_DOCK";
+ public static final String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
+ public static final String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
+ public static final String CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET =
+ "android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET";
+ public static final String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER";
+ public static final String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR";
+ public static final String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR";
+ public static final String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS";
+ public static final String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL";
+ public static final String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY";
+ public static final String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS";
+ public static final String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING";
+ public static final String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC";
+ public static final String CATEGORY_APP_FILES = "android.intent.category.APP_FILES";
+ public static final String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
+ public static final String EXTRA_TEXT = "android.intent.extra.TEXT";
+ public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+ public static final String EXTRA_STREAM = "android.intent.extra.STREAM";
+ public static final String EXTRA_EMAIL = "android.intent.extra.EMAIL";
+ public static final String EXTRA_CC = "android.intent.extra.CC";
+ public static final String EXTRA_BCC = "android.intent.extra.BCC";
+ public static final String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
+ public static final String EXTRA_INTENT = "android.intent.extra.INTENT";
+ public static final String EXTRA_USER_ID = "android.intent.extra.USER_ID";
+ public static final String EXTRA_TASK_ID = "android.intent.extra.TASK_ID";
+ public static final String EXTRA_ATTRIBUTION_TAGS = "android.intent.extra.ATTRIBUTION_TAGS";
+ public static final String EXTRA_START_TIME = "android.intent.extra.START_TIME";
+ public static final String EXTRA_END_TIME = "android.intent.extra.END_TIME";
+ public static final String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
+ public static final String EXTRA_EXCLUDE_COMPONENTS
+ = "android.intent.extra.EXCLUDE_COMPONENTS";
+ public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
+ public static final String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER
+ = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
+ public static final String EXTRA_CONTENT_ANNOTATIONS
+ = "android.intent.extra.CONTENT_ANNOTATIONS";
+ public static final String EXTRA_RESULT_RECEIVER
+ = "android.intent.extra.RESULT_RECEIVER";
+ public static final String EXTRA_TITLE = "android.intent.extra.TITLE";
+ public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
+ public static final String EXTRA_INSTANT_APP_SUCCESS =
+ "android.intent.extra.INSTANT_APP_SUCCESS";
+ public static final String EXTRA_INSTANT_APP_FAILURE =
+ "android.intent.extra.INSTANT_APP_FAILURE";
+ public static final String EXTRA_INSTANT_APP_HOSTNAME =
+ "android.intent.extra.INSTANT_APP_HOSTNAME";
+ public static final String EXTRA_INSTANT_APP_TOKEN =
+ "android.intent.extra.INSTANT_APP_TOKEN";
+ public static final String EXTRA_INSTANT_APP_ACTION = "android.intent.extra.INSTANT_APP_ACTION";
+ public static final String EXTRA_INSTANT_APP_BUNDLES =
+ "android.intent.extra.INSTANT_APP_BUNDLES";
+ public static final String EXTRA_INSTANT_APP_EXTRAS =
+ "android.intent.extra.INSTANT_APP_EXTRAS";
+ public static final String EXTRA_UNKNOWN_INSTANT_APP =
+ "android.intent.extra.UNKNOWN_INSTANT_APP";
+ @Deprecated
+ public static final String EXTRA_VERSION_CODE = "android.intent.extra.VERSION_CODE";
+ public static final String EXTRA_LONG_VERSION_CODE = "android.intent.extra.LONG_VERSION_CODE";
+ public static final String EXTRA_CALLING_PACKAGE
+ = "android.intent.extra.CALLING_PACKAGE";
+ public static final String EXTRA_VERIFICATION_BUNDLE
+ = "android.intent.extra.VERIFICATION_BUNDLE";
+ public static final String EXTRA_REPLACEMENT_EXTRAS =
+ "android.intent.extra.REPLACEMENT_EXTRAS";
+ public static final String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER =
+ "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
+ public static final String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
+ public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
+ public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM";
+ public static final String EXTRA_USER_REQUESTED_SHUTDOWN =
+ "android.intent.extra.USER_REQUESTED_SHUTDOWN";
+ public static final String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
+ public static final String EXTRA_USER_INITIATED = "android.intent.extra.USER_INITIATED";
+ public static final String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
+ public static final String EXTRA_UID = "android.intent.extra.UID";
+ public static final String EXTRA_PACKAGES = "android.intent.extra.PACKAGES";
+ public static final String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
+ public static final String EXTRA_REMOVED_FOR_ALL_USERS
+ = "android.intent.extra.REMOVED_FOR_ALL_USERS";
+ public static final String EXTRA_REPLACING = "android.intent.extra.REPLACING";
+ public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
+ public static final String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE";
+ public static final int EXTRA_DOCK_STATE_UNDOCKED = 0;
+ public static final int EXTRA_DOCK_STATE_DESK = 1;
+ public static final int EXTRA_DOCK_STATE_CAR = 2;
+ public static final int EXTRA_DOCK_STATE_LE_DESK = 3;
+ public static final int EXTRA_DOCK_STATE_HE_DESK = 4;
+ public static final String METADATA_DOCK_HOME = "android.dock_home";
+ public static final String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
+ public static final String EXTRA_REMOTE_INTENT_TOKEN =
+ "android.intent.extra.remote_intent_token";
+ @Deprecated public static final String EXTRA_CHANGED_COMPONENT_NAME =
+ "android.intent.extra.changed_component_name";
+ public static final String EXTRA_CHANGED_COMPONENT_NAME_LIST =
+ "android.intent.extra.changed_component_name_list";
+ public static final String EXTRA_CHANGED_PACKAGE_LIST =
+ "android.intent.extra.changed_package_list";
+ public static final String EXTRA_CHANGED_UID_LIST =
+ "android.intent.extra.changed_uid_list";
+ public static final String EXTRA_DISTRACTION_RESTRICTIONS =
+ "android.intent.extra.distraction_restrictions";
+ public static final String EXTRA_CLIENT_LABEL =
+ "android.intent.extra.client_label";
+ public static final String EXTRA_CLIENT_INTENT =
+ "android.intent.extra.client_intent";
+ public static final String EXTRA_LOCAL_ONLY =
+ "android.intent.extra.LOCAL_ONLY";
+ public static final String EXTRA_ALLOW_MULTIPLE =
+ "android.intent.extra.ALLOW_MULTIPLE";
+ public static final String EXTRA_USER_HANDLE =
+ "android.intent.extra.user_handle";
+ public static final String EXTRA_USER =
+ "android.intent.extra.USER";
+ public static final String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list";
+ public static final String EXTRA_RESTRICTIONS_BUNDLE =
+ "android.intent.extra.restrictions_bundle";
+ public static final String EXTRA_RESTRICTIONS_INTENT =
+ "android.intent.extra.restrictions_intent";
+ public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
+ public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
+ = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
+ public static final String EXTRA_TIME = "android.intent.extra.TIME";
+ @SuppressLint("ActionValue")
+ public static final String EXTRA_TIMEZONE = "time-zone";
+ public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT =
+ "android.intent.extra.TIME_PREF_24_HOUR_FORMAT";
+ public static final int EXTRA_TIME_PREF_VALUE_USE_12_HOUR = 0;
+ public static final int EXTRA_TIME_PREF_VALUE_USE_24_HOUR = 1;
+ public static final int EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT = 2;
+ public static final String EXTRA_REASON = "android.intent.extra.REASON";
+ public static final String EXTRA_WIPE_EXTERNAL_STORAGE = "android.intent.extra.WIPE_EXTERNAL_STORAGE";
+ public static final String EXTRA_WIPE_ESIMS = "com.android.internal.intent.extra.WIPE_ESIMS";
+ public static final String EXTRA_SIM_ACTIVATION_RESPONSE =
+ "android.intent.extra.SIM_ACTIVATION_RESPONSE";
+ public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
+ @Deprecated
+ public static final String EXTRA_QUICK_VIEW_ADVANCED =
+ "android.intent.extra.QUICK_VIEW_ADVANCED";
+ public static final String EXTRA_QUICK_VIEW_FEATURES =
+ "android.intent.extra.QUICK_VIEW_FEATURES";
+ public static final String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
+ public static final String EXTRA_CONTENT_QUERY = "android.intent.extra.CONTENT_QUERY";
+ public static final String EXTRA_MEDIA_RESOURCE_TYPE =
+ "android.intent.extra.MEDIA_RESOURCE_TYPE";
+ public static final String EXTRA_AUTO_LAUNCH_SINGLE_CHOICE =
+ "android.intent.extra.AUTO_LAUNCH_SINGLE_CHOICE";
+ public static final int EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC = 0;
+ public static final int EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC = 1;
+ public static final String EXTRA_LOCUS_ID = "android.intent.extra.LOCUS_ID";
+ public static final String EXTRA_VISIBILITY_ALLOW_LIST =
+ "android.intent.extra.VISIBILITY_ALLOW_LIST";
+ @IntDef(flag = true, value = {
+ FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION,
+ FLAG_GRANT_PERSISTABLE_URI_PERMISSION, FLAG_GRANT_PREFIX_URI_PERMISSION })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface GrantUriMode {}
+ @IntDef(flag = true, value = {
+ FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AccessUriMode {}
+ public static boolean isAccessUriMode(int modeFlags) {
+ return false;
+ }
+ @IntDef(flag = true, value = {
+ FLAG_GRANT_READ_URI_PERMISSION,
+ FLAG_GRANT_WRITE_URI_PERMISSION,
+ FLAG_FROM_BACKGROUND,
+ FLAG_DEBUG_LOG_RESOLUTION,
+ FLAG_EXCLUDE_STOPPED_PACKAGES,
+ FLAG_INCLUDE_STOPPED_PACKAGES,
+ FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
+ FLAG_GRANT_PREFIX_URI_PERMISSION,
+ FLAG_DEBUG_TRIAGED_MISSING,
+ FLAG_IGNORE_EPHEMERAL,
+ FLAG_ACTIVITY_MATCH_EXTERNAL,
+ FLAG_ACTIVITY_NO_HISTORY,
+ FLAG_ACTIVITY_SINGLE_TOP,
+ FLAG_ACTIVITY_NEW_TASK,
+ FLAG_ACTIVITY_MULTIPLE_TASK,
+ FLAG_ACTIVITY_CLEAR_TOP,
+ FLAG_ACTIVITY_FORWARD_RESULT,
+ FLAG_ACTIVITY_PREVIOUS_IS_TOP,
+ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
+ FLAG_ACTIVITY_BROUGHT_TO_FRONT,
+ FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
+ FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,
+ FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+ FLAG_ACTIVITY_NEW_DOCUMENT,
+ FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+ FLAG_ACTIVITY_NO_USER_ACTION,
+ FLAG_ACTIVITY_REORDER_TO_FRONT,
+ FLAG_ACTIVITY_NO_ANIMATION,
+ FLAG_ACTIVITY_CLEAR_TASK,
+ FLAG_ACTIVITY_TASK_ON_HOME,
+ FLAG_ACTIVITY_RETAIN_IN_RECENTS,
+ FLAG_ACTIVITY_LAUNCH_ADJACENT,
+ FLAG_ACTIVITY_REQUIRE_NON_BROWSER,
+ FLAG_ACTIVITY_REQUIRE_DEFAULT,
+ FLAG_RECEIVER_REGISTERED_ONLY,
+ FLAG_RECEIVER_REPLACE_PENDING,
+ FLAG_RECEIVER_FOREGROUND,
+ FLAG_RECEIVER_NO_ABORT,
+ FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT,
+ FLAG_RECEIVER_BOOT_UPGRADE,
+ FLAG_RECEIVER_INCLUDE_BACKGROUND,
+ FLAG_RECEIVER_EXCLUDE_BACKGROUND,
+ FLAG_RECEIVER_FROM_SHELL,
+ FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS,
+ FLAG_RECEIVER_OFFLOAD,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Flags {}
+ @IntDef(flag = true, value = {
+ FLAG_FROM_BACKGROUND,
+ FLAG_DEBUG_LOG_RESOLUTION,
+ FLAG_EXCLUDE_STOPPED_PACKAGES,
+ FLAG_INCLUDE_STOPPED_PACKAGES,
+ FLAG_DEBUG_TRIAGED_MISSING,
+ FLAG_IGNORE_EPHEMERAL,
+ FLAG_ACTIVITY_MATCH_EXTERNAL,
+ FLAG_ACTIVITY_NO_HISTORY,
+ FLAG_ACTIVITY_SINGLE_TOP,
+ FLAG_ACTIVITY_NEW_TASK,
+ FLAG_ACTIVITY_MULTIPLE_TASK,
+ FLAG_ACTIVITY_CLEAR_TOP,
+ FLAG_ACTIVITY_FORWARD_RESULT,
+ FLAG_ACTIVITY_PREVIOUS_IS_TOP,
+ FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
+ FLAG_ACTIVITY_BROUGHT_TO_FRONT,
+ FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
+ FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,
+ FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+ FLAG_ACTIVITY_NEW_DOCUMENT,
+ FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+ FLAG_ACTIVITY_NO_USER_ACTION,
+ FLAG_ACTIVITY_REORDER_TO_FRONT,
+ FLAG_ACTIVITY_NO_ANIMATION,
+ FLAG_ACTIVITY_CLEAR_TASK,
+ FLAG_ACTIVITY_TASK_ON_HOME,
+ FLAG_ACTIVITY_RETAIN_IN_RECENTS,
+ FLAG_ACTIVITY_LAUNCH_ADJACENT,
+ FLAG_RECEIVER_REGISTERED_ONLY,
+ FLAG_RECEIVER_REPLACE_PENDING,
+ FLAG_RECEIVER_FOREGROUND,
+ FLAG_RECEIVER_NO_ABORT,
+ FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT,
+ FLAG_RECEIVER_BOOT_UPGRADE,
+ FLAG_RECEIVER_INCLUDE_BACKGROUND,
+ FLAG_RECEIVER_EXCLUDE_BACKGROUND,
+ FLAG_RECEIVER_FROM_SHELL,
+ FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS,
+ FLAG_RECEIVER_OFFLOAD,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MutableFlags {}
+ public static final int FLAG_GRANT_READ_URI_PERMISSION = 0x00000001;
+ public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 0x00000002;
+ public static final int FLAG_FROM_BACKGROUND = 0x00000004;
+ public static final int FLAG_DEBUG_LOG_RESOLUTION = 0x00000008;
+ public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 0x00000010;
+ public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020;
+ public static final int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 0x00000040;
+ public static final int FLAG_GRANT_PREFIX_URI_PERMISSION = 0x00000080;
+ public static final int FLAG_DIRECT_BOOT_AUTO = 0x00000100;
+ @Deprecated
+ public static final int FLAG_DEBUG_TRIAGED_MISSING = FLAG_DIRECT_BOOT_AUTO;
+ public static final int FLAG_IGNORE_EPHEMERAL = 0x00000200;
+ public static final int FLAG_ACTIVITY_NO_HISTORY = 0x40000000;
+ public static final int FLAG_ACTIVITY_SINGLE_TOP = 0x20000000;
+ public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
+ public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
+ public static final int FLAG_ACTIVITY_CLEAR_TOP = 0x04000000;
+ public static final int FLAG_ACTIVITY_FORWARD_RESULT = 0x02000000;
+ public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 0x01000000;
+ public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 0x00800000;
+ public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 0x00400000;
+ public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000;
+ public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 0x00100000;
+ @Deprecated
+ public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
+ public static final int FLAG_ACTIVITY_NEW_DOCUMENT = FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
+ public static final int FLAG_ACTIVITY_NO_USER_ACTION = 0x00040000;
+ public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 0X00020000;
+ public static final int FLAG_ACTIVITY_NO_ANIMATION = 0X00010000;
+ public static final int FLAG_ACTIVITY_CLEAR_TASK = 0X00008000;
+ public static final int FLAG_ACTIVITY_TASK_ON_HOME = 0X00004000;
+ public static final int FLAG_ACTIVITY_RETAIN_IN_RECENTS = 0x00002000;
+ public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000;
+ public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 0x00000800;
+ public static final int FLAG_ACTIVITY_REQUIRE_NON_BROWSER = 0x00000400;
+ public static final int FLAG_ACTIVITY_REQUIRE_DEFAULT = 0x00000200;
+ public static final int FLAG_RECEIVER_REGISTERED_ONLY = 0x40000000;
+ public static final int FLAG_RECEIVER_REPLACE_PENDING = 0x20000000;
+ public static final int FLAG_RECEIVER_FOREGROUND = 0x10000000;
+ public static final int FLAG_RECEIVER_OFFLOAD = 0x80000000;
+ public static final int FLAG_RECEIVER_NO_ABORT = 0x08000000;
+ public static final int FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT = 0x04000000;
+ public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x02000000;
+ public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;
+ public static final int FLAG_RECEIVER_EXCLUDE_BACKGROUND = 0x00800000;
+ public static final int FLAG_RECEIVER_FROM_SHELL = 0x00400000;
+ public static final int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 0x00200000;
+ public static final int IMMUTABLE_FLAGS = FLAG_GRANT_READ_URI_PERMISSION
+ | FLAG_GRANT_WRITE_URI_PERMISSION | FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+ | FLAG_GRANT_PREFIX_URI_PERMISSION;
+ private static final int LOCAL_FLAG_FROM_COPY = 1 << 0;
+ private static final int LOCAL_FLAG_FROM_PARCEL = 1 << 1;
+ private static final int LOCAL_FLAG_FROM_PROTECTED_COMPONENT = 1 << 2;
+ private static final int LOCAL_FLAG_UNFILTERED_EXTRAS = 1 << 3;
+ private static final int LOCAL_FLAG_FROM_URI = 1 << 4;
+ @IntDef(flag = true, value = {
+ URI_ALLOW_UNSAFE,
+ URI_ANDROID_APP_SCHEME,
+ URI_INTENT_SCHEME,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface UriFlags {}
+ public static final int URI_INTENT_SCHEME = 1<<0;
+ public static final int URI_ANDROID_APP_SCHEME = 1<<1;
+ public static final int URI_ALLOW_UNSAFE = 1<<2;
+
+ private static final int COPY_MODE_ALL = 0;
+ private static final int COPY_MODE_FILTER = 1;
+ private static final int COPY_MODE_HISTORY = 2;
+ @IntDef(value = {
+ COPY_MODE_ALL,
+ COPY_MODE_FILTER,
+ COPY_MODE_HISTORY
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CopyMode {}
+ public Intent() {
+ }
+ public Intent(Intent o) {
+ this(o, COPY_MODE_ALL);
+ }
+ private Intent(Intent o, @CopyMode int copyMode) {
+ }
+ @Override
+ public Object clone() {
+ return null;
+ }
+ public Intent cloneFilter() {
+ return null;
+ }
+ public Intent(String action) {
+ setAction(action);
+ }
+ public Intent(String action, Uri uri) {
+ }
+ public Intent(Context packageContext, Class> cls) {
+
+ }
+ public Intent(String action, Uri uri,
+ Context packageContext, Class> cls) {
+ }
+ public static Intent makeMainActivity(ComponentName mainActivity) {
+ return null;
+ }
+ public static Intent makeMainSelectorActivity(String selectorAction,
+ String selectorCategory) {
+ return null;
+ }
+ public static Intent makeRestartActivityTask(ComponentName mainActivity) {
+ return null;
+ }
+ @Deprecated
+ public static Intent getIntent(String uri) throws URISyntaxException {
+ return null;
+ }
+ public static Intent parseUri(String uri, @UriFlags int flags) throws URISyntaxException {
+ return null;
+ }
+ private static Intent parseUriInternal(String uri, @UriFlags int flags)
+ throws URISyntaxException {
+ return null;
+ }
+ public static Intent getIntentOld(String uri) throws URISyntaxException {
+ return null;
+ }
+ private static Intent getIntentOld(String uri, int flags) throws URISyntaxException {
+ return null;
+ }
+ public interface CommandOptionHandler {
+ }
+ public static void printIntentArgsHelp(PrintWriter pw, String prefix) {
+
+ }
+ public String getAction() {
+ return null;
+ }
+ public Uri getData() {
+ return null;
+ }
+ public String getDataString() {
+ return null;
+ }
+ public String getScheme() {
+ return null;
+ }
+ public String getType() {
+ return null;
+ }
+ public String resolveType(Context context) {
+ return null;
+ }
+ public String resolveType(ContentResolver resolver) {
+ return null;
+ }
+ public Set getCategories() {
+ return null;
+ }
+ @Deprecated
+ public Object getExtra(String name) {
+ return null;
+ }
+ public boolean getBooleanExtra(String name, boolean defaultValue) {
+ return false;
+ }
+ public byte getByteExtra(String name, byte defaultValue) {
+ return 0;
+ }
+ public short getShortExtra(String name, short defaultValue) {
+ return 0;
+ }
+ public char getCharExtra(String name, char defaultValue) {
+ return 0;
+ }
+ public int getIntExtra(String name, int defaultValue) {
+ return 0;
+ }
+ public long getLongExtra(String name, long defaultValue) {
+ return 0;
+ }
+ public float getFloatExtra(String name, float defaultValue) {
+ return 0;
+ }
+ public double getDoubleExtra(String name, double defaultValue) {
+ return 0;
+ }
+ public String getStringExtra(String name) {
+ return null;
+ }
+ public CharSequence getCharSequenceExtra(String name) {
+ return null;
+ }
+ public T getParcelableExtra(String name) {
+ return null;
+ }
+ public Parcelable[] getParcelableArrayExtra(String name) {
+ return null;
+ }
+ public ArrayList getParcelableArrayListExtra(String name) {
+ return null;
+ }
+ public Serializable getSerializableExtra(String name) {
+ return null;
+ }
+ public ArrayList getIntegerArrayListExtra(String name) {
+ return null;
+ }
+ public ArrayList getStringArrayListExtra(String name) {
+ return null;
+ }
+ public ArrayList getCharSequenceArrayListExtra(String name) {
+ return null;
+ }
+ public boolean[] getBooleanArrayExtra(String name) {
+ return null;
+ }
+ public byte[] getByteArrayExtra(String name) {
+ return null;
+ }
+ public short[] getShortArrayExtra(String name) {
+ return null;
+ }
+ public char[] getCharArrayExtra(String name) {
+ return null;
+ }
+ public int[] getIntArrayExtra(String name) {
+ return null;
+ }
+ public long[] getLongArrayExtra(String name) {
+ return null;
+ }
+ public float[] getFloatArrayExtra(String name) {
+ return null;
+ }
+ public double[] getDoubleArrayExtra(String name) {
+ return null;
+ }
+ public String[] getStringArrayExtra(String name) {
+ return null;
+ }
+ public CharSequence[] getCharSequenceArrayExtra(String name) {
+ return null;
+ }
+ public Bundle getBundleExtra(String name) {
+ return null;
+ }
+ @Deprecated
+ public IBinder getIBinderExtra(String name) {
+ return null;
+ }
+ @Deprecated
+ public Object getExtra(String name, Object defaultValue) {
+ Object result = defaultValue;
+ if (mExtras != null) {
+ Object result2 = mExtras.get(name);
+ if (result2 != null) {
+ result = result2;
+ }
+ }
+ return null;
+ }
+ public Bundle getExtras() {
+ return null;
+ }
+ public void removeUnsafeExtras() {
+ }
+ public boolean canStripForHistory() {
+ return false;
+ }
+ public Intent maybeStripForHistory() {
+ // TODO Scan and remove possibly heavy instances like Bitmaps from unparcelled extras?
+ if (!canStripForHistory()) {
+ return null;
+ }
+ return null;
+ }
+ public @Flags int getFlags() {
+ return 0;
+ }
+ public boolean isExcludingStopped() {
+ return false;
+ }
+ public String getPackage() {
+ return null;
+ }
+ public ComponentName getComponent() {
+ return null;
+ }
+ public Rect getSourceBounds() {
+ return null;
+ }
+ public ComponentName resolveActivity(PackageManager pm) {
+ return null;
+ }
+ public ActivityInfo resolveActivityInfo(PackageManager pm,
+ int flags) {
+ return null;
+ }
+ public ComponentName resolveSystemService(PackageManager pm,
+ int flags) {
+ return null;
+ }
+ public Intent setAction(String action) {
+ return null;
+ }
+ public Intent setData(Uri data) {
+ return null;
+ }
+ public Intent setDataAndNormalize(Uri data) {
+ return null;
+ }
+ public Intent setType(String type) {
+ return null;
+ }
+ public Intent setTypeAndNormalize(String type) {
+ return null;
+ }
+ public Intent setDataAndType(Uri data, String type) {
+ return null;
+ }
+ public Intent setDataAndTypeAndNormalize(Uri data, String type) {
+ return null;
+ }
+ public Intent setIdentifier(String identifier) {
+ return null;
+ }
+ public Intent addCategory(String category) {
+ return null;
+ }
+ public void removeCategory(String category) {
+
+ }
+ public void setSelector(Intent selector) {
+
+ }
+ public void setClipData(ClipData clip) {
+
+ }
+ public void prepareToLeaveUser(int userId) {
+ }
+ private Bundle mExtras = null;
+ public Intent putExtra(String name, boolean value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putBoolean(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, byte value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putByte(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, char value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putChar(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, short value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putShort(name, value);
+ return null;
+ }
+ public Intent putExtraInt(String name, int value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putInt(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, int value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putInt(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, long value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putLong(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, float value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putFloat(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, double value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putDouble(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, String value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putString(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, CharSequence value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putCharSequence(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, Parcelable value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putParcelable(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, Parcelable[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putParcelableArray(name, value);
+ return null;
+ }
+ public Intent putParcelableArrayListExtra(String name,
+ ArrayList extends Parcelable> value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putParcelableArrayList(name, value);
+ return null;
+ }
+ public Intent putIntegerArrayListExtra(String name,
+ ArrayList value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putIntegerArrayList(name, value);
+ return null;
+ }
+ public Intent putStringArrayListExtra(String name, ArrayList value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putStringArrayList(name, value);
+ return null;
+ }
+ public Intent putCharSequenceArrayListExtra(String name,
+ ArrayList value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putCharSequenceArrayList(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, Serializable value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putSerializable(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, boolean[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putBooleanArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, byte[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putByteArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, short[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putShortArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, char[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putCharArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, int[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putIntArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, long[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putLongArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, float[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putFloatArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, double[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putDoubleArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, String[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putStringArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, CharSequence[] value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putCharSequenceArray(name, value);
+ return null;
+ }
+ public Intent putExtra(String name, Bundle value) {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ mExtras.putBundle(name, value);
+ return null;
+ }
+ @Deprecated
+ public Intent putExtra(String name, IBinder value) {
+ return null;
+ }
+ public Intent putExtras(Intent src) {
+ return null;
+ }
+ public Intent putExtras(Bundle extras) {
+ return null;
+ }
+ public Intent replaceExtras(Intent src) {
+ return null;
+ }
+ public Intent replaceExtras(Bundle extras) {
+ mExtras = extras != null ? new Bundle(extras) : null;
+ return null;
+ }
+ public void removeExtra(String name) {
+ if (mExtras != null) {
+ mExtras.remove(name);
+ if (mExtras.size() == 0) {
+ mExtras = null;
+ }
+ }
+ }
+ public Intent setFlags(@Flags int flags) {
+ return null;
+ }
+ public Intent addFlags(@Flags int flags) {
+ return null;
+ }
+ public void removeFlags(@Flags int flags) {
+
+ }
+ public Intent setPackage(String packageName) {
+ return null;
+ }
+ public Intent setComponent(ComponentName component) {
+ return null;
+ }
+ public Intent setClassName(Context packageContext,
+ String className) {
+ return null;
+ }
+ public Intent setClassName(String packageName, String className) {
+ return null;
+ }
+ public Intent setClass(Context packageContext, Class> cls) {
+ return null;
+ }
+ public void setSourceBounds(Rect r) {
+
+ }
+ @IntDef(flag = true, value = {
+ FILL_IN_ACTION,
+ FILL_IN_DATA,
+ FILL_IN_CATEGORIES,
+ FILL_IN_COMPONENT,
+ FILL_IN_PACKAGE,
+ FILL_IN_SOURCE_BOUNDS,
+ FILL_IN_SELECTOR,
+ FILL_IN_CLIP_DATA
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FillInFlags {}
+ public static final int FILL_IN_ACTION = 1<<0;
+ public static final int FILL_IN_DATA = 1<<1;
+ public static final int FILL_IN_CATEGORIES = 1<<2;
+ public static final int FILL_IN_COMPONENT = 1<<3;
+ public static final int FILL_IN_PACKAGE = 1<<4;
+ public static final int FILL_IN_SOURCE_BOUNDS = 1<<5;
+ public static final int FILL_IN_SELECTOR = 1<<6;
+ public static final int FILL_IN_CLIP_DATA = 1<<7;
+ public static final int FILL_IN_IDENTIFIER = 1<<8;
+ @FillInFlags
+ public int fillIn(Intent other, @FillInFlags int flags) {
+ return 0;
+ }
+ public static final class FilterComparison {
+ public FilterComparison(Intent intent) {
+ }
+ public Intent getIntent() {
+ return null;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return false;
+ }
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+ }
+ public boolean filterEquals(Intent other) {
+ return false;
+ }
+ private boolean hasPackageEquivalentComponent() {
+ return false;
+ }
+ public int filterHashCode() {
+ return 0;
+ }
+ @Override
+ public String toString() {
+ return null;
+ }
+ public String toInsecureString() {
+ return null;
+ }
+ public String toShortString(boolean secure, boolean comp, boolean extras, boolean clip) {
+ return null;
+ }
+ public void toShortString(StringBuilder b, boolean secure, boolean comp, boolean extras,
+ boolean clip) {
+ }
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, boolean secure, boolean comp,
+ boolean extras, boolean clip) {
+
+ }
+ private void dumpDebugWithoutFieldId(ProtoOutputStream proto, boolean secure, boolean comp,
+ boolean extras, boolean clip) {}
+ @Deprecated
+ public String toURI() {
+ return null;
+ }
+ public String toUri(@UriFlags int flags) {
+ return null;
+ }
+ private void toUriFragment(StringBuilder uri, String scheme, String defAction,
+ String defPackage, int flags) {
+
+ }
+ private void toUriInner(StringBuilder uri, String scheme, String defAction,
+ String defPackage, int flags) {
+
+ }
+ public int describeContents() {
+ return 0;
+ }
+ public void writeToParcel(Parcel out, int flags) {}
+ public static final Creator CREATOR
+ = new Creator() {
+ public Intent createFromParcel(Parcel in) {
+ return null;
+ }
+ public Intent[] newArray(int size) {
+ return null;
+ }
+ };
+ protected Intent(Parcel in) {
+ }
+ public void readFromParcel(Parcel in) {}
+ public static Intent parseIntent(Resources resources,
+ XmlPullParser parser, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+ return null;
+ }
+ public void saveToXml(XmlSerializer out) throws IOException {
+
+ }
+ public static Intent restoreFromXml(XmlPullParser in) throws IOException,
+ XmlPullParserException {
+ return null;
+ }
+ public static String normalizeMimeType(String type) {
+ return null;
+ }
+ public void prepareToLeaveProcess(Context context) {
+
+ }
+ public void prepareToLeaveProcess(boolean leavingPackage) {}
+ public void prepareToEnterProcess(boolean fromProtectedComponent, AttributionSource source) {}
+ public boolean hasWebURI() {
+ return false;
+ }
+ public boolean isWebIntent() {
+ return false;
+ }
+ private boolean isImageCaptureIntent() {
+ return false;
+ }
+ public boolean isImplicitImageCaptureIntent() {
+ return false;
+ }
+ public void fixUris(int contentUserHint) {
+ }
+ public boolean migrateExtraStreamToClipData() {
+ return false;
+ }
+ public boolean migrateExtraStreamToClipData(Context context) {
+ return false;
+ }
+ private Uri maybeConvertFileToContentUri(Context context, Uri uri) {
+ return null;
+ }
+ public static String dockStateToString(int dock) {
+ return null;
+ }
+ private static ClipData.Item makeClipItem(ArrayList streams, ArrayList texts,
+ ArrayList htmlTexts, int which) {
+ return null;
+ }
+ public boolean isDocument() {
+ return false;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/content/IntentFilter.java b/rxandroidble/src/test/java/android/content/IntentFilter.java
new file mode 100644
index 000000000..0f7dbd4bd
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/IntentFilter.java
@@ -0,0 +1,47 @@
+package android.content;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AndroidException;
+public class IntentFilter implements Parcelable {
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+
+ }
+
+ public static class MalformedMimeTypeException extends AndroidException {
+ public MalformedMimeTypeException() {
+ }
+ public MalformedMimeTypeException(String name) {
+ super(name);
+ }
+ }
+ public static IntentFilter create(String action, String dataType) {
+ try {
+ return new IntentFilter(action, dataType);
+ } catch (MalformedMimeTypeException e) {
+ throw new RuntimeException("Bad MIME type", e);
+ }
+ }
+ String mAction;
+ public IntentFilter(String action, String dataType)
+ throws MalformedMimeTypeException {
+ mAction = action;
+ }
+ public IntentFilter(String action)
+ throws MalformedMimeTypeException {
+ mAction = action;
+
+ }
+ public final boolean hasAction(String action) {
+ return action.equals(mAction);
+ }
+
+
+}
diff --git a/rxandroidble/src/test/java/android/content/MemorySharedPreferences.java b/rxandroidble/src/test/java/android/content/MemorySharedPreferences.java
new file mode 100644
index 000000000..8868a5ea7
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/MemorySharedPreferences.java
@@ -0,0 +1,134 @@
+package android.content;
+import androidx.annotation.Nullable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+public class MemorySharedPreferences implements SharedPreferences{
+ private final HashMap map = new HashMap<>();
+ public MemorySharedPreferences() {
+ }
+ private class MemoryEditor implements Editor {
+ private Editor put(String key, Object value) {
+ map.put(key, value);
+ notifyListeners(key);
+ return this;
+ }
+ @Override
+ public Editor putString(String key, String value) {
+ return put(key, value);
+ }
+ @Override
+ public Editor putStringSet(String key, Set values) {
+ return put(key, values);
+ }
+ @Override
+ public Editor putInt(String key, int value) {
+ return put(key, value);
+ }
+ @Override
+ public Editor putLong(String key, long value) {
+ return put(key, value);
+ }
+ @Override
+ public Editor putFloat(String key, float value) {
+ return put(key, value);
+ }
+ @Override
+ public Editor putBoolean(String key, boolean value) {
+ return put(key, value);
+ }
+ @Override
+ public Editor remove(String key) {
+ map.remove(key);
+ notifyListeners(key);
+ return this;
+ }
+ @Override
+ public Editor clear() {
+ Set keys = map.keySet();
+ map.clear();
+ for (String key : keys) {
+ notifyListeners(key);
+ }
+ return this;
+ }
+ @Override
+ public boolean commit() {
+ return false;
+ }
+ @Override
+ public void apply() {
+ }
+ }
+ private final Editor editor = new MemoryEditor();
+ @Override
+ public Map getAll() {
+ return map;
+ }
+ @Override
+ public String getString(String key, String defValue) {
+ Object obj = map.get(key);
+ if (obj instanceof String) {
+ return (String) obj;
+ }
+ return defValue;
+ }
+ @Override
+ public Set getStringSet(String key, Set defValues) {
+ return defValues;
+ }
+ @Override
+ public int getInt(String key, int defValue) {
+ Object obj = map.get(key);
+ if (obj instanceof Integer) {
+ return (int) obj;
+ }
+ return defValue;
+ }
+ @Override
+ public long getLong(String key, long defValue) {
+ Object obj = map.get(key);
+ if (obj instanceof Long) {
+ return (long) obj;
+ }
+ return defValue;
+ }
+ @Override
+ public float getFloat(String key, float defValue) {
+ Object obj = map.get(key);
+ if (obj instanceof Float) {
+ return (float) obj;
+ }
+ return defValue;
+ }
+ @Override
+ public boolean getBoolean(String key, boolean defValue) {
+ Object obj = map.get(key);
+ if (obj instanceof Boolean) {
+ return (Boolean) obj;
+ }
+ return defValue;
+ }
+ @Override
+ public boolean contains(String key) {
+ return map.containsKey(key);
+ }
+ public Editor edit() {
+ return editor;
+ }
+ HashSet listeners = new HashSet<>();
+ @Override
+ public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
+ listeners.add(listener);
+ }
+ @Override
+ public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
+ listeners.remove(listener);
+ }
+ private void notifyListeners(String key) {
+ for (OnSharedPreferenceChangeListener listener : listeners) {
+ listener.onSharedPreferenceChanged(this, key);
+ }
+ }
+}
diff --git a/rxandroidble/src/test/java/android/content/res/Configuration.java b/rxandroidble/src/test/java/android/content/res/Configuration.java
new file mode 100644
index 000000000..532fddaf4
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/res/Configuration.java
@@ -0,0 +1,28 @@
+package android.content.res;
+import android.os.Parcel;
+import android.os.Parcelable;
+public final class Configuration implements Parcelable, Comparable {
+ public static final int NAVIGATION_UNDEFINED = 0;
+ public static final int NAVIGATION_NONAV = 1;
+ public static final int NAVIGATION_DPAD = 2;
+ public static final int NAVIGATION_TRACKBALL = 3;
+ public static final int NAVIGATION_WHEEL = 4;
+ public int navigation;
+ public Configuration() {
+ this.navigation = 0;
+ }
+ public Configuration(int navigation) {
+ this.navigation = navigation;
+ }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+ @Override
+ public int compareTo(Configuration o) {
+ return 0;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/content/res/Resources.java b/rxandroidble/src/test/java/android/content/res/Resources.java
new file mode 100644
index 000000000..df28b2788
--- /dev/null
+++ b/rxandroidble/src/test/java/android/content/res/Resources.java
@@ -0,0 +1,18 @@
+package android.content.res;
+public class Resources {
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+ public void setConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ }
+ private Configuration configuration;
+ public Resources(Configuration configuration) {
+ this.configuration = configuration;
+ }
+ public final class Theme {
+ }
+ public String getResourceName(int resid) {
+ return null;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/location/LocationManager.java b/rxandroidble/src/test/java/android/location/LocationManager.java
new file mode 100644
index 000000000..a86f30f0f
--- /dev/null
+++ b/rxandroidble/src/test/java/android/location/LocationManager.java
@@ -0,0 +1,6 @@
+package android.location;
+
+public class LocationManager {
+
+ public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
+}
diff --git a/rxandroidble/src/test/java/android/os/Build.java b/rxandroidble/src/test/java/android/os/Build.java
new file mode 100644
index 000000000..59ffe8033
--- /dev/null
+++ b/rxandroidble/src/test/java/android/os/Build.java
@@ -0,0 +1,50 @@
+package android.os;
+public class Build {
+ public static class VERSION_CODES {
+ public static final int CUR_DEVELOPMENT = 10000;
+ public static final int BASE = 1;
+ public static final int BASE_1_1 = 2;
+ public static final int CUPCAKE = 3;
+ public static final int DONUT = 4;
+ public static final int ECLAIR = 5;
+ public static final int ECLAIR_0_1 = 6;
+ public static final int ECLAIR_MR1 = 7;
+ public static final int FROYO = 8;
+ public static final int GINGERBREAD = 9;
+ public static final int GINGERBREAD_MR1 = 10;
+ public static final int HONEYCOMB = 11;
+ public static final int HONEYCOMB_MR1 = 12;
+ public static final int HONEYCOMB_MR2 = 13;
+ public static final int ICE_CREAM_SANDWICH = 14;
+ public static final int ICE_CREAM_SANDWICH_MR1 = 15;
+ public static final int JELLY_BEAN = 16;
+ public static final int JELLY_BEAN_MR1 = 17;
+ public static final int JELLY_BEAN_MR2 = 18;
+ public static final int KITKAT = 19;
+ public static final int KITKAT_WATCH = 20;
+ public static final int L = 21;
+ public static final int LOLLIPOP = 21;
+ public static final int LOLLIPOP_MR1 = 22;
+ public static final int M = 23;
+ public static final int N = 24;
+ public static final int N_MR1 = 25;
+ public static final int O = 26;
+ public static final int O_MR1 = 27;
+ public static final int P = 28;
+ public static final int Q = 29;
+ public static final int R = 30;
+ public static final int S = 31;
+ }
+ public static class VERSION {
+ public static final String INCREMENTAL = "7602718";
+ public static final String RELEASE = "11";
+ public static final String RELEASE_OR_CODENAME = "11";
+ public static final String BASE_OS = "";
+ public static final String SECURITY_PATCH = "2021-08-05";
+ public static final int MEDIA_PERFORMANCE_CLASS = 0;
+ public static final String SDK = "31";
+ public static final int SDK_INT = 31;
+ public static final int PREVIEW_SDK_INT = 0;
+ public static final String CODENAME = "REL";
+ }
+}
diff --git a/rxandroidble/src/test/java/android/os/Bundle.java b/rxandroidble/src/test/java/android/os/Bundle.java
new file mode 100644
index 000000000..4d3500a9b
--- /dev/null
+++ b/rxandroidble/src/test/java/android/os/Bundle.java
@@ -0,0 +1,532 @@
+package android.os;
+import android.util.ArrayMap;
+import android.util.Size;
+import android.util.SizeF;
+import android.util.SparseArray;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+@SuppressWarnings({"unchecked"})
+public final class Bundle implements Cloneable, Parcelable {
+ static final int FLAG_HAS_FDS = 1 << 8;
+ static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
+ static final int FLAG_ALLOW_FDS = 1 << 10;
+ public static final Bundle EMPTY;
+ private Map mMap = new HashMap<>();
+ public static final Bundle STRIPPED;
+ static {
+ EMPTY = new Bundle();
+ EMPTY.mMap = new ArrayMap<>();
+ STRIPPED = new Bundle();
+ STRIPPED.putInt("STRIPPED", 1);
+ }
+ public Bundle() {
+ }
+ public Bundle(Bundle bundle) {
+ mMap = bundle.mMap;
+ }
+ public Object clone() {
+ return new Bundle(this);
+ }
+ public boolean containsKey(String key) {
+ return mMap.containsKey(key);
+ }
+ public void clear() {
+ mMap.clear();
+ }
+ public Set keySet() {
+ return mMap.keySet();
+ }
+ public int size() {
+ return mMap.size();
+ }
+ public void remove(String key) {
+ mMap.remove(key);
+ }
+ public void putAll(Bundle bundle) {
+ mMap.putAll(bundle.mMap);
+ }
+ public int getSize() {
+ return size();
+ }
+ public boolean hasFileDescriptors() {
+ return false;
+ }
+ public void putByte(String key, byte value) {
+ mMap.put(key, value);
+ }
+ public void putBoolean(String key, boolean value) {
+ mMap.put(key, value);
+ }
+ public void putDouble(String key, double value) {
+ mMap.put(key, value);
+ }
+ public void putInt(String key, int value) {
+ mMap.put(key, value);
+ }
+ public void putLong(String key, long value) {
+ mMap.put(key, value);
+ }
+ public void putChar(String key, char value) {
+ mMap.put(key, value);
+ }
+ public void putShort(String key, short value) {
+ mMap.put(key, value);
+ }
+ public void putFloat(String key, float value) {
+ mMap.put(key, value);
+ }
+ public void putString(String key, String value) {
+ mMap.put(key, value);
+ }
+ public void putCharSequence(String key, CharSequence value) {
+ mMap.put(key, value);
+ }
+ public void putParcelable(String key, Parcelable value) {
+ mMap.put(key, value);
+ }
+ public void putSize(String key, Size value) {
+ mMap.put(key, value);
+ }
+ public void putSizeF(String key, SizeF value) {
+ mMap.put(key, value);
+ }
+ public void putParcelableArray(String key, Parcelable[] value) {
+ mMap.put(key, value);
+ }
+ public void putParcelableArrayList(String key,
+ ArrayList extends Parcelable> value) {
+ mMap.put(key, value);
+ }
+ public void putParcelableList(String key, List extends Parcelable> value) {
+ mMap.put(key, value);
+ }
+ public void putSparseParcelableArray(String key,
+ SparseArray extends Parcelable> value) {
+ mMap.put(key, value);
+ }
+ public void putIntegerArrayList(String key, ArrayList value) {
+ mMap.put(key, value);
+ }
+ public void putStringArrayList(String key, ArrayList value) {
+ mMap.put(key, value);
+ }
+ public void putCharSequenceArrayList(String key,
+ ArrayList value) {
+ mMap.put(key, value);
+ }
+ public void putSerializable(String key, Serializable value) {
+ mMap.put(key, value);
+ }
+ public void putByteArray(String key, byte[] value) {
+ mMap.put(key, value);
+ }
+ public void putShortArray(String key, short[] value) {
+ mMap.put(key, value);
+ }
+ public void putCharArray(String key, char[] value) {
+ mMap.put(key, value);
+ }
+ public void putFloatArray(String key, float[] value) {
+ mMap.put(key, value);
+ }
+ public void putIntArray(String key, int[] value) {
+ mMap.put(key, value);
+ }
+ public void putLongArray(String key, long[] value) {
+ mMap.put(key, value);
+ }
+ public void putDoubleArray(String key, double[] value) {
+ mMap.put(key, value);
+ }
+ public void putBooleanArray(String key, boolean[] value) {
+ mMap.put(key, value);
+ }
+ public void putStringArray(String key, String[] value) {
+ mMap.put(key, value);
+ }
+ public void putCharSequenceArray(String key, CharSequence[] value) {
+ mMap.put(key, value);
+ }
+ public void putBundle(String key, Bundle value) {
+ mMap.put(key, value);
+ }
+ public void putBinder(String key, IBinder value) {
+ mMap.put(key, value);
+ }
+ @Deprecated
+ public void putIBinder(String key, IBinder value) {
+ mMap.put(key, value);
+ }
+ public byte getByte(String key) {
+ return getByte(key, (byte) 0);
+ }
+ public Byte getByte(String key, byte defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Byte) {
+ return (Byte) val;
+ }
+ return defaultValue;
+ }
+ public boolean getBoolean(String key) {
+ return getBoolean(key, false);
+ }
+ public boolean getBoolean(String key, boolean defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Boolean) {
+ return (boolean) val;
+ }
+ return defaultValue;
+ }
+ public char getChar(String key) {
+ return getChar(key, (char) 0);
+ }
+ public char getChar(String key, char defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Character) {
+ return (Character) val;
+ }
+ return defaultValue;
+ }
+ public short getShort(String key) {
+ return getShort(key, (short) 0);
+ }
+ public short getShort(String key, short defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Short) {
+ return (Short) val;
+ }
+ return defaultValue;
+ }
+ public float getFloat(String key) {
+ return getFloat(key, 0);
+ }
+ public float getFloat(String key, float defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Float) {
+ return (Float) val;
+ }
+ return defaultValue;
+ }
+ public double getDouble(String key) {
+ return getDouble(key, 0);
+ }
+ public double getDouble(String key, double defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Double) {
+ return (Double) val;
+ }
+ return defaultValue;
+ }
+ public int getInt(String key) {
+ return getInt(key, 0);
+ }
+ public int getInt(String key, int defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Integer) {
+ return (Integer) val;
+ }
+ return defaultValue;
+ }
+ public long getLong(String key) {
+ return getLong(key, 0);
+ }
+ public long getLong(String key, long defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof Long) {
+ return (Long) val;
+ }
+ return defaultValue;
+ }
+ public String getString(String key) {
+ return getString(key, "");
+ }
+ public String getString(String key, String defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof String) {
+ return (String) val;
+ }
+ return defaultValue;
+ }
+ public CharSequence getCharSequence(String key) {
+ return getCharSequence(key, null);
+ }
+ public CharSequence getCharSequence(String key, CharSequence defaultValue) {
+ Object val = mMap.get(key);
+ if (val instanceof CharSequence) {
+ return (CharSequence) val;
+ }
+ return defaultValue;
+ }
+ public Size getSize(String key) {
+ final Object o = mMap.get(key);
+ try {
+ return (Size) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public SizeF getSizeF(String key) {
+ final Object o = mMap.get(key);
+ try {
+ return (SizeF) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public Bundle getBundle(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (Bundle) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public T getParcelable(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (T) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public Parcelable[] getParcelableArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (Parcelable[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public ArrayList getParcelableArrayList(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public SparseArray getSparseParcelableArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (SparseArray) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public Serializable getSerializable(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (Serializable) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public ArrayList getIntegerArrayList(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public ArrayList getStringArrayList(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public ArrayList getCharSequenceArrayList(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public byte[] getByteArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (byte[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public short[] getShortArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (short[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public char[] getCharArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (char[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public float[] getFloatArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (float[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public boolean[] getBooleanArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (boolean[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public int[] getIntArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (int[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public long[] getLongArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (long[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public double[] getDoubleArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (double[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public String[] getStringArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (String[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public CharSequence[] getCharSequenceArray(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (CharSequence[]) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public Object get(String key) {
+ return mMap.get(key);
+ }
+ @Deprecated
+ public IBinder getIBinder(String key) {
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (IBinder) o;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ @Override
+ public Bundle createFromParcel(Parcel in) {
+ return in.readBundle();
+ }
+ @Override
+ public Bundle[] newArray(int size) {
+ return new Bundle[size];
+ }
+ };
+ public int describeContents() {
+ int mask = 0;
+ if (hasFileDescriptors()) {
+ mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
+ }
+ return mask;
+ }
+ public void writeToParcel(Parcel parcel, int flags) {
+ }
+ public void readFromParcel(Parcel parcel) {
+ }
+ public synchronized String toString() {
+ return "Bundle[" + mMap.toString() + "]";
+ }
+ public synchronized String toShortString() {
+ return mMap.toString();
+ }
+}
diff --git a/rxandroidble/src/test/java/android/os/DeadObjectException.java b/rxandroidble/src/test/java/android/os/DeadObjectException.java
new file mode 100644
index 000000000..4c5274402
--- /dev/null
+++ b/rxandroidble/src/test/java/android/os/DeadObjectException.java
@@ -0,0 +1,9 @@
+package android.os;
+public class DeadObjectException extends RemoteException {
+ public DeadObjectException() {
+ super();
+ }
+ public DeadObjectException(String message) {
+ super(message);
+ }
+}
diff --git a/rxandroidble/src/test/java/android/os/ParcelUuid.java b/rxandroidble/src/test/java/android/os/ParcelUuid.java
new file mode 100644
index 000000000..8287e495a
--- /dev/null
+++ b/rxandroidble/src/test/java/android/os/ParcelUuid.java
@@ -0,0 +1,55 @@
+package android.os;
+import java.util.UUID;
+public final class ParcelUuid implements Parcelable {
+ private final UUID mUuid;
+ public ParcelUuid(UUID uuid) {
+ mUuid = uuid;
+ }
+ public static ParcelUuid fromString(String uuid) {
+ return new ParcelUuid(UUID.fromString(uuid));
+ }
+ public UUID getUuid() {
+ return mUuid;
+ }
+ @Override
+ public String toString() {
+ return mUuid.toString();
+ }
+ @Override
+ public int hashCode() {
+ return mUuid.hashCode();
+ }
+ @Override
+ public boolean equals(Object object) {
+ if (object == null) {
+ return false;
+ }
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof ParcelUuid)) {
+ return false;
+ }
+ ParcelUuid that = (ParcelUuid) object;
+ return (this.mUuid.equals(that.mUuid));
+ }
+ public static final Creator CREATOR =
+ new Creator() {
+ public ParcelUuid createFromParcel(Parcel source) {
+ long mostSigBits = source.readLong();
+ long leastSigBits = source.readLong();
+ UUID uuid = new UUID(mostSigBits, leastSigBits);
+ return new ParcelUuid(uuid);
+ }
+ public ParcelUuid[] newArray(int size) {
+ return new ParcelUuid[size];
+ }
+ };
+ public int describeContents() {
+ return 0;
+ }
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mUuid.getMostSignificantBits());
+ dest.writeLong(mUuid.getLeastSignificantBits());
+ }
+}
diff --git a/rxandroidble/src/test/java/android/os/RemoteException.java b/rxandroidble/src/test/java/android/os/RemoteException.java
new file mode 100644
index 000000000..c1267f9c3
--- /dev/null
+++ b/rxandroidble/src/test/java/android/os/RemoteException.java
@@ -0,0 +1,27 @@
+package android.os;
+import android.util.AndroidException;
+public class RemoteException extends AndroidException {
+ public RemoteException() {
+ super();
+ }
+ public RemoteException(String message) {
+ super(message);
+ }
+ public RemoteException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+ public RemoteException(Throwable cause) {
+ this(cause.getMessage(), cause, true, false);
+ }
+ public RuntimeException rethrowAsRuntimeException() {
+ throw new RuntimeException(this);
+ }
+ public RuntimeException rethrowFromSystemServer() {
+ if (this instanceof DeadObjectException) {
+ throw new RuntimeException(new DeadSystemException());
+ } else {
+ throw new RuntimeException(this);
+ }
+ }
+}
diff --git a/rxandroidble/src/test/java/android/util/AndroidException.java b/rxandroidble/src/test/java/android/util/AndroidException.java
new file mode 100644
index 000000000..412ecd96c
--- /dev/null
+++ b/rxandroidble/src/test/java/android/util/AndroidException.java
@@ -0,0 +1,18 @@
+package android.util;
+public class AndroidException extends Exception {
+ public AndroidException() {
+ }
+ public AndroidException(String name) {
+ super(name);
+ }
+ public AndroidException(String name, Throwable cause) {
+ super(name, cause);
+ }
+ public AndroidException(Exception cause) {
+ super(cause);
+ }
+ protected AndroidException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+};
diff --git a/rxandroidble/src/test/java/android/util/Log.java b/rxandroidble/src/test/java/android/util/Log.java
new file mode 100644
index 000000000..547fb9638
--- /dev/null
+++ b/rxandroidble/src/test/java/android/util/Log.java
@@ -0,0 +1,79 @@
+package android.util;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.UnknownHostException;
+public final class Log {
+ public static final int VERBOSE = 2;
+ public static final int DEBUG = 3;
+ public static final int INFO = 4;
+ public static final int WARN = 5;
+ public static final int ERROR = 6;
+ public static final int ASSERT = 7;
+ private Log() {
+ }
+ public static int v(String tag, String msg) {
+ return println(LOG_ID_MAIN, VERBOSE, tag, msg);
+ }
+ public static int v(String tag, String msg, Throwable tr) {
+ return println(LOG_ID_MAIN, VERBOSE, tag, msg + '\n' + getStackTraceString(tr));
+ }
+ public static int d(String tag, String msg) {
+ return println(LOG_ID_MAIN, DEBUG, tag, msg);
+ }
+ public static int d(String tag, String msg, Throwable tr) {
+ return println(LOG_ID_MAIN, DEBUG, tag, msg + '\n' + getStackTraceString(tr));
+ }
+ public static int i(String tag, String msg) {
+ return println(LOG_ID_MAIN, INFO, tag, msg);
+ }
+ public static int i(String tag, String msg, Throwable tr) {
+ return println(LOG_ID_MAIN, INFO, tag, msg + '\n' + getStackTraceString(tr));
+ }
+ public static int w(String tag, String msg) {
+ return println(LOG_ID_MAIN, WARN, tag, msg);
+ }
+ public static int w(String tag, String msg, Throwable tr) {
+ return println(LOG_ID_MAIN, WARN, tag, msg + '\n' + getStackTraceString(tr));
+ }
+ public static int w(String tag, Throwable tr) {
+ return println(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr));
+ }
+ public static int e(String tag, String msg) {
+ return println(LOG_ID_MAIN, ERROR, tag, msg);
+ }
+ public static int e(String tag, String msg, Throwable tr) {
+ return println(LOG_ID_MAIN, ERROR, tag, msg + '\n' + getStackTraceString(tr));
+ }
+ public static String getStackTraceString(Throwable tr) {
+ if (tr == null) {
+ return "";
+ }
+ // This is to reduce the amount of log spew that apps do in the non-error
+ // condition of the network being unavailable.
+ Throwable t = tr;
+ while (t != null) {
+ if (t instanceof UnknownHostException) {
+ return "";
+ }
+ t = t.getCause();
+ }
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ tr.printStackTrace(pw);
+ pw.flush();
+ return sw.toString();
+ }
+ public static int println(int priority, String tag, String msg) {
+ return println(LOG_ID_MAIN, priority, tag, msg);
+ }
+ public static final int LOG_ID_MAIN = 0;
+ public static final int LOG_ID_RADIO = 1;
+ public static final int LOG_ID_EVENTS = 2;
+ public static final int LOG_ID_SYSTEM = 3;
+ public static final int LOG_ID_CRASH = 4;
+ @SuppressWarnings("unused")
+ public static int println(int bufID,
+ int priority, String tag, String msg) {
+ return 0;
+ }
+}
diff --git a/rxandroidble/src/test/java/android/util/Pair.java b/rxandroidble/src/test/java/android/util/Pair.java
new file mode 100644
index 000000000..c718022b9
--- /dev/null
+++ b/rxandroidble/src/test/java/android/util/Pair.java
@@ -0,0 +1,29 @@
+package android.util;
+import java.util.Objects;
+public class Pair {
+ public final F first;
+ public final S second;
+ public Pair(F first, S second) {
+ this.first = first;
+ this.second = second;
+ }
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Pair)) {
+ return false;
+ }
+ Pair, ?> p = (Pair, ?>) o;
+ return Objects.equals(p.first, first) && Objects.equals(p.second, second);
+ }
+ @Override
+ public int hashCode() {
+ return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
+ }
+ @Override
+ public String toString() {
+ return "Pair{" + String.valueOf(first) + " " + String.valueOf(second) + "}";
+ }
+ public static Pair create(A a, B b) {
+ return new Pair(a, b);
+ }
+}
diff --git a/rxandroidble/src/test/java/android/util/SparseArray.java b/rxandroidble/src/test/java/android/util/SparseArray.java
new file mode 100644
index 000000000..6e679cb73
--- /dev/null
+++ b/rxandroidble/src/test/java/android/util/SparseArray.java
@@ -0,0 +1,30 @@
+package android.util;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+public class SparseArray {
+ private final ArrayList keys = new ArrayList<>();
+ private final HashMap mHashMap = new HashMap<>();
+ public SparseArray() {
+ }
+ public void put(int key, E value) {
+ mHashMap.put(key, value);
+ keys.add(key);
+ Collections.sort(keys);
+ }
+ public void append(int key, E value) {
+ put(key, value);
+ }
+ public E get(int key) {
+ return mHashMap.get(key);
+ }
+ public int size() {
+ return mHashMap.size();
+ }
+ public int keyAt(int i) {
+ if (i > keys.size()) {
+ throw new ArrayIndexOutOfBoundsException(i);
+ }
+ return keys.get(i);
+ }
+}
\ No newline at end of file
diff --git a/sample-kotlin/build.gradle b/sample-kotlin/build.gradle
index f42dd3847..552872b90 100644
--- a/sample-kotlin/build.gradle
+++ b/sample-kotlin/build.gradle
@@ -21,13 +21,16 @@ android {
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility = rootProject.ext.sourceCompatibilityVersion
+ targetCompatibility = rootProject.ext.targetCompatibilityVersion
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
- test.java.srcDirs += 'src/test/kotlin'
+ test.java.srcDirs = [
+ 'src/test/kotlin',
+ '../rxandroidble/src/test/java' // this produces a warning about duplicate content roots, but it is still required
+ ]
}
}
@@ -45,7 +48,7 @@ dependencies {
// AndroidX
implementation rootProject.ext.libs.appcompat
implementation rootProject.ext.libs.material_design
- implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation rootProject.ext.libs.annotations
// RxBinding
@@ -62,5 +65,4 @@ dependencies {
// Test
testImplementation project(':mockrxandroidble')
testImplementation rootProject.ext.libs.junit
- testImplementation rootProject.ext.libs.robolectric
}
diff --git a/sample-kotlin/src/test/kotlin/com/polidea/rxandroidble2/samplekotlin/example4_characteristic/advanced/PresenterTest.kt b/sample-kotlin/src/test/kotlin/com/polidea/rxandroidble2/samplekotlin/example4_characteristic/advanced/PresenterTest.kt
index 78f172e3f..b33fe7e21 100644
--- a/sample-kotlin/src/test/kotlin/com/polidea/rxandroidble2/samplekotlin/example4_characteristic/advanced/PresenterTest.kt
+++ b/sample-kotlin/src/test/kotlin/com/polidea/rxandroidble2/samplekotlin/example4_characteristic/advanced/PresenterTest.kt
@@ -4,16 +4,11 @@ import android.bluetooth.BluetoothGattCharacteristic.PROPERTY_INDICATE
import android.bluetooth.BluetoothGattCharacteristic.PROPERTY_NOTIFY
import android.bluetooth.BluetoothGattCharacteristic.PROPERTY_READ
import android.bluetooth.BluetoothGattCharacteristic.PROPERTY_WRITE
-import android.os.Build
import com.polidea.rxandroidble2.RxBleDevice
import com.polidea.rxandroidble2.mockrxandroidble.RxBleClientMock
-import com.polidea.rxandroidble2.samplekotlin.BuildConfig
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
-import org.junit.*
-import org.junit.runner.*
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.annotation.Config
+import org.junit.jupiter.api.Test
import java.util.UUID
private const val deviceName = "TestDevice"
@@ -27,8 +22,6 @@ private val characteristicData = "Polidea".toByteArray()
private val descriptorUUID = UUID.fromString("00001337-0000-1000-8000-00805f9b34fb")
private val descriptorData = "Config".toByteArray()
-@RunWith(RobolectricTestRunner::class)
-@Config(manifest = Config.NONE, constants = BuildConfig::class, sdk = [Build.VERSION_CODES.LOLLIPOP])
class PresenterTest {
private val characteristicNotificationSubject = PublishSubject.create()
diff --git a/sample/build.gradle b/sample/build.gradle
index 74ab034a9..a71817cf4 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -28,8 +28,8 @@ android {
}
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility = rootProject.ext.sourceCompatibilityVersion
+ targetCompatibility = rootProject.ext.targetCompatibilityVersion
}
}
@@ -41,8 +41,8 @@ dependencies {
implementation project(path: ':rxandroidble')
implementation rootProject.ext.libs.appcompat
implementation rootProject.ext.libs.material_design
- implementation 'com.jakewharton:butterknife:10.2.1'
- annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
+ implementation 'com.jakewharton:butterknife:10.2.3'
+ annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
implementation rootProject.ext.libs.rxandroid
implementation rootProject.ext.libs.rxjava
implementation rootProject.ext.libs.rxjava_binding