Comments and questions from a pass of looking at the camera_hal_delegate* files.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.ccFile media/capture/video/chromeos/camera_hal_delegate.cc (right):
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.cc#newcode44media/capture/video/chromeos/camera_hal_delegate.cc:44:
module_task_runner_(module_task_runner),
For passing scoped_refptr<>, I believe it is now recommended to pass by
value and then use std::move() if no copy is needed.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.cc#newcode113media/capture/video/chromeos/camera_hal_delegate.cc:113: }
The contents of the above method look reasonable, but I am not familiar
with the APIs for establishing Mojo connections. I recommend asking
rockot@ or yzshen@ to help review this part.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.hFile media/capture/video/chromeos/camera_hal_delegate.h (right):
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.h#newcode24media/capture/video/chromeos/camera_hal_delegate.h:24: // function calls
to CameraHalDelegate.
As a reader, here, I would expect to find a description of what this
class does, which is missing here and is not obvious from the class
name. The information who is using the class is useful, but dangerous to
include in the class-level description, because it is easy to become
inaccurate. IMHO, it is better to rely on the code search tool to find
usages.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.h#newcode35media/capture/video/chromeos/camera_hal_delegate.h:35: const
scoped_refptr<base::SingleThreadTaskRunner> module_task_runner);
Either here or in the class-level description it would be helpful to
have an explanation of what |module_task_runner| is needed for.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.h#newcode39media/capture/video/chromeos/camera_hal_delegate.h:39: // Called by
VideoCaptureDeviceFactoryChromeOS::Init on the browser UI thread.
I recommend removing the information about by who and on which thread
this gets called (it is already inaccurate).
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.h#newcode45media/capture/video/chromeos/camera_hal_delegate.h:45: // on.
This raises the following question (in me, as a reader): If the
interface exposed here is so similar to VideoCaptureDeviceFactory, what
is actually the purpose of VideoCaptureDeviceFactoryChromeOS? Why do we
need it? What does it do that is worth having it separate from this
class?
A good place for this information would be the class-level description.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.h#newcode55media/capture/video/chromeos/camera_hal_delegate.h:55: // be called on
any thread.
Hmm, the method signature does look asynchronous, though. Does the
comment above mean that this implementation guarantees that the callback
is invoked synchronously? If so, why not use a return value instead of a
callback?
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate.h#newcode74media/capture/video/chromeos/camera_hal_delegate.h:74: void
StartForTesting(arc::mojom::CameraModulePtrInfo info);
The need for a test-only API like this is often an indicator of a design
issue.
In the case of this class, this is caused by the class wanting to do
both establishing the Mojo connection and using it, which are almost
unrelated responsibilities. I recommend resolving this by splitting out
the responsibility of establishing the Mojo connection to a factory
class, something like:
class ServiceCameraHalDelegateFactory {
public:
scoped_refptr<CameraHalDelegate>
CreateCameraHalDelegate(scoped_refptr<base::SingleThreadTaskRunner>
module_task_runner);
// ...
};
This class would contain the logic from StartCameraModuleIpc(). The
class CameraHalDelegate, would get its |camera_module_| via dependency
injection from the constructor, i.e.:
class CameraHalDelegate {
public:
CameraHalDelegate(
const scoped_refptr<base::SingleThreadTaskRunner>
module_task_runner,
arc::mojom::CameraModulePtr camera_module);
};
Unit tests can then instantiate CameraHalDelegate through its public
constructor using a mock for |camera_module|.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.ccFile media/capture/video/chromeos/camera_hal_delegate_unittest.cc
(right):
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.cc#newcode42media/capture/video/chromeos/camera_hal_delegate_unittest.cc:42: }
Same as in the production code, this while loop looks suspicious and can
probably be replaced with a more official way of other reference holders
signaling us when they have finished whatever we need to wait for here.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.cc#newcode47media/capture/video/chromeos/camera_hal_delegate_unittest.cc:47: void
Wait() {
Couldn't find where this is used. Can it be removed?
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.cc#newcode57media/capture/video/chromeos/camera_hal_delegate_unittest.cc:57:
std::unique_ptr<base::MessageLoop> message_loop_;
IIUC, it is now encouraged to use a ScopedTaskEnvironment instead, see
https://docs.google.com/document/d/1QabRo8c7D9LsYY3cEcaPQbOCLo8Tu-6VLykYXyl3Pkk/edithttps://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.cc#newcode67media/capture/video/chromeos/camera_hal_delegate_unittest.cc:67: };
I would be okay with this, but not sure if this may violate the Chromium
C++11 allowed feature list. Assuming the lambda expression leads to the
auto type expanding to std::function<...>, which is on the banned
feature list.
If so, I guess we could just define the lambdas directly where they are
used instead of storing them in a temporary variable.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.cc#newcode117media/capture/video/chromeos/camera_hal_delegate_unittest.cc:117:
ASSERT_EQ(std::to_string(0), descriptors[0].device_id);
Where does this expectation come from? I do not see the deivce_id being
set up in the mock.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.cc#newcode129media/capture/video/chromeos/camera_hal_delegate_unittest.cc:129:
ASSERT_EQ(PIXEL_FORMAT_NV12, supported_formats[0].pixel_format);
Where do these expected values come from?
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.hFile media/capture/video/chromeos/camera_hal_delegate_unittest.h
(right):
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.h#newcode35media/capture/video/chromeos/camera_hal_delegate_unittest.h:35: void
OpenDevice(int32_t camera_id, OpenDeviceCallback callback) {
should we use the "override" keyword here (and for the other overriden
methods, including the destructor)?
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/camera_hal_delegate_unittest.h#newcode63media/capture/video/chromeos/camera_hal_delegate_unittest.h:63:
arc::mojom::CameraModulePtrInfo GetInterfacePtrInfo() {
This could be simplified by just creating an instance and binding for
this in the test setup code that wants to use this.
Together with my other recommendation of using dependency injection to
pass CameraHalDelegate its |camera_module_|, this might look something
like this:
class CameraHalDelegateTest : public ::testing::Test {
public:
CameraHalDelegateTest()
: mock_camera_module_binding_(&mock_camera_module_),
hal_delegate_thread_("HalDelegateThread") {}
void SetUp() override {
hal_delegate_thread_.Start();
CameraModulePtr camera_module;
mock_camera_module_binding_.Bind(mojo::MakeRequest(&camera_module));
camera_hal_delegate_ =
new CameraHalDelegate(hal_delegate_thread_.task_runner(),
std::move(camera_module));
}
protected:
scoped_refptr<CameraHalDelegate> camera_hal_delegate_;
testing::StrictMock<unittest_internal::MockCameraModule>
mock_camera_module_;
mojo::Binding<CameraModule> mock_camera_module_binding_;
};
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/mojo/arc_camera3.mojomFile media/capture/video/chromeos/mojo/arc_camera3.mojom (right):
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/mojo/arc_camera3.mojom#newcode260media/capture/video/chromeos/mojo/arc_camera3.mojom:260: //
Camera3CallbackOps, see the comments about Camear3DeviceOps above.
typo: Camera3DeviceOps
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/mojo/arc_camera3.mojom#newcode288media/capture/video/chromeos/mojo/arc_camera3.mojom:288:
OpenDevice@0(int32 camera_id) => (int32 result, Camera3DeviceOps?
device_ops);
When I worked on the video_capture service mojoms, I was told that the
standard "Mojo" way of "returning" an instance of an interface is not to
use an output parameter but instead pass-in a "request" along with the
input parameters, see for example
https://cs.chromium.org/chromium/src/services/video_capture/public/interfaces/device_factory.mojom?dr.
Assuming that is still the case, we may want to do this here as well.
https://codereview.chromium.org/2837273004/diff/320001/media/capture/video/chromeos/mojo/arc_camera3.mojom#newcode297media/capture/video/chromeos/mojo/arc_camera3.mojom:297:
SetCallbacks@3(CameraModuleCallbacks callbacks) => (int32 result);
Any reason why we wouldn't want to use an enum for result codes instead
of an int32?
https://codereview.chromium.org/2837273004/