Bug 853703 - Support SUPL NI. r=jaliu

This commit is contained in:
Alphan Chen 2016-01-15 10:32:24 +08:00
parent 0fac40ffa6
commit a649a9687f
3 changed files with 175 additions and 1 deletions

View File

@ -1137,6 +1137,33 @@ window.addEventListener('ContentStart', function update_onContentStart() {
}, "geolocation-device-events", false);
})();
(function suplNiNotifyStatusTracker() {
Services.obs.addObserver(function(aSubject, aTopic, aData) {
shell.sendChromeEvent({
type: 'supl-notification',
id: aData
});
}, "supl-ni-notify", false);
})();
(function suplNiVerifyStatusTracker() {
Services.obs.addObserver(function(aSubject, aTopic, aData) {
shell.sendChromeEvent({
type: 'supl-verification',
id: aData
});
}, "supl-ni-verify", false);
})();
(function suplNiVerifyTimeoutStatusTracker() {
Services.obs.addObserver(function(aSubject, aTopic, aData) {
shell.sendChromeEvent({
type: 'supl-verification-timeout',
id: aData
});
}, "supl-ni-verify-timeout", false);
})();
(function headphonesStatusTracker() {
Services.obs.addObserver(function(aSubject, aTopic, aData) {
shell.sendChromeEvent({

View File

@ -55,6 +55,15 @@
#endif
#define FLUSH_AIDE_DATA 0
#define SUPL_NI_NOTIFY "supl-ni-notify"
#define SUPL_NI_VERIFY "supl-ni-verify"
#define SUPL_NI_VERIFY_TIMEOUT "supl-ni-verify-timeout"
/* This flag is for sending chrome event to close the pop-up window.
The value is determined here which should not be used by GpsNiNotifyFlags.
GPS_NI_NEED_NOTIFY (0x0001)
GPS_NI_NEED_VERIFY (0x0002)
GPS_NI_PRIVACY_OVERRIDE (0x0004) */
#define GPS_NI_NEED_TIMEOUT 0xFFFF
using namespace mozilla;
using namespace mozilla::dom;
@ -73,6 +82,10 @@ static const char* kSettingRilDefaultServiceId = "ril.data.defaultServiceId";
// Both of these settings can be toggled in the Gaia Developer settings screen.
static const char* kSettingDebugEnabled = "geolocation.debugging.enabled";
static const char* kSettingDebugGpsIgnored = "geolocation.debugging.gps-locations-ignored";
// Gaia will modify the value of settings key(supl.verification.choice)
// when user make his/her choice of SUPL NI verification.
static const char* kSettingSuplVerificationChoice = "supl.verification.choice";
// While most methods of GonkGPSGeolocationProvider should only be
// called from main thread, we deliberately put the Init and ShutdownGPS
@ -84,13 +97,17 @@ NS_IMPL_ISUPPORTS(GonkGPSGeolocationProvider,
/* static */ GonkGPSGeolocationProvider* GonkGPSGeolocationProvider::sSingleton = nullptr;
GpsCallbacks GonkGPSGeolocationProvider::mCallbacks;
GpsNiCallbacks GonkGPSGeolocationProvider::mGPSNiCallbacks;
// This array is used for recording the request_id of replied SUPL NI request.
// In "TimeoutResponseEvent", we will check this array before replying the
// default response.
static nsTArray<int> repliedSuplNiReqIds;
#ifdef MOZ_B2G_RIL
AGpsCallbacks GonkGPSGeolocationProvider::mAGPSCallbacks;
AGpsRilCallbacks GonkGPSGeolocationProvider::mAGPSRILCallbacks;
#endif // MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
{
@ -327,6 +344,106 @@ GonkGPSGeolocationProvider::RequestUtcTimeCallback()
{
}
void
GonkGPSGeolocationProvider::SetNiResponse(int id, int response)
{
MOZ_ASSERT(mGpsNiInterface);
mGpsNiInterface->respond(id, response);
}
bool
GonkGPSGeolocationProvider::SendChromeEvent(int id, GpsNiNotifyFlags flags)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
if (flags == GPS_NI_NEED_VERIFY) {
RefPtr<GonkGPSGeolocationProvider> provider = GonkGPSGeolocationProvider::GetSingleton();
provider->SetNiResponse(id, GPS_NI_RESPONSE_NORESP);
}
return false;
}
nsCString str = nsPrintfCString("%d", id);
if (flags == GPS_NI_NEED_NOTIFY) {
obs->NotifyObservers(nullptr, SUPL_NI_NOTIFY, NS_ConvertUTF8toUTF16(str).get());
} else if (flags == GPS_NI_NEED_VERIFY) {
obs->NotifyObservers(nullptr, SUPL_NI_VERIFY, NS_ConvertUTF8toUTF16(str).get());
} else if (flags == GPS_NI_NEED_TIMEOUT) {
obs->NotifyObservers(nullptr, SUPL_NI_VERIFY_TIMEOUT, NS_ConvertUTF8toUTF16(str).get());
}
return true;
}
void
GonkGPSGeolocationProvider::GPSNiNotifyCallback(GpsNiNotification *notification)
{
class GPSNiNotifyEvent : public nsRunnable {
public:
GPSNiNotifyEvent(GpsNiNotification *aNotification)
: mNotification(aNotification)
{}
NS_IMETHOD Run() {
int id = mNotification->notification_id;
GpsNiNotifyFlags flags = mNotification->notify_flags;
if (gDebug_isLoggingEnabled) {
nsContentUtils::LogMessageToConsole(
"GPSNiNotifyCallback id:%d, flag:%x, timeout:%d, default response:%d\n",
id, flags, mNotification->timeout, mNotification->default_response);
}
RefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
if(!provider->SendChromeEvent(id, flags)) {
nsContentUtils::LogMessageToConsole(
"SendChromeEvent Failed(id:%d, flags:%x)", id, flags);
return NS_OK;
}
class TimeoutResponseEvent : public Task {
public:
TimeoutResponseEvent(int id, int defaultResp)
: mId(id), mDefaultResp(defaultResp)
{}
void Run() {
for (uint32_t idx = 0; idx < repliedSuplNiReqIds.Length() ; idx++) {
if(repliedSuplNiReqIds[idx] == mId) {
repliedSuplNiReqIds.RemoveElementAt(idx);
return;
}
}
RefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
if (!provider->SendChromeEvent(mId, GPS_NI_NEED_TIMEOUT)) {
nsContentUtils::LogMessageToConsole(
"SendChromeEvent Failed(id:%d, flags:%x", mId, GPS_NI_NEED_TIMEOUT);
}
provider->SetNiResponse(mId, mDefaultResp);
return;
}
private:
int mId;
int mDefaultResp;
};
if (flags == GPS_NI_NEED_VERIFY) {
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new TimeoutResponseEvent(id, mNotification->default_response),
mNotification->timeout*1000);
}
return NS_OK;
}
private:
GpsNiNotification *mNotification;
};
NS_DispatchToMainThread(new GPSNiNotifyEvent(notification));
return;
}
#ifdef MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::AGPSStatusCallback(AGpsStatus* status)
@ -782,6 +899,9 @@ GonkGPSGeolocationProvider::Init()
mCallbacks.request_utc_time_cb = RequestUtcTimeCallback;
#endif
mGPSNiCallbacks.notify_cb = GPSNiNotifyCallback;
mGPSNiCallbacks.create_thread_cb = CreateThreadCallback;
#ifdef MOZ_B2G_RIL
mAGPSCallbacks.status_cb = AGPSStatusCallback;
mAGPSCallbacks.create_thread_cb = CreateThreadCallback;
@ -796,6 +916,12 @@ GonkGPSGeolocationProvider::Init()
return;
}
mGpsNiInterface =
static_cast<const GpsNiInterface*>(mGpsInterface->get_extension(GPS_NI_INTERFACE));
if (mGpsNiInterface) {
mGpsNiInterface->init(&mGPSNiCallbacks);
}
#ifdef MOZ_B2G_RIL
mAGpsInterface =
static_cast<const AGpsInterface*>(mGpsInterface->get_extension(AGPS_INTERFACE));
@ -1198,6 +1324,22 @@ GonkGPSGeolocationProvider::Observe(nsISupports* aSubject,
gDebug_isLoggingEnabled =
setting.mValue.isBoolean() ? setting.mValue.toBoolean() : false;
return NS_OK;
} else if (setting.mKey.EqualsASCII(kSettingSuplVerificationChoice)) {
nsContentUtils::LogMessageToConsole("geo: received the choice of supl ni verification\n");
int id = setting.mValue.toNumber();
RefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
// The value of this key is based on notification_id:
// positive value(notification_id) means the choice is yes,
// negative value(notification_id * -1) means the choice is no.
if (id >= 0) {
provider->SetNiResponse(id, GPS_NI_RESPONSE_ACCEPT);
repliedSuplNiReqIds.AppendElement(id);
} else {
provider->SetNiResponse(id*-1, GPS_NI_RESPONSE_DENY);
repliedSuplNiReqIds.AppendElement(id*-1);
}
return NS_OK;
}
#ifdef MOZ_B2G_RIL
else if (setting.mKey.EqualsASCII(kSettingRilDefaultServiceId)) {

View File

@ -64,6 +64,7 @@ private:
static void ReleaseWakelockCallback();
static pthread_t CreateThreadCallback(const char* name, void (*start)(void*), void* arg);
static void RequestUtcTimeCallback();
static void GPSNiNotifyCallback(GpsNiNotification *notification);
#ifdef MOZ_B2G_RIL
static void AGPSStatusCallback(AGpsStatus* status);
static void AGPSRILSetIDCallback(uint32_t flags);
@ -71,6 +72,7 @@ private:
#endif
static GpsCallbacks mCallbacks;
static GpsNiCallbacks mGPSNiCallbacks;
#ifdef MOZ_B2G_RIL
static AGpsCallbacks mAGPSCallbacks;
static AGpsRilCallbacks mAGPSRILCallbacks;
@ -81,6 +83,8 @@ private:
void ShutdownGPS();
void InjectLocation(double latitude, double longitude, float accuracy);
void RequestSettingValue(const char* aKey);
void SetNiResponse(int id, int response);
bool SendChromeEvent(int id, GpsNiNotifyFlags flags);
#ifdef MOZ_B2G_RIL
void UpdateRadioInterface();
bool IsValidRilServiceId(uint32_t aServiceId);
@ -115,6 +119,7 @@ private:
bool mSupportsTimeInjection;
const GpsInterface* mGpsInterface;
const GpsNiInterface* mGpsNiInterface;
#ifdef MOZ_B2G_RIL
const AGpsInterface* mAGpsInterface;
const AGpsRilInterface* mAGpsRilInterface;