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

WIP - Issue #181 - Wear Support #198

Closed
wants to merge 21 commits into from
Closed

WIP - Issue #181 - Wear Support #198

wants to merge 21 commits into from

Conversation

pohh
Copy link

@pohh pohh commented Dec 11, 2014

@barbeau This is getting quite large so I figure I'll take a break and get some feedback.

I would like to get an app on the wearable which has 2 use cases:

  1. Browses starred stops.
  2. View ArrivalInfo for a stop.

Designwise, I created a long running NodeService on the device which is the sole interface for the wearable to the Oba data.

The wearable fires messages to the NodeService to request data synchronization updates.

The NodeService will then update the Wearable datastores with the requested data updates via Wearable.DataApi calls. The source of these data updates can be direct calls to the ObaApi or data from the ObaProvider, depending on the use case requirements.

For now I've only implemented the first use case of retrieving Starred Stops.

Implementing a polling ArrivalInfo hook into the NodeService would be next on my agenda.

I tried to document any areas I feel required extra inspection with todo tags.

@barbeau
Copy link
Member

barbeau commented Dec 11, 2014

Thanks @pohh! My schedule is pretty slammed right now, but I'll try to take a look in the next few days.

Also - is it possible to test this on a Wear emulator? If so, did you find any good tutorials for setting this up? I don't have a Wear device and haven't delved into Wear development yet.

@pohh
Copy link
Author

pohh commented Dec 11, 2014

Instructions for real device + wear emulator:
https://developer.android.com/training/wearables/apps/creating.html#SetupEmulator

Instructions for device emulator + wear emulator:
http://kennethmascarenhas.wordpress.com/2014/08/19/developing-for-android-wear-with-emulators/

install the updated onebusawayandroid module to the device to replace your exiting onebusaway installation. This is required because I added a new service.

Then install the wear module to the wearable. If everything is working smoothly you should see a scrollable list of your starred stops. Currently there is no auto refresh mechanism but you can force an update by tapping "Load More" on the wearable activity.

I'm sure some of the logic I've done is captured In other parts of the current code base, so if you could point out any inconsistencies in the design and/or style we can talk about how to refactor appropriately. Looking forward to your feedback.

@barbeau
Copy link
Member

barbeau commented Dec 15, 2014

@pohh I set this up running on Wearable emulator and real device (LG G3 w/ Android 4.4.2), and installed fresh copies of the onebusaway-android and wear apps to the device and wear emulator, respectively.

However, I was only able to get the "Load More" button on the wearable to show up:

image

Swiping, tapping, etc. had no effect, other than to dismiss the card. ADB log is below, and I don't see any obvious issues:

12-15 17:49:55.119    1792-1792/com.joulespersecond.seattlebusbot D/﹕ HostConnection::get() New Host Connection established 0xb819c9c0, tid 1792
12-15 17:49:55.139    1792-1792/com.joulespersecond.seattlebusbot W/EGL_emulation﹕ eglSurfaceAttrib not implemented
12-15 17:49:55.149    1792-1792/com.joulespersecond.seattlebusbot D/OpenGLRenderer﹕ Enabling debug mode 0
12-15 17:49:55.149    1792-1792/com.joulespersecond.seattlebusbot D/OBA::GoogleApiHelper﹕ google api client connected
12-15 17:49:55.149    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ onConnectionComplete
12-15 17:49:55.149    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ refreshDataItems::uri::wear:/starredstops
12-15 17:49:55.149    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:50:00.069    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createRefreshDataItemsResultCallback::onResult
12-15 17:50:00.069    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:02.040    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:02.040    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:03.150    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:03.150    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:09.880    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:09.880    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:10.080    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:10.080    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:11.110    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:11.110    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:11.280    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:11.280    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:15.330    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:15.330    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:15.970    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:15.970    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:16.130    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:16.130    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:16.630    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:16.630    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:17.280    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:17.290    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:51:17.800    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:51:17.800    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:57:15.836    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:57:15.846    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:57:16.916    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:57:16.916    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes
12-15 17:57:22.486    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ requestStarredStops
12-15 17:57:22.486    1792-1792/com.joulespersecond.seattlebusbot D/OBA::wear::MainActivity﹕ createConnectedNodesCallback::gettingConnectedNodes

Any ideas?

