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

Repackaging AWARE features as cordova plugins #501

Open
xubowenhaoren opened this issue Feb 13, 2020 · 139 comments
Open

Repackaging AWARE features as cordova plugins #501

xubowenhaoren opened this issue Feb 13, 2020 · 139 comments
Labels
enhancement New feature or request

Comments

@xubowenhaoren
Copy link
Contributor

Hello,

After a lengthy trial-and-error of integrating emission into AWARE, we find out that it would be more flexible to merge the AWARE sync adapters and sensors to emission directly. What suggestions do you have for us to get started on the migration?

@shankari
Copy link
Contributor

shankari commented Feb 13, 2020

The high level goal is that we want to modify the AWARE code as little as possible so that we can pull updates from them as they occur. This implies that the ideal structure will involve a wrapper that represents the cordova bits.

First, let us consider the anatomy of an AWARE plugin.
@xubowenhaoren pointed to the battery plugin as the easiest to understand.

https://github.com/denzilferreira/aware-client/blob/master/aware-core/src/main/java/com/aware/Battery.java

It looks like:

  1. AWARE does not use SQLite directly but uses the ContentProvider interface instead. The rows are constructed as ContentValues objects and then put into the resolver

    context.getContentResolver().insert(Battery_Data.CONTENT_URI, rowData);
    
  2. Each ContentProvider (and by extension, each sensor), has its own SyncAdapter associated with it. The sync request is set here ContentResolver.requestSync(request);

So probably the easiest approach is to continue using the ContentProvider architecture for AWARE. In terms of syncing, you can choose to sync to an AWARE server and then merge the data on the server side, or you can write a new SyncAdapter that syncs the data to an e-mission server.

Note that every sensor in AWARE has its own sync adapter. But the base class appears to be
https://github.com/denzilferreira/aware-client/blob/master/aware-core/src/main/java/com/aware/syncadapters/AwareSyncAdapter.java
Modifying the onPerformSync method of that adapter (or any of the methods it calls, such as offloadData) should make it possible to choose where the data goes to the server.

But that decision is independent of pluginizing the sensor. IMHO, the easiest way to pluginize this code is to leave it untouched and to write a wrapper that inherits from CordovaPlugin. You could either define an external method to start the data collection, which would be consistent with accepting consent and then turning on tracking, or you could just implement the init method of the plugin and have it create the BatteryService and start it.

@shankari
Copy link
Contributor

You could also choose to do this in two steps:

  1. Only pluginize the sensor, and continue to send the data to an AWARE server
  2. After getting that to work, implement a new sync adapter to e-mission if necessary

That will also get you familiar with cordova and reduce the unknown factor.

@shankari
Copy link
Contributor

There are many examples of cordova plugins on the internet. Including the Cordova battery plugin https://github.com/apache/cordova-plugin-battery-status that you can look at for an example of the the cordova plugin interface.

This defines an externally callable method called "start" which sets up the listeners. In your case, that would call onCreate on the AWARE battery service. You would then call start from the javascript during onboarding and everything will Just Work.
https://github.com/apache/cordova-plugin-battery-status/blob/master/src/android/BatteryListener.java#L57

I think cordova also has a user guide or some kind of similar documentation.

@xubowenhaoren
Copy link
Contributor Author

You mentioned that each e-mission plugin only runs after the user consents. So in the repackaging, do I need to check for user contents as well?

@shankari
Copy link
Contributor

shankari commented Feb 13, 2020

It is up to you. You are building your own version of the app and can do whatever you want. Theoretically, you can call markConsented on the e-mission plugin without showing anything to the user since it is just a javascript call.

So it is possible using the e-mission plugin to skip the consent. I just chose to believe that most people will be careful of consent and gave them the tools to handle it properly. e.g. the markConsented method.

So basically if I didn't have the method, then people would have to build it in and everybody is lazy. I made it easier (the default) to start tracking only after consent, and harder to remove it (have to edit onboarding).

@shankari
Copy link
Contributor

@ariasfelipe also wrote a shake detection plugin that used local processing on the phone to detect shakes. This is a much more scalable solution because otherwise the volume of accelerometer data is too high. He demoed it, but I am not sure how well it works in the real world.
https://github.com/e-mission/e-mission-shake-detect/

@shankari
Copy link
Contributor

@xubowenhaoren if you just want an example of wrapping native code in a plugin, I would not recommend the shake detect code, since it is much more complex than you need.
You should use the step-by-step cordova guide
https://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/
combined with the simplistic example
https://github.com/ModusCreateOrg/cordova-plugin-example
or other tutorials on the internet
https://blogs.sap.com/2017/08/18/step-by-step-to-create-a-custom-cordova-plugin-for-android-and-consume-it-in-your-ui5-application/

