/* returns a new global reference which needs to be released later */ static jobject CC_CALL cc_jni_GetSystemServiceObject(const char* name) { struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); JNIEnv* env = cc_jni_get_env(); jobject retval = NULL; if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return NULL; } jstring service = (*env)->NewStringUTF(env, name); jmethodID mid; mid = (*env)->GetStaticMethodID(env, _activity_class, "getContext", "()Landroid/content/Context;"); jobject context = (*env)->CallStaticObjectMethod(env, _activity_class, mid); mid = (*env)->GetMethodID(env, _activity_class, "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;"); jobject manager = (*env)->CallObjectMethod(env, context, mid, service); (*env)->DeleteLocalRef(env, service); retval = manager ? (*env)->NewGlobalRef(env, manager) : NULL; LocalReferenceHolder_Cleanup(&refs); return retval; }
/* returns 0 on success or -1 on error (others undefined then) * returns truthy or falsy value in plugged, charged and battery * returns the value in seconds and percent or -1 if not available */ int CC_CALL cc_jni_get_power_info(int* plugged, int* charged, int* battery, int* seconds, int* percent) { struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); JNIEnv* env = cc_jni_get_env(); jmethodID mid; if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return -1; } mid = (*env)->GetStaticMethodID(env, _activity_class, "getContext", "()Landroid/content/Context;"); jobject context = (*env)->CallStaticObjectMethod(env, _activity_class, mid); jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); jclass cls = (*env)->FindClass(env, "android/content/IntentFilter"); mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); jobject filter = (*env)->NewObject(env, cls, mid, action); (*env)->DeleteLocalRef(env, action); mid = (*env)->GetMethodID(env, _activity_class, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); (*env)->DeleteLocalRef(env, filter); cls = (*env)->GetObjectClass(env, intent); jstring iname; jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); #define GET_INT_EXTRA(var, key) \ iname = (*env)->NewStringUTF(env, key); \ int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ (*env)->DeleteLocalRef(env, iname); jstring bname; jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); #define GET_BOOL_EXTRA(var, key) \ bname = (*env)->NewStringUTF(env, key); \ int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ (*env)->DeleteLocalRef(env, bname); if (plugged) { GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */ if (plug == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } /* 1 == BatteryManager.BATTERY_PLUGGED_AC */ /* 2 == BatteryManager.BATTERY_PLUGGED_USB */ *plugged = (0 < plug) ? 1 : 0; } if (charged) { GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */ if (status == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } /* 5 == BatteryManager.BATTERY_STATUS_FULL */ *charged = (status == 5) ? 1 : 0; } if (battery) { GET_BOOL_EXTRA(present, "present") /* == BatteryManager.EXTRA_PRESENT (API 5) */ *battery = present ? 1 : 0; } if (seconds) { *seconds = -1; /* not possible */ } if (percent) { GET_INT_EXTRA(level, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */ GET_INT_EXTRA(scale, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */ if ((level == -1) || (scale == -1)) { LocalReferenceHolder_Cleanup(&refs); return -1; } *percent = level * 100 / scale; } (*env)->DeleteLocalRef(env, intent); LocalReferenceHolder_Cleanup(&refs); return 0; }
/* * CODE CHUNK IMPORTED FROM SDL 2.0 * returns 0 on success or -1 on error (others undefined then) * returns truthy or falsy value in plugged, charged and battery * returns the value in seconds and percent or -1 if not available */ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent) { env = Android_JNI_GetEnv(); refs = LocalReferenceHolder_Setup(__FUNCTION__); if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return -1; } mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); cls = (*env)->FindClass(env, "android/content/IntentFilter"); mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); filter = (*env)->NewObject(env, cls, mid, action); (*env)->DeleteLocalRef(env, action); mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); (*env)->DeleteLocalRef(env, filter); cls = (*env)->GetObjectClass(env, intent); imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); // Watch out for C89 scoping rules because of the macro #define GET_INT_EXTRA(var, key) \ int var; \ iname = (*env)->NewStringUTF(env, key); \ var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ (*env)->DeleteLocalRef(env, iname); bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); // Watch out for C89 scoping rules because of the macro #define GET_BOOL_EXTRA(var, key) \ int var; \ bname = (*env)->NewStringUTF(env, key); \ var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ (*env)->DeleteLocalRef(env, bname); if (plugged) { // Watch out for C89 scoping rules because of the macro GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) if (plug == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } // 1 == BatteryManager.BATTERY_PLUGGED_AC // 2 == BatteryManager.BATTERY_PLUGGED_USB *plugged = (0 < plug) ? 1 : 0; } if (charged) { // Watch out for C89 scoping rules because of the macro GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) if (status == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } // 5 == BatteryManager.BATTERY_STATUS_FULL *charged = (status == 5) ? 1 : 0; } if (battery) { GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) *battery = present ? 1 : 0; } if (seconds) { *seconds = -1; // not possible } if (percent) { int level; int scale; // Watch out for C89 scoping rules because of the macro { GET_INT_EXTRA(level_temp, "level") // == BatteryManager.EXTRA_LEVEL (API 5) level = level_temp; } // Watch out for C89 scoping rules because of the macro { GET_INT_EXTRA(scale_temp, "scale") // == BatteryManager.EXTRA_SCALE (API 5) scale = scale_temp; } if ((level == -1) || (scale == -1)) { LocalReferenceHolder_Cleanup(&refs); return -1; } *percent = level * 100 / scale; } (*env)->DeleteLocalRef(env, intent); LocalReferenceHolder_Cleanup(&refs); return 0; }