Bug 47078 - [Chromium] DeviceMotion plumbing
Summary: [Chromium] DeviceMotion plumbing
Status: RESOLVED WONTFIX
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 528+ (Nightly build)
Hardware: Other OS X 10.5
: P2 Normal
Assignee: Hans Wennborg
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-04 04:19 PDT by Hans Wennborg
Modified: 2013-04-08 14:16 PDT (History)
6 users (show)

See Also:


Attachments
Patch (33.12 KB, patch)
2010-10-04 06:17 PDT, Hans Wennborg
no flags Details | Formatted Diff | Diff
Patch (34.55 KB, patch)
2010-10-05 09:29 PDT, Hans Wennborg
no flags Details | Formatted Diff | Diff
Patch (34.53 KB, patch)
2010-10-06 02:45 PDT, Hans Wennborg
no flags Details | Formatted Diff | Diff
Patch (35.40 KB, patch)
2010-10-07 07:35 PDT, Hans Wennborg
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Hans Wennborg 2010-10-04 04:19:11 PDT
[Chromium] DeviceMotion plumbing
Comment 1 Hans Wennborg 2010-10-04 06:17:19 PDT
Created attachment 69625 [details]
Patch
Comment 2 Jeremy Orlow 2010-10-04 10:02:16 PDT
Please cc darin on reviews that touch the WebKit layer.

WIll review later.
Comment 3 Darin Fisher (:fishd, Google) 2010-10-04 11:16:19 PDT
Comment on attachment 69625 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=69625&action=review