The shake detect code does allow the user to configure the prompt that is displayed when the shake is detected. What kind of local processing are you planning to do, and what do you want as the resulting output?

@xubowenhaoren
Copy link
Contributor Author

I want the output to match current AWARE standards, making a functionally equivalent migration. Therefore, I would likely need to follow AWARE's approach of wrapping data. Here is one of their data providers.

@shankari
Copy link
Contributor

shankari commented Feb 16, 2020

with the approach outlined in #501 (comment) you will continue to use the AWARE data format. In fact, you will continue to use their local storage and their server (at least in step 1). So I am not sure what this comment means.

Note that in #501 (comment), I am talking about wrapping code, not data

Update 1:

You don't care about the AWARE implementation details. Once the AWARE services are launched in the background, they will continue to do their stuff in their way. If that changes in the new rewrite, you are not affected.

All you need to do is to wrap the code and launch the aware services properly from the init or exec function of the plugin. Nothing else.

Update 2:

In other words, remember all the lectures on software modularity :) focus on the interface and not the implementation.

@xubowenhaoren
Copy link
Contributor Author

Thanks for the clarification. It seems like you've made structural changes to the e-mission-docs and I cannot find your notes on how to add a new plugin to a client. The closest I could find is this deployment guide.

@shankari
Copy link
Contributor

@xubowenhaoren I don't think I ever had notes on how to add a new plugin to a client.

Apache Cordova is standard, well-documented technology, and I don't want to duplicate their documentation.

I have added links to the Apache Cordova documentation on creating and managing plugins
#501 (comment)
along with a link to a third party guide.

@xubowenhaoren
Copy link
Contributor Author

Now, looking back at what you initially suggested last time and what I've done at this point, I'm afraid that my approach has been somewhat misdirected. What I've done is that I tried to copy over AWARE codes, change them to override e-mission methods and fix any dependency issues along the way. With that said, there are certainly AWARE modules (e.g. SSL certificate helpers) that I don't know how to handle yet.

I think this is NOT what you meant by "creating wrappers" to codes (not data).

@xubowenhaoren
Copy link
Contributor Author

About the user consent: before we start collectin the user data, we would ask the participant to sign a consent form. This is done before the participants install their apps, and it's very unlikely that the consent criteria need to change during the study. So we don't need to handle consents in this repackaging of the app.

@shankari
Copy link
Contributor

I suggest that you create a cordova plugin with the following interface.

in www/aware.js:

/*global cordova, module*/

var exec = require("cordova/exec")

var Aware = {
}

in src/android/AwarePlugin.java something like this

import aware.....AwareService;

public class AwarePlugin extends CordovaPlugin {
    public static final String TAG = "AwarePlugin";

    @Override
    public void pluginInitialize() {
        AwareService service = new AwareService();
        service.start();
    }
}

@xubowenhaoren
Copy link
Contributor Author

AWARE clients read aware-core status and modify aware-core settings via a central Aware.settings method. In this repackaging, this would not be directly accessible. Should I then expose Aware.settings in aware.js as JS methods, then use the AwarePlugin.java interface to call the native Aware.settings method?

@shankari
Copy link
Contributor

shankari commented Feb 24, 2020

Yes. In that case, you would want to do something like

in www/aware.js (similar to datacollection.js)

/*global cordova, module*/

var exec = require("cordova/exec")

var Aware = {
    getConfig: function () {
        return new Promise(function(resolve, reject) {
            exec(resolve, reject, "Aware", "getConfig", []);
        });
    },
    setConfig: function (newConfig) {
        return new Promise(function(resolve, reject) {
            exec(resolve, reject, "Aware", "setConfig", [newConfig]);
        });
    },
}

in src/android/AwarePlugin.java (similar to DataCollectionPlugin.java)

import aware.....AwareService;

public class AwarePlugin extends CordovaPlugin {
    public static final String TAG = "AwarePlugin";

    @Override
    public void pluginInitialize() {
        AwareService service = new AwareService();
        service.start();
    }

    @Override
    public boolean execute(String action, JSONArray data, final CallbackContext callbackContext) throws JSONException {
        if (action.equals("getConfig")) {
            // call AWARE code to get settings
        } else if (action.equals("setConfig")) {
           // call AWARE code to set settings
        }
    }
}

@shankari
Copy link
Contributor

I believe that this is the main AWARE service which launches all the other services depending on the settings.
https://github.com/denzilferreira/aware-client/blob/master/aware-core/src/main/java/com/aware/Aware.java