I'll comment separately in-line on some code-specific items.

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.2'
compile 'com.google.android.gms:play-services-wearable:6.1.71'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer not to put a dependency for Google Play Services (wear or normal) in the core module. There are some Android devices (e.g., Google Glass, some AOSP builds) that won't have Play Services for certain reasons. I'd prefer to only include dependencies for canonical AOSP and open-source support libraries. This means that there will be some duplicated code surrounding the GoogleApiClient (on this note - see #199 - we're now using this for location too) and other classes. If we start duplicating a lot of code between components we might want to pull out a separate Play Services support module.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the play services should be abstracted out. I think I put it here because the base OBA-android module had a play services dependency already built in.

Just wanted to note though that wearables require syncing with an Android device which has the Android Wear app, and the Android Wear app already has a hard dependency on Play Services.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the play services should be abstracted out. I think I put it here because the base OBA-android module had a play services dependency already built in.

oba-android does have a dependency on play services. We've had a number of requests for a pure open-source version of OBA Android, though, so hopefully we can work in a build variant for that in the future.

Just wanted to note though that wearables require syncing with an Android device which has the Android Wear app, and the Android Wear app already has a hard dependency on Play Services.

Ok, good to know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pohh Are there any requirements you're aware of with play services version dependencies between oba-wear and oba-android? For example, is there a minimum version of play services that oba-android must be running to be able to communicate with oba-wear?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the -wear library is a superset of the normal play services library, similar to appcompat-v7 and appcompat-v4.

The playservices-wear and playservices should compile, as far as communication protocols though I can't say for sure. In the past my wear apps seemed to work when I forgot to update play services, and even after I updated, so I assume there is some level of compatibility with at least the minor revs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving forward I will remove the play services dependency from the core module and put the appropriate dependencies into the wear and oba modules.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im back. working through the issues again. this is resolved in latest commit.

@pohh
Copy link
Author

pohh commented Dec 15, 2014

Regarding the logs, what do the log for the device looking like?

The signing key and applicationId of the wear module and the device need to be identical or else they are unable to communicate.

@barbeau
Copy link
Member

barbeau commented Dec 15, 2014

@pohh Ah, sorry, I'm an idiot. I missed the whole install Wear app and forward ADB ports steps, which are kind of important. :)

Ok, seems be able to fetch data now! I now see starred stops:

image

The first time it executed after I installed Wear app I saw "Load More" as the first list entry, with other stops following it. After exiting and entering it looks they are sorted correctly.

It seems I'm having issues with the Wear emulator, though. For example, with the above image on my emulator, I can't scroll up/down at all, and if I tap "Fletcher..." stop I see handleStopDataClick::N 42nd St @ Hellenic Dr in ADB. At first I thought it was OBA wear app specific, but it seems like it affects the entire Wear UI. For example, I could swipe right to dismiss the OBA wear app. I can swipe down to mute/unmute and its very responsive. But, at the main screen, now I can't swipe up:

image

...even though I could earlier, which is how I launched the OBA wear app again on the wearable. If I re-launch from Studio it will show me the OBA wear app again with the list, and I can start to scroll up/down and it will freeze again after around a second.

Do you know if there are known issues with the Wear emulator?

@pohh
Copy link
Author

pohh commented Dec 16, 2014

@pohh Ah, sorry, I'm an idiot. I missed the whole install Wear app and forward ADB ports steps, which are kind of important. :)

No worries, I was hung up on that too at first.

The first time it executed after I installed Wear app I saw "Load More" as the first list entry, with other stops following it. After exiting and entering it looks they are sorted correctly.

I havent completely fleshed out the data syncing bit yet. Still trying to understand the lifecycle of events with the Wear data store, so I think I probably need to rework my "first load" trigger.

It seems I'm having issues with the Wear emulator, though. For example, with the above image on my emulator, I can't scroll up/down at all,

I believe the logcats on the wearable or the device will indiicate which stop data is being synced over. Could you double check that the logcats match the emulator display? The Load More entry should only render at the end of the list, so the fact that you can see it makes me think you are only getting 2 starred stops. Do you have more than 2 starred?

and if I tap "Fletcher..." stop I see handleStopDataClick::N 42nd St @ Hellenic Dr in ADB.

I did not finish implementing the handleStopDataClick. At that point I would make a network call to the OBA API to get the scheduled arrivals for that stop, and a new Wear Activity would be pushed on the Wearable screen.

At first I thought it was OBA wear app specific, but it seems like it affects the entire Wear UI. For example, I could swipe right to dismiss the OBA wear app. I can swipe down to mute/unmute and its very responsive.

I believe once you swipe right then the app is gone for good. If you wanted to start it up again you have to tap the screen, scroll to the bottom of the selection list, tap start, and then scroll to the One Bus Away app and tap to start.

But, at the main screen, now I can't swipe up:
...even though I could earlier, which is how I launched the OBA wear app again on the wearable. If I re-launch from Studio it will show me the OBA wear app again with the list, and I can start to scroll up/down and it will freeze again after around a second.

Do you know if there are known issues with the Wear emulator?

I'm not sure how you were able to get back to the wearable app by swiping up, from the home screen, as I thought that type of functionality is reserved for scrolling through notifications only. I will try to repro on my end, both in hardware and emulator.

@barbeau
Copy link
Member

barbeau commented Dec 16, 2014

The Load More entry should only render at the end of the list, so the fact that you can see it makes me think you are only getting 2 starred stops. Do you have more than 2 starred?

I only had 2 stops starred during this test, so the number of stops is correct.

I did not finish implementing the handleStopDataClick. At that point I would make a network call to the OBA API to get the scheduled arrivals for that stop, and a new Wear Activity would be pushed on the Wearable screen.

I wasn't expecting it to fetch arrival times, but what caught me off guard is that when I tap on the "Fletcher..." stop I see a different stop name in ADB ("N 42nd St @ Hellenic Dr"). I think this may be related to my other emulator problems (freezing, etc.). I'll try to play with this more tomorrow. I'm using the Intel HAXM accelerator, so maybe that's causing problems.

I'm not sure how you were able to get back to the wearable app by swiping up, from the home screen, as I thought that type of functionality is reserved for scrolling through notifications only.

I think you might be right, after I pushed a demo notification to the emulator later I was able to swipe up again. I was able to get to a wear app list somehow on the emulator, but I couldn't figure out how to get back there. With the other freezing going on, its tough to figure out what works and what doesn't.

@barbeau
Copy link
Member

barbeau commented Dec 16, 2014

@pohh Just tried this again on a new Wear emulator without HAXM enabled (i.e., "Use Host GPU" unchecked), and (ironically) its much smoother now, and doesn't seem to be locking up. Taps on stops also now show the correct ADB output corresponding to that stop. So, seems that HAXM was the issue.

@@ -54,6 +55,7 @@ public void onCreate() {

initOba();
initObaRegion();
NodeService.schedule(this); // @todo: poh - figure out optimal way to start this service
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pohh just to make sure I have this right - here's my understanding of the general Wear lifecycle:

  • User must start the oba-android app at least once to start the NodeService service. After this, NodeService will continue to run indefinitely in the background, even when the oba-android app is not running.
  • When the user interacts with the oba-wear app (running on the Wearable), oba-wear passes messages to the NodeService in oba-android to fetch starred stops and trigger API calls, which passes the resulting data back to oba-wear.

Is the above generally correct? If so, I guess NodeService would need to be setup to run on device boot as well, perhaps within BootstrapService?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this ends up using boot receiver, its also related to #41

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the above generally correct? If so, I guess NodeService would need to be setup to run on device boot as well, perhaps within BootstrapService?

I tried this initially but the bootstrap receiver only starts on boot, not on application start. So the user would need to reboot the device to get the service to start up. In the use case where the user updated to a wear version of OBA and did not reboot, the wear service would not start up and the wear app would be nonfunctional.

Thinking about it some more I think I can do one of 2 things:

  • use a WearListenerService. Saw this in the docs but wasn't sure if it was a service intended to run on the wearable or on the device.
  • Have the wearable itself send a message to the application to startup the service

Leaning towards the second option as it seems easier to implement and I'm assuming it's less subject to change since it's a more mature API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaning towards the second option as it seems easier to implement and I'm assuming it's less subject to change since it's a more mature API.

I'll defer to your judgement on this, since I know very little about Wear.

@pohh
Copy link
Author

pohh commented Dec 16, 2014

I only had 2 stops starred during this test, so the number of stops is correct.

In the case with only 2 stops, the screenshot posted looks correct since we are looking at a list where all 3 elements fit on the screen.

If you add more stops the list should be scrollable. Do you have a suggestion on a different implementation or see any cases where the current implementation should be reworked?

@barbeau
Copy link
Member

barbeau commented Dec 16, 2014

Do you have a suggestion on a different implementation or see any cases where the current implementation should be reworked?

No, I think this implementation looks good - I think all the issues I had were related to the Wear emulator freezing due to HAXM acceleration. I also wasn't able to reproduce the "Load More" item appearing above the two stops on initial use, so maybe this was related to buggy emulator too.

@barbeau barbeau changed the title Issue 181 wear support WIP - Issue #181 - Wear Support Feb 25, 2015
@barbeau barbeau closed this Nov 23, 2015
@barbeau
Copy link
Member

barbeau commented Nov 23, 2015

This PR was automatically closed by Github due to the deletion of the develop branch - we're moving back to using master as the main branch.

@pohh Is this still something you're interested in working on? Just trying to get a handle of how this PR might look going forward - whether I need to pull into a branch to preserve the initial work for someone else to look at, or whether you want to rebase on master and continue work.

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

Successfully merging this pull request may close these issues.

2 participants