import("//build/config/android/rules.gni") # For generate_jni().
}
+if (is_tizen) {
+ import("//tizen_src/chromium_impl/services/device/generic_sensor/generic_sensor_efl.gni")
+}
+
source_set("generic_sensor") {
visibility = [ "//services/device:*" ]
]
}
+ if (is_tizen) {
+ sources += external_device_sensor_efl_sources
+ }
+
if (is_chromeos) {
deps += [ "//chromeos/components/sensors:buildflags" ]
}
#include "services/device/generic_sensor/platform_sensor_provider_mac.h"
#elif BUILDFLAG(IS_ANDROID)
#include "services/device/generic_sensor/platform_sensor_provider_android.h"
+#elif BUILDFLAG(IS_TIZEN)
+#include "services/device/generic_sensor/platform_sensor_provider_efl.h"
#elif BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#include "build/build_config.h"
return std::make_unique<PlatformSensorProviderMac>();
#elif BUILDFLAG(IS_ANDROID)
return std::make_unique<PlatformSensorProviderAndroid>();
+#elif BUILDFLAG(IS_TIZEN)
+ return std::make_unique<PlatformSensorProviderEfl>();
#elif BUILDFLAG(IS_WIN)
if (PlatformSensorProvider::UseWindowsWinrt()) {
return std::make_unique<PlatformSensorProviderWinrt>();
--- /dev/null
+# Copyright (c) 2019 Samsung Electronics. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+external_device_sensor_efl_sources = [
+ "//tizen_src/chromium_impl/services/device/generic_sensor/platform_sensor_efl.cc",
+ "//tizen_src/chromium_impl/services/device/generic_sensor/platform_sensor_efl.h",
+ "//tizen_src/chromium_impl/services/device/generic_sensor/platform_sensor_provider_efl.cc",
+ "//tizen_src/chromium_impl/services/device/generic_sensor/platform_sensor_provider_efl.h",
+ "//tizen_src/chromium_impl/services/device/generic_sensor/platform_sensor_reader_efl.cc",
+ "//tizen_src/chromium_impl/services/device/generic_sensor/platform_sensor_reader_efl.h",
+]
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/device/generic_sensor/platform_sensor_efl.h"
+
+#include "base/time/time.h"
+#include "services/device/generic_sensor/platform_sensor_reader_efl.h"
+#include "tizen/system_info.h"
+
+namespace device {
+
+namespace {
+
+// Checks if at least one value has been changed.
+bool HaveValuesChanged(const SensorReading& lhs, const SensorReading& rhs) {
+ if (IsEmulatorArch()) {
+ // On emulators, sensor readings are constant unless changed in control
+ // panel sensor sliders, because of which few devicemotion web-tct
+ // failures were seen on testhub. To avoid the same, we skip below values
+ // comparison and force send to blink for succesfully dispatching events.
+ return true;
+ }
+
+ for (size_t i = 0; i < SensorReadingRaw::kValuesCount; ++i) {
+ if (lhs.raw.values[i] != rhs.raw.values[i])
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+PlatformSensorEfl::PlatformSensorEfl(mojom::SensorType type,
+ SensorReadingSharedBuffer* reading_buffer,
+ PlatformSensorProvider* provider)
+ : PlatformSensor(type, reading_buffer, provider),
+ default_configuration_(PlatformSensorConfiguration()),
+ weak_factory_(this) {
+ sensor_reader_ = SensorReaderEfl::Create(weak_factory_.GetWeakPtr(), type);
+}
+
+PlatformSensorEfl::~PlatformSensorEfl() {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+}
+
+mojom::ReportingMode PlatformSensorEfl::GetReportingMode() {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ return mojom::ReportingMode::ON_CHANGE;
+}
+
+void PlatformSensorEfl::UpdatePlatformSensorReading(SensorReading reading) {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ if (GetReportingMode() == mojom::ReportingMode::ON_CHANGE &&
+ !HaveValuesChanged(reading, old_values_)) {
+ return;
+ }
+ old_values_ = reading;
+ reading.raw.timestamp =
+ (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
+ UpdateSharedBufferAndNotifyClients(reading);
+}
+
+void PlatformSensorEfl::NotifyPlatformSensorError() {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ NotifySensorError();
+}
+
+bool PlatformSensorEfl::StartSensor(
+ const PlatformSensorConfiguration& configuration) {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ sensor_reader_->StartFetchingData(configuration);
+ return true;
+}
+
+void PlatformSensorEfl::StopSensor() {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ sensor_reader_->StopFetchingData();
+}
+
+bool PlatformSensorEfl::CheckSensorConfiguration(
+ const PlatformSensorConfiguration& configuration) {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ return configuration.frequency() > 0 &&
+ configuration.frequency() <= default_configuration_.frequency();
+}
+
+PlatformSensorConfiguration PlatformSensorEfl::GetDefaultConfiguration() {
+ DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
+ return default_configuration_;
+}
+
+} // namespace device
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_EFL_H_
+#define SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_EFL_H_
+
+#include "services/device/generic_sensor/platform_sensor.h"
+
+namespace device {
+
+class SensorReaderEfl;
+
+class PlatformSensorEfl : public PlatformSensor {
+ public:
+ PlatformSensorEfl(mojom::SensorType type,
+ SensorReadingSharedBuffer* reading_buffer,
+ PlatformSensorProvider* provider);
+
+ PlatformSensorEfl(const PlatformSensorEfl&) = delete;
+ PlatformSensorEfl& operator=(const PlatformSensorEfl&) = delete;
+
+ mojom::ReportingMode GetReportingMode() override;
+
+ // Called by a sensor reader. Takes new readings.
+ void UpdatePlatformSensorReading(SensorReading reading);
+
+ // Called by a sensor reader if an error occurs.
+ void NotifyPlatformSensorError();
+
+ protected:
+ ~PlatformSensorEfl() override;
+ bool StartSensor(const PlatformSensorConfiguration& configuration) override;
+ void StopSensor() override;
+ bool CheckSensorConfiguration(
+ const PlatformSensorConfiguration& configuration) override;
+ PlatformSensorConfiguration GetDefaultConfiguration() override;
+
+ private:
+ const PlatformSensorConfiguration default_configuration_;
+
+ // A sensor reader that reads values from sensor files
+ // and stores them to a SensorReading structure.
+ std::unique_ptr<SensorReaderEfl> sensor_reader_;
+
+ // Stores previously read values that are used to
+ // determine whether the recent values are changed
+ // and IPC can be notified that updates are available.
+ SensorReading old_values_;
+
+ base::WeakPtrFactory<PlatformSensorEfl> weak_factory_;
+};
+
+} // namespace device
+
+#endif // SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_EFL_H_
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/device/generic_sensor/platform_sensor_provider_efl.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
+#include "services/device/generic_sensor/platform_sensor_efl.h"
+#include "services/device/generic_sensor/platform_sensor_reader_efl.h"
+
+namespace device {
+
+PlatformSensorProviderEfl::PlatformSensorProviderEfl() {}
+
+PlatformSensorProviderEfl::~PlatformSensorProviderEfl() {}
+
+void PlatformSensorProviderEfl::CreateSensorInternal(
+ mojom::SensorType type,
+ SensorReadingSharedBuffer* reading_buffer,
+ CreateSensorCallback callback) {
+ if (!SensorReaderEfl::IsSensorTypeSupported(type)) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ scoped_refptr<PlatformSensorEfl> sensor =
+ new PlatformSensorEfl(type, reading_buffer, this);
+ std::move(callback).Run(sensor);
+}
+
+void PlatformSensorProviderEfl::FreeResources() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+} // namespace device
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_DEVICE_GENERIC_SENSOR_PUBLIC_PLATFORM_SENSOR_PROVIDER_EFL_H_
+#define SERVICES_DEVICE_GENERIC_SENSOR_PUBLIC_PLATFORM_SENSOR_PROVIDER_EFL_H_
+
+#include "services/device/generic_sensor/platform_sensor_provider.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+} // namespace base
+
+namespace device {
+
+class PlatformSensorEfl;
+
+class PlatformSensorProviderEfl : public PlatformSensorProvider {
+ public:
+ PlatformSensorProviderEfl();
+ ~PlatformSensorProviderEfl() override;
+
+ PlatformSensorProviderEfl(const PlatformSensorProviderEfl&) = delete;
+ PlatformSensorProviderEfl& operator=(const PlatformSensorProviderEfl&) =
+ delete;
+
+ protected:
+ void CreateSensorInternal(mojom::SensorType type,
+ SensorReadingSharedBuffer* reading_buffer,
+ CreateSensorCallback callback) override;
+
+ void FreeResources() override;
+
+ private:
+ friend struct base::DefaultSingletonTraits<PlatformSensorProviderEfl>;
+};
+
+} // namespace device
+
+#endif // SERVICES_DEVICE_GENERIC_SENSOR_PUBLIC_PLATFORM_SENSOR_PROVIDER_EFL_H_
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/device/generic_sensor/platform_sensor_reader_efl.h"
+
+#include "base/threading/thread_restrictions.h"
+#include "services/device/generic_sensor/platform_sensor_efl.h"
+
+namespace device {
+
+// static
+bool SensorReaderEfl::IsSensorTypeSupported(mojom::SensorType type) {
+ sensor_type_e sensor_type;
+ switch (type) {
+ case mojom::SensorType::ACCELEROMETER:
+ case mojom::SensorType::LINEAR_ACCELERATION:
+ sensor_type = SENSOR_ACCELEROMETER;
+ break;
+ case mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::GYROSCOPE:
+ sensor_type = SENSOR_GYROSCOPE;
+ break;
+ default:
+ return false;
+ }
+
+ bool supported = false;
+ sensor_is_supported(sensor_type, &supported);
+ if (!supported)
+ LOG(INFO) << "Sensor type : " << type << " not supported!";
+ else
+ LOG(INFO) << "Sensor type : " << type << " is supported..";
+
+ return supported;
+}
+
+// static
+std::unique_ptr<SensorReaderEfl> SensorReaderEfl::Create(
+ base::WeakPtr<PlatformSensorEfl> sensor,
+ mojom::SensorType type) {
+ return std::make_unique<SensorReaderEfl>(sensor, type);
+}
+
+SensorReaderEfl::~SensorReaderEfl() {
+ if (sensor_accelerometer_) {
+ sensor_listener_unset_event_cb(listener_accelerometer_);
+ sensor_listener_stop(listener_accelerometer_);
+ sensor_destroy_listener(listener_accelerometer_);
+ }
+
+ if (sensor_gyroscope_) {
+ sensor_listener_stop(listener_gyroscope_);
+ sensor_destroy_listener(listener_gyroscope_);
+ }
+}
+
+SensorReaderEfl::SensorReaderEfl(base::WeakPtr<PlatformSensorEfl> sensor,
+ mojom::SensorType type)
+ : sensor_(sensor), is_reading_active_(false), type_(type) {
+ sensor_accelerometer_ = nullptr;
+ sensor_gyroscope_ = nullptr;
+ listener_accelerometer_ = nullptr;
+ listener_gyroscope_ = nullptr;
+ has_last_reading_ = false;
+
+ Initialize();
+}
+
+void SensorReaderEfl::Initialize() {
+ switch (type_) {
+ case mojom::SensorType::ACCELEROMETER:
+ case mojom::SensorType::LINEAR_ACCELERATION:
+ sensor_get_default_sensor(SENSOR_ACCELEROMETER, &sensor_accelerometer_);
+ if (sensor_accelerometer_)
+ sensor_create_listener(sensor_accelerometer_, &listener_accelerometer_);
+ break;
+ case mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::GYROSCOPE:
+ sensor_get_default_sensor(SENSOR_GYROSCOPE, &sensor_gyroscope_);
+ if (sensor_gyroscope_)
+ sensor_create_listener(sensor_gyroscope_, &listener_gyroscope_);
+ break;
+ default:
+ return;
+ }
+}
+
+void SensorReaderEfl::StartFetchingData(
+ const PlatformSensorConfiguration& configuration) {
+ if (is_reading_active_)
+ StopFetchingData();
+
+ SetListenerCallbacks();
+}
+
+void SensorReaderEfl::StopFetchingData() {
+ is_reading_active_ = false;
+
+ UnsetListenerCallbacks();
+}
+
+void SensorReaderEfl::SetListenerCallbacks() {
+ switch (type_) {
+ case mojom::SensorType::ACCELEROMETER:
+ case mojom::SensorType::LINEAR_ACCELERATION: {
+ int min_interval = 0;
+ sensor_get_min_interval(&sensor_accelerometer_, &min_interval);
+ sensor_listener_set_event_cb(listener_accelerometer_, min_interval,
+ SensorReaderEfl::OnSensorDataChanged, this);
+ if (SENSOR_ERROR_NONE == sensor_listener_start(listener_accelerometer_))
+ LOG(INFO) << "Accelerometer Listener started";
+ else
+ LOG(INFO) << "Accelerometer Listener failed to start";
+ break;
+ }
+ case mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::GYROSCOPE: {
+ int min_interval = 0;
+ sensor_get_min_interval(&sensor_gyroscope_, &min_interval);
+ sensor_listener_set_event_cb(listener_gyroscope_, min_interval,
+ SensorReaderEfl::OnSensorDataChanged, this);
+ if (SENSOR_ERROR_NONE == sensor_listener_start(listener_gyroscope_))
+ LOG(INFO) << "Gyroscope Listener started";
+ else
+ LOG(INFO) << "Gyroscope Listener failed to start";
+ break;
+ }
+ default:
+ return;
+ }
+
+ is_reading_active_ = true;
+}
+
+void SensorReaderEfl::UnsetListenerCallbacks() {
+ if (sensor_accelerometer_) {
+ sensor_listener_unset_event_cb(listener_accelerometer_);
+ sensor_listener_stop(listener_accelerometer_);
+ }
+ if (sensor_gyroscope_)
+ sensor_listener_stop(listener_gyroscope_);
+}
+
+void SensorReaderEfl::OnSensorDataChanged(sensor_h sensor,
+ sensor_event_s* event,
+ void* user_data) {
+ SensorReaderEfl* self = static_cast<SensorReaderEfl*>(user_data);
+ SensorReading readings;
+
+ switch (self->type_) {
+ case mojom::SensorType::LINEAR_ACCELERATION: {
+ double x = event->values[0];
+ double y = event->values[1];
+ double z = event->values[2];
+
+ double gravityX = x * 0.2f;
+ double gravityY = y * 0.2f;
+ double gravityZ = z * 0.2f;
+
+ if (self->has_last_reading_) {
+ gravityX += (self->last_reading_.acceleration_including_gravity.x -
+ self->last_reading_.linear_acceleration.x) *
+ 0.8f;
+ gravityY += (self->last_reading_.acceleration_including_gravity.y -
+ self->last_reading_.linear_acceleration.y) *
+ 0.8f;
+ gravityZ += (self->last_reading_.acceleration_including_gravity.z -
+ self->last_reading_.linear_acceleration.z) *
+ 0.8f;
+ }
+
+ readings.accel.x = x - gravityX;
+ readings.accel.y = y - gravityX;
+ readings.accel.z = z - gravityZ;
+
+ self->last_reading_.acceleration_including_gravity.x = x;
+ self->last_reading_.acceleration_including_gravity.y = y;
+ self->last_reading_.acceleration_including_gravity.z = z;
+
+ self->last_reading_.linear_acceleration.x = readings.accel.x;
+ self->last_reading_.linear_acceleration.y = readings.accel.y;
+ self->last_reading_.linear_acceleration.z = readings.accel.z;
+ self->has_last_reading_ = true;
+ break;
+ }
+ case mojom::SensorType::ACCELEROMETER: {
+ readings.accel.x = event->values[0];
+ readings.accel.y = event->values[1];
+ readings.accel.z = event->values[2];
+ break;
+ }
+ case mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
+ case mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES: {
+ // For orientation data, capture gyroscope readings and write to
+ // |orientation_euler|
+ sensor_event_s event_gyroscope;
+ if (SENSOR_ERROR_NONE ==
+ sensor_listener_read_data(self->listener_gyroscope_,
+ &event_gyroscope)) {
+ LOG(INFO) << "Rotation rate available";
+ readings.orientation_euler.x = event_gyroscope.values[0];
+ readings.orientation_euler.y = event_gyroscope.values[1];
+ readings.orientation_euler.z = event_gyroscope.values[2];
+ }
+ break;
+ }
+ case mojom::SensorType::GYROSCOPE: {
+ sensor_event_s event_gyroscope;
+ if (SENSOR_ERROR_NONE ==
+ sensor_listener_read_data(self->listener_gyroscope_,
+ &event_gyroscope)) {
+ LOG(INFO) << "Rotation rate available";
+ readings.gyro.x = event_gyroscope.values[0];
+ readings.gyro.y = event_gyroscope.values[1];
+ readings.gyro.z = event_gyroscope.values[2];
+ }
+ break;
+ }
+ default:
+ LOG(INFO) << "Unknown sensor type!";
+ return;
+ }
+
+ // Update readings to shared buffer
+ if (self->is_reading_active_ && self->sensor_) {
+ self->sensor_->PostTaskToMainSequence(
+ FROM_HERE,
+ base::BindOnce(&PlatformSensorEfl::UpdatePlatformSensorReading,
+ self->sensor_, readings));
+ }
+}
+
+void SensorReaderEfl::NotifyReadError() {
+ if (is_reading_active_ && sensor_) {
+ sensor_->PostTaskToMainSequence(
+ FROM_HERE,
+ base::BindOnce(&PlatformSensorEfl::NotifyPlatformSensorError, sensor_));
+ }
+}
+
+} // namespace device
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_READER_EFL_H_
+#define SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_READER_EFL_H_
+
+#include <sensor/sensor.h>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
+#include "services/device/public/mojom/sensor.mojom.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace device {
+
+class PlatformSensorConfiguration;
+class PlatformSensorEfl;
+
+// A generic reader class that can be implemented with two different strategies:
+// polling and on trigger. All methods are not thread-safe and must be called
+// on a polling thread that allows I/O.
+class SensorReaderEfl {
+ public:
+ // Creates a new instance of SensorReaderEfl. At the moment, only polling
+ // reader is supported.
+ static std::unique_ptr<SensorReaderEfl> Create(
+ base::WeakPtr<PlatformSensorEfl> sensor,
+ mojom::SensorType type);
+
+ SensorReaderEfl(base::WeakPtr<PlatformSensorEfl> sensor,
+ mojom::SensorType type);
+ ~SensorReaderEfl();
+
+ SensorReaderEfl(const SensorReaderEfl&) = delete;
+ SensorReaderEfl& operator=(const SensorReaderEfl&) = delete;
+
+ // Starts fetching data based on strategy this reader has chosen.
+ // Only polling strategy is supported at the moment.
+ void StartFetchingData(const PlatformSensorConfiguration& configuration);
+ // Stops fetching data.
+ void StopFetchingData();
+
+ static void OnSensorDataChanged(sensor_h sensor,
+ sensor_event_s* event,
+ void* user_data);
+ static bool IsSensorTypeSupported(mojom::SensorType type);
+
+ private:
+ // Initializes system sensor handles and sets/unsets listener callbacks.
+ void Initialize();
+ void SetListenerCallbacks();
+ void UnsetListenerCallbacks();
+
+ // A sensor that this reader is owned by and notifies about errors and
+ // readings to.
+ base::WeakPtr<PlatformSensorEfl> sensor_;
+
+ // A task runner that is used to report about new readings and errors
+ // to a |sensor_|.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ // Indicates if reading is active.
+ bool is_reading_active_;
+
+ // Notifies |sensor_| about an error.
+ void NotifyReadError();
+
+ // Sensor type
+ mojom::SensorType type_;
+
+ // Previously calculated readings used for calculating Linear Acceleration.
+ struct LastReading {
+ SensorReadingXYZ acceleration_including_gravity;
+ SensorReadingXYZ linear_acceleration;
+ };
+ struct LastReading last_reading_;
+ bool has_last_reading_;
+
+ // capi-system-sensor handles.
+ sensor_h sensor_accelerometer_;
+ sensor_h sensor_gyroscope_;
+ sensor_listener_h listener_accelerometer_;
+ sensor_listener_h listener_gyroscope_;
+};
+
+} // namespace device
+
+#endif // SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_READER_EFL_H_