@xubowenhaoren
Copy link
Contributor Author

Hi,

I realize that the whole aware-core service can be incorporated conveniently via a maven import. Could you point me to an example showing how I can achieve this in a Cordova plugin.xml?

@shankari
Copy link
Contributor

shankari commented Mar 2, 2020

searching for "plugin.xml maven", I find the cordova plugin documentation
https://cordova.apache.org/docs/en/dev/plugin_ref/spec.html
which includes the example

On Android (as of cordova-android@4.0.0), framework tags are used to include Maven dependencies, or to include bundled library projects.

@xubowenhaoren
Copy link
Contributor Author

Thanks! But here we have a follow-up problem. Since now we import aware-core services via maven, how should we register the services (e.g. Aware.java) in the Cordova plugin.xml?

@shankari
Copy link
Contributor

shankari commented Mar 2, 2020

With the FQN,

so you would do something like

        <service
            android:name="com.aware....FooService"
            android:enabled="true"
            android:exported="false">
        </service>

@xubowenhaoren
Copy link
Contributor Author

Another follow-up: in line 119, you are linking the project source codes and res files in the project.xml. Do I need to do this for the aware-core files?

@shankari
Copy link
Contributor

shankari commented Mar 2, 2020

No. Those are only for source code that will be compiled as part of the plugin, not complied libraries.

@shankari shankari changed the title Repackaging AWARE features as e-mission plugins Repackaging AWARE features as cordova plugins Mar 30, 2020
@xubowenhaoren
Copy link
Contributor Author

Hello,

I wish to add a (placeholder) UI page that will eventually be replaced by the functional Aware UI. Where can I add this page as a fragment on the current e-mission UI? Is it the main.js?

@shankari
Copy link
Contributor

shankari commented Apr 3, 2020

Probably the easiest is to add a new tab. You can look at examples of current tabs or the angular router documentation.

@xubowenhaoren
Copy link
Contributor Author

  <!-- Diary Tab -->
  <ion-tab title="Diary" icon="ion-map" href="#/root/main/diary">
    <ion-nav-view name="main-diary"></ion-nav-view>
  </ion-tab>

In the Diary Tab above, what does the href attribute refer to? Also, after I put in the web UI files in www/js and www/templates, what do I need to put in main.html to refer to those files?

@shankari
Copy link
Contributor

shankari commented Apr 3, 2020

@xubowenhaoren this is not e-mission specific, this is standard angular-ui-router syntax. There are hundreds of tutorials on angular-ui-router. Please check them out.

@xubowenhaoren
Copy link
Contributor Author

xubowenhaoren commented Apr 5, 2020

To check if I get this right:

The main.js has a list of angular.module, each with a $stateProvider$.
The main.html defines the actual order of these modules.

Take the root.main.accessmap as an example. In main.js, it is defined as

    .state('root.main.accessmap', {
    url: '/accessmap',
    views: {
      'main-accessmap': {
        templateUrl: 'templates/accessmap/accessmap.html',
        controller: 'AccessMapCtrl'
      }
    },
  })

The templateUrl specifies the HTML location of the page while controller defines the JS elements (e.g. buttons) in js/accessmap/accessmap.js.

As a self-answer to my earlier question , href is for ionic to navigate through pages and not workspace file locations; name in ion-nav-view corresponds to the views in main.js.

Please address any mistakes or missing pieces.

@xubowenhaoren
Copy link
Contributor Author

We found that during the Cordova call to the native Aware plugin, the Authority it got was edu.berkeley.eecs.emission.provider.aware.

However, if you look into the sync_barometer.xml in Aware-core, the authority is com.aware.provider.barometer.

We think that the authority mismatch can be a problem; however, one native Android app that we've worked on, has the package name "com.aware.plugin.cmu.sup".

@shankari
Copy link
Contributor

Yes, so this mismatch is the reason that the sync adapter is not launching the sync service correctly. If you look at the implementation of Aware_Provider.getAuthority, it uses context.getPackageName() + ".provider.aware";

