ares_library_init_android.3 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. .\"
  2. .\" Copyright (C) 2017 by John Schember
  3. .\"
  4. .\" Permission to use, copy, modify, and distribute this
  5. .\" software and its documentation for any purpose and without
  6. .\" fee is hereby granted, provided that the above copyright
  7. .\" notice appear in all copies and that both that copyright
  8. .\" notice and this permission notice appear in supporting
  9. .\" documentation, and that the name of M.I.T. not be used in
  10. .\" advertising or publicity pertaining to distribution of the
  11. .\" software without specific, written prior permission.
  12. .\" M.I.T. makes no representations about the suitability of
  13. .\" this software for any purpose. It is provided "as is"
  14. .\" without express or implied warranty.
  15. .\"
  16. .TH ARES_LIBRARY_INIT_ANDROID 3 "13 Sept 2017"
  17. .SH NAME
  18. ares_library_init_android \- c-ares library Android initialization
  19. .SH SYNOPSIS
  20. .nf
  21. #include <ares.h>
  22. int ares_library_init_android(jobject \fIconnectivity_manager\fP)
  23. int ares_library_android_initialized();
  24. void ares_library_init_jvm(JavaVM *\fIjvm\fP)
  25. .fi
  26. .SH DESCRIPTION
  27. The \fIares_library_init_android(3)\fP function performs initializations
  28. internally required by the c-ares library when used on Android. This can take
  29. place anytime after \fIares_library_init(3)\fP. It must take place after
  30. \fIares_library_init_jvm\fP. ares_library_init_android must be called before
  31. DNS resolution will work on Android 8 (Oreo) or newer when targetSdkVersion is
  32. set to 26+.
  33. As of Android 8 (API level 26) getting DNS server information has
  34. becomei more restrictive and can only be accessed using the
  35. Connectivity Manager. It is necessary to pass the connectivity
  36. manager to c-ares via JNI. Also, the ACCESS_NETWORK_STATE permission
  37. must be present in the Android application.
  38. Android older than 8 do not need to to be initialized as they
  39. are less restrictive. However, this is a run time not compile time
  40. limitation. Proper Android initialization should take place regardless
  41. of the targeted Android version.
  42. Deinitialization will take place though \fIares_library_cleanup(3)\fP.
  43. The \fBares_library_init_jvm\fP function allows the caller to register the JVM
  44. with c-ares. It's meant to be called during JNI_OnLoad because you're
  45. guaranteed to have the JVM in that function. The JVM is required in order to
  46. use the Connectivty Manager registered using
  47. \fIares_library_init_android(3)\fP. This must be call before
  48. \fIares_library_init_android(3)\fP.
  49. The \fBares_library_android_initialized\fP function can be used to check
  50. whether c-ares has been initialized for use with Android.
  51. .SH RETURN VALUES
  52. ARES_SUCCESS will be returned on success otherwise an error code will be
  53. returned.
  54. .SH THREAD SAFETY
  55. .B These init functions are not thread safe.
  56. You have to call it once the program has started, but this call must be done
  57. before the program starts any other thread. This is required to avoid
  58. potential race conditions in library initialization, and also due to the fact
  59. these might call functions from other libraries that
  60. are thread unsafe, and could conflict with any other thread that is already
  61. using these other libraries.
  62. .SH JNI
  63. Accessing the Connectivity Manager though Java:
  64. Register the \fIares_library_android_init\fP.
  65. .nf
  66. static JNINativeMethod funcs[] = {
  67. { "initialize_native", "(Landroid/net/ConnectivityManager;)I",
  68. (void *)&ares_library_init_android}
  69. };
  70. JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
  71. {
  72. JNIEnv *env = NULL;
  73. jclass cls = NULL;
  74. jint res;
  75. if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK)
  76. return -1;
  77. cls = (*env)->FindClass(env, JNIT_CLASS);
  78. if (cls == NULL)
  79. return -1;
  80. res = (*env)->RegisterNatives(env, cls, funcs, sizeof(funcs)/sizeof(funcs[0]));
  81. if (res != 0)
  82. return -1;
  83. ares_library_init_jvm(vm);
  84. return JNI_VERSION_1_6;
  85. }
  86. .fi
  87. Calling the registered function from Java:
  88. .nf
  89. public class MyObject {
  90. static {
  91. System.loadLibrary("cares");
  92. }
  93. private static native boolean initialize_native(ConnectivityManager
  94. connectivity_manager);
  95. public static boolean initialize(Context context) {
  96. initialize_native((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE));
  97. }
  98. }
  99. .fi
  100. Initializing the Connectivity Manager in JNI directly using an Android
  101. Context. It is assumed the JVM has aleady been registered through
  102. \fIJNI_OnLoad\fP.
  103. .nf
  104. void initialize(jobject android_context)
  105. {
  106. jclass obj_cls = jni_get_class(env, "android/content/Context");
  107. jmethodID obj_mid = jni_get_method_id(env, obj_cls, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
  108. jfieldID fid = (*env)->GetStaticFieldID(env, obj_cls, "CONNECTIVITY_SERVICE", "Ljava/lang/String;");
  109. jstring str = (*env)->GetStaticObjectField(env, obj_cls, fid);
  110. connectivity_manager = (*env)->CallObjectMethod(env, android_context, obj_mid, str);
  111. if (connectivity_manager == NULL)
  112. return;
  113. ares_library_init_android(connectivity_manager);
  114. }
  115. .fi
  116. .SH AVAILABILITY
  117. This function was first introduced in c-ares version 1.15.0.
  118. .SH SEE ALSO
  119. .BR ares_library_init(3),
  120. .BR ares_library_cleanup(3),
  121. .SH AUTHOR
  122. John Schember
  123. .PP
  124. Copyright (C) 2017 by John Schember