diff --git a/content/browser/device_sensors/data_fetcher_shared_memory.h b/content/browser/device_sensors/data_fetcher_shared_memory.h index a0d9828c2a5b81..beb8254efb6803 100644 --- a/content/browser/device_sensors/data_fetcher_shared_memory.h +++ b/content/browser/device_sensors/data_fetcher_shared_memory.h @@ -35,6 +35,10 @@ class CONTENT_EXPORT DataFetcherSharedMemory DataFetcherSharedMemory(); ~DataFetcherSharedMemory() override; +#if defined(OS_ANDROID) + void Shutdown() override; +#endif + private: bool Start(ConsumerType consumer_type, void* buffer) override; bool Stop(ConsumerType consumer_type) override; diff --git a/content/browser/device_sensors/data_fetcher_shared_memory_android.cc b/content/browser/device_sensors/data_fetcher_shared_memory_android.cc index 477be76585a0ca..e2676a14d72ef2 100644 --- a/content/browser/device_sensors/data_fetcher_shared_memory_android.cc +++ b/content/browser/device_sensors/data_fetcher_shared_memory_android.cc @@ -56,4 +56,9 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) { return false; } +void DataFetcherSharedMemory::Shutdown() { + DataFetcherSharedMemoryBase::Shutdown(); + SensorManagerAndroid::GetInstance()->Shutdown(); +} + } // namespace content diff --git a/content/browser/device_sensors/data_fetcher_shared_memory_base.cc b/content/browser/device_sensors/data_fetcher_shared_memory_base.cc index 60450092c2a908..0b9a178d9e9cbb 100644 --- a/content/browser/device_sensors/data_fetcher_shared_memory_base.cc +++ b/content/browser/device_sensors/data_fetcher_shared_memory_base.cc @@ -165,7 +165,7 @@ bool DataFetcherSharedMemoryBase::StopFetchingDeviceData( return true; } -void DataFetcherSharedMemoryBase::StopFetchingAllDeviceData() { +void DataFetcherSharedMemoryBase::Shutdown() { StopFetchingDeviceData(CONSUMER_TYPE_MOTION); StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); StopFetchingDeviceData(CONSUMER_TYPE_LIGHT); diff --git a/content/browser/device_sensors/data_fetcher_shared_memory_base.h b/content/browser/device_sensors/data_fetcher_shared_memory_base.h index fc1f031d499197..c13c37800aae5e 100644 --- a/content/browser/device_sensors/data_fetcher_shared_memory_base.h +++ b/content/browser/device_sensors/data_fetcher_shared_memory_base.h @@ -33,7 +33,7 @@ class CONTENT_EXPORT DataFetcherSharedMemoryBase { // Should be called before destruction to make sure all active // sensors are unregistered. - void StopFetchingAllDeviceData(); + virtual void Shutdown(); // Returns the shared memory handle of the device sensor data // duplicated into the given process. This method should only be diff --git a/content/browser/device_sensors/device_inertial_sensor_service.cc b/content/browser/device_sensors/device_inertial_sensor_service.cc index 840ce254bc1c0b..37952475532c92 100644 --- a/content/browser/device_sensors/device_inertial_sensor_service.cc +++ b/content/browser/device_sensors/device_inertial_sensor_service.cc @@ -94,7 +94,7 @@ DeviceInertialSensorService::GetSharedMemoryHandleForProcess( void DeviceInertialSensorService::Shutdown() { if (data_fetcher_) { - data_fetcher_->StopFetchingAllDeviceData(); + data_fetcher_->Shutdown(); data_fetcher_.reset(); } is_shutdown_ = true; @@ -103,7 +103,7 @@ void DeviceInertialSensorService::Shutdown() { void DeviceInertialSensorService::SetDataFetcherForTesting( DataFetcherSharedMemory* test_data_fetcher) { if (data_fetcher_) - data_fetcher_->StopFetchingAllDeviceData(); + data_fetcher_->Shutdown(); data_fetcher_.reset(test_data_fetcher); } diff --git a/content/browser/device_sensors/sensor_manager_android.cc b/content/browser/device_sensors/sensor_manager_android.cc index 715a7c736ea674..0158dd7c4055b8 100644 --- a/content/browser/device_sensors/sensor_manager_android.cc +++ b/content/browser/device_sensors/sensor_manager_android.cc @@ -7,9 +7,11 @@ #include #include "base/android/jni_android.h" +#include "base/bind.h" #include "base/memory/singleton.h" #include "base/metrics/histogram.h" #include "content/browser/device_sensors/inertial_sensor_consts.h" +#include "content/public/browser/browser_thread.h" #include "jni/DeviceSensors_jni.h" using base::android::AttachCurrentThread; @@ -41,7 +43,8 @@ SensorManagerAndroid::SensorManagerAndroid() is_light_buffer_ready_(false), is_motion_buffer_ready_(false), is_orientation_buffer_ready_(false), - is_using_backup_sensors_for_orientation_(false) { + is_using_backup_sensors_for_orientation_(false), + is_shutdown_(false) { memset(received_motion_data_, 0, sizeof(received_motion_data_)); device_sensors_.Reset(Java_DeviceSensors_getInstance( AttachCurrentThread(), base::android::GetApplicationContext())); @@ -196,7 +199,25 @@ bool SensorManagerAndroid::isUsingBackupSensorsForOrientation() { bool SensorManagerAndroid::StartFetchingDeviceLightData( DeviceLightHardwareBuffer* buffer) { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + StartFetchingLightDataOnUI(buffer); + } else { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SensorManagerAndroid::StartFetchingLightDataOnUI, + base::Unretained(this), + buffer)); + } + return true; +} + +void SensorManagerAndroid::StartFetchingLightDataOnUI( + DeviceLightHardwareBuffer* buffer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(buffer); + if (is_shutdown_) + return; + { base::AutoLock autolock(light_buffer_lock_); device_light_buffer_ = buffer; @@ -207,10 +228,25 @@ bool SensorManagerAndroid::StartFetchingDeviceLightData( base::AutoLock autolock(light_buffer_lock_); SetLightBufferValue(std::numeric_limits::infinity()); } - return success; } void SensorManagerAndroid::StopFetchingDeviceLightData() { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + StopFetchingLightDataOnUI(); + return; + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SensorManagerAndroid::StopFetchingLightDataOnUI, + base::Unretained(this))); +} + +void SensorManagerAndroid::StopFetchingLightDataOnUI() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (is_shutdown_) + return; + Stop(kTypeLight); { base::AutoLock autolock(light_buffer_lock_); @@ -226,17 +262,36 @@ void SensorManagerAndroid::SetLightBufferValue(double lux) { device_light_buffer_->data.value = lux; device_light_buffer_->seqlock.WriteEnd(); } + // --- Device Motion bool SensorManagerAndroid::StartFetchingDeviceMotionData( DeviceMotionHardwareBuffer* buffer) { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + StartFetchingMotionDataOnUI(buffer); + } else { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SensorManagerAndroid::StartFetchingMotionDataOnUI, + base::Unretained(this), + buffer)); + } + return true; +} + +void SensorManagerAndroid::StartFetchingMotionDataOnUI( + DeviceMotionHardwareBuffer* buffer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(buffer); + if (is_shutdown_) + return; + { base::AutoLock autolock(motion_buffer_lock_); device_motion_buffer_ = buffer; ClearInternalMotionBuffers(); } - bool success = Start(kTypeMotion); + Start(kTypeMotion); // If no motion data can ever be provided, the number of active device motion // sensors will be zero. In that case flag the shared memory buffer @@ -246,10 +301,25 @@ bool SensorManagerAndroid::StartFetchingDeviceMotionData( base::AutoLock autolock(motion_buffer_lock_); CheckMotionBufferReadyToRead(); } - return success; } void SensorManagerAndroid::StopFetchingDeviceMotionData() { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + StopFetchingMotionDataOnUI(); + return; + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SensorManagerAndroid::StopFetchingMotionDataOnUI, + base::Unretained(this))); +} + +void SensorManagerAndroid::StopFetchingMotionDataOnUI() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (is_shutdown_) + return; + Stop(kTypeMotion); { base::AutoLock autolock(motion_buffer_lock_); @@ -308,7 +378,25 @@ void SensorManagerAndroid::SetOrientationBufferReadyStatus(bool ready) { bool SensorManagerAndroid::StartFetchingDeviceOrientationData( DeviceOrientationHardwareBuffer* buffer) { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + StartFetchingOrientationDataOnUI(buffer); + } else { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SensorManagerAndroid::StartFetchingOrientationDataOnUI, + base::Unretained(this), + buffer)); + } + return true; +} + +void SensorManagerAndroid::StartFetchingOrientationDataOnUI( + DeviceOrientationHardwareBuffer* buffer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(buffer); + if (is_shutdown_) + return; + { base::AutoLock autolock(orientation_buffer_lock_); device_orientation_buffer_ = buffer; @@ -328,11 +416,25 @@ bool SensorManagerAndroid::StartFetchingDeviceOrientationData( is_using_backup_sensors_for_orientation_ = isUsingBackupSensorsForOrientation(); } - - return success; } void SensorManagerAndroid::StopFetchingDeviceOrientationData() { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + StopFetchingOrientationDataOnUI(); + return; + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SensorManagerAndroid::StopFetchingOrientationDataOnUI, + base::Unretained(this))); +} + +void SensorManagerAndroid::StopFetchingOrientationDataOnUI() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (is_shutdown_) + return; + Stop(kTypeOrientation); { base::AutoLock autolock(orientation_buffer_lock_); @@ -343,4 +445,9 @@ void SensorManagerAndroid::StopFetchingDeviceOrientationData() { } } +void SensorManagerAndroid::Shutdown() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + is_shutdown_ = true; +} + } // namespace content diff --git a/content/browser/device_sensors/sensor_manager_android.h b/content/browser/device_sensors/sensor_manager_android.h index 714b8ec04165bd..535efa1c1c92a6 100644 --- a/content/browser/device_sensors/sensor_manager_android.h +++ b/content/browser/device_sensors/sensor_manager_android.h @@ -52,6 +52,8 @@ class CONTENT_EXPORT SensorManagerAndroid { DeviceOrientationHardwareBuffer* buffer); void StopFetchingDeviceOrientationData(); + void Shutdown(); + protected: enum EventType { // These constants should match DEVICE_ORIENTATION, DEVICE_MOTION and @@ -69,6 +71,16 @@ class CONTENT_EXPORT SensorManagerAndroid { virtual void Stop(EventType event_type); virtual int GetNumberActiveDeviceMotionSensors(); + void StartFetchingLightDataOnUI(DeviceLightHardwareBuffer* buffer); + void StopFetchingLightDataOnUI(); + + void StartFetchingMotionDataOnUI(DeviceMotionHardwareBuffer* buffer); + void StopFetchingMotionDataOnUI(); + + void StartFetchingOrientationDataOnUI( + DeviceOrientationHardwareBuffer* buffer); + void StopFetchingOrientationDataOnUI(); + private: friend struct DefaultSingletonTraits; @@ -104,6 +116,7 @@ class CONTENT_EXPORT SensorManagerAndroid { base::Lock orientation_buffer_lock_; bool is_using_backup_sensors_for_orientation_; + bool is_shutdown_; DISALLOW_COPY_AND_ASSIGN(SensorManagerAndroid); }; diff --git a/content/browser/device_sensors/sensor_manager_android_unittest.cc b/content/browser/device_sensors/sensor_manager_android_unittest.cc index 5ce25fb1532e81..39f86e1d17fe5d 100644 --- a/content/browser/device_sensors/sensor_manager_android_unittest.cc +++ b/content/browser/device_sensors/sensor_manager_android_unittest.cc @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "content/browser/device_sensors/inertial_sensor_consts.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -16,7 +17,7 @@ namespace { class FakeSensorManagerAndroid : public SensorManagerAndroid { public: - FakeSensorManagerAndroid() { } + FakeSensorManagerAndroid() {} ~FakeSensorManagerAndroid() override {} int GetNumberActiveDeviceMotionSensors() override { @@ -29,7 +30,6 @@ class FakeSensorManagerAndroid : public SensorManagerAndroid { protected: bool Start(EventType event_type) override { return true; } - void Stop(EventType event_type) override {} private: @@ -47,6 +47,7 @@ class AndroidSensorManagerTest : public testing::Test { scoped_ptr light_buffer_; scoped_ptr motion_buffer_; scoped_ptr orientation_buffer_; + content::TestBrowserThreadBundle thread_bundle_; }; TEST_F(AndroidSensorManagerTest, ThreeDeviceMotionSensorsActive) { diff --git a/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java b/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java index 81eab0f244906f..427a0456c865a4 100644 --- a/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java +++ b/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java @@ -22,7 +22,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.Callable; /** * Android implementation of the device {motion|orientation|light} APIs. @@ -394,13 +393,9 @@ private SensorManagerProxy getSensorManagerProxy() { return mSensorManagerProxy; } - SensorManager sensorManager = ThreadUtils.runOnUiThreadBlockingNoException( - new Callable() { - @Override - public SensorManager call() { - return (SensorManager) mAppContext.getSystemService(Context.SENSOR_SERVICE); - } - }); + ThreadUtils.assertOnUiThread(); + SensorManager sensorManager = + (SensorManager) mAppContext.getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null) { mSensorManagerProxy = new SensorManagerProxyImpl(sensorManager);