Skip to content

Commit

Permalink
Bug 1172740 - Implement Android HAL backend for alarms. r=snorp
Browse files Browse the repository at this point in the history
  • Loading branch information
reuben committed Oct 1, 2015
1 parent 1948589 commit 576abdd
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 3 deletions.
51 changes: 51 additions & 0 deletions hal/android/AndroidAlarm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "Hal.h"
#include "AndroidBridge.h"

#include "GeneratedJNINatives.h"

using namespace mozilla::hal;

namespace mozilla {

class AlarmReceiver : public widget::AlarmReceiver::Natives<AlarmReceiver>
{
private:
AlarmReceiver();

public:
static void NotifyAlarmFired() {
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
hal::NotifyAlarmFired();
});
NS_DispatchToMainThread(runnable);
}
};

namespace hal_impl {

bool
EnableAlarm()
{
AlarmReceiver::Init();
return true;
}

void
DisableAlarm()
{
widget::GeckoAppShell::DisableAlarm();
}

bool
SetAlarm(int32_t aSeconds, int32_t aNanoseconds)
{
return widget::GeckoAppShell::SetAlarm(aSeconds, aNanoseconds);
}

} // hal_impl
} // mozilla
5 changes: 4 additions & 1 deletion hal/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ SOURCES += [
]

if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
LOCAL_INCLUDES += [
'/widget/android',
]
UNIFIED_SOURCES += [
'android/AndroidAlarm.cpp',
'android/AndroidSensor.cpp',
'fallback/FallbackAlarm.cpp',
'fallback/FallbackPower.cpp',
'linux/LinuxMemory.cpp',
]
Expand Down
3 changes: 3 additions & 0 deletions mobile/android/b2gdroid/app/b2gdroid.js
Original file line number Diff line number Diff line change
Expand Up @@ -1022,4 +1022,7 @@ pref("dom.wakelock.enabled", true);

pref("dom.webcomponents.enabled", true);

// Enable the Alarms API
pref("dom.mozAlarms.enabled", true);

pref("layout.css.scroll-snap.enabled", true);
2 changes: 2 additions & 0 deletions mobile/android/b2gdroid/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
android:process="org.mozilla.b2gdroid.UpdateService">
</service>

<receiver android:name="org.mozilla.gecko.AlarmReceiver" >
</receiver>
</application>

</manifest>
42 changes: 42 additions & 0 deletions mobile/android/base/AlarmReceiver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko;

import org.mozilla.gecko.annotation.WrapForJNI;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;

import java.util.Timer;
import java.util.TimerTask;

public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
final WakeLock wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "GeckoAlarm");
wakeLock.acquire();

AlarmReceiver.notifyAlarmFired();
TimerTask releaseLockTask = new TimerTask() {
@Override
public void run() {
wakeLock.release();
}
};
Timer timer = new Timer();
// 5 seconds ought to be enough for anybody
timer.schedule(releaseLockTask, 5*1000);
}

@WrapForJNI
private static native void notifyAlarmFired();
}
7 changes: 5 additions & 2 deletions mobile/android/base/AndroidManifest.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,13 @@
</receiver>

<service android:name="org.mozilla.gecko.Restarter"
android:exported="false"
android:process="@[email protected]">
android:exported="false"
android:process="@[email protected]">
</service>

<receiver android:name="org.mozilla.gecko.AlarmReceiver" >
</receiver>

#include ../services/manifests/FxAccountAndroidManifest_activities.xml.in
#include ../services/manifests/HealthReportAndroidManifest_activities.xml.in
#include ../services/manifests/SyncAndroidManifest_activities.xml.in
Expand Down
26 changes: 26 additions & 0 deletions mobile/android/base/GeckoAppShell.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
Expand Down Expand Up @@ -603,6 +604,31 @@ public static void enableLocationHighAccuracy(final boolean enable) {
locationHighAccuracyEnabled = enable;
}

