mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
1946205e7c
Currently when either of these methods fail, we log something and rely on the calling code to null check. Since these failures are serious and likely unrecoverable, it's better to define these methods as infallible and just crash if they do fail.
998 lines
33 KiB
C++
998 lines
33 KiB
C++
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; 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/. */
|
|
|
|
#include "mozilla/Hal.h"
|
|
#include "nsIFile.h"
|
|
#include "nsString.h"
|
|
|
|
#include "AndroidBridge.h"
|
|
#include "AndroidGraphicBuffer.h"
|
|
|
|
#include <jni.h>
|
|
#include <pthread.h>
|
|
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <sched.h>
|
|
|
|
#include "nsAppShell.h"
|
|
#include "nsWindow.h"
|
|
#include <android/log.h>
|
|
#include "nsIObserverService.h"
|
|
#include "mozilla/Services.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
#ifdef MOZ_CRASHREPORTER
|
|
#include "nsICrashReporter.h"
|
|
#include "nsExceptionHandler.h"
|
|
#endif
|
|
|
|
#include "mozilla/unused.h"
|
|
|
|
#include "mozilla/dom/SmsMessage.h"
|
|
#include "mozilla/dom/mobilemessage/Constants.h"
|
|
#include "mozilla/dom/mobilemessage/Types.h"
|
|
#include "mozilla/dom/mobilemessage/PSms.h"
|
|
#include "mozilla/dom/mobilemessage/SmsParent.h"
|
|
#include "mozilla/layers/APZCTreeManager.h"
|
|
#include "nsIMobileMessageDatabaseService.h"
|
|
#include "nsPluginInstanceOwner.h"
|
|
#include "nsSurfaceTexture.h"
|
|
#include "GeckoProfiler.h"
|
|
#include "nsMemoryPressure.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
using namespace mozilla::dom::mobilemessage;
|
|
using namespace mozilla::layers;
|
|
|
|
/* Forward declare all the JNI methods as extern "C" */
|
|
|
|
extern "C" {
|
|
/*
|
|
* Incoming JNI methods
|
|
*/
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv *jenv, jclass jc)
|
|
{
|
|
AndroidBridge::ConstructBridge(jenv);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv *jenv, jclass jc, jobject event)
|
|
{
|
|
// poke the appshell
|
|
if (nsAppShell::gAppShell)
|
|
nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeFromJavaObject(jenv, event));
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_processNextNativeEvent(JNIEnv *jenv, jclass, jboolean mayWait)
|
|
{
|
|
// poke the appshell
|
|
if (nsAppShell::gAppShell)
|
|
nsAppShell::gAppShell->ProcessNextNativeEvent(mayWait != JNI_FALSE);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_setLayerClient(JNIEnv *jenv, jclass, jobject obj)
|
|
{
|
|
AndroidBridge::Bridge()->SetLayerClient(jenv, obj);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *jenv, jclass jc)
|
|
{
|
|
if (nsAppShell::gAppShell)
|
|
nsAppShell::gAppShell->OnResume();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *jenv, jclass, jstring jStackTrace)
|
|
{
|
|
#ifdef MOZ_CRASHREPORTER
|
|
const nsJNIString stackTrace16(jStackTrace, jenv);
|
|
const NS_ConvertUTF16toUTF8 stackTrace8(stackTrace16);
|
|
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("JavaStackTrace"), stackTrace8);
|
|
#endif // MOZ_CRASHREPORTER
|
|
|
|
abort();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_notifyBatteryChange(JNIEnv* jenv, jclass,
|
|
jdouble aLevel,
|
|
jboolean aCharging,
|
|
jdouble aRemainingTime)
|
|
{
|
|
class NotifyBatteryChangeRunnable : public nsRunnable {
|
|
public:
|
|
NotifyBatteryChangeRunnable(double aLevel, bool aCharging, double aRemainingTime)
|
|
: mLevel(aLevel)
|
|
, mCharging(aCharging)
|
|
, mRemainingTime(aRemainingTime)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
hal::NotifyBatteryChange(hal::BatteryInformation(mLevel, mCharging, mRemainingTime));
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
double mLevel;
|
|
bool mCharging;
|
|
double mRemainingTime;
|
|
};
|
|
|
|
nsCOMPtr<nsIRunnable> runnable = new NotifyBatteryChangeRunnable(aLevel, aCharging, aRemainingTime);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
#ifdef MOZ_WEBSMS_BACKEND
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsReceived(JNIEnv* jenv, jclass,
|
|
jstring aSender,
|
|
jstring aBody,
|
|
jint aMessageClass,
|
|
jlong aTimestamp)
|
|
{
|
|
class NotifySmsReceivedRunnable : public nsRunnable {
|
|
public:
|
|
NotifySmsReceivedRunnable(const SmsMessageData& aMessageData)
|
|
: mMessageData(aMessageData)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
|
if (!obs) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
|
|
obs->NotifyObservers(message, kSmsReceivedObserverTopic, nullptr);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
SmsMessageData mMessageData;
|
|
};
|
|
|
|
// TODO Need to correct the message `threadId` parameter value. Bug 859098
|
|
SmsMessageData message(0, 0, eDeliveryState_Received, eDeliveryStatus_Success,
|
|
nsJNIString(aSender, jenv), EmptyString(),
|
|
nsJNIString(aBody, jenv),
|
|
static_cast<MessageClass>(aMessageClass),
|
|
aTimestamp, false);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable = new NotifySmsReceivedRunnable(message);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsSent(JNIEnv* jenv, jclass,
|
|
jint aId,
|
|
jstring aReceiver,
|
|
jstring aBody,
|
|
jlong aTimestamp,
|
|
jint aRequestId)
|
|
{
|
|
class NotifySmsSentRunnable : public nsRunnable {
|
|
public:
|
|
NotifySmsSentRunnable(const SmsMessageData& aMessageData,
|
|
int32_t aRequestId)
|
|
: mMessageData(aMessageData)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
/*
|
|
* First, we are going to notify all SmsManager that a message has
|
|
* been sent. Then, we will notify the SmsRequest object about it.
|
|
*/
|
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
|
if (!obs) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
|
|
obs->NotifyObservers(message, kSmsSentObserverTopic, nullptr);
|
|
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
request->NotifyMessageSent(message);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
SmsMessageData mMessageData;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
// TODO Need to add the message `messageClass` parameter value. Bug 804476
|
|
// TODO Need to correct the message `threadId` parameter value. Bug 859098
|
|
SmsMessageData message(aId, 0, eDeliveryState_Sent, eDeliveryStatus_Pending,
|
|
EmptyString(), nsJNIString(aReceiver, jenv),
|
|
nsJNIString(aBody, jenv), eMessageClass_Normal,
|
|
aTimestamp, true);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable = new NotifySmsSentRunnable(message, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDelivery(JNIEnv* jenv, jclass,
|
|
jint aId,
|
|
jint aDeliveryStatus,
|
|
jstring aReceiver,
|
|
jstring aBody,
|
|
jlong aTimestamp)
|
|
{
|
|
class NotifySmsDeliveredRunnable : public nsRunnable {
|
|
public:
|
|
NotifySmsDeliveredRunnable(const SmsMessageData& aMessageData)
|
|
: mMessageData(aMessageData)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
|
if (!obs) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
|
|
const char* topic = (mMessageData.deliveryStatus() == eDeliveryStatus_Success)
|
|
? kSmsDeliverySuccessObserverTopic
|
|
: kSmsDeliveryErrorObserverTopic;
|
|
obs->NotifyObservers(message, topic, nullptr);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
SmsMessageData mMessageData;
|
|
};
|
|
|
|
// TODO Need to add the message `messageClass` parameter value. Bug 804476
|
|
// TODO Need to correct the message `threadId` parameter value. Bug 859098
|
|
SmsMessageData message(aId, 0, eDeliveryState_Sent,
|
|
static_cast<DeliveryStatus>(aDeliveryStatus),
|
|
EmptyString(), nsJNIString(aReceiver, jenv),
|
|
nsJNIString(aBody, jenv), eMessageClass_Normal,
|
|
aTimestamp, true);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable = new NotifySmsDeliveredRunnable(message);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsSendFailed(JNIEnv* jenv, jclass,
|
|
jint aError,
|
|
jint aRequestId)
|
|
{
|
|
class NotifySmsSendFailedRunnable : public nsRunnable {
|
|
public:
|
|
NotifySmsSendFailedRunnable(int32_t aError,
|
|
int32_t aRequestId)
|
|
: mError(aError)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
request->NotifySendMessageFailed(mError);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
int32_t mError;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifySmsSendFailedRunnable(aError, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifyGetSms(JNIEnv* jenv, jclass,
|
|
jint aId,
|
|
jint aDeliveryStatus,
|
|
jstring aReceiver,
|
|
jstring aSender,
|
|
jstring aBody,
|
|
jlong aTimestamp,
|
|
jint aRequestId)
|
|
{
|
|
class NotifyGetSmsRunnable : public nsRunnable {
|
|
public:
|
|
NotifyGetSmsRunnable(const SmsMessageData& aMessageData,
|
|
int32_t aRequestId)
|
|
: mMessageData(aMessageData)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
|
|
request->NotifyMessageGot(message);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
SmsMessageData mMessageData;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
nsJNIString receiver = nsJNIString(aReceiver, jenv);
|
|
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
|
|
: eDeliveryState_Sent;
|
|
|
|
// TODO Need to add the message `read` parameter value. Bug 748391
|
|
// TODO Need to add the message `messageClass` parameter value. Bug 804476
|
|
// TODO Need to correct the message `threadId` parameter value. Bug 859098
|
|
SmsMessageData message(aId, 0, state,
|
|
static_cast<DeliveryStatus>(aDeliveryStatus),
|
|
nsJNIString(aSender, jenv), receiver,
|
|
nsJNIString(aBody, jenv), eMessageClass_Normal,
|
|
aTimestamp, true);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable = new NotifyGetSmsRunnable(message, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifyGetSmsFailed(JNIEnv* jenv, jclass,
|
|
jint aError,
|
|
jint aRequestId)
|
|
{
|
|
class NotifyGetSmsFailedRunnable : public nsRunnable {
|
|
public:
|
|
NotifyGetSmsFailedRunnable(int32_t aError,
|
|
int32_t aRequestId)
|
|
: mError(aError)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
request->NotifyGetMessageFailed(mError);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
int32_t mError;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifyGetSmsFailedRunnable(aError, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDeleted(JNIEnv* jenv, jclass,
|
|
jboolean aDeleted,
|
|
jint aRequestId)
|
|
{
|
|
class NotifySmsDeletedRunnable : public nsRunnable {
|
|
public:
|
|
NotifySmsDeletedRunnable(bool aDeleted, int32_t aRequestId)
|
|
: mDeleted(aDeleted)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
// For android, we support only single SMS deletion.
|
|
request->NotifyMessageDeleted(&mDeleted, 1);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
bool mDeleted;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifySmsDeletedRunnable(aDeleted, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDeleteFailed(JNIEnv* jenv, jclass,
|
|
jint aError,
|
|
jint aRequestId)
|
|
{
|
|
class NotifySmsDeleteFailedRunnable : public nsRunnable {
|
|
public:
|
|
NotifySmsDeleteFailedRunnable(int32_t aError,
|
|
int32_t aRequestId)
|
|
: mError(aError)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
request->NotifyDeleteMessageFailed(mError);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
int32_t mError;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifySmsDeleteFailedRunnable(aError, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifyNoMessageInList(JNIEnv* jenv, jclass,
|
|
jint aRequestId)
|
|
{
|
|
class NotifyNoMessageInListRunnable : public nsRunnable {
|
|
public:
|
|
NotifyNoMessageInListRunnable(int32_t aRequestId)
|
|
: mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
request->NotifyNoMessageInList();
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifyNoMessageInListRunnable(aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifyListCreated(JNIEnv* jenv, jclass,
|
|
jint aListId,
|
|
jint aMessageId,
|
|
jint aDeliveryStatus,
|
|
jstring aReceiver,
|
|
jstring aSender,
|
|
jstring aBody,
|
|
jlong aTimestamp,
|
|
jint aRequestId)
|
|
{
|
|
class NotifyCreateMessageListRunnable : public nsRunnable {
|
|
public:
|
|
NotifyCreateMessageListRunnable(int32_t aListId,
|
|
const SmsMessageData& aMessageData,
|
|
int32_t aRequestId)
|
|
: mListId(aListId)
|
|
, mMessageData(aMessageData)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
|
|
request->NotifyMessageListCreated(mListId, message);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
int32_t mListId;
|
|
SmsMessageData mMessageData;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsJNIString receiver = nsJNIString(aReceiver, jenv);
|
|
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
|
|
: eDeliveryState_Sent;
|
|
|
|
// TODO Need to add the message `read` parameter value. Bug 748391
|
|
// TODO Need to add the message `messageClass` parameter value. Bug 804476
|
|
// TODO Need to correct the message `threadId` parameter value. Bug 859098
|
|
SmsMessageData message(aMessageId, 0, state,
|
|
static_cast<DeliveryStatus>(aDeliveryStatus),
|
|
nsJNIString(aSender, jenv), receiver,
|
|
nsJNIString(aBody, jenv), eMessageClass_Normal,
|
|
aTimestamp, true);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifyCreateMessageListRunnable(aListId, message, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifyGotNextMessage(JNIEnv* jenv, jclass,
|
|
jint aMessageId,
|
|
jint aDeliveryStatus,
|
|
jstring aReceiver,
|
|
jstring aSender,
|
|
jstring aBody,
|
|
jlong aTimestamp,
|
|
jint aRequestId)
|
|
{
|
|
class NotifyGotNextMessageRunnable : public nsRunnable {
|
|
public:
|
|
NotifyGotNextMessageRunnable(const SmsMessageData& aMessageData,
|
|
int32_t aRequestId)
|
|
: mMessageData(aMessageData)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
|
|
request->NotifyNextMessageInListGot(message);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
SmsMessageData mMessageData;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsJNIString receiver = nsJNIString(aReceiver, jenv);
|
|
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
|
|
: eDeliveryState_Sent;
|
|
|
|
// TODO Need to add the message `read` parameter value. Bug 748391
|
|
// TODO Need to add the message `messageClass` parameter value. Bug 804476
|
|
// TODO Need to correct the message `threadId` parameter value. Bug 859098
|
|
SmsMessageData message(aMessageId, 0, state,
|
|
static_cast<DeliveryStatus>(aDeliveryStatus),
|
|
nsJNIString(aSender, jenv), receiver,
|
|
nsJNIString(aBody, jenv), eMessageClass_Normal,
|
|
aTimestamp, true);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifyGotNextMessageRunnable(message, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoSmsManager_notifyReadingMessageListFailed(JNIEnv* jenv, jclass,
|
|
jint aError,
|
|
jint aRequestId)
|
|
{
|
|
class NotifyReadListFailedRunnable : public nsRunnable {
|
|
public:
|
|
NotifyReadListFailedRunnable(int32_t aError,
|
|
int32_t aRequestId)
|
|
: mError(aError)
|
|
, mRequestId(aRequestId)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsCOMPtr<nsIMobileMessageCallback> request =
|
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
|
|
|
request->NotifyReadMessageListFailed(mError);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
int32_t mError;
|
|
int32_t mRequestId;
|
|
};
|
|
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifyReadListFailedRunnable(aError, aRequestId);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
#endif // MOZ_WEBSMS_BACKEND
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_scheduleComposite(JNIEnv*, jclass)
|
|
{
|
|
nsWindow::ScheduleComposite();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_scheduleResumeComposition(JNIEnv*, jclass, jint width, jint height)
|
|
{
|
|
nsWindow::ScheduleResumeComposition(width, height);
|
|
}
|
|
|
|
NS_EXPORT float JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity(JNIEnv*, jclass)
|
|
{
|
|
return nsWindow::ComputeRenderIntegrity();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult(JNIEnv* jenv, jclass, jstring filePath, jlong callback)
|
|
{
|
|
class NotifyFilePickerResultRunnable : public nsRunnable {
|
|
public:
|
|
NotifyFilePickerResultRunnable(nsString& fileDir, long callback) :
|
|
mFileDir(fileDir), mCallback(callback) {}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
nsFilePickerCallback* handler = (nsFilePickerCallback*)mCallback;
|
|
handler->handleResult(mFileDir);
|
|
handler->Release();
|
|
return NS_OK;
|
|
}
|
|
private:
|
|
nsString mFileDir;
|
|
long mCallback;
|
|
};
|
|
nsString path = nsJNIString(filePath, jenv);
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new NotifyFilePickerResultRunnable(path, (long)callback);
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
static int
|
|
NextPowerOfTwo(int value) {
|
|
// code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
|
|
if (0 == value--) {
|
|
return 1;
|
|
}
|
|
value = (value >> 1) | value;
|
|
value = (value >> 2) | value;
|
|
value = (value >> 4) | value;
|
|
value = (value >> 8) | value;
|
|
value = (value >> 16) | value;
|
|
return value + 1;
|
|
}
|
|
|
|
#define MAX_LOCK_ATTEMPTS 10
|
|
|
|
static bool LockWindowWithRetry(void* window, unsigned char** bits, int* width, int* height, int* format, int* stride)
|
|
{
|
|
int count = 0;
|
|
|
|
while (count < MAX_LOCK_ATTEMPTS) {
|
|
if (AndroidBridge::Bridge()->LockWindow(window, bits, width, height, format, stride))
|
|
return true;
|
|
|
|
count++;
|
|
usleep(500);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
NS_EXPORT jobject JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_getSurfaceBits(JNIEnv* jenv, jclass, jobject surface)
|
|
{
|
|
static jclass jSurfaceBitsClass = nullptr;
|
|
static jmethodID jSurfaceBitsCtor = 0;
|
|
static jfieldID jSurfaceBitsWidth, jSurfaceBitsHeight, jSurfaceBitsFormat, jSurfaceBitsBuffer;
|
|
|
|
jobject surfaceBits = nullptr;
|
|
unsigned char* bitsCopy = nullptr;
|
|
int dstWidth, dstHeight, dstSize;
|
|
|
|
void* window = AndroidBridge::Bridge()->AcquireNativeWindow(jenv, surface);
|
|
if (!window)
|
|
return nullptr;
|
|
|
|
unsigned char* bits;
|
|
int srcWidth, srcHeight, format, srcStride;
|
|
|
|
// So we lock/unlock once here in order to get whatever is currently the front buffer. It sucks.
|
|
if (!LockWindowWithRetry(window, &bits, &srcWidth, &srcHeight, &format, &srcStride))
|
|
return nullptr;
|
|
|
|
AndroidBridge::Bridge()->UnlockWindow(window);
|
|
|
|
// This is lock will result in the front buffer, since the last unlock rotated it to the back. Probably.
|
|
if (!LockWindowWithRetry(window, &bits, &srcWidth, &srcHeight, &format, &srcStride))
|
|
return nullptr;
|
|
|
|
// These are from android.graphics.PixelFormat
|
|
int bpp;
|
|
switch (format) {
|
|
case 1: // RGBA_8888
|
|
bpp = 4;
|
|
break;
|
|
case 4: // RGB_565
|
|
bpp = 2;
|
|
break;
|
|
default:
|
|
goto cleanup;
|
|
}
|
|
|
|
dstWidth = NextPowerOfTwo(srcWidth);
|
|
dstHeight = NextPowerOfTwo(srcHeight);
|
|
dstSize = dstWidth * dstHeight * bpp;
|
|
|
|
bitsCopy = (unsigned char*)malloc(dstSize);
|
|
bzero(bitsCopy, dstSize);
|
|
for (int i = 0; i < srcHeight; i++) {
|
|
memcpy(bitsCopy + ((dstHeight - i - 1) * dstWidth * bpp), bits + (i * srcStride * bpp), srcStride * bpp);
|
|
}
|
|
|
|
if (!jSurfaceBitsClass) {
|
|
jSurfaceBitsClass = (jclass)jenv->NewGlobalRef(jenv->FindClass("org/mozilla/gecko/SurfaceBits"));
|
|
jSurfaceBitsCtor = jenv->GetMethodID(jSurfaceBitsClass, "<init>", "()V");
|
|
|
|
jSurfaceBitsWidth = jenv->GetFieldID(jSurfaceBitsClass, "width", "I");
|
|
jSurfaceBitsHeight = jenv->GetFieldID(jSurfaceBitsClass, "height", "I");
|
|
jSurfaceBitsFormat = jenv->GetFieldID(jSurfaceBitsClass, "format", "I");
|
|
jSurfaceBitsBuffer = jenv->GetFieldID(jSurfaceBitsClass, "buffer", "Ljava/nio/ByteBuffer;");
|
|
}
|
|
|
|
surfaceBits = jenv->NewObject(jSurfaceBitsClass, jSurfaceBitsCtor);
|
|
jenv->SetIntField(surfaceBits, jSurfaceBitsWidth, dstWidth);
|
|
jenv->SetIntField(surfaceBits, jSurfaceBitsHeight, dstHeight);
|
|
jenv->SetIntField(surfaceBits, jSurfaceBitsFormat, format);
|
|
jenv->SetObjectField(surfaceBits, jSurfaceBitsBuffer, jenv->NewDirectByteBuffer(bitsCopy, dstSize));
|
|
|
|
cleanup:
|
|
AndroidBridge::Bridge()->UnlockWindow(window);
|
|
AndroidBridge::Bridge()->ReleaseNativeWindow(window);
|
|
|
|
return surfaceBits;
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_onFullScreenPluginHidden(JNIEnv* jenv, jclass, jobject view)
|
|
{
|
|
class ExitFullScreenRunnable : public nsRunnable {
|
|
public:
|
|
ExitFullScreenRunnable(jobject view) : mView(view) {}
|
|
|
|
NS_IMETHODIMP Run() {
|
|
JNIEnv* env = AndroidBridge::GetJNIEnv();
|
|
nsPluginInstanceOwner::ExitFullScreen(mView);
|
|
env->DeleteGlobalRef(mView);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
jobject mView;
|
|
};
|
|
|
|
nsCOMPtr<nsIRunnable> runnable = new ExitFullScreenRunnable(jenv->NewGlobalRef(view));
|
|
NS_DispatchToMainThread(runnable);
|
|
}
|
|
|
|
NS_EXPORT jobject JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue(JNIEnv* jenv, jclass, jobject queue)
|
|
{
|
|
static jclass jMessageQueueCls = nullptr;
|
|
static jfieldID jMessagesField;
|
|
static jmethodID jNextMethod;
|
|
if (!jMessageQueueCls) {
|
|
jMessageQueueCls = (jclass) jenv->NewGlobalRef(jenv->FindClass("android/os/MessageQueue"));
|
|
jNextMethod = jenv->GetMethodID(jMessageQueueCls, "next", "()Landroid/os/Message;");
|
|
jMessagesField = jenv->GetFieldID(jMessageQueueCls, "mMessages", "Landroid/os/Message;");
|
|
}
|
|
|
|
if (!jMessageQueueCls || !jNextMethod)
|
|
return nullptr;
|
|
|
|
if (jMessagesField) {
|
|
jobject msg = jenv->GetObjectField(queue, jMessagesField);
|
|
// if queue.mMessages is null, queue.next() will block, which we don't want
|
|
// It turns out to be an order of magnitude more performant to do this extra check here and
|
|
// block less vs. one fewer checks here and more blocking.
|
|
if (!msg) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
return jenv->CallObjectMethod(queue, jNextMethod);
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_onSurfaceTextureFrameAvailable(JNIEnv* jenv, jclass, jobject surfaceTexture, jint id)
|
|
{
|
|
nsSurfaceTexture* st = nsSurfaceTexture::Find(id);
|
|
if (!st) {
|
|
__android_log_print(ANDROID_LOG_ERROR, "GeckoJNI", "Failed to find nsSurfaceTexture with id %d", id);
|
|
return;
|
|
}
|
|
|
|
st->NotifyFrameAvailable();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_GeckoAppShell_dispatchMemoryPressure(JNIEnv* jenv, jclass)
|
|
{
|
|
NS_DispatchMemoryPressure(MemPressure_New);
|
|
}
|
|
|
|
NS_EXPORT jdouble JNICALL
|
|
Java_org_mozilla_gecko_GeckoJavaSampler_getProfilerTime(JNIEnv *jenv, jclass jc)
|
|
{
|
|
return profiler_time();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_abortAnimation(JNIEnv* env, jobject instance)
|
|
{
|
|
APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
|
|
if (controller) {
|
|
// TODO: Pass in correct values for presShellId and viewId.
|
|
controller->CancelAnimation(ScrollableLayerGuid(nsWindow::RootLayerTreeId(), 0, 0));
|
|
}
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject instance)
|
|
{
|
|
if (!AndroidBridge::Bridge()) {
|
|
return;
|
|
}
|
|
|
|
NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(instance);
|
|
if (oldRef && !oldRef->isNull()) {
|
|
MOZ_ASSERT(false, "Registering a new NPZC when we already have one");
|
|
delete oldRef;
|
|
}
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, jobject instance, jobject event)
|
|
{
|
|
APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
|
|
if (controller) {
|
|
AndroidGeckoEvent* wrapper = AndroidGeckoEvent::MakeFromJavaObject(env, event);
|
|
const MultiTouchInput& input = wrapper->MakeMultiTouchInput(nsWindow::TopWindow());
|
|
delete wrapper;
|
|
if (input.mType >= 0) {
|
|
controller->ReceiveInputEvent(input, nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_handleMotionEvent(JNIEnv* env, jobject instance, jobject event)
|
|
{
|
|
// FIXME implement this
|
|
}
|
|
|
|
NS_EXPORT jlong JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback(JNIEnv* env, jobject instance)
|
|
{
|
|
if (!AndroidBridge::Bridge()) {
|
|
return -1;
|
|
}
|
|
|
|
return AndroidBridge::Bridge()->RunDelayedTasks();
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject instance)
|
|
{
|
|
if (!AndroidBridge::Bridge()) {
|
|
return;
|
|
}
|
|
|
|
NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(nullptr);
|
|
if (!oldRef || oldRef->isNull()) {
|
|
MOZ_ASSERT(false, "Clearing a non-existent NPZC");
|
|
} else {
|
|
delete oldRef;
|
|
}
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(JNIEnv* env, jobject instance, jboolean prevented)
|
|
{
|
|
APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
|
|
if (controller) {
|
|
// TODO: Pass in correct values for presShellId and viewId.
|
|
controller->ContentReceivedTouch(ScrollableLayerGuid(nsWindow::RootLayerTreeId(), 0, 0), prevented);
|
|
}
|
|
}
|
|
|
|
NS_EXPORT jboolean JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint(JNIEnv* env, jobject instance)
|
|
{
|
|
// FIXME implement this
|
|
return true;
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_setOverScrollMode(JNIEnv* env, jobject instance, jint overscrollMode)
|
|
{
|
|
// FIXME implement this
|
|
}
|
|
|
|
NS_EXPORT jint JNICALL
|
|
Java_org_mozilla_gecko_gfx_NativePanZoomController_getOverScrollMode(JNIEnv* env, jobject instance)
|
|
{
|
|
// FIXME implement this
|
|
return 0;
|
|
}
|
|
|
|
NS_EXPORT jboolean JNICALL
|
|
Java_org_mozilla_gecko_ANRReporter_requestNativeStack(JNIEnv*, jclass)
|
|
{
|
|
if (profiler_is_active()) {
|
|
// Don't proceed if profiler is already running
|
|
return JNI_FALSE;
|
|
}
|
|
// WARNING: we are on the ANR reporter thread at this point and it is
|
|
// generally unsafe to use the profiler from off the main thread. However,
|
|
// the risk here is limited because for most users, the profiler is not run
|
|
// elsewhere. See the discussion in Bug 863777, comment 13
|
|
const char *NATIVE_STACK_FEATURES[] = {"leaf", "threads", "privacy"};
|
|
// Buffer one sample and let the profiler wait a long time
|
|
profiler_start(100, 10000, NATIVE_STACK_FEATURES,
|
|
sizeof(NATIVE_STACK_FEATURES) / sizeof(char*),
|
|
nullptr, 0);
|
|
return JNI_TRUE;
|
|
}
|
|
|
|
NS_EXPORT jstring JNICALL
|
|
Java_org_mozilla_gecko_ANRReporter_getNativeStack(JNIEnv* jenv, jclass)
|
|
{
|
|
if (!profiler_is_active()) {
|
|
// Maybe profiler support is disabled?
|
|
return nullptr;
|
|
}
|
|
char *profile = profiler_get_profile();
|
|
while (profile && !strlen(profile)) {
|
|
// no sample yet?
|
|
sched_yield();
|
|
profile = profiler_get_profile();
|
|
}
|
|
jstring result = nullptr;
|
|
if (profile) {
|
|
result = jenv->NewStringUTF(profile);
|
|
free(profile);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
NS_EXPORT void JNICALL
|
|
Java_org_mozilla_gecko_ANRReporter_releaseNativeStack(JNIEnv* jenv, jclass)
|
|
{
|
|
if (!profiler_is_active()) {
|
|
// Maybe profiler support is disabled?
|
|
return;
|
|
}
|
|
mozilla_sampler_stop();
|
|
}
|
|
|
|
}
|