Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrome.dart fails to abstract chrome apis on android (cordova) based applications #227

Open
ToddG opened this issue Jun 19, 2015 · 3 comments

Comments

@ToddG
Copy link

ToddG commented Jun 19, 2015

I have written a Chrome Desktop/Chrome Mobile (Cordova) application that uses the chrome.bluetooth API. Is it possible for chrome.dart to wrap the cordova chrome api implementations? If not what is the proposed work-around?

Typically, my service layer methods query for the chrome service, and then perform some an action such as connect|disconnect a device, list all devices, etc.

  @override
  Future connect(GenericBluetoothDevice device) {
    return new Future.sync(() {
      if (!chrome.bluetooth.available) {
        throw new StateError("Cannot connect device. ScoutBluetoothService not started, chrome.bluetooth is not available.");
      }
      return chrome.bluetoothSocket.create()
      .then((chrome.BluetoothCreateInfo bluetoothCreateInfo) {
        chrome.bluetoothSocket.connect(bluetoothCreateInfo.socketId, device.address, SDP_UUID)
...

So, my existing code is written in dart and has a dependency on chrome.dart. In a perfect world, the underlying implementation would be transparent to me and I could just use chrome.dart on both chrome desktop and on chrome mobile (via cordova).

Any suggestions?

@adambender
Copy link
Contributor

This is an interesting use case and while I dont know much about Cordova what I can tell you is that we auto-generate the Dart APIs from metadata in Chrome itself. That metadata describes the APIs for Chrome Extensions and Chrome Packged Apps in a machine parseable way. My understanding is that neither Chrome Packaged App nor Chrome Extensions are supported on mobile versions so chrome.dart won't be of much help to you in that case. What I think would be required would be a new feature that parse Cordova's APIs and emit the appropriate Dart. You can certainly file a feature request to support additional API sources (like Cordova) but to be completely honest it isnt something we would likely get to for some time. The work around (again without knowing much about Cordova) would be to use dart:js interop to invoke the Cordova api directly.

@ToddG
Copy link
Author

ToddG commented Jun 22, 2015

Adam, thanks for the quick response!

I completely understand. This is a bit of an outlier, and in fact, hard
to tell where the problem is exactly. I did further research on this and
found that (on Android) chrome.bluetooth.getAdapterState() successfully
returned data, but other methods such as
chrome.bluetooth.getDevices()failed. I suspect issues with the Chrome
API impl on Android.

As you suggested, I've moved on to use dart:js... for my use case, I'm
talking to the Cordova BluetoothSerial plugin via dart:js from my dart code.

Here's an example implementation of my dart wrapper for getDevices():

Future<List<GenericBluetoothDevice>>getDevices() {
   return newFuture.sync(() {
     Completer c =newCompleter();
     logger.info("cordova invoking getDevices");
     voidonSuccess(JsArray data) {
      /*
        dartData: [{id: 00:18:9A:30:A7:43, class: 7936, address: 00:18:9A:30:A7:43, name: HQ_UHF_READER}]", source: chrome-extension://dfojickiabkojihjpddjdhgphbihlefn/scout.html.polymer.bootstrap.dart.js (13579)
      */
       List dartData = _toDartSimpleObject(data);
       logger.info("cordova getDevices succeeded: dartData:${dartData}");
       List<GenericBluetoothDevice> devices = dartData.map((Map d) =>newGenericBluetoothDevice(d['address'],d['name'],false,false)).toList();
       devices.forEach((GenericBluetoothDevice d) => logger.info("cordova BT DEVICE:${d}"));
       c.complete(devices);
     }

     voidonFailure(e) {
       logger.info("cordova getDevices failed: e:${_toDartSimpleObject(e)}");
       c.complete([]);
     }

     context['bluetoothSerial'].callMethod('list',[(data) {onSuccess(data);},(error) {onFailure(error);}]);
     returnc.future;
   });
}

I'm not super fluent in js, so the tricky part for me was recognizing
the data type being passed to the onSuccess() method, and then figuring
out a way to dissect it...a bit more difficult on the device as you
don't have window.console.log to examine artifacts.

This method helped to deconstruct the onSuccess() parameters:

/// from https://stackoverflow.com/questions/19691693/how-to-convert-javascript-object-to-dart-map
_toDartSimpleObject(thing) {
if(thingisJsArray) {
List res =newList();
JsArray a = thingasJsArray;
a.forEach((otherthing) {
res.add(_toDartSimpleObject(otherthing));
});
returnres;

}else if(thingisJsObject) {
Map res =newMap();
JsObject o = thingasJsObject;
Iterable k = context['Object'].callMethod('keys',[o]);
k.forEach((String k) {
res[k] = _toDartSimpleObject(o[k]);
});
returnres;

}else{
returnthing;
}
}

Thanks again for the response. If I turn up anything that further
isolates the dart <-> chrome (Android) interop issues, I'll let you know.

-Todd

On 06/22/2015 07:38 AM, Adam Bender wrote:

This is an interesting use case and while I dont know much about
Cordova what I can tell you is that we auto-generate the Dart APIs
from metadata in Chrome itself. That metadata describes the APIs for
Chrome Extensions and Chrome Packged Apps in a machine parseable way.
My understanding is that neither Chrome Packaged App nor Chrome
Extensions are supported on mobile versions so chrome.dart won't be of
much help to you in that case. What I think would be required would be
a new feature that parse Cordova's APIs and emit the appropriate Dart.
You can certainly file a feature request to support additional API
sources (like Cordova) but to be completely honest it isnt something
we would likely get to for some time. The work around (again without
knowing much about Cordova) would be to use dart:js interop to invoke
the Cordova api directly.


Reply to this email directly or view it on GitHub
#227 (comment).

@adam-singer
Copy link
Member

Parsing cordova apis would be nice if they were represented by IDL, last, last I recall (2 years ago) there was no plans of doing that. It was mostly hand wired together with sticks and crazy glue. I think chrome.dart should work within chrome mobile apps for most usages, but there might be corner cases where something blows up and hard to tell why.

@ToddG I'd check with the chrome mobile apps team if whatever behavior your seeing with the android/javascript version is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants