Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3635c96 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

GPS: Generalize SUPL support to include AGPS for CDMA

parent b4735b6c
Loading
Loading
Loading
Loading
+55 −62
Original line number Diff line number Diff line
@@ -31,31 +31,31 @@ static pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER;
static jmethodID method_reportLocation;
static jmethodID method_reportStatus;
static jmethodID method_reportSvStatus;
static jmethodID method_reportSuplStatus;
static jmethodID method_reportAGpsStatus;
static jmethodID method_xtraDownloadRequest;

static const GpsInterface* sGpsInterface = NULL;
static const GpsXtraInterface* sGpsXtraInterface = NULL;
static const GpsSuplInterface* sGpsSuplInterface = NULL;
static const AGpsInterface* sAGpsInterface = NULL;

// data written to by GPS callbacks
static GpsLocation  sGpsLocation;
static GpsStatus    sGpsStatus;
static GpsSvStatus  sGpsSvStatus;
static GpsSuplStatus    sGpsSuplStatus;
static AGpsStatus   sAGpsStatus;

// a copy of the data shared by android_location_GpsLocationProvider_wait_for_event
// and android_location_GpsLocationProvider_read_status
static GpsLocation  sGpsLocationCopy;
static GpsStatus    sGpsStatusCopy;
static GpsSvStatus  sGpsSvStatusCopy;
static GpsSuplStatus    sGpsSuplStatusCopy;
static AGpsStatus   sAGpsStatusCopy;

enum CallbackType {
    kLocation = 1,
    kStatus = 2,
    kSvStatus = 4,
    kSuplStatus = 8,
    kAGpsStatus = 8,
    kXtraDownloadRequest = 16,
    kDisableRequest = 32,
}; 
@@ -96,12 +96,12 @@ static void sv_status_callback(GpsSvStatus* sv_status)
    pthread_mutex_unlock(&sEventMutex);
}

static void supl_status_callback(GpsSuplStatus* supl_status)
static void agps_status_callback(AGpsStatus* agps_status)
{
    pthread_mutex_lock(&sEventMutex);

    sPendingCallbacks |= kSuplStatus;
    memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus));
    sPendingCallbacks |= kAGpsStatus;
    memcpy(&sAGpsStatus, agps_status, sizeof(AGpsStatus));

    pthread_cond_signal(&sEventCond);
    pthread_mutex_unlock(&sEventMutex);
@@ -126,15 +126,15 @@ GpsXtraCallbacks sGpsXtraCallbacks = {
    download_request_callback,
};

GpsSuplCallbacks sGpsSuplCallbacks = {
    supl_status_callback,
AGpsCallbacks sAGpsCallbacks = {
    agps_status_callback,
};

static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
    method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
    method_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)V");
    method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V");
    method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
}

@@ -151,10 +151,10 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o
    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
        return false;

    if (!sGpsSuplInterface)
        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
    if (sGpsSuplInterface)
        sGpsSuplInterface->init(&sGpsSuplCallbacks);
    if (!sAGpsInterface)
        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
    if (sAGpsInterface)
        sAGpsInterface->init(&sAGpsCallbacks);
    return true;
}

@@ -187,12 +187,6 @@ static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject o
    return (sGpsInterface->stop() == 0);
}

static void android_location_GpsLocationProvider_set_fix_frequency(JNIEnv* env, jobject obj, jint fixFrequency)
{
    if (sGpsInterface->set_fix_frequency)
        sGpsInterface->set_fix_frequency(fixFrequency);
}

static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags)
{
    sGpsInterface->delete_aiding_data(flags);
@@ -212,7 +206,7 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job
    memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));
    memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy));
    memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy));
    memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy));
    memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy));
    pthread_mutex_unlock(&sEventMutex);   

    if (pendingCallbacks & kLocation) { 
@@ -228,8 +222,8 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job
    if (pendingCallbacks & kSvStatus) {
        env->CallVoidMethod(obj, method_reportSvStatus);
    }
    if (pendingCallbacks & kSuplStatus) {
        env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status);
    if (pendingCallbacks & kAGpsStatus) {
        env->CallVoidMethod(obj, method_reportAGpsStatus, sAGpsStatusCopy.type, sAGpsStatusCopy.status);
    }  
    if (pendingCallbacks & kXtraDownloadRequest) {    
        env->CallVoidMethod(obj, method_xtraDownloadRequest);
@@ -299,50 +293,50 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j
    env->ReleaseByteArrayElements(data, bytes, 0);
}

static void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
{
    if (!sGpsSuplInterface) {
        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
    if (!sAGpsInterface) {
        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
    }
    if (sGpsSuplInterface) {
    if (sAGpsInterface) {
        if (apn == NULL) {
            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
            return;
        }
        const char *apnStr = env->GetStringUTFChars(apn, NULL);
        sGpsSuplInterface->data_conn_open(apnStr);
        sAGpsInterface->data_conn_open(apnStr);
        env->ReleaseStringUTFChars(apn, apnStr);
    }
}

static void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj)
static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
{
    if (!sGpsSuplInterface) {
        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
    if (!sAGpsInterface) {
        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
    }
    if (sGpsSuplInterface) {
        sGpsSuplInterface->data_conn_closed();
    if (sAGpsInterface) {
        sAGpsInterface->data_conn_closed();
    }
}

static void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj)
static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
{
    if (!sGpsSuplInterface) {
        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
    if (!sAGpsInterface) {
        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
    }
    if (sGpsSuplInterface) {
        sGpsSuplInterface->data_conn_failed();
    if (sAGpsInterface) {
        sAGpsInterface->data_conn_failed();
    }
}

static void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj,
        jint addr, jint port)
static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
        jint type, jint addr, jint port)
{
    if (!sGpsSuplInterface) {
        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
    if (!sAGpsInterface) {
        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
    }
    if (sGpsSuplInterface) {
        sGpsSuplInterface->set_server(addr, port);
    if (sAGpsInterface) {
        sAGpsInterface->set_server(type, addr, port);
    }
}

@@ -355,17 +349,16 @@ static JNINativeMethod sMethods[] = {
    {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup},
    {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start},
    {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop},
	{"native_set_fix_frequency", "(I)V", (void*)android_location_GpsLocationProvider_set_fix_frequency},
    {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data},
    {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event},
    {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status},
    {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time},
    {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra},
    {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data},
 	{"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open},
 	{"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed},
 	{"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed},
 	{"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server},
    {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open},
    {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed},
    {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed},
    {"native_set_agps_server", "(III)V", (void*)android_location_GpsLocationProvider_set_agps_server},
};

int register_android_location_GpsLocationProvider(JNIEnv* env)
+100 −67
Original line number Diff line number Diff line
@@ -109,13 +109,13 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    private static final int GPS_STATUS_ENGINE_ON = 3;
    private static final int GPS_STATUS_ENGINE_OFF = 4;

    // these need to match GpsSuplStatusValue defines in gps.h
    /** SUPL status event values. */
    private static final int GPS_REQUEST_SUPL_DATA_CONN = 1;
    private static final int GPS_RELEASE_SUPL_DATA_CONN = 2;
    private static final int GPS_SUPL_DATA_CONNECTED = 3;
    private static final int GPS_SUPL_DATA_CONN_DONE = 4;
    private static final int GPS_SUPL_DATA_CONN_FAILED = 5;
    // these need to match GpsApgsStatusValue defines in gps.h
    /** AGPS status event values. */
    private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
    private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
    private static final int GPS_AGPS_DATA_CONNECTED = 3;
    private static final int GPS_AGPS_DATA_CONN_DONE = 4;
    private static final int GPS_AGPS_DATA_CONN_FAILED = 5;

    // these need to match GpsLocationFlags enum in gps.h
    private static final int LOCATION_INVALID = 0;
@@ -125,7 +125,7 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    private static final int LOCATION_HAS_BEARING = 8;
    private static final int LOCATION_HAS_ACCURACY = 16;

// IMPORTANT - the GPS_DELETE_* symbols here must match constants in GpsLocationProvider.java
// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h
    private static final int GPS_DELETE_EPHEMERIS = 0x0001;
    private static final int GPS_DELETE_ALMANAC = 0x0002;
    private static final int GPS_DELETE_POSITION = 0x0004;
@@ -140,10 +140,14 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
    private static final int GPS_DELETE_ALL = 0xFFFF;

    // for mSuplDataConnectionState
    private static final int SUPL_DATA_CONNECTION_CLOSED = 0;
    private static final int SUPL_DATA_CONNECTION_OPENING = 1;
    private static final int SUPL_DATA_CONNECTION_OPEN = 2;
    // these need to match AGpsType enum in gps.h
    private static final int AGPS_TYPE_SUPL = 1;
    private static final int AGPS_TYPE_C2K = 2;

    // for mAGpsDataConnectionState
    private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
    private static final int AGPS_DATA_CONNECTION_OPENING = 1;
    private static final int AGPS_DATA_CONNECTION_OPEN = 2;

    private static final String PROPERTIES_FILE = "/etc/gps.conf";

@@ -203,9 +207,12 @@ public class GpsLocationProvider extends ILocationProvider.Stub {

    private String mSuplHost;
    private int mSuplPort;
    private String mC2KHost;
    private int mC2KPort;
    private boolean mSetSuplServer;
    private String mSuplApn;
    private int mSuplDataConnectionState;
    private boolean mSetC2KServer;
    private String mAGpsApn;
    private int mAGpsDataConnectionState;
    private final ConnectivityManager mConnMgr;

    // Wakelocks
@@ -293,11 +300,12 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
                if (Config.LOGD) {
                    Log.d(TAG, "state: " + state +  " apnName: " + apnName + " reason: " + reason);
                }
                // FIXME - might not have an APN on CDMA
                if ("CONNECTED".equals(state) && apnName != null && apnName.length() > 0) {
                    mSuplApn = apnName;
                    if (mSuplDataConnectionState == SUPL_DATA_CONNECTION_OPENING) {
                        native_supl_data_conn_open(mSuplApn);
                        mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN;
                    mAGpsApn = apnName;
                    if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
                        native_agps_data_conn_open(mAGpsApn);
                        mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
                    }
                }
            }
@@ -336,14 +344,26 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
            mProperties.load(stream);
            stream.close();
            mNtpServer = mProperties.getProperty("NTP_SERVER", null);

            mSuplHost = mProperties.getProperty("SUPL_HOST");
            String suplPortString = mProperties.getProperty("SUPL_PORT");
            if (mSuplHost != null && suplPortString != null) {
            String portString = mProperties.getProperty("SUPL_PORT");
            if (mSuplHost != null && portString != null) {
                try {
                    mSuplPort = Integer.parseInt(suplPortString);
                    mSuplPort = Integer.parseInt(portString);
                    mSetSuplServer = true;
                } catch (NumberFormatException e) {
                    Log.e(TAG, "unable to parse SUPL_PORT: " + suplPortString);
                    Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
                }
            }

            mC2KHost = mProperties.getProperty("C2K_HOST");
            portString = mProperties.getProperty("C2K_PORT");
            if (mC2KHost != null && portString != null) {
                try {
                    mC2KPort = Integer.parseInt(portString);
                    mSetC2KServer = true;
                } catch (NumberFormatException e) {
                    Log.e(TAG, "unable to parse C2K_PORT: " + portString);
                }
            }
        } catch (IOException e) {
@@ -358,7 +378,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    public boolean requiresNetwork() {
        // We want updateNetworkState() to get called when the network state changes
        // for XTRA and NTP time injection support.
        return (mNtpServer != null || native_supports_xtra() || mSuplHost != null);
        return (mNtpServer != null || native_supports_xtra() ||
                mSuplHost != null || mC2KHost != null);
    }

    public void updateNetworkState(int state) {
@@ -561,7 +582,6 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
                interval = 1;
            }
            mFixInterval = interval;
            native_set_fix_frequency(mFixInterval);
        }
    }

@@ -871,38 +891,38 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    }

    /**
     * called from native code to update SUPL status
     * called from native code to update AGPS status
     */
    private void reportSuplStatus(int status) {
    private void reportAGpsStatus(int type, int status) {
        switch (status) {
            case GPS_REQUEST_SUPL_DATA_CONN:
            case GPS_REQUEST_AGPS_DATA_CONN:
                 int result = mConnMgr.startUsingNetworkFeature(
                        ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
                if (result == Phone.APN_ALREADY_ACTIVE) {
                    native_supl_data_conn_open(mSuplApn);
                    mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN;
                    native_agps_data_conn_open(mAGpsApn);
                    mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
                } else if (result == Phone.APN_REQUEST_STARTED) {
                    mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPENING;
                    mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
                } else {
                    native_supl_data_conn_failed();
                    native_agps_data_conn_failed();
                }
                break;
            case GPS_RELEASE_SUPL_DATA_CONN:
                if (mSuplDataConnectionState != SUPL_DATA_CONNECTION_CLOSED) {
            case GPS_RELEASE_AGPS_DATA_CONN:
                if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
                    mConnMgr.stopUsingNetworkFeature(
                            ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
                    native_supl_data_conn_closed();
                    mSuplDataConnectionState = SUPL_DATA_CONNECTION_CLOSED;
                    native_agps_data_conn_closed();
                    mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
                }
                break;
            case GPS_SUPL_DATA_CONNECTED:
                // Log.d(TAG, "GPS_SUPL_DATA_CONNECTED");
            case GPS_AGPS_DATA_CONNECTED:
                // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
                break;
            case GPS_SUPL_DATA_CONN_DONE:
                // Log.d(TAG, "GPS_SUPL_DATA_CONN_DONE");
            case GPS_AGPS_DATA_CONN_DONE:
                // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
                break;
            case GPS_SUPL_DATA_CONN_FAILED:
                // Log.d(TAG, "GPS_SUPL_DATA_CONN_FAILED");
            case GPS_AGPS_DATA_CONN_FAILED:
                // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
                break;
        }
    }
@@ -914,6 +934,29 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
        }
    }

    private boolean setAGpsServer(int type, String host, int port) {
        try {
            InetAddress inetAddress = InetAddress.getByName(host);
            if (inetAddress != null) {
                byte[] addrBytes = inetAddress.getAddress();
                long addr = 0;
                for (int i = 0; i < addrBytes.length; i++) {
                    int temp = addrBytes[i];
                    // signed -> unsigned
                    if (temp < 0) temp = 256 + temp;
                    addr = addr * 256 + temp;
                }
                // use MS-Based position mode if SUPL support is enabled
                mPositionMode = GPS_POSITION_MODE_MS_BASED;
                native_set_agps_server(type, (int)addr, port);
            }
        } catch (UnknownHostException e) {
            Log.e(TAG, "unknown host for server " + host);
            return false;
        }
        return true;
    }

    private class GpsEventThread extends Thread {

        public GpsEventThread() {
@@ -985,7 +1028,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
                        }
                    }
                    waitTime = getWaitTime();
                } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && waitTime > 0)
                } while (!mDone && ((!mXtraDownloadRequested &&
                        !mSetSuplServer && !mSetC2KServer && waitTime > 0)
                        || !mNetworkAvailable));
                if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop");
                
@@ -1012,26 +1056,15 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
                        }
                    }

                    // Set the SUPL server address if we have not yet
                    // Set the AGPS server addresses if we have not yet
                    if (mSetSuplServer) {
                        try {
                            InetAddress inetAddress = InetAddress.getByName(mSuplHost);
                            if (inetAddress != null) {
                                byte[] addrBytes = inetAddress.getAddress();
                                long addr = 0;
                                for (int i = 0; i < addrBytes.length; i++) {
                                    int temp = addrBytes[i];
                                    // signed -> unsigned
                                    if (temp < 0) temp = 256 + temp;
                                    addr = addr * 256 + temp;
                                }
                                // use MS-Based position mode if SUPL support is enabled
                                mPositionMode = GPS_POSITION_MODE_MS_BASED;
                                native_set_supl_server((int)addr, mSuplPort);
                        if (setAGpsServer(AGPS_TYPE_SUPL, mSuplHost, mSuplPort)) {
                            mSetSuplServer = false;
                        }
                        } catch (UnknownHostException e) {
                            Log.e(TAG, "unknown host for SUPL server " + mSuplHost);
                    }
                    if (mSetC2KServer) {
                        if (setAGpsServer(AGPS_TYPE_C2K, mC2KHost, mC2KPort)) {
                            mSetC2KServer = false;
                        }
                    }

@@ -1125,9 +1158,9 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    private native boolean native_supports_xtra();
    private native void native_inject_xtra_data(byte[] data, int length);

    // SUPL Support    
    private native void native_supl_data_conn_open(String apn);
    private native void native_supl_data_conn_closed();
    private native void native_supl_data_conn_failed();
    private native void native_set_supl_server(int addr, int port);
    // AGPS Support    
    private native void native_agps_data_conn_open(String apn);
    private native void native_agps_data_conn_closed();
    private native void native_agps_data_conn_failed();
    private native void native_set_agps_server(int type, int addr, int port);
}