Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: device/generic_sensor/platform_sensor_ambient_light_mac.cc

Issue 2332903002: [sensors] [mac] Implement ambient light sensor for macOS (Closed)
Patch Set: Fixes from additional comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "device/generic_sensor/platform_sensor_ambient_light_mac.h"
6
7 #include <IOKit/IOMessage.h>
8
9 #include "base/bind.h"
10 #include "device/base/synchronization/shared_memory_seqlock_buffer.h"
11 #include "device/generic_sensor/platform_sensor_provider_mac.h"
12 #include "device/generic_sensor/shared/device_sensors_consts.h"
13 #include "device/generic_sensor/shared/device_util_mac.h"
14
15 namespace {
16 enum LmuFunctionIndex {
17 kGetSensorReadingID = 0, // getSensorReading(int *, int *)
18 };
19 } // namespace
20
21 namespace device {
22
23 struct Reading {
Robert Sesek 2016/10/05 21:00:17 Move the anon namespace into device and put this i
24 double timestamp;
25 double lux;
26 double unused[];
27 };
28
29 using DeviceLightHardwareBuffer = SharedMemorySeqLockBuffer<Reading>;
30
31 PlatformSensorAmbientLightMac::PlatformSensorAmbientLightMac(
32 mojom::SensorType type,
33 mojo::ScopedSharedBufferMapping mapping,
34 uint64_t buffer_size,
35 PlatformSensorProvider* provider,
36 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
37 : PlatformSensor(type, std::move(mapping), provider),
38 light_sensor_port_(nullptr),
39 task_runner_(std::move(task_runner)),
40 current_lux_(0) {
41 // Tested and verified by riju that the following call works on
42 // MacBookPro9,1 : Macbook Pro 15" (Mid 2012 model)
43 // MacBookPro10,1 : Macbook Pro 15" (Retina Display, Early 2013 model).
44 // MacBookPro10,2 : Macbook Pro 13" (Retina Display, Early 2013 model).
45 // MacBookAir5,2 : Macbook Air 13" (Mid 2012 model) (by François Beaufort).
46 // MacBookAir6,2 : Macbook Air 13" (Mid 2013 model).
47 // Testing plans : please download the code and follow the comments :-
48 // https://gist.github.com/riju/74af8c81a665e412d122/
49 // and add an entry here about the model and the status returned by the code.
50
51 // Look up a registered IOService object whose class is AppleLMUController.
52 light_sensor_service_.reset(IOServiceGetMatchingService(
Robert Sesek 2016/10/05 21:00:17 Any reason to not do this in StartSensor()?
53 kIOMasterPortDefault, IOServiceMatching("AppleLMUController")));
54 }
55
56 PlatformSensorAmbientLightMac::~PlatformSensorAmbientLightMac() {
57 if (light_sensor_port_)
58 IONotificationPortDestroy(light_sensor_port_);
59 }
60
61 mojom::ReportingMode PlatformSensorAmbientLightMac::GetReportingMode() {
62 return mojom::ReportingMode::ON_CHANGE;
63 }
64
65 bool PlatformSensorAmbientLightMac::CheckSensorConfiguration(
66 const PlatformSensorConfiguration& configuration) {
67 return configuration.frequency() > 0 &&
68 configuration.frequency() <=
69 mojom::SensorConfiguration::kMaxAllowedFrequency;
70 }
71
72 PlatformSensorConfiguration
73 PlatformSensorAmbientLightMac::GetDefaultConfiguration() {
74 PlatformSensorConfiguration default_configuration;
75 default_configuration.set_frequency(kDefaultAmbientLightFrequencyHz);
76 return default_configuration;
77 }
78
79 void PlatformSensorAmbientLightMac::IOServiceCallback(void* context,
80 io_service_t service,
81 natural_t message_type,
82 void* message_argument) {
83 PlatformSensorAmbientLightMac* sensor =
84 static_cast<PlatformSensorAmbientLightMac*>(context);
85 uint32_t scalar_output_count = 2;
86 uint64_t lux_values[2];
87 kern_return_t kr = IOConnectCallMethod(
88 sensor->light_sensor_object_, LmuFunctionIndex::kGetSensorReadingID,
89 nullptr, 0, nullptr, 0, lux_values, &scalar_output_count, nullptr, 0);
90
91 if (kr == KERN_SUCCESS)
92 sensor->UpdateReading(lux_values);
93 }
94
95 bool PlatformSensorAmbientLightMac::StartSensor(
96 const PlatformSensorConfiguration& configuration) {
97 // Return early if the ambient light sensor is not present.
98 if (!light_sensor_service_)
99 return false;
100
101 light_sensor_port_ = IONotificationPortCreate(kIOMasterPortDefault);
Robert Sesek 2016/10/05 21:00:17 Can StartSensor be called twice? If so, then light
102 if (!light_sensor_port_)
103 return false;
104
105 IONotificationPortSetDispatchQueue(
106 light_sensor_port_,
107 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));
108
109 kern_return_t kr = IOServiceAddInterestNotification(
110 light_sensor_port_, light_sensor_service_, kIOGeneralInterest,
111 IOServiceCallback, this, light_sensor_notification_.InitializeInto());
112 if (kr != KERN_SUCCESS)
113 return false;
114
115 kr = IOServiceOpen(light_sensor_service_, mach_task_self(), 0,
116 light_sensor_object_.InitializeInto());
117
118 return kr == KERN_SUCCESS;
119 }
120
121 void PlatformSensorAmbientLightMac::StopSensor() {
122 if (light_sensor_port_)
123 IONotificationPortDestroy(light_sensor_port_);
124
125 light_sensor_port_ = nullptr;
126
127 light_sensor_notification_.reset();
128 light_sensor_object_.reset();
129 }
130
131 void PlatformSensorAmbientLightMac::UpdateReading(uint64_t lux_values[2]) {
132 uint64_t mean = (lux_values[0] + lux_values[1]) / 2;
133 double lux = LMUvalueToLux(mean);
134 if (lux == current_lux_)
135 return;
136 current_lux_ = lux;
137 DeviceLightHardwareBuffer* light_buffer =
138 static_cast<DeviceLightHardwareBuffer*>(shared_buffer_mapping_.get());
139 light_buffer->seqlock.WriteBegin();
140 light_buffer->data.timestamp =
141 base::Time::Now().ToDoubleT() * base::Time::kMillisecondsPerSecond;
142 light_buffer->data.lux = lux;
143 light_buffer->seqlock.WriteEnd();
144 task_runner_->PostTask(
145 FROM_HERE,
146 base::Bind(&PlatformSensorAmbientLightMac::NotifySensorReadingChanged,
147 this));
148 }
149
150 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698