com_android_server_location_GpsLocationProvider.cpp revision c21a08f747f6fd1d7b8c98176ff70abc57cf58a0
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "GpsLocationProvider"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "hardware_legacy/gps.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/Log.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <pthread.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pthread_mutex_t sEventMutex = PTHREAD_MUTEX_INITIALIZER;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportLocation;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportStatus;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_reportSvStatus;
3458bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic jmethodID method_reportSuplStatus;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID method_xtraDownloadRequest;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const GpsInterface* sGpsInterface = NULL;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const GpsXtraInterface* sGpsXtraInterface = NULL;
39105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectstatic const GpsSuplInterface* sGpsSuplInterface = NULL;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// data written to by GPS callbacks
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsLocation  sGpsLocation;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsStatus    sGpsStatus;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsSvStatus  sGpsSvStatus;
4558bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic GpsSuplStatus    sGpsSuplStatus;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// a copy of the data shared by android_location_GpsLocationProvider_wait_for_event
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// and android_location_GpsLocationProvider_read_status
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsLocation  sGpsLocationCopy;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsStatus    sGpsStatusCopy;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic GpsSvStatus  sGpsSvStatusCopy;
5258bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic GpsSuplStatus    sGpsSuplStatusCopy;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum CallbackType {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kLocation = 1,
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kStatus = 2,
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kSvStatus = 4,
5858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    kSuplStatus = 8,
5958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    kXtraDownloadRequest = 16,
6058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    kDisableRequest = 32,
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int sPendingCallbacks;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void location_callback(GpsLocation* location)
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_lock(&sEventMutex);
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sPendingCallbacks |= kLocation;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(&sGpsLocation, location, sizeof(sGpsLocation));
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_cond_signal(&sEventCond);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_unlock(&sEventMutex);
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void status_callback(GpsStatus* status)
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_lock(&sEventMutex);
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sPendingCallbacks |= kStatus;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(&sGpsStatus, status, sizeof(sGpsStatus));
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_cond_signal(&sEventCond);
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_unlock(&sEventMutex);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void sv_status_callback(GpsSvStatus* sv_status)
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_lock(&sEventMutex);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sPendingCallbacks |= kSvStatus;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(&sGpsSvStatus, sv_status, sizeof(GpsSvStatus));
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_cond_signal(&sEventCond);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_unlock(&sEventMutex);
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9958bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void supl_status_callback(GpsSuplStatus* supl_status)
10058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{
10158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    pthread_mutex_lock(&sEventMutex);
10258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood
10358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    sPendingCallbacks |= kSuplStatus;
10458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus));
10558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood
10658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    pthread_cond_signal(&sEventCond);
10758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    pthread_mutex_unlock(&sEventMutex);
10858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood}
10958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGpsCallbacks sGpsCallbacks = {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    location_callback,
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_callback,
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sv_status_callback,
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdownload_request_callback()
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_lock(&sEventMutex);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sPendingCallbacks |= kXtraDownloadRequest;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_cond_signal(&sEventCond);
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_unlock(&sEventMutex);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectGpsXtraCallbacks sGpsXtraCallbacks = {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    download_request_callback,
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12958bda987665af759c379cd494ff4873ac61acf29Mike LockwoodGpsSuplCallbacks sGpsSuplCallbacks = {
13058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    supl_status_callback,
13158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood};
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
13758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    method_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)V");
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!sGpsInterface)
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sGpsInterface = gps_get_interface();
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (sGpsInterface != NULL);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!sGpsInterface)
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sGpsInterface = gps_get_interface();
15158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
15258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        return false;
15358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood
15458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (!sGpsSuplInterface)
15558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
15658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (sGpsSuplInterface)
15758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface->init(&sGpsSuplCallbacks);
158c21a08f747f6fd1d7b8c98176ff70abc57cf58a0Mike Lockwood    return true;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_disable(JNIEnv* env, jobject obj)
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_lock(&sEventMutex);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sPendingCallbacks |= kDisableRequest;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_cond_signal(&sEventCond);
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_unlock(&sEventMutex);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj)
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sGpsInterface->cleanup();
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
174105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj, jint positionMode,
175105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        jboolean singleFix, jint fixFrequency)
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
177105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    int result = sGpsInterface->set_position_mode(positionMode, (singleFix ? 0 : fixFrequency));
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result) {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (sGpsInterface->start() == 0);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj)
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (sGpsInterface->stop() == 0);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_set_fix_frequency(JNIEnv* env, jobject obj, jint fixFrequency)
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sGpsInterface->set_fix_frequency)
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sGpsInterface->set_fix_frequency(fixFrequency);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags)
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sGpsInterface->delete_aiding_data(flags);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, jobject obj)
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_lock(&sEventMutex);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_cond_wait(&sEventCond, &sEventMutex);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // copy and clear the callback flags
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int pendingCallbacks = sPendingCallbacks;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sPendingCallbacks = 0;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // copy everything and unlock the mutex before calling into Java code to avoid the possibility
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // of timeouts in the GPS engine.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy));
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy));
21558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy));
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pthread_mutex_unlock(&sEventMutex);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pendingCallbacks & kLocation) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags,
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude,
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (jdouble)sGpsLocationCopy.altitude,
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing,
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pendingCallbacks & kStatus) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pendingCallbacks & kSvStatus) {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->CallVoidMethod(obj, method_reportSvStatus);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (pendingCallbacks & kSuplStatus) {
23258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status);
23358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pendingCallbacks & kXtraDownloadRequest) {
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->CallVoidMethod(obj, method_xtraDownloadRequest);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pendingCallbacks & kDisableRequest) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // don't need to do anything - we are just poking so wait_for_event will return.
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj,
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray,
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jintArray maskArray)
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // this should only be called from within a call to reportStatus, so we don't need to lock here
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint* prns = env->GetIntArrayElements(prnArray, 0);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloat* snrs = env->GetFloatArrayElements(snrArray, 0);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint* mask = env->GetIntArrayElements(maskArray, 0);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int num_svs = sGpsSvStatusCopy.num_svs;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < num_svs; i++) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        prns[i] = sGpsSvStatusCopy.sv_list[i].prn;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        snrs[i] = sGpsSvStatusCopy.sv_list[i].snr;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        elev[i] = sGpsSvStatusCopy.sv_list[i].elevation;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        azim[i] = sGpsSvStatusCopy.sv_list[i].azimuth;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mask[0] = sGpsSvStatusCopy.ephemeris_mask;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mask[1] = sGpsSvStatusCopy.almanac_mask;
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mask[2] = sGpsSvStatusCopy.used_in_fix_mask;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseIntArrayElements(prnArray, prns, 0);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseFloatArrayElements(snrArray, snrs, 0);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseFloatArrayElements(elevArray, elev, 0);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseFloatArrayElements(azumArray, azim, 0);
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseIntArrayElements(maskArray, mask, 0);
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return num_svs;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj, jlong time,
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jlong timeReference, jint uncertainty)
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sGpsInterface->inject_time(time, timeReference, uncertainty);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj)
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!sGpsXtraInterface) {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sGpsXtraInterface = (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sGpsXtraInterface) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int result = sGpsXtraInterface->init(&sGpsXtraCallbacks);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (result) {
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sGpsXtraInterface = NULL;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (sGpsXtraInterface != NULL);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj,
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jbyteArray data, jint length)
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jbyte* bytes = env->GetByteArrayElements(data, 0);
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sGpsXtraInterface->inject_xtra_data((char *)bytes, length);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseByteArrayElements(data, bytes, 0);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30258bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
303105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{
304105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    if (!sGpsSuplInterface) {
305105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
306105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
307105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    if (sGpsSuplInterface) {
30858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        if (apn == NULL) {
30958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
31058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood            return;
31158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        }
31258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        const char *apnStr = env->GetStringUTFChars(apn, NULL);
31358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface->data_conn_open(apnStr);
31458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        env->ReleaseStringUTFChars(apn, apnStr);
315105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project}
317105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
31858bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj)
319105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project{
320105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    if (!sGpsSuplInterface) {
321105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
322105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
323105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    if (sGpsSuplInterface) {
32458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface->data_conn_closed();
32558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    }
32658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood}
32758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood
32858bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj)
32958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{
33058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (!sGpsSuplInterface) {
33158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
33258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    }
33358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (sGpsSuplInterface) {
33458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface->data_conn_failed();
33558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    }
33658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood}
33758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood
33858bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodstatic void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj,
33958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        jint addr, jint port)
34058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood{
34158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (!sGpsSuplInterface) {
34258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
34358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    }
34458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood    if (sGpsSuplInterface) {
34558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood        sGpsSuplInterface->set_server(addr, port);
346105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
347105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project}
348105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported},
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_init", "()Z", (void*)android_location_GpsLocationProvider_init},
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_disable", "()V", (void*)android_location_GpsLocationProvider_disable},
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup},
356105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project	{"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start},
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop},
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_set_fix_frequency", "(I)V", (void*)android_location_GpsLocationProvider_set_fix_frequency},
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data},
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event},
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status},
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time},
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra},
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data},
36558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 	{"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open},
36658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 	{"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed},
36758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 	{"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed},
368105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 	{"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server},
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_location_GpsLocationProvider(JNIEnv* env)
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return jniRegisterNativeMethods(env, "com/android/internal/location/GpsLocationProvider", sMethods, NELEM(sMethods));
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
377