diff --git a/configure.in b/configure.in index 99e6e4d97d6c..2b17bcd603cd 100644 --- a/configure.in +++ b/configure.in @@ -313,7 +313,7 @@ if test -n "$gonkdir" ; then STLPORT_CPPFLAGS="-I$gonkdir/ndk/sources/cxx-stl/stlport/stlport/" STLPORT_LIBS="-lstlport" - CPPFLAGS="-DANDROID -I$gonkdir/bionic/libc/include/ -I$gonkdir/bionic/libc/kernel/common -I$gonkdir/bionic/libc/arch-arm/include -I$gonkdir/bionic/libc/kernel/arch-arm -I$gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/system/core/include -I$gonkdir/bionic -I$gonkdir/frameworks/base/include $STLPORT_CPPFLAGS $CPPFLAGS" + CPPFLAGS="-DANDROID -I$gonkdir/bionic/libc/include/ -I$gonkdir/bionic/libc/kernel/common -I$gonkdir/bionic/libc/arch-arm/include -I$gonkdir/bionic/libc/kernel/arch-arm -I$gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/hardware/libhardware_legacy/include -I$gonkdir/system/core/include -I$gonkdir/bionic -I$gonkdir/frameworks/base/include $STLPORT_CPPFLAGS $CPPFLAGS" CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS" CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions $CXXFLAGS" LIBS="$LIBS $STLPORT_LIBS" diff --git a/hal/Makefile.in b/hal/Makefile.in index 2065d691f53c..dc5fa1abd41d 100644 --- a/hal/Makefile.in +++ b/hal/Makefile.in @@ -41,6 +41,7 @@ srcdir = @srcdir@ VPATH = \ $(srcdir) \ $(srcdir)/android \ + $(srcdir)/gonk \ $(srcdir)/fallback \ $(srcdir)/sandbox \ $(srcdir)/linux \ @@ -70,6 +71,8 @@ CPPSRCS = \ ifeq (android,$(MOZ_WIDGET_TOOLKIT)) CPPSRCS += AndroidHal.cpp +else ifeq (gonk,$(MOZ_WIDGET_TOOLKIT)) +CPPSRCS += GonkHal.cpp else ifeq (Linux,$(OS_TARGET)) CPPSRCS += LinuxHal.cpp ifdef MOZ_ENABLE_DBUS diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp new file mode 100644 index 000000000000..7dc8bcad16a6 --- /dev/null +++ b/hal/gonk/GonkHal.cpp @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et ft=cpp : */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Code. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Jones + * Michael Wu + * Justin Lebar + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "hardware_legacy/uevent.h" +#include "Hal.h" +#include "mozilla/dom/battery/Constants.h" +#include "mozilla/FileUtils.h" +#include "nsAlgorithm.h" +#include "nsThreadUtils.h" +#include +#include +#include +#include + +using mozilla::hal::WindowIdentifier; + +namespace mozilla { +namespace hal_impl { + +void +Vibrate(const nsTArray& pattern, const WindowIdentifier &) +{} + +void +CancelVibrate(const WindowIdentifier &) +{} + +namespace { + +class BatteryUpdater : public nsRunnable { +public: + NS_IMETHOD Run() + { + hal::BatteryInformation info; + hal_impl::GetCurrentBatteryInformation(&info); + hal::NotifyBatteryChange(info); + return NS_OK; + } +}; + +class UEventWatcher : public nsRunnable { +public: + UEventWatcher() + : mUpdater(new BatteryUpdater()) + , mRunning(false) + { + } + + NS_IMETHOD Run() + { + while (mRunning) { + char buf[1024]; + int count = uevent_next_event(buf, sizeof(buf) - 1); + if (!count) { + NS_WARNING("uevent_next_event() returned 0!"); + continue; + } + + buf[sizeof(buf) - 1] = 0; + if (strstr(buf, "battery")) + NS_DispatchToMainThread(mUpdater); + } + return NS_OK; + } + + bool mRunning; + +private: + nsRefPtr mUpdater; +}; + +} // anonymous namespace + +static bool sUEventInitialized = false; +static UEventWatcher *sWatcher = NULL; +static nsIThread *sWatcherThread = NULL; + +void +EnableBatteryNotifications() +{ + if (!sUEventInitialized) + sUEventInitialized = uevent_init(); + if (!sUEventInitialized) { + NS_WARNING("uevent_init() failed!"); + return; + } + + if (!sWatcher) + sWatcher = new UEventWatcher(); + NS_ADDREF(sWatcher); + + sWatcher->mRunning = true; + nsresult rv = NS_NewThread(&sWatcherThread, sWatcher); + if (NS_FAILED(rv)) + NS_WARNING("Failed to get new thread for uevent watching"); +} + +void +DisableBatteryNotifications() +{ + sWatcher->mRunning = false; + sWatcherThread->Shutdown(); + NS_IF_RELEASE(sWatcherThread); + delete sWatcher; +} + +void +GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo) +{ + FILE *capacityFile = fopen("/sys/class/power_supply/battery/capacity", "r"); + double capacity = dom::battery::kDefaultLevel * 100; + if (capacityFile) + fscanf(capacityFile, "%lf", &capacity); + fclose(capacityFile); + + FILE *chargingFile = fopen("/sys/class/power_supply/battery/charging_source", "r"); + int chargingSrc = 1; + if (chargingFile) + fscanf(chargingFile, "%d", &chargingSrc); + fclose(chargingFile); + + aBatteryInfo->level() = capacity / 100; + aBatteryInfo->charging() = chargingSrc == 1; + aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime; +} + +namespace { + +/** + * RAII class to help us remember to close file descriptors. + */ +const char *screenEnabledFilename = "/sys/power/state"; +const char *screenBrightnessFilename = "/sys/class/backlight/pwm-backlight/brightness"; + +template +bool ReadFromFile(const char *filename, char (&buf)[n]) +{ + int fd = open(filename, O_RDONLY); + ScopedClose autoClose(fd); + if (fd < 0) { + HAL_LOG(("Unable to open file %s.", filename)); + return false; + } + + ssize_t numRead = read(fd, buf, n); + if (numRead < 0) { + HAL_LOG(("Error reading from file %s.", filename)); + return false; + } + + buf[PR_MIN(numRead, n - 1)] = '\0'; + return true; +} + +void WriteToFile(const char *filename, const char *toWrite) +{ + int fd = open(filename, O_WRONLY); + ScopedClose autoClose(fd); + if (fd < 0) { + HAL_LOG(("Unable to open file %s.", filename)); + return; + } + + if (write(fd, toWrite, strlen(toWrite)) < 0) { + HAL_LOG(("Unable to write to file %s.", filename)); + return; + } +} + +// We can write to screenEnabledFilename to enable/disable the screen, but when +// we read, we always get "mem"! So we have to keep track ourselves whether +// the screen is on or not. +bool sScreenEnabled = true; + +} // anonymous namespace + +bool +GetScreenEnabled() +{ + return sScreenEnabled; +} + +void +SetScreenEnabled(bool enabled) +{ + WriteToFile(screenEnabledFilename, enabled ? "on" : "mem"); + sScreenEnabled = enabled; +} + +double +GetScreenBrightness() +{ + char buf[32]; + ReadFromFile(screenBrightnessFilename, buf); + + errno = 0; + unsigned long val = strtoul(buf, NULL, 10); + if (errno) { + HAL_LOG(("Cannot parse contents of %s; expected an unsigned " + "int, but contains \"%s\".", + screenBrightnessFilename, buf)); + return 1; + } + + if (val > 255) { + HAL_LOG(("Got out-of-range brightness %d, truncating to 1.0", val)); + val = 255; + } + + return val / 255.0; +} + +void +SetScreenBrightness(double brightness) +{ + // Don't use De Morgan's law to push the ! into this expression; we want to + // catch NaN too. + if (!(0 <= brightness && brightness <= 1)) { + HAL_LOG(("SetScreenBrightness: Dropping illegal brightness %f.", + brightness)); + return; + } + + // Convert the value in [0, 1] to an int between 0 and 255, then write to a + // string. + int val = static_cast(round(brightness * 255)); + char str[4]; + DebugOnly numChars = snprintf(str, sizeof(str), "%d", val); + MOZ_ASSERT(numChars < static_cast(sizeof(str))); + + WriteToFile(screenBrightnessFilename, str); +} + +} // hal_impl +} // mozilla diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in index 29f232cff364..aa32d1499cd0 100644 --- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -424,6 +424,7 @@ ifeq (gonk,$(MOZ_WIDGET_TOOLKIT)) OS_LIBS += \ -lui \ -lmedia \ + -lhardware_legacy \ $(NULL) endif