So as far as I can figure out, context.getPackageName() (https://developer.android.com/reference/android/content/Context#getPackageName()) returns the

Return the name of this application's package.

So I am not sure how it returns com.aware.provider.barometer even in the pure native AWARE client.

Are you sure you are printing the correct authority? You are printing the authority in the plugin code, and not in the broadcaster code which is where the ContentResolver is really called from. Add new logging statements to print the authority right in the ContextBroadcaster before the sync method is invoked

@xubowenhaoren
Copy link
Contributor Author

JitPack finally fetched my up-to-date commit. Here are the latest syncing logs:

2020-06-17 00:06:46.629 30367-30639/edu.berkeley.eecs.emission D/AwarePlugin: manual syncing...
2020-06-17 00:06:46.653 30367-30639/edu.berkeley.eecs.emission D/AwarePlugin: Account {name=awareframework, type=com.awareframework}
2020-06-17 00:06:46.662 30367-30639/edu.berkeley.eecs.emission D/AwarePlugin: edu.berkeley.eecs.emission.provider.aware
2020-06-17 00:06:46.667 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-17 00:06:46.667 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: 
2020-06-17 00:06:46.668 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Syncing now
2020-06-17 00:06:46.670 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.aware
2020-06-17 00:06:46.677 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-17 00:06:46.677 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: false
2020-06-17 00:06:46.678 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-17 00:06:46.679 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-17 00:06:46.679 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-17 00:06:46.679 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Syncing now
2020-06-17 00:06:46.680 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications

Two points that we can make:

  1. Since Aware-core gets the provider through the package name, then any client, whether native or not, won't match with the Aware's provider name.
  2. If so, how did the native client manage to sync?

I will revisit the native app and observe its syncing logs tomorrow.

@shankari
Copy link
Contributor

shankari commented Jun 17, 2020

@xubowenhaoren That is what I said earlier #501 (comment)

So I am not sure how it returns com.aware.provider.barometer even in the pure native AWARE client.

Have you checked the steps in

Are you sure you are printing the correct authority? You are printing the authority in the plugin code, and not in the broadcaster code which is where the ContentResolver is really called from.

@xubowenhaoren
Copy link
Contributor Author

Here are the syncing logs from a native AWARE Android client:

2020-06-18 00:58:24.575 8621-8621/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-18 00:58:24.575 8621-8621/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster onReceive: 
2020-06-18 00:58:24.575 8621-8621/com.aware.plugin.cmu.sup D/AWARE Aware.java: Syncing now
2020-06-18 00:58:24.576 8621-8621/com.aware.plugin.cmu.sup D/AWARE Aware.java: Account {name=awareframework, type=com.awareframework} com.aware.plugin.cmu.sup.provider.aware
2020-06-18 00:58:24.578 8621-8621/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-18 00:58:24.578 8621-8621/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster onReceive: false
2020-06-18 00:58:24.578 8621-8621/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-18 00:58:24.578 8621-8621/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: true
2020-06-18 00:58:24.578 8621-8621/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: true
2020-06-18 00:58:24.578 8621-8621/com.aware.plugin.cmu.sup D/AWARE Applications: Syncing now
2020-06-18 00:58:24.579 8621-8621/com.aware.plugin.cmu.sup D/AWARE Applications: Account {name=awareframework, type=com.awareframework} com.aware.plugin.cmu.sup.provider.applications
2020-06-18 00:58:24.634 8621-9621/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: onPerformSync called
2020-06-18 00:58:24.634 8621-9622/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: onPerformSync called
2020-06-18 00:58:24.652 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467104648 log_message=STUDY-SYNC: aware_device
2020-06-18 00:58:24.652 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467104650 log_message=STUDY-SYNC: applications_foreground
2020-06-18 00:58:24.679 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Syncing applications_foreground to: [study server link] in batches of 10000
2020-06-18 00:58:24.679 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Syncing aware_device to: [study server link] in batches of 10000
2020-06-18 00:58:25.092 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467105089 log_message=STUDY-SYNC: aware_studies
2020-06-18 00:58:25.109 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Syncing aware_studies to: [study server link] in batches of 10000
2020-06-18 00:58:25.437 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467105433 log_message={"table":"applications_foreground","last_sync_timestamp":1592467100705}
2020-06-18 00:58:25.446 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Sync OK into applications_foreground [ 2 rows ]
2020-06-18 00:58:25.456 8621-9622/com.aware.plugin.cmu.sup D/AWARE: applications_foreground sync time: 00:00
2020-06-18 00:58:25.474 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467105471 log_message=STUDY-SYNC: applications_history
2020-06-18 00:58:25.487 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Syncing applications_history to: [study server link] in batches of 10000
2020-06-18 00:58:25.799 8621-8752/com.aware.plugin.cmu.sup V/FA: Inactivity, disconnecting from the service
2020-06-18 00:58:25.916 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467105914 log_message=STUDY-SYNC: applications_notifications
2020-06-18 00:58:25.929 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467105926 log_message={"table":"aware_studies","last_sync_timestamp":0}
2020-06-18 00:58:25.929 8621-9622/com.aware.plugin.cmu.sup D/AWARE: Syncing applications_notifications to: [study server link] in batches of 10000
2020-06-18 00:58:25.937 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Sync OK into aware_studies [ 1 rows ]
2020-06-18 00:58:25.938 8621-9621/com.aware.plugin.cmu.sup D/AWARE: aware_studies sync time: 00:00
2020-06-18 00:58:25.955 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=726d46c9-c2ab-407a-ac5d-b62b8294eafc timestamp=1592467105953 log_message=STUDY-SYNC: aware_log
2020-06-18 00:58:25.968 8621-9621/com.aware.plugin.cmu.sup D/AWARE: Syncing aware_log to: [study server link] in batches of 10000

@xubowenhaoren
Copy link
Contributor Author

@xubowenhaoren That is what I said earlier #501 (comment)

So I am not sure how it returns com.aware.provider.barometer even in the pure native AWARE client.

Have you checked the steps in

Are you sure you are printing the correct authority? You are printing the authority in the plugin code, and not in the broadcaster code which is where the ContentResolver is really called from.

Hmm, I think I added logs in onReceive() of the ContextBroadcaster.

@shankari
Copy link
Contributor

shankari commented Jun 18, 2020

Did you? Can you double check, maybe change the log message to say "inside ContextBroadcaster" and ensure that they are actually being printed out? If you have the same logs in multiple places, you don't know which are getting called and which are getting skipped.

I only see the provider from Aware Applications. What are the providers from the other call sites?

2020-06-17 00:06:46.680 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications

@shankari
Copy link
Contributor

If you add the other providers and still can't figure it out, maybe ask the AWARE team how they ensure provider match up?

@xubowenhaoren
Copy link
Contributor Author

xubowenhaoren commented Jun 20, 2020

Did you? Can you double-check, maybe change the log message to say "inside ContextBroadcaster" and ensure that they are being printed out? If you have the same logs in multiple places, you don't know which are getting called and which are getting skipped.

I only see the provider from Aware Applications. What are the providers from the other call sites?

2020-06-17 00:06:46.680 30367-30367/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications

That might be acceptable. You can see that native Aware is also calling the sync from Aware Applications.

@xubowenhaoren
Copy link
Contributor Author

I've added the "inside ContextBroadcaster" checks; now let's wait a bit for JitPack to populate. I will contact the Aware team if it doesn't reveal more clue.

@shankari
Copy link
Contributor

That might be acceptable. You can see that native Aware is also calling the sync from Aware Applications.

native Aware is also calling the sync from the same three places (Aware.java, sensor, applications). Not clear which one results in the onPerformSync. Do you have any reason to believe that it is the one from Applications?

@xubowenhaoren
Copy link
Contributor Author

You are right; I shouldn't rely on the logcat orders. Let me attach the latest logs here and ask the AWARE team.

2020-06-23 00:34:50.873 29576-30065/edu.berkeley.eecs.emission D/AwarePlugin: checking battery
2020-06-23 00:34:50.878 29576-30065/edu.berkeley.eecs.emission D/AwarePlugin- Aware: Battery Optimizations: true
2020-06-23 00:34:50.884 29576-30065/edu.berkeley.eecs.emission D/AwarePlugin: Is study: true, is core running: true
2020-06-23 00:34:55.664 29576-30065/edu.berkeley.eecs.emission D/AwarePlugin: manual syncing...
2020-06-23 00:34:55.683 29576-30065/edu.berkeley.eecs.emission D/AwarePlugin: Account {name=awareframework, type=com.awareframework}
2020-06-23 00:34:55.689 29576-30065/edu.berkeley.eecs.emission D/AwarePlugin: edu.berkeley.eecs.emission.provider.aware
2020-06-23 00:34:55.694 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster INSIDE
2020-06-23 00:34:55.694 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-23 00:34:55.694 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: 
2020-06-23 00:34:55.694 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Syncing now
2020-06-23 00:34:55.697 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.aware
2020-06-23 00:34:55.705 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster INSIDE
2020-06-23 00:34:55.705 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: false
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster INSIDE
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Syncing now
2020-06-23 00:34:55.708 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications

@shankari
Copy link
Contributor

I see the account information and provider information for both Aware and Aware Applications

2020-06-23 00:34:55.697 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.aware
...
2020-06-23 00:34:55.708 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications

But not for Aware Sensor.

2020-06-23 00:34:55.705 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster INSIDE
2020-06-23 00:34:55.705 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: false

Do you have log statements there too? Why are they not getting printed out? Is that related to

2020-06-23 00:34:55.706 29576-29576/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: false

@xubowenhaoren
Copy link
Contributor Author

Great catch! I added the missing log statement. Currently waiting for JitPack to re-package.

@xubowenhaoren
Copy link
Contributor Author

After adding the log statement, here are the results for the emission plugin:

2020-06-28 11:34:45.024 29712-30077/edu.berkeley.eecs.emission D/AwarePlugin: manual syncing...
2020-06-28 11:34:45.030 29712-30077/edu.berkeley.eecs.emission D/AwarePlugin: Account {name=awareframework, type=com.awareframework}
2020-06-28 11:34:45.036 29712-30077/edu.berkeley.eecs.emission D/AwarePlugin: edu.berkeley.eecs.emission.provider.aware
2020-06-28 11:34:45.040 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster INSIDE
2020-06-28 11:34:45.040 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:34:45.040 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: 
2020-06-28 11:34:45.040 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Syncing now
2020-06-28 11:34:45.041 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.aware
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster INSIDE
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: false
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster INSIDE
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-28 11:34:45.044 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Syncing now
2020-06-28 11:34:45.045 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications
2020-06-28 11:34:52.311 29712-30077/edu.berkeley.eecs.emission D/AwarePlugin: manual syncing...
2020-06-28 11:34:52.318 29712-30077/edu.berkeley.eecs.emission D/AwarePlugin: Account {name=awareframework, type=com.awareframework}
2020-06-28 11:34:52.322 29712-30077/edu.berkeley.eecs.emission D/AwarePlugin: edu.berkeley.eecs.emission.provider.aware
2020-06-28 11:34:52.336 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster INSIDE
2020-06-28 11:34:52.336 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:34:52.336 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: ContextBroadcaster onReceive: 
2020-06-28 11:34:52.336 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Syncing now
2020-06-28 11:34:52.337 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware.java: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.aware
2020-06-28 11:34:52.339 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster INSIDE
2020-06-28 11:34:52.339 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:34:52.339 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Aware_Sensor: ContextBroadcaster onReceive: false
2020-06-28 11:34:52.340 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster INSIDE
2020-06-28 11:34:52.340 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:34:52.340 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-28 11:34:52.340 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: ContextBroadcaster onReceive: true
2020-06-28 11:34:52.340 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Syncing now
2020-06-28 11:34:52.340 29712-29712/edu.berkeley.eecs.emission D/AwarePlugin- Aware Applications: Account {name=awareframework, type=com.awareframework} edu.berkeley.eecs.emission.provider.applications
2020-06-28 11:35:00.039 29712-29712/edu.berkeley.eecs.emission D/AWARE::Scheduler: Checking for scheduled tasks: edu.berkeley.eecs.emission
2020-06-28 11:35:00.043 29712-29712/edu.berkeley.eecs.emission D/AWARE::Scheduler: Scheduled tasks for edu.berkeley.eecs.emission: 1
2020-06-28 11:35:00.050 29712-29712/edu.berkeley.eecs.emission I/AWARE::Scheduler: Time now is: Sun Jun 28 11:35:00 PDT 2020
2020-06-28 11:35:00.052 29712-29712/edu.berkeley.eecs.emission I/AWARE::Scheduler: Scheduler info: id=schedule_aware_keep_alive schedule={"schedule":{"schedule_id":"schedule_aware_keep_alive","action":{"type":"service","intent_action":"ACTION_AWARE_KEEP_ALIVE","class":"edu.berkeley.eecs.emission\/com.aware.Aware"},"trigger":{"interval":30,"random":{},"context":[],"condition":[]}}}
2020-06-28 11:35:00.058 29712-29712/edu.berkeley.eecs.emission I/AWARE::Scheduler: Scheduler last triggered: Sun Jun 28 11:34:08 PDT 2020
2020-06-28 11:35:00.059 29712-29712/edu.berkeley.eecs.emission D/AWARE::Scheduler: Checking interval elapsed: 1 vs 30 minutes elapsed
2020-06-28 11:35:00.059 29712-29712/edu.berkeley.eecs.emission D/AWARE::Scheduler: Trigger interval: false

Here are the results for the native client:

2020-06-28 11:38:29.037 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster INSIDE
2020-06-28 11:38:29.037 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:38:29.037 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster onReceive: 
2020-06-28 11:38:29.037 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware.java: Syncing now
2020-06-28 11:38:29.038 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware.java: Account {name=awareframework, type=com.awareframework} com.aware.plugin.cmu.sup.provider.aware
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster INSIDE
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster onReceive: false
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster INSIDE
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: true
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: true
2020-06-28 11:38:29.041 1084-1084/com.aware.plugin.cmu.sup D/AWARE Applications: Syncing now
2020-06-28 11:38:29.042 1084-1084/com.aware.plugin.cmu.sup D/AWARE Applications: Account {name=awareframework, type=com.awareframework} com.aware.plugin.cmu.sup.provider.applications
2020-06-28 11:38:29.107 1084-2451/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: onPerformSync called
2020-06-28 11:38:29.121 1084-2452/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: onPerformSync called
2020-06-28 11:38:29.141 1084-2451/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=a2a0ffc5-300b-4aa0-a8ab-5ddb26753aa2 timestamp=1593369509138 log_message=STUDY-SYNC: aware_device
2020-06-28 11:38:29.153 1084-2452/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=a2a0ffc5-300b-4aa0-a8ab-5ddb26753aa2 timestamp=1593369509150 log_message=STUDY-SYNC: applications_foreground

We notice that the even in the native client, the account information doesn't print with Aware_Sensor, so it might not be related to the manual syncing.

@shankari
Copy link
Contributor

@xubowenhaoren fair enough. Any response from the AWARE team?

@xubowenhaoren
Copy link
Contributor Author

Not yet. We may need to look at this by ourselves during the meeting.

@shankari
Copy link
Contributor

shankari commented Jul 7, 2020

There is an even simpler and more obvious check for the account that is used. I am not sure whether you have already tried it.

The method signature of onPerformSync is

	public void onPerformSync(Account account, Bundle extras, String authority,
			ContentProviderClient provider, SyncResult syncResult) {

So you can add log statements into the AWARE onPerformSync to print out the incoming parameters. So we can know exactly which account and authority was used for the successful sync in the native client. This may give us a clue on how to set up the values for the plugin.

@xubowenhaoren
Copy link
Contributor Author

Here are the successful sync messages in the native client:

2020-07-09 19:39:22.462 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster INSIDE
2020-07-09 19:39:22.463 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-07-09 19:39:22.463 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware.java: ContextBroadcaster onReceive: 
2020-07-09 19:39:22.463 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware.java: Syncing now
2020-07-09 19:39:22.464 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware.java: Account {name=awareframework, type=com.awareframework} com.aware.plugin.cmu.sup.provider.aware
2020-07-09 19:39:22.466 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster INSIDE
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Aware_Sensor: ContextBroadcaster onReceive: false
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster INSIDE
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: ACTION_AWARE_SYNC_DATA
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: true
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Applications: ContextBroadcaster onReceive: true
2020-07-09 19:39:22.467 32270-32270/com.aware.plugin.cmu.sup D/AWARE Applications: Syncing now
2020-07-09 19:39:22.468 32270-32270/com.aware.plugin.cmu.sup D/AWARE Applications: Account {name=awareframework, type=com.awareframework} com.aware.plugin.cmu.sup.provider.applications
2020-07-09 19:39:22.563 32270-1316/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: onPerformSync called
2020-07-09 19:39:22.564 32270-1316/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: Account Account {name=awareframework, type=com.awareframework} authority com.aware.plugin.cmu.sup.provider.aware provider android.content.ContentProviderClient@db95908
2020-07-09 19:39:22.564 32270-1318/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: onPerformSync called
2020-07-09 19:39:22.564 32270-1318/com.aware.plugin.cmu.sup D/AWARE AwareSyncAdapter: Account Account {name=awareframework, type=com.awareframework} authority com.aware.plugin.cmu.sup.provider.applications provider android.content.ContentProviderClient@53b88a1
2020-07-09 19:39:22.589 32270-1318/com.aware.plugin.cmu.sup D/AWARE: Aware_Log: 
    device_id=70df3d1f-7916-4e87-a532-35b8c650369c timestamp=1594348762584 log_message=STUDY-SYNC: applications_foreground

@xubowenhaoren
Copy link
Contributor Author

The key to solve the syncing problem is to add the account/provider/authority configuration in your app build.gradle. Our example is

android {
    defaultConfig {
        resValue "string", "provider_applications", android.defaultConfig.applicationId + ".provider.applications"
        resValue "string", "provider_aware", android.defaultConfig.applicationId + ".provider.aware"
    }

@xubowenhaoren
Copy link
Contributor Author

I tried to automate the provider/authority configuration via build-extras.gradle (link).

While Cordova is able to inject the strings into generated.xml, the applicationId is wrong:

<string name="provider_accelerometer" translatable="false">null.provider.accelerometer</string>
    <string name="provider_applications" translatable="false">null.provider.applications</string>
    <string name="provider_aware" translatable="false">null.provider.aware</string>
    <string name="provider_barometer" translatable="false">null.provider.barometer</string>
    <string name="provider_battery" translatable="false">null.provider.battery</string>
    <string name="provider_bluetooth" translatable="false">null.provider.bluetooth</string>
--- The rest are the same ---

@shankari
Copy link
Contributor

shankari commented Jul 14, 2020

You also have to set the application ID in build.gradle

https://developer.android.com/studio/build/application-id

It looks like it is required, so I am not sure why it is not set in the cordova app. Are there multiple build-extras.gradle?

@xubowenhaoren
Copy link
Contributor Author

I bet the native app is doing this and cordova is not.

Yes the native app is doing this:

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.aware.plugin.cmu.sup"
        minSdkVersion 24
        targetSdkVersion target_sdk
    ...

But so is Cordova. This is my auto generated /phone-app/platforms/android/app/build.gradle:

android {
    defaultConfig {
        versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
        applicationId privateHelpers.extractStringFromManifest("package")

        if (cdvMinSdkVersion != null) {
            minSdkVersion cdvMinSdkVersion
        }

Since the Cordova app already sets the applicationId, I probably shouldn't override it with a hardcoded value in my build-extras.gradle.

@shankari
Copy link
Contributor

Not sure what privateHelpers.extractStringFromManifest("package") returns. As a first step, can you try to use

resValue "string", "provider_accelerometer", <your hardcoded value> + ".provider.accelerometer"
....

to ensure that everything works? We can debug the applicationId issue after that

@xubowenhaoren
Copy link
Contributor Author

Yes, the hardcode approach works. Here is my latest build.gradle with sync working.

I will now temporarily shift gears to work on the UI and add more features to the plugin.

@shankari
Copy link
Contributor

shankari commented Jul 16, 2020

I would just document (for now) that anybody else who wants to use the plugin needs to change the hardcoded value to their own hardcoded app package. We can debug it later.

@xubowenhaoren
Copy link
Contributor Author

xubowenhaoren commented Aug 9, 2020

Hello, the following issue appeared after I upgrade emission to SDK 29. Feature-wise, the buttons don't interact with the plugin any more. If you wish to recreate the issue, you can use my fork here https://github.com/xubowenhaoren/e-mission-phone/tree/aware

2020-08-09 14:54:55.592 17141-17141/edu.berkeley.eecs.emission I/chromium: [INFO:CONSOLE(23)] "Finished changing state from {"url":"/goals","views":{"main-goals":{"templateUrl":"templates/main-goals.html","controller":"GoalsCtrl"}},"name":"root.main.goals"} to {"url":"/aware","views":{"main-aware":{"templateUrl":"templates/aware/aware.html","controller":"AwareCtrl"}},"name":"root.main.aware"}", source: http://localhost/js/controllers.js (23)
2020-08-09 14:54:55.615 17141-17141/edu.berkeley.eecs.emission I/chromium: [INFO:CONSOLE(26794)] "Error: [$injector:unpr] Unknown provider: $cordovaInAppBrowserProvider <- $cordovaInAppBrowser <- AwareCtrl
    http://errors.angularjs.org/1.5.3/$injector/unpr?p0=%24cordovaInAppBrowserProvider%20%3C-%20%24cordovaInAppBrowser%20%3C-%20AwareCtrl
        at http://localhost/lib/ionic/js/ionic.bundle.js:13438:12
        at http://localhost/lib/ionic/js/ionic.bundle.js:17788:19
        at Object.getService [as get] (http://localhost/lib/ionic/js/ionic.bundle.js:17941:39)
        at http://localhost/lib/ionic/js/ionic.bundle.js:17793:45
        at getService (http://localhost/lib/ionic/js/ionic.bundle.js:17941:39)
        at injectionArgs (http://localhost/lib/ionic/js/ionic.bundle.js:17965:58)
        at Object.instantiate (http://localhost/lib/ionic/js/ionic.bundle.js:18007:18)
        at $controller (http://localhost/lib/ionic/js/ionic.bundle.js:23412:28)
        at Object.self.appendViewElement (http://localhost/lib/ionic/js/ionic.bundle.js:59900:24)
        at Object.render (http://localhost/lib/ionic/js/ionic.bundle.js:57893:41)", source: http://localhost/lib/ionic/js/ionic.bundle.js (26794)

@shankari
Copy link
Contributor

shankari commented Aug 9, 2020

@xubowenhaoren you need to remove the dependency on $cordovaInAppBrowser. Please see e-mission/e-mission-phone@61513d9

@xubowenhaoren
Copy link
Contributor Author

Thanks, everything is working again.

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

No branches or pull requests

2 participants