@WrapForJNI
public static boolean setAlarm(int aSeconds, int aNanoSeconds) {
AlarmManager am = (AlarmManager)
getContext().getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(getContext(), AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

// AlarmManager only supports millisecond precision
long time = ((long)aSeconds * 1000) + ((long)aNanoSeconds/1_000_000L);
am.setExact(AlarmManager.RTC_WAKEUP, time, pi);

return true;
}

@WrapForJNI
public static void disableAlarm() {
AlarmManager am = (AlarmManager)
getContext().getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(getContext(), AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
}

@WrapForJNI
public static void enableSensor(int aSensortype) {
GeckoInterface gi = getGeckoInterface();
Expand Down
1 change: 1 addition & 0 deletions mobile/android/base/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ gbjar.sources += [
'ActionModeCompat.java',
'ActionModeCompatView.java',
'ActivityHandlerHelper.java',
'AlarmReceiver.java',
'AndroidGamepadManager.java',
'animation/AnimationUtils.java',
'animation/AnimatorProxy.java',
Expand Down
15 changes: 15 additions & 0 deletions widget/android/GeneratedJNINatives.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ class ANRReporter::Natives : public mozilla::jni::NativeImpl<ANRReporter, Impl>
template<class Impl>
constexpr JNINativeMethod ANRReporter::Natives<Impl>::methods[];

template<class Impl>
class AlarmReceiver::Natives : public mozilla::jni::NativeImpl<AlarmReceiver, Impl>
{
public:
static constexpr JNINativeMethod methods[] = {

mozilla::jni::MakeNativeMethod<AlarmReceiver::NotifyAlarmFired_t>(
mozilla::jni::NativeStub<AlarmReceiver::NotifyAlarmFired_t, Impl>
::template Wrap<&Impl::NotifyAlarmFired>)
};
};

template<class Impl>
constexpr JNINativeMethod AlarmReceiver::Natives<Impl>::methods[];

template<class Impl>
class GeckoJavaSampler::Natives : public mozilla::jni::NativeImpl<GeckoJavaSampler, Impl>
{
Expand Down
21 changes: 21 additions & 0 deletions widget/android/GeneratedJNIWrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ constexpr char ANRReporter::ReleaseNativeStack_t::signature[];
constexpr char ANRReporter::RequestNativeStack_t::name[];
constexpr char ANRReporter::RequestNativeStack_t::signature[];

constexpr char AlarmReceiver::name[];

constexpr char AlarmReceiver::NotifyAlarmFired_t::name[];
constexpr char AlarmReceiver::NotifyAlarmFired_t::signature[];

constexpr char DownloadsIntegration::name[];

constexpr char DownloadsIntegration::ScanMedia_t::name[];
Expand Down Expand Up @@ -137,6 +142,14 @@ auto GeckoAppShell::DeleteMessageWrapper(int32_t a0, int32_t a1) -> void
return mozilla::jni::Method<DeleteMessageWrapper_t>::Call(nullptr, nullptr, a0, a1);
}

constexpr char GeckoAppShell::DisableAlarm_t::name[];
constexpr char GeckoAppShell::DisableAlarm_t::signature[];

auto GeckoAppShell::DisableAlarm() -> void
{
return mozilla::jni::Method<DisableAlarm_t>::Call(nullptr, nullptr);
}

constexpr char GeckoAppShell::DisableBatteryNotifications_t::name[];
constexpr char GeckoAppShell::DisableBatteryNotifications_t::signature[];

Expand Down Expand Up @@ -617,6 +630,14 @@ auto GeckoAppShell::SendMessageWrapper(mozilla::jni::String::Param a0, mozilla::
return mozilla::jni::Method<SendMessageWrapper_t>::Call(nullptr, nullptr, a0, a1, a2);
}

constexpr char GeckoAppShell::SetAlarm_t::name[];
constexpr char GeckoAppShell::SetAlarm_t::signature[];

auto GeckoAppShell::SetAlarm(int32_t a0, int32_t a1) -> bool
{
return mozilla::jni::Method<SetAlarm_t>::Call(nullptr, nullptr, a0, a1);
}

constexpr char GeckoAppShell::SetFullScreen_t::name[];
constexpr char GeckoAppShell::SetFullScreen_t::signature[];

Expand Down
69 changes: 69 additions & 0 deletions widget/android/GeneratedJNIWrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,39 @@ class ANRReporter : public mozilla::jni::Class<ANRReporter>
template<class Impl> class Natives;
};

class AlarmReceiver : public mozilla::jni::Class<AlarmReceiver>
{
public:
typedef mozilla::jni::Ref<AlarmReceiver> Ref;
typedef mozilla::jni::LocalRef<AlarmReceiver> LocalRef;
typedef mozilla::jni::GlobalRef<AlarmReceiver> GlobalRef;
typedef const mozilla::jni::Param<AlarmReceiver>& Param;

static constexpr char name[] =
"org/mozilla/gecko/AlarmReceiver";

protected:
AlarmReceiver(jobject instance) : Class(instance) {}

public:
struct NotifyAlarmFired_t {
typedef AlarmReceiver Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "notifyAlarmFired";
static constexpr char signature[] =
"()V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};

public:
template<class Impl> class Natives;
};

class DownloadsIntegration : public mozilla::jni::Class<DownloadsIntegration>
{
public:
Expand Down Expand Up @@ -376,6 +409,23 @@ class GeckoAppShell : public mozilla::jni::Class<GeckoAppShell>

static auto DeleteMessageWrapper(int32_t, int32_t) -> void;

public:
struct DisableAlarm_t {
typedef GeckoAppShell Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "disableAlarm";
static constexpr char signature[] =
"()V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};

static auto DisableAlarm() -> void;

public:
struct DisableBatteryNotifications_t {
typedef GeckoAppShell Owner;
Expand Down Expand Up @@ -1458,6 +1508,25 @@ class GeckoAppShell : public mozilla::jni::Class<GeckoAppShell>

static auto SendMessageWrapper(mozilla::jni::String::Param, mozilla::jni::String::Param, int32_t) -> void;

public:
struct SetAlarm_t {
typedef GeckoAppShell Owner;
typedef bool ReturnType;
typedef bool SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t> Args;
static constexpr char name[] = "setAlarm";
static constexpr char signature[] =
"(II)Z";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};

static auto SetAlarm(int32_t, int32_t) -> bool;

public:
struct SetFullScreen_t {
typedef GeckoAppShell Owner;
Expand Down

0 comments on commit 576abdd

Please sign in to comment.