static void jni_get (void *data_in, void *data_out)
{
   struct jni_params *in_params = (struct jni_params*)data_in;
   struct jni_out_params_char *out_args = (struct jni_out_params_char*)data_out;
   char obj_method_name[128];
   char obj_method_signature[128];
   jclass class_ptr = NULL;
   jobject obj = NULL;
   jmethodID giid = NULL;
   jstring ret_char;

   snprintf(obj_method_name, sizeof(obj_method_name), "getStringExtra");
   snprintf(obj_method_signature, sizeof(obj_method_signature), "(Ljava/lang/String;)Ljava/lang/String;");

   GET_OBJECT_CLASS(in_params->env, class_ptr, in_params->class_obj);
   GET_METHOD_ID(in_params->env, giid, class_ptr, in_params->method_name, in_params->method_signature);
   CALL_OBJ_METHOD(in_params->env, obj, in_params->class_obj, giid);

   GET_OBJECT_CLASS(in_params->env, class_ptr, obj);
   GET_METHOD_ID(in_params->env, giid, class_ptr, obj_method_name, obj_method_signature);

   CALL_OBJ_METHOD_PARAM(in_params->env, ret_char, obj, giid, (*in_params->env)->NewStringUTF(in_params->env, out_args->in));

   if (giid != NULL && ret_char)
   {
      const char *test_argv = (*in_params->env)->GetStringUTFChars(in_params->env, ret_char, 0);
      strncpy(out_args->out, test_argv, out_args->out_sizeof);
      (*in_params->env)->ReleaseStringUTFChars(in_params->env, ret_char, test_argv);
   }
}
static bool android_gfx_ctx_get_metrics(void *data,
	enum display_metric_types type, float *value)
{
   jclass metrics_class;
   jobject metrics;
   jmethodID getMetrics;
   struct android_app *android_app = (struct android_app*)g_android;
   JNIEnv *env           = (JNIEnv*)jni_thread_getenv();

   GET_METHOD_ID(env, getMetrics, android_app->activity, "getMetrics", "()Landroid/util/DisplayMetrics;");
   if (!getMetrics)
      goto error;

   CALL_OBJ_STATIC_METHOD(env, metrics, android_app->activity, getMetrics);
   GET_OBJECT_CLASS(env, metrics_class, metrics);

   /* Density */
   float density         = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "density", "F"));
   float scaled_density  = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "scaledDensity", "F"));
   int     density_dpi   = (*env)->GetIntField(env,   metrics, (*env)->GetFieldID(env, metrics_class, "densityDpi", "I"));

   /* Size */
   int     width_pixels  = (*env)->GetIntField(env, metrics,   (*env)->GetFieldID(env, metrics_class, "widthPixels", "I"));
   int    height_pixels  = (*env)->GetIntField(env, metrics,   (*env)->GetFieldID(env, metrics_class, "heightPixels", "I"));

   /* DPI */
   /* Apparently xdpi and ydpi can't be trusted to be implemented correctly, so don't try to rely on it...
    *
    * https://groups.google.com/forum/#!topic/android-developers/QjUlaRohRPI
    *
    * "The xdpi and ydpi are supposed to be the real DPI of the screen...  though as you've seen, 
    * many devices don't set it correctly. :(  This is our fault, it isn't actually used anywhere 
    * in the platform, so people don't realize they have a bad value, and we haven't had a CTS 
    * test to try to make sure it is sane (it's not clear how that test should work).  Worse, we 
    * shipping the original Droid with a graphics driver that reports the wrong value here...  
    * in fact that reported that same damnable 96."
    *
    * Unfortunately, I don't have a good solution if you want to get the real exactly screen dots per inch.  
    * One thing you could do is compare xdpi/ydpi with densityDpi and if they are significantly 
    * far apart, assume the values are bad and just fall back on densityDpi as an approximation.  
    *
    * Be careful on this, because a correctly working device may have densityDpi fairly different 
    * than the real dpi -- for example the Samsung TAB uses high density even though its screen's 
    * really density is a fair amount lower than 240."
    */
   float xdpi = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "xdpi", "F"));
   float ydpi = (*env)->GetFloatField(env, metrics, (*env)->GetFieldID(env, metrics_class, "ydpi", "F"));

   (void)width_pixels;
   (void)height_pixels;
   (void)scaled_density;
   (void)density;
   (void)density_dpi;

   switch (type)
   {
      case DISPLAY_METRIC_MM_WIDTH:
         /* can't guarantee this to be accurate - so return false anyway. */
         *value = xdpi;
         return false;
      case DISPLAY_METRIC_MM_HEIGHT:
         /* can't guarantee this to be accurate - so return false anyway. */
         *value = ydpi;
         return false;
      case DISPLAY_METRIC_DPI:
         /* just go with quantized DPI. */
         *value = density_dpi;
         break;
      case DISPLAY_METRIC_NONE:
      default:
         *value = 0;
         return false;
   }

   return true;

error:
   return false;
}