// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/device_orientation/data_fetcher_impl_android.h" #include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "content/browser/device_orientation/orientation.h" #include "jni/DeviceOrientation_jni.h" using base::android::AttachCurrentThread; using base::android::CheckException; using base::android::GetClass; using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaLocalRef; namespace content { namespace { // This should match ProviderImpl::kDesiredSamplingIntervalMs. // TODO(husky): Make that constant public so we can use it directly. const int kPeriodInMilliseconds = 100; base::LazyInstance > g_jni_obj = LAZY_INSTANCE_INITIALIZER; } // namespace DataFetcherImplAndroid::DataFetcherImplAndroid() { } void DataFetcherImplAndroid::Init(JNIEnv* env) { bool result = RegisterNativesImpl(env); DCHECK(result); g_jni_obj.Get().Reset(Java_DeviceOrientation_create(env)); } DataFetcher* DataFetcherImplAndroid::Create() { scoped_ptr fetcher(new DataFetcherImplAndroid); if (fetcher->Start(kPeriodInMilliseconds)) return fetcher.release(); LOG(ERROR) << "DataFetcherImplAndroid::Start failed!"; return NULL; } DataFetcherImplAndroid::~DataFetcherImplAndroid() { Stop(); } const DeviceData* DataFetcherImplAndroid::GetDeviceData( DeviceData::Type type) { if (type != DeviceData::kTypeOrientation) return NULL; return GetOrientation(); } const Orientation* DataFetcherImplAndroid::GetOrientation() { // Do we have a new orientation value? (It's safe to do this outside the lock // because we only skip the lock if the value is null. We always enter the // lock if we're going to make use of the new value.) if (next_orientation_.get()) { base::AutoLock autolock(next_orientation_lock_); next_orientation_.swap(current_orientation_); } if (!current_orientation_.get()) return new Orientation(); return current_orientation_.get(); } void DataFetcherImplAndroid::GotOrientation( JNIEnv*, jobject, double alpha, double beta, double gamma) { base::AutoLock autolock(next_orientation_lock_); Orientation* orientation = new Orientation(); orientation->set_alpha(alpha); orientation->set_beta(beta); orientation->set_gamma(gamma); orientation->set_absolute(true); next_orientation_ = orientation; } bool DataFetcherImplAndroid::Start(int rate_in_milliseconds) { DCHECK(!g_jni_obj.Get().is_null()); return Java_DeviceOrientation_start(AttachCurrentThread(), g_jni_obj.Get().obj(), reinterpret_cast(this), rate_in_milliseconds); } void DataFetcherImplAndroid::Stop() { DCHECK(!g_jni_obj.Get().is_null()); Java_DeviceOrientation_stop(AttachCurrentThread(), g_jni_obj.Get().obj()); } } // namespace content