Skip to content

Commit

Permalink
Succeed to build BT4Facade #16
Browse files Browse the repository at this point in the history
  • Loading branch information
kuri65536 committed Feb 5, 2017
1 parent f010ff8 commit be74205
Show file tree
Hide file tree
Showing 19 changed files with 698 additions and 65 deletions.
2 changes: 1 addition & 1 deletion android/Bluetooth4Facade/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.googlecode.android_scripting.btfacade" android:installLocation="auto"
package="com.googlecode.android_scripting.bt4facade" android:installLocation="auto"
>
</manifest>

@@ -1,5 +1,6 @@
package com.googlecode.android_scripting.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;

Expand All @@ -13,11 +14,18 @@
*/

public class BluetoothNonpublicApi {
// BUG: negative number = under searching...
// adapter
public static final int STATE_UNKNOWN = -1; // temporary
public static final int STATE_BLE_ON = 15;
public static final String ACTION_BLE_STATE_CHANGED =
"android.bluetooth.adapter.action.BLE_STATE_CHANGED";

// profile
// BUG: numbers around 65536 = under searching...
public static final int PRIORITY_AUTO_CONNECT = 1000;
public static final int PRIORITY_ON = 100;
public static final int PRIORITY_OFF = 0;
public static final int PRIORITY_UNDEFINED = -65536;
public static final int PRIORITY_UNDEFINED = -1;

public static final int MAP = 9;
public static final int PAN = 5;
Expand All @@ -29,6 +37,21 @@ public class BluetoothNonpublicApi {
public static final int INPUT_DEVICE = 4;
public static final int AVRCP_CONTROLLER = 12;

// Device
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 int PAIRING_VARIANT_CONSENT = 3;

// MapClient
public static final String ACTION_MESSAGE_RECEIVED =
"android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED";
public static final String ACTION_MESSAGE_SENT_SUCCESSFULLY =
"android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY";
public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY =
"android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY";

public static boolean connectProfile(BluetoothProfile prf, BluetoothDevice sink) {
Log.e("connect function won't work with no-system app.");
if (prf == null) {return false;}
Expand Down Expand Up @@ -122,4 +145,59 @@ public static boolean setPriorityProfile(BluetoothProfile prf,
}
return false;
}

public static Integer getLeState(BluetoothAdapter adp
) {
Log.e("getLeState function won't work with no-system app.");
if (adp == null) {return STATE_UNKNOWN;}

try {
Method method = adp.getClass().getMethod("getLeState");
if(method != null) {
return (Integer)method.invoke(adp);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return STATE_UNKNOWN;
}

public static void setScanMode(BluetoothAdapter adp,
Integer mode) {

setScanMode(true, adp, mode, null);
}

public static void setScanMode(BluetoothAdapter adp,
Integer mode,
Integer duration) {
setScanMode(false, adp, mode, duration);
}

public static void setScanMode(boolean f2opt,
BluetoothAdapter adp,
Integer mode,
Integer duration) {
Log.e("setScanMode function won't work with no-system app.");
if (adp == null) {return;}

try {
Method method = adp.getClass().getMethod("setScanMode");
if(method != null) {
if (f2opt) {method.invoke(adp, mode);}
else {method.invoke(adp, mode, duration);}
return;
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Expand Up @@ -14,7 +14,7 @@
* the License.
*/

package com.googlecode.android_scripting.facade.bluetooth;
package com.googlecode.android_scripting.bluetooth;

import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
Expand Down Expand Up @@ -46,8 +46,10 @@ public void onReceive(Context c, Intent intent) {
Log.d("Bluetooth pairing intent received: " + action);
BluetoothDevice mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
/* TODO: try to implement.
mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
*/
int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
Log.d("Processing Action Paring Request with type " + type);
int pin = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY,0);
Expand All @@ -57,7 +59,7 @@ public void onReceive(Context c, Intent intent) {
result.putString("DeviceAddress", deviceAddress);
mEventFacade.postEvent("BluetoothActionPairingRequest", result.clone());
result.clear();
if(type == BluetoothDevice.PAIRING_VARIANT_CONSENT) {
if(type == BluetoothNonpublicApi.PAIRING_VARIANT_CONSENT) {
mDevice.setPairingConfirmation(true);
Log.d("Connection auto-confirmed by consent");
abortBroadcast(); // Abort the broadcast so Settings app doesn't get it.
Expand All @@ -71,7 +73,8 @@ public void onReceive(Context c, Intent intent) {
try {
userConfirmEvent = mEventFacade.eventWaitFor(
"BluetoothActionPairingRequestUserConfirm",
true, DEFAULT_TIMEOUT_MS);
DEFAULT_TIMEOUT_MS);
// true, DEFAULT_TIMEOUT_MS);
} catch (InterruptedException e) {
Log.d("Connection interrupted");
userConfirmEvent = null;
Expand All @@ -93,7 +96,8 @@ public void onReceive(Context c, Intent intent) {
abortBroadcast(); // Abort the broadcast so Settings app doesn't get it.
}
}
else if(action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) {
else if(action.equals(BluetoothNonpublicApi.ACTION_CONNECTION_ACCESS_REQUEST)) {
/* TODO: try to implement.
int type = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.ERROR);
Log.d("Processing Action Connection Access Request type " + type);
if(type == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS ||
Expand All @@ -115,7 +119,8 @@ else if(action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) {
Log.d("Sending connection access acceptance intent.");
abortBroadcast();
c.sendBroadcast(newIntent, android.Manifest.permission.BLUETOOTH_ADMIN);
}
}
*/
}
}

Expand Down
Expand Up @@ -32,6 +32,7 @@
import com.googlecode.android_scripting.Constants;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.MainThread;
import com.googlecode.android_scripting.bluetooth.BluetoothNonpublicApi;
import com.googlecode.android_scripting.facade.EventFacade;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
Expand Down Expand Up @@ -162,9 +163,9 @@ class BleStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
int state = mBluetoothAdapter.getLeState();
if (state == BluetoothAdapter.STATE_BLE_ON) {
if (action.equals(BluetoothNonpublicApi.ACTION_BLE_STATE_CHANGED)) {
int state = BluetoothNonpublicApi.getLeState(mBluetoothAdapter);
if (state == BluetoothNonpublicApi.STATE_BLE_ON) {
mEventFacade.postEvent("BleStateChangedOn", new Bundle());
mService.unregisterReceiver(mBleStateReceiver);
} else if (state == BluetoothAdapter.STATE_OFF) {
Expand All @@ -177,7 +178,8 @@ public void onReceive(Context context, Intent intent) {


public static boolean deviceMatch(BluetoothDevice device, String deviceID) {
return deviceID.equals(device.getAliasName()) || deviceID.equals(device.getAddress());
// if (deviceID.equals(device.getAliasName())) {return true;}
return deviceID.equals(device.getAddress());
}

public static <T> BluetoothDevice getDevice(ConcurrentHashMap<String, T> devices, String device)
Expand Down Expand Up @@ -214,8 +216,8 @@ public static boolean deviceExists(Collection<BluetoothDevice> devices, String d

@Rpc(description = "Requests that the device be made connectable.")
public void bluetoothMakeConnectable() {
mBluetoothAdapter
.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
BluetoothNonpublicApi.setScanMode(mBluetoothAdapter,
BluetoothAdapter.SCAN_MODE_CONNECTABLE);
}

@Rpc(description = "Returns active Bluetooth connections.")
Expand Down Expand Up @@ -327,8 +329,8 @@ public void bluetoothMakeDiscoverable(
@RpcDefault("300")
Integer duration) {
Log.d("Making discoverable for " + duration + " seconds.\n");
mBluetoothAdapter
.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, duration);
BluetoothNonpublicApi.setScanMode(mBluetoothAdapter,
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, duration);
if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, duration);
Expand Down Expand Up @@ -393,7 +395,7 @@ public String bluetoothReadLine(
@Rpc(description = "Requests that the device be not discoverable.")
public void bluetoothMakeUndiscoverable() {
Log.d("Making undiscoverable\n");
mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_NONE);
BluetoothNonpublicApi.setScanMode(mBluetoothAdapter, BluetoothAdapter.SCAN_MODE_NONE);
}

@Rpc(description = "Queries a remote device for it's name or null if it can't be resolved")
Expand Down Expand Up @@ -457,7 +459,9 @@ public Boolean checkBluetoothState() {

@Rpc(description = "Factory reset bluetooth settings.", returns = "True if successful.")
public boolean bluetoothFactoryReset() {
return mBluetoothAdapter.factoryReset();
Log.e("factoryReset won't work in no-system app.");
return false;
// return mBluetoothAdapter.factoryReset();
}

@Rpc(description = "Toggle Bluetooth on and off.", returns = "True if Bluetooth is enabled.")
Expand All @@ -473,7 +477,6 @@ public Boolean toggleBluetoothState(
enabled = !checkBluetoothState();
}
if (enabled) {
return mBluetoothAdapter.enable();
if (prompt) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// TODO(damonkohler): Use the result to determine if this was successful. At any rate, keep
Expand Down Expand Up @@ -554,51 +557,64 @@ public boolean bluetoothConfigHciSnoopLog(
@RpcParameter(name = "value", description = "enable or disable log")
Boolean value
) {
return mBluetoothAdapter.configHciSnoopLog(value);
Log.e("configHciSnoopLog won't work in no-system app.");
return false;
// TODO: try to implement.
// return mBluetoothAdapter.configHciSnoopLog(value);
}

@Rpc(description = "Get Bluetooth controller activity energy info.")
public String bluetoothGetControllerActivityEnergyInfo(
@RpcParameter(name = "value")
Integer value
) {
return "Disabled in user app SL4A";
/* TODO: try to implement.
BluetoothActivityEnergyInfo energyInfo = mBluetoothAdapter
.getControllerActivityEnergyInfo(value);
while (energyInfo == null) {
energyInfo = mBluetoothAdapter.getControllerActivityEnergyInfo(value);
}
return energyInfo.toString();
*/
}

@Rpc(description = "Return true if hardware has entries" +
"available for matching beacons.")
public boolean bluetoothIsHardwareTrackingFiltersAvailable() {
return mBluetoothAdapter.isHardwareTrackingFiltersAvailable();
Log.e("isHardwareTrackingFiltersAvailable won't in no-system app.");
return false;
// TODO: try to implement.
// return mBluetoothAdapter.isHardwareTrackingFiltersAvailable();
}

@Rpc(description = "Gets the current state of LE.")
public int bluetoothGetLeState() {
return mBluetoothAdapter.getLeState();
return BluetoothNonpublicApi.getLeState(mBluetoothAdapter);
}

@Rpc(description = "Enables BLE functionalities.")
public boolean bluetoothEnableBLE() {
mService.registerReceiver(mBleStateReceiver,
new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED));
return mBluetoothAdapter.enableBLE();
new IntentFilter(BluetoothNonpublicApi.ACTION_BLE_STATE_CHANGED));
Log.e("enableBLE won't work in no-system app.");
return false;
// return mBluetoothAdapter.enableBLE();
}

@Rpc(description = "Disables BLE functionalities.")
public boolean bluetoothDisableBLE() {
mService.registerReceiver(mBleStateReceiver,
new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED));
return mBluetoothAdapter.disableBLE();
new IntentFilter(BluetoothNonpublicApi.ACTION_BLE_STATE_CHANGED));
Log.e("disableBLE won't work in no-system app.");
return false;
// return mBluetoothAdapter.disableBLE();
}

@Rpc(description = "Listen for a Bluetooth LE State Change.")
public boolean bluetoothListenForBleStateChange() {
mService.registerReceiver(mBleStateReceiver,
new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED));
new IntentFilter(BluetoothNonpublicApi.ACTION_BLE_STATE_CHANGED));
return true;
}

Expand Down
Expand Up @@ -96,7 +96,7 @@ public Integer bluetoothA2dpSinkGetPriority(
@RpcParameter(name = "device", description = "Mac address of a BT device.")
String deviceStr)
throws Exception {
if (sA2dpSinkProfile == null) return BluetoothProfile.PRIORITY_UNDEFINED;
if (sA2dpSinkProfile == null) return BluetoothNonpublicApi.PRIORITY_UNDEFINED;
BluetoothDevice device =
Bluetooth4Facade.getDevice(mBluetoothAdapter.getBondedDevices(), deviceStr);
return BluetoothNonpublicApi.getPriorityProfile(sA2dpSinkProfile, device);
Expand Down

0 comments on commit be74205

Please sign in to comment.