> WebKit/chromium/public/WebDeviceMotionData.h:42
> +    WEBKIT_API static WebDeviceMotionData* create(bool canProvideXAcceleration, double xAcceleration,

why heap allocated?

normally, when we use WebPrivatePtr to implement a type, it means that we
provide a constructor, destructor, initialize, reset, assign, etc. methods.
please see WebNode for an example.
Comment 4 Jeremy Orlow 2010-10-04 11:27:01 PDT
Comment on attachment 69625 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=69625&action=review

looks pretty good minus comments

> WebKit/chromium/public/WebDeviceMotionClient.h:38
> +    virtual void setController(WebDeviceMotionController*) = 0;

We no longer make webkit api's pure virtual.  Use WEBKIT_ASSERT_NOT_IMPLEMENTED and return 0 when necessary.

>> WebKit/chromium/public/WebDeviceMotionData.h:42
>> +    WEBKIT_API static WebDeviceMotionData* create(bool canProvideXAcceleration, double xAcceleration,
> 
> why heap allocated?
> 
> normally, when we use WebPrivatePtr to implement a type, it means that we
> provide a constructor, destructor, initialize, reset, assign, etc. methods.
> please see WebNode for an example.

Note that we use heap allocation only when we have virtual methods and code living in Chromium.

> WebKit/chromium/src/DeviceMotionClientProxy.cpp:72
> +

newline seems excessive...could maybe even combine the two if statements with an ||

> WebKit/chromium/src/DeviceMotionClientProxy.h:43
> +    ~DeviceMotionClientProxy();

Virtual is probably good for documentation

> WebKit/chromium/src/WebDeviceMotionController.cpp:43
> +    PassRefPtr<WebCore::DeviceMotionData> motion(*deviceMotionData);

RefPtr
Comment 5 Hans Wennborg 2010-10-05 09:29:30 PDT
Thank you both for the review.

(In reply to comment #3)
> (From update of attachment 69625 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=69625&action=review
> 
> > WebKit/chromium/public/WebDeviceMotionData.h:42
> > +    WEBKIT_API static WebDeviceMotionData* create(bool canProvideXAcceleration, double xAcceleration,
> 
> why heap allocated?
Fixed that now.

> normally, when we use WebPrivatePtr to implement a type, it means that we
> provide a constructor, destructor, initialize, reset, assign, etc. methods.
> please see WebNode for an example.
Done. (Skipping assign because I don't think it's needed.)

(In reply to comment #4)
> (From update of attachment 69625 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=69625&action=review
> 
> looks pretty good minus comments
> 
> > WebKit/chromium/public/WebDeviceMotionClient.h:38
> > +    virtual void setController(WebDeviceMotionController*) = 0;
> 
> We no longer make webkit api's pure virtual.  Use WEBKIT_ASSERT_NOT_IMPLEMENTED and return 0 when necessary.
Done using WEBKIT_ASSERT_NOT_REACHED (couldn't find WEBKIT_ASSERT_NOT_IMPLEMENTED.)

> 
> >> WebKit/chromium/public/WebDeviceMotionData.h:42
> >> +    WEBKIT_API static WebDeviceMotionData* create(bool canProvideXAcceleration, double xAcceleration,
> > 
> > why heap allocated?
> > 
> > normally, when we use WebPrivatePtr to implement a type, it means that we
> > provide a constructor, destructor, initialize, reset, assign, etc. methods.
> > please see WebNode for an example.
> 
> Note that we use heap allocation only when we have virtual methods and code living in Chromium.
> 
> > WebKit/chromium/src/DeviceMotionClientProxy.cpp:72
> > +
> 
> newline seems excessive...could maybe even combine the two if statements with an ||
Done. Keeping them on separate lines as they kind of test for different things, and I hope to remove the former statement eventually.

> 
> > WebKit/chromium/src/DeviceMotionClientProxy.h:43
> > +    ~DeviceMotionClientProxy();
> 
> Virtual is probably good for documentation
Done.

> 
> > WebKit/chromium/src/WebDeviceMotionController.cpp:43
> > +    PassRefPtr<WebCore::DeviceMotionData> motion(*deviceMotionData);
> 
> RefPtr
Done. It got slightly involved though :S (compiler doesn't see that it can use WebDeviceMotionData's conversion operator to PassRefPtr and use that to construct a RefPtr)
Comment 6 Hans Wennborg 2010-10-05 09:29:56 PDT
Created attachment 69795 [details]
Patch
Comment 7 Jeremy Orlow 2010-10-05 09:37:51 PDT
Comment on attachment 69795 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=69795&action=review

LGTM, but it'd be nice to have Darin sign off on it.

> WebKit/chromium/public/WebDeviceMotionClient.h:43
> +    virtual WebDeviceMotionData* currentDeviceMotion() const { WEBKIT_ASSERT_NOT_REACHED(); return 0; }

anything over one statement needs to be on multiple lines.  Unfortunately.

> WebKit/chromium/public/WebDeviceMotionController.h:39
> +    WebDeviceMotionController(WebCore::DeviceMotionController*);

Needs WEBKIT_API

> WebKit/chromium/src/WebDeviceMotionController.cpp:43
> +    RefPtr<WebCore::DeviceMotionData> motion(static_cast<PassRefPtr<WebCore::DeviceMotionData> >(*deviceMotionData));

Ugh...ok, maybe what was there was better.
Comment 8 Hans Wennborg 2010-10-05 09:44:36 PDT
(In reply to comment #7)
> (From update of attachment 69795 [details])
> > WebKit/chromium/public/WebDeviceMotionController.h:39
> > +    WebDeviceMotionController(WebCore::DeviceMotionController*);
> 
> Needs WEBKIT_API

But it will never be called from outside WebKit (and can never be, because outside WebKit, the caller would not be able to pass in a WebCore::DeviceMotionController*).
Comment 9 Hans Wennborg 2010-10-06 02:44:39 PDT
(In reply to comment #7)
> (From update of attachment 69795 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=69795&action=review
> 
> LGTM, but it'd be nice to have Darin sign off on it.
> 
> > WebKit/chromium/public/WebDeviceMotionClient.h:43
> > +    virtual WebDeviceMotionData* currentDeviceMotion() const { WEBKIT_ASSERT_NOT_REACHED(); return 0; }
> 
> anything over one statement needs to be on multiple lines.  Unfortunately.
Done.

> > WebKit/chromium/public/WebDeviceMotionController.h:39
> > +    WebDeviceMotionController(WebCore::DeviceMotionController*);
> 
> Needs WEBKIT_API
As noted above, the intention is not to make this part of the API, as it is only called inside the WebKit layer.

Is it ok to just ommit the WEBKIT_API like I did, or should I use #if WEBKIT_IMPLEMENTATION to hide it? (And then probably declare a dummy private default constructor to make ut unconstructable.)

> > WebKit/chromium/src/WebDeviceMotionController.cpp:43
> > +    RefPtr<WebCore::DeviceMotionData> motion(static_cast<PassRefPtr<WebCore::DeviceMotionData> >(*deviceMotionData));
> 
> Ugh...ok, maybe what was there was better.
Putting it back the way it was.


Darin: does this look ok to you?
Comment 10 Hans Wennborg 2010-10-06 02:45:07 PDT
Created attachment 69908 [details]
Patch
Comment 11 Darin Fisher (:fishd, Google) 2010-10-06 08:45:36 PDT
Comment on attachment 69908 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=69908&action=review

> WebKit/chromium/public/WebDeviceMotionClient.h:40
> +    virtual void setController(WebDeviceMotionController*) { WEBKIT_ASSERT_NOT_REACHED(); }

why is setController an explicit method here?  couldn't you also pass the WebDeviceMotionController
to the method on WebViewClient used to fetch the WebDeviceMotionClient?

when does the WebDeviceMotionController pointer get freed?

> WebKit/chromium/public/WebDeviceMotionClient.h:43
> +    virtual WebDeviceMotionData* currentDeviceMotion() const

nit: currentDeviceMotion -> currentDeviceMotionData

why is currentDeviceMotion returned by pointer and not by value?  the whole
point of using WebPrivatePtr<...wrapping a RefCounted type...> is to support
passing the container type by value.

> WebKit/chromium/public/WebDeviceMotionController.h:39
> +    WebDeviceMotionController(WebCore::DeviceMotionController*);

this constructor should be wrapped with WEBKIT_IMPLEMENTATION, and i presume
that the default constructor should be declared but marked private.  i see
that WebDeviceOrientationController has the same problem.

> WebKit/chromium/public/WebDeviceMotionController.h:47
> +    WebCore::DeviceMotionController* m_controller;

i don't understand what the memory management is here?  this looks like a crash
waiting to happen.

> WebKit/chromium/public/WebDeviceMotionData.h:39
> +class WebDeviceMotionData {

Looking at the way this class is used, I'm not sure why you didn't just
do the same thing as you did for WebDeviceOrientation.  It seems like it
does not need to be a wrapper around the WebCore type.  It can just be
a simple class with member variables for the various fields.

> WebKit/chromium/public/WebDeviceMotionData.h:74
> +    WEBKIT_API void init();

what is the reason for making these private?

why aren't you providing a copy constructor and assignment operator?  those
are typically provided since WebDeviceMotionData is really just like a
RefPtr<DeviceMotionData>.  it can be copied around, and all of the memory
management happens implicitly.
Comment 12 Darin Fisher (:fishd, Google) 2010-10-06 08:51:41 PDT
Comment on attachment 69908 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=69908&action=review

> WebKit/chromium/public/WebDeviceMotionData.h:42
> +    WebDeviceMotionData(bool canProvideXAcceleration, double xAcceleration,

also, functions with large numbers of parameters are really unfortunate.  it is
very easy to make a mistake when calling such a function.

a better solution would probably look like this:

  class WebFoo {
  public:
      WebFoo() : m_hasBar(false), m_bar(0.0) {
      }

      void setBar(double bar) {
          m_hasBar = true;
          m_bar = bar;
      }
      bool hasBar() const { return m_hasBar; }
      double bar() const { return m_bar; }

      // ditto for other fields

  private:
      bool m_hasBar;
      double m_bar;
  };

at the place where you construct and initialize such a class, you would just
have a bunch of setBar calls, one for each of the properties you want to set.

on the chromium side, this structure would be trivial to write ParamTraits for
in order to support IPC serialization.  see chrome/common/webkit_param_traits.h.

if you applied this approach to device orientation as well, then you could
delete ViewMsg_DeviceOrientationUpdated_Params.
Comment 13 Hans Wennborg 2010-10-07 07:34:36 PDT
Thank you very much for the review.

> > WebKit/chromium/public/WebDeviceMotionClient.h:40
> > +    virtual void setController(WebDeviceMotionController*) { WEBKIT_ASSERT_NOT_REACHED(); }
> 
> why is setController an explicit method here?  couldn't you also pass the WebDeviceMotionController
> to the method on WebViewClient used to fetch the WebDeviceMotionClient?
Hmm, the DeviceMotionController that WebDeviceMotionController wraps is created and owned by the Page, which is created *after* the WebDeviceMotionClient, so I don't see how we could make that work.

The setController method here mirrors the setController method on DeviceMotionClient. I suppose we could find another way to push motion data to the controller, but I think we would end up needing it anyway when adding a mock client similar to DeviceOrientationClientMock, which I plan to do.

> when does the WebDeviceMotionController pointer get freed?
The client whose setController method is called is responsible for freeing it. I suppose I could add a comment about that, or do you think there is a way to show it more clearly through code?

> > WebKit/chromium/public/WebDeviceMotionClient.h:43
> > +    virtual WebDeviceMotionData* currentDeviceMotion() const
> 
> nit: currentDeviceMotion -> currentDeviceMotionData
Hmm, the method is called currentDeviceMotion in DeviceMotionClient. I'm happy to rename them both, but in that case I'd like to do them at the same time, and in a separate patch.

> why is currentDeviceMotion returned by pointer and not by value?  the whole
> point of using WebPrivatePtr<...wrapping a RefCounted type...> is to support
> passing the container type by value.
It's returned by pointer to match the DeviceMotionClient method, and so that the method can return NULL (meaning it has no current motion data). I think this is better than adding a null state to WebDeviceMotionData like we did with WebDeviceOrientation, but I don't have any strong feelings here.

> > WebKit/chromium/public/WebDeviceMotionController.h:39
> > +    WebDeviceMotionController(WebCore::DeviceMotionController*);
> 
> this constructor should be wrapped with WEBKIT_IMPLEMENTATION, and i presume
> that the default constructor should be declared but marked private.  i see
> that WebDeviceOrientationController has the same problem.
Done. I will apply this and the other improvements from this discussion to the device orientation code when this patch passes review.

> > WebKit/chromium/public/WebDeviceMotionController.h:47
> > +    WebCore::DeviceMotionController* m_controller;
> 
> i don't understand what the memory management is here?  this looks like a crash
> waiting to happen.
The memory management here is the same as for DeviceMotionClient::setController. The setController method takes a weak pointer to the controller. Since the controller is a WebCore class we can't just pass it to the WebDeviceMotionClient::setController method, but put it in this thin wrapper, and let the WebDeviceMotionClient take ownership of the wrapper.

Thinking more about this, we should probably forward the DeviceMotionClient::deviceMotionControllerDestroyed() method too, so we can signal when the pointer to the controller becomes invalid. Doing that.

> > WebKit/chromium/public/WebDeviceMotionData.h:39
> > +class WebDeviceMotionData {
> 
> Looking at the way this class is used, I'm not sure why you didn't just
> do the same thing as you did for WebDeviceOrientation.  It seems like it
> does not need to be a wrapper around the WebCore type.  It can just be
> a simple class with member variables for the various fields.
Doing this. You're right, it is probably easier.

> > WebKit/chromium/public/WebDeviceMotionData.h:74
> > +    WEBKIT_API void init();
> 
> what is the reason for making these private?
This does not apply to the new WebDeviceMotionData.

> why aren't you providing a copy constructor and assignment operator?  those
> are typically provided since WebDeviceMotionData is really just like a
> RefPtr<DeviceMotionData>.  it can be copied around, and all of the memory
> management happens implicitly.
This does not exist in the new WebDeviceMotionData.

(In reply to comment #12)
> > WebKit/chromium/public/WebDeviceMotionData.h:42
> > +    WebDeviceMotionData(bool canProvideXAcceleration, double xAcceleration,
> 
> also, functions with large numbers of parameters are really unfortunate.  it is
> very easy to make a mistake when calling such a function.
> 
> a better solution would probably look like this:
> 
>   class WebFoo {
>   public:
>       WebFoo() : m_hasBar(false), m_bar(0.0) {
>       }
> 
>       void setBar(double bar) {
>           m_hasBar = true;
>           m_bar = bar;
>       }
>       bool hasBar() const { return m_hasBar; }
>       double bar() const { return m_bar; }
> 
>       // ditto for other fields
> 
>   private:
>       bool m_hasBar;
>       double m_bar;
>   };
> 
> at the place where you construct and initialize such a class, you would just
> have a bunch of setBar calls, one for each of the properties you want to set.
Doing this. Will update the device orientation code to do the same after this patch.

> on the chromium side, this structure would be trivial to write ParamTraits for
> in order to support IPC serialization.  see chrome/common/webkit_param_traits.h.
Will do.

> if you applied this approach to device orientation as well, then you could
> delete ViewMsg_DeviceOrientationUpdated_Params.
Looking forward to it :)
Comment 14 Hans Wennborg 2010-10-07 07:35:03 PDT
Created attachment 70089 [details]
Patch
Comment 15 Jeremy Orlow 2010-10-08 11:02:59 PDT
Darin, are you happy with this?
Comment 16 Hans Wennborg 2010-10-13 10:00:49 PDT
I'm now blocked on this. Any input would be most welcome.
Comment 17 Jeremy Orlow 2010-10-13 10:36:06 PDT
Comment on attachment 70089 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=70089&action=review

these are my only concerns.  Are you ok Darin?

> WebKit/chromium/src/WebDeviceMotionController.cpp:41
> +void WebDeviceMotionController::didChangeDeviceMotion(const WebDeviceMotionData* deviceMotionData)

In cases like this, we should use & rather than *.

> WebKit/chromium/src/WebDeviceMotionController.cpp:43
> +    PassRefPtr<WebCore::DeviceMotionData> motion(*deviceMotionData);

I'm still surprised this can't be done any more cleanly...but I know sometimes this stuff can be a mess.
Comment 18 James Robinson 2010-12-30 15:41:39 PST
Is this still pending?  Does this patch still apply?  It's been sitting here a long time.
Comment 19 Hans Wennborg 2011-01-04 04:18:47 PST
Comment on attachment 70089 [details]
Patch

This is not currently pending (and the patch most likely doesn't apply anymore).

I expect to get back to this eventually, but taking it out of the review queue for now.
Comment 20 Hans Wennborg 2012-06-15 07:36:44 PDT
For anyone interested, this work has moved to Bug 89197.