Bug 709590 - Update screen orientation from sensor notification. r=jlebar

This commit is contained in:
Cervantes Yu 2012-02-23 14:25:53 +01:00
Родитель c15bf6c02a
Коммит eda9cbfbb7
2 изменённых файлов: 76 добавлений и 0 удалений

Просмотреть файл

@ -50,8 +50,10 @@
#include <sys/types.h>
#include <unistd.h>
#include "mozilla/Hal.h"
#include "nscore.h"
#include "mozilla/FileUtils.h"
#include "mozilla/HalSensor.h"
#include "mozilla/Mutex.h"
#include "mozilla/Services.h"
#include "nsAppShell.h"
@ -80,6 +82,7 @@
using namespace mozilla;
using namespace android;
using namespace hal;
bool gDrawRequest = false;
static nsAppShell *gAppShell = NULL;
@ -660,15 +663,81 @@ GeckoInputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChanne
return OK;
}
class ScreenRotateEvent : public nsRunnable {
public:
ScreenRotateEvent(nsIScreen* aScreen, PRUint32 aRotation)
: mScreen(aScreen),
mRotation(aRotation) {
}
NS_IMETHOD Run() {
return mScreen->SetRotation(mRotation);
}
private:
nsCOMPtr<nsIScreen> mScreen;
PRUint32 mRotation;
};
class OrientationSensorObserver : public ISensorObserver {
public:
OrientationSensorObserver ()
: mLastUpdate(0) {
}
void Notify(const SensorData& aSensorData) {
nsCOMPtr<nsIScreenManager> screenMgr =
do_GetService("@mozilla.org/gfx/screenmanager;1");
nsCOMPtr<nsIScreen> screen;
screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
MOZ_ASSERT(aSensorData.sensor() == SensorType::SENSOR_ORIENTATION);
InfallibleTArray<float> values = aSensorData.values();
// float azimuth = values[0]; // unused
float pitch = values[1];
float roll = values[2];
PRUint32 rotation;
if (roll > 45)
rotation = nsIScreen::ROTATION_90_DEG;
else if (roll < -45)
rotation = nsIScreen::ROTATION_270_DEG;
else if (pitch < -45)
rotation = nsIScreen::ROTATION_0_DEG;
else if (pitch > 45)
rotation = nsIScreen::ROTATION_180_DEG;
else
return; // don't rotate if undecidable
PRUint32 currRotation;
nsresult res;
res = screen->GetRotation(&currRotation);
if (NS_FAILED(res) || rotation == currRotation)
return;
PRTime now = PR_Now();
MOZ_ASSERT(now > mLastUpdate);
if (now - mLastUpdate < sMinUpdateInterval)
return;
mLastUpdate = now;
NS_DispatchToMainThread(new ScreenRotateEvent(screen, rotation));
}
private:
PRTime mLastUpdate;
static const PRTime sMinUpdateInterval = 500 * 1000; // 500 ms
};
nsAppShell::nsAppShell()
: mNativeCallbackRequest(false)
, mHandlers()
, mObserver(new OrientationSensorObserver())
{
gAppShell = this;
RegisterSensorObserver(SENSOR_ORIENTATION, mObserver);
}
nsAppShell::~nsAppShell()
{
UnregisterSensorObserver(SENSOR_ORIENTATION, mObserver);
status_t result = mReaderThread->requestExitAndWait();
if (result)
LOG("Could not stop reader thread - %d", result);

Просмотреть файл

@ -41,6 +41,8 @@
#include <queue>
#include "mozilla/Mutex.h"
#include "mozilla/Observer.h"
#include "nsAutoPtr.h"
#include "nsBaseAppShell.h"
#include "nsRect.h"
#include "nsTArray.h"
@ -50,6 +52,10 @@
namespace mozilla {
bool ProcessNextEvent();
void NotifyEvent();
namespace hal {
class SensorData;
typedef Observer<SensorData> ISensorObserver;
}
}
extern bool gDrawRequest;
@ -109,6 +115,7 @@ private:
android::sp<GeckoInputDispatcher> mDispatcher;
android::sp<android::InputReader> mReader;
android::sp<android::InputReaderThread> mReaderThread;
nsAutoPtr<mozilla::hal::ISensorObserver> mObserver;
};
#endif /* nsAppShell_h */