1ARES_LIBRARY_INIT_ANDROID(3)Library Functions ManualARES_LIBRARY_INIT_ANDROID(3)
2
3
4

NAME

6       ares_library_init_android - c-ares library Android initialization
7

SYNOPSIS

9       #include <ares.h>
10
11       int ares_library_init_android(jobject connectivity_manager)
12
13       int ares_library_android_initialized();
14
15       void ares_library_init_jvm(JavaVM *jvm)
16
17

DESCRIPTION

19       The   ares_library_init_android(3)  function  performs  initializations
20       internally required by the c-ares library when used  on  Android.  This
21       can  take  place anytime after ares_library_init(3). It must take place
22       after ares_library_init_jvm. ares_library_init_android must  be  called
23       before  DNS resolution will work on Android 8 (Oreo) or newer when tar‐
24       getSdkVersion is set to 26+.
25
26       As of Android 8 (API level  26)  getting  DNS  server  information  has
27       becomei  more restrictive and can only be accessed using the Connectiv‐
28       ity Manager. It is necessary to pass the connectivity manager to c-ares
29       via  JNI.  Also, the ACCESS_NETWORK_STATE permission must be present in
30       the Android application.
31
32       Android older than 8 do not need to to be initialized as they are  less
33       restrictive.  However,  this is a run time not compile time limitation.
34       Proper Android initialization should take place regardless of the  tar‐
35       geted Android version.
36
37       Deinitialization will take place though ares_library_cleanup(3).
38
39       The  ares_library_init_jvm  function  allows the caller to register the
40       JVM with c-ares.  It's meant to be  called  during  JNI_OnLoad  because
41       you're guaranteed to have the JVM in that function. The JVM is required
42       in  order   to   use   the   Connectivty   Manager   registered   using
43       ares_library_init_android(3).     This     must    be    call    before
44       ares_library_init_android(3).
45
46       The ares_library_android_initialized function  can  be  used  to  check
47       whether c-ares has been initialized for use with Android.
48

RETURN VALUES

50       ARES_SUCCESS  will  be returned on success otherwise an error code will
51       be returned.
52

THREAD SAFETY

54       These init functions are not thread safe.  You have to call it once the
55       program  has  started,  but  this  call must be done before the program
56       starts any other thread. This is required to avoid potential race  con‐
57       ditions in library initialization, and also due to the fact these might
58       call functions from other libraries that are thread unsafe,  and  could
59       conflict  with  any  other  thread  that  is  already using these other
60       libraries.
61

JNI

63       Accessing the Connectivity Manager though Java:
64
65       Register the ares_library_android_init.
66         static JNINativeMethod funcs[] = {
67         { "initialize_native",     "(Landroid/net/ConnectivityManager;)I",
68           (void *)&ares_library_init_android}
69         };
70
71         JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
72         {
73           JNIEnv *env = NULL;
74           jclass  cls = NULL;
75           jint    res;
76
77           if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK)
78             return -1;
79
80           cls = (*env)->FindClass(env, JNIT_CLASS);
81           if (cls == NULL)
82             return -1;
83
84           res = (*env)->RegisterNatives(env, cls, funcs, sizeof(funcs)/sizeof(funcs[0]));
85           if (res != 0)
86             return -1;
87
88           ares_library_init_jvm(vm);
89           return JNI_VERSION_1_6;
90         }
91       Calling the registered function from Java:
92         public class MyObject {
93           static {
94             System.loadLibrary("cares");
95           }
96
97           private static native boolean initialize_native(ConnectivityManager
98             connectivity_manager);
99
100           public static boolean initialize(Context context) {
101             initialize_native((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE));
102           }
103         }
104       Initializing the Connectivity Manager in JNI directly using an  Android
105       Context.  It  is  assumed  the  JVM  has aleady been registered through
106       JNI_OnLoad.
107         void initialize(jobject android_context)
108         {
109           jclass obj_cls = jni_get_class(env, "android/content/Context");
110           jmethodID obj_mid = jni_get_method_id(env, obj_cls, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
111           jfieldID fid = (*env)->GetStaticFieldID(env, obj_cls, "CONNECTIVITY_SERVICE", "Ljava/lang/String;");
112           jstring str = (*env)->GetStaticObjectField(env, obj_cls, fid);
113           connectivity_manager = (*env)->CallObjectMethod(env, android_context, obj_mid, str);
114           if (connectivity_manager == NULL)
115             return;
116           ares_library_init_android(connectivity_manager);
117         }
118

AVAILABILITY

120       This function was first introduced in c-ares version 1.15.0.
121

SEE ALSO

123       ares_library_init(3), ares_library_cleanup(3),
124

AUTHOR

126       John Schember
127
128       Copyright (C) 2017 by John Schember
129
130
131
132
133                                 13 Sept 2017     ARES_LIBRARY_INIT_ANDROID(3)
Impressum