Predecessor articles
"Android 5.0 how to correctly enable Isloggable (a) __ use detailed"
Profile
In the above "How to correctly enable the Android 5.0 isloggable (a) __ use detailed" in the analysis of the use of isloggable, this article mainly analyzes the isloggable implementation principle and the user version of the system root permanent enable Isloggable and use scripts to automatically set isloggable related properties.
This article is from Http://blog.csdn.net/yihongyuelan reprint please be sure to indicate the source
Isloggable Working principle
Isloggable defined in the Frameworks/base/core/java/android/util/log.java:
/** * Checks to see whether or not a log for the specified tag was loggable at the specified level. * The default level of any tag are set to INFO. This means, above and including * INFO'll be logged. Before you the calls to a logging method you should check to see * If your tag should is logged. You can change the default level by setting a system property: * ' SetProp log.tag.<your_log_tag> <level& gt; ' * Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or suppress. Suppress would * turn off all logging for your tag. You can also create a local.prop file and the * following in it: * ' log.tag.<your_log_tag>=<l Evel> ' * and place that in/data/local.prop. * * @param tag the tag to check. * @param level to check. * @return Whether or not, this was allowed to be logged. * @throws IllegalArgumentException is thrown if the tag.length () > 23. */public static native Boolean isloggable (String tag, int. level);
the native implementation of Isloggable is in Frameworks/base/core/jni/android_util_log.cpp:
static jninativemethod gmethods[] = {/* name, signature, Funcptr */{"isloggable", "(Ljava/lang/string;i) Z", (void*) android_util_log_isloggable}, {"Println_native", "(iiljava/lang/string; ljava/lang/string;) I ", (void*) android_util_log_println_native},};static Jboolean android_util_log_isloggable ( jnienv* env, Jobject clazz, jstring tag, jint level) {//... Omit Jboolean result = false; if ((strlen (chars) +sizeof (log_namespace)) > Property_key_max) {char buf2[200]; snprintf (buf2, sizeof (BUF2), "Log tag \"%s\ "exceeds limit of%zu characters\n", chars, Property_key_max- sizeof (Log_namespace)); Jnithrowexception (env, "java/lang/illegalargumentexception", buf2); } else {//Call local Isloggalbe method result = isloggable (chars, level); } env->releasestringutfchars (tag, chars); return result;}
As you can see from the code, the return value of android_util_log_isloggable () depends on the Isloggable () method in Android_util_log.cpp:
#define LOG_NAMESPACE "Log.tag." Static Jboolean isloggable (const char* tag, jint level) { String8 key; Key.append (log_namespace); Key.append (tag); Char buf[property_value_max];//Gets the value of the property log.tag.<your_tag> if (Property_get (key.string (), buf, "") <= 0) { buf[0] = ' + '; } int logLevel = Tolevel (BUF); Return logLevel >= 0 && level >= logLevel;}
The isloggable () in android_util_log.cpp first gets the value of the Log.tag.<your_tag> property by Property_get (), and if the property is not set, the buf[0] is set to null. The value of LogLevel is obtained by the Tolevel () method, and the final return value is determined by loglevel >= 0 && level >=loglevel. The Tolevel () method reads as follows:
static int Tolevel (const char* value) { switch (value[0]) {case ' V ': return levels.verbose; Case ' D ': return levels.debug; Case ' I ': return levels.info; Case ' W ': return levels.warn; Case ' E ': return levels.error; Case ' A ': return levels.assert; Case ' S ': return-1; Suppress } return levels.info;}
Levels is the object of the struct levels_t, the assignment is done in the Register_android_util_log () method, and the Register_android_util_log () The method is to complete the call through Reg_jni (Register_android_util_log) in AndroidRuntime.cpp at system startup, with the following code:
struct levels_t {jint verbose; Jint Debug; Jint info; Jint warn; Jint error; Jint assert;}; Static levels_t Levels;int Register_android_util_log (jnienv* env) {Jclass clazz = Findclassordie (env, "Android/util/Log "); Gets the value of Verbose/debug/info/warn/error/assert in Android.util.Log and assigns levels Levels.verbose = Env->getstaticintfield ( Clazz, Getstaticfieldidordie (env, Clazz, "VERBOSE", "I")); Levels.debug = Env->getstaticintfield (Clazz, Getstaticfieldidordie (env, Clazz, "Debug", "I")); Levels.info = Env->getstaticintfield (Clazz, Getstaticfieldidordie (env, clazz, "info", "I")); Levels.warn = Env->getstaticintfield (Clazz, Getstaticfieldidordie (env, Clazz, "warn", "I")); Levels.error = Env->getstaticintfield (Clazz, Getstaticfieldidordie (env, Clazz, "error", "I")); Levels.assert = Env->getstaticintfield (Clazz, Getstaticfieldidordie (env, Clazz, "assert", "I")); Return Registermethodsordie (env, "Android/util/log", Gmethods, Nelem (gmethods));} In the Tolevel () method, if the character array value[0] matches v/d/i/w/e/a/s the corresponding int value is returned, and if value[0] is empty, the default value of Levels.info is 4. Look back at the Isloggable () method in Android_util_log.cpp:
Static Jboolean isloggable (const char* tag, jint level) { //... Omit int logLevel = Tolevel (BUF); Return logLevel >= 0 && level >= logLevel;}
Because the data in the levels struct is from android.util.Log, the minimum value is 2 (VERBOSE) and the maximum value is 7 (ASSERT), so LogLevel >=0 is always true. Level >=loglevel will be judged based on the level specified by the user, such as
Android.util.Log.isLoggable ("Incall", Android.util.Log.DEBUG);
The level here is debug, which is 3, equivalent to level >= LogLevel to 3 >= logLevel. If you do not set the value of the property value Log.tag.InCall, the default return for LogLevel is 4 (INFO), so 3 >= 4 does not return false, so loglevel >=0 && level >= LogLevel returns FALSE, and if the value of set Log.tag.InCall is D or V, the LogLevel returns 3 or 2, so level >= loglevel is formed, which makes isloggable return true.
About Android Property system
Read the property values in the isloggable invocation process, which is a simple understanding of the workflow of the Android properties system. As shown in the following:
Figure 1 Android Property system (Pic from @rxwen)
Blue indicates a standalone process, orange indicates shared memory, and white indicates a property file. The property value is obtained by means of the property consumer, and when the system starts, the value of the attribute in the persistent file is loaded into the shared memory, and if the property value is set The setter submits the requirements through the socket to the property service, which writes the attribute values to the shared memory.
Because the settings property, such as Log.tag.InCall D, is written to shared memory, after the device restarts, the shared memory is re-requested and the properties file is loaded, and the properties that are manually set are not written to the properties file, so the properties of the Log.tag.InCall are invalidated after the device is restarted.
Local. prop file loading process
In the previous "Android 5.0 how to correctly enable Isloggable (a) __ use detailed" mentioned, if you want to restart after the set Log.tag.<your_tag> property is still valid, you need to write Log.tag.incall=d/ Data/local.prop file, the system loads the properties file under the path after the device is restarted. So how did this step get done? This involves the initialization process of the Android property system.
The Android property service is initialized during the Init process, and the properties file under the specified path is loaded during initialization, as shown in the loading process:
Figure 2 Property Files init flow
The file path is involved in the diagram:
/system/core/init/init.cpp
/system/core/init/init_parser.cpp
/system/core/init/builtins.cpp
/system/core/init/property_service.cpp
/system/core/rootdir/init.rc
After the init process is started, the main () method is executed first, then the Init.rc file is loaded via Init_parse_config_file (), and the init.rc file is parsed, and finally the resolved service, The action and its command are stored in the linked list. After completing the INIT.RC parsing, the command in the linked list is removed and executed by the Execute_one_command () method. The properties related action in Init.rc is as follows:
# Load Properties from/system/+/factory after fs mount.on load_all_props_action load_all_props start Logd-rein It
The definition of Load_all_props is in/system/core/init/keywords.h:
#ifndef keyword//. #define __make_keyword_enum__#define KEYWORD (symbol, flags, Nargs, func) k_# #symbol, ENUM { K_unknown, #endif //... KEYWORD (load_persist_props, command, 0, do_load_persist_props) KEYWORD (load_all_props, command, 0, Do_ Load_all_props) //... #ifdef __make_keyword_enum__ Keyword_count,}; #undef __make_keyword_enum__#undef Keyword#endif
Final call to/system/core/init/property_service.cpp in the Load_all_props () method:
void Load_all_props () { load_properties_from_file (prop_path_system_build, NULL); Load_properties_from_file (Prop_path_vendor_build, NULL); Load_properties_from_file (Prop_path_bootimage_build, NULL); Load_properties_from_file (Prop_path_factory, "ro.*"); Load_override_properties (); /* Read Persistent properties after all the default values have been loaded. * /Load_persistent_properties ();}
Expand the Load_override_properties () method to see:
static void Load_override_properties () { if (allow_local_prop_override) { char Debuggable[prop_value_max]; int ret = Property_get ("ro.debuggable", debuggable); if (Ret && (strcmp (debuggable, "1") = = 0)) { load_properties_from_file (prop_path_local_override, NULL); } }}
The properties files are loaded by means of load_properties_from_file () and Load_override_properties (), and the paths of these files are defined in the/bionic/libc/include/sys/_system_ In Properties.h:
#define Prop_path_ramdisk_default " /default.prop" #define Prop_path_system_build "/system/build.prop" # Define Prop_path_vendor_build "/vendor/build.prop" #define Prop_path_local_override "/data/local.prop" # Define Prop_path_factory "/factory/factory.prop"
However, it is important to note that the/system/build.prop,/vendor/build.prop,/factory/factory.prop files are loaded if they exist, and/data/ Local.prop this file, only at ro.debuggable=1 time will load, that is/data/local.prop only in the case of Userdebug/eng, will be loaded by the system. User version of the system to permanently open the isloggable principle
In the previous "Android 5.0 how to correctly enable Isloggable (a) __ use of the detailed", has given the method to isloggable and the pros and cons of the various methods of comparison. Where the current device is the user version, but it can be permanently turned on isloggable after root permission is obtained. As you can see from the previous analysis, in the user version of the system, the/data/local.prop property file is not read by the properties service, but the/system/build.prop property file is either user or userdebug/ The ENG version is read, so the log.tag.<your_tag> is appended directly to the/system/build.prop file.
You can also use the following script (Windows) to set Isloggable property values (you can use ADB remount if you need adbd to get root privileges):
@echo Offecho ============= Open Hidden Logs =============echo ============= version 0.2 =============echo ============ = 20150605 =============echo ============= SEVEN =============rem update:rem 1. Rename the script to OpenHiddenLogs.bat.REM 2. Adaptation of user mode device. REM 3. ADD the instructions and steps. REM Instructions:rem This script was used to enable some hide logs on Android Platforms.rem Android property system provide s an approach to enable isloggable (String tag, int. level). REM you'll find some code in Android as Below:rem private static final String TAG = "Telecom"; REM public static Final Boolean DEBUG = Android.util.Log.isLoggable (TAG, Android.util.Log.DEBUG); rem if (DEBUG) {rem ANDROID.UTIL.LOG.D (TAG, Getprefix (obj) + str1 + str2); REM}rem If you want to enable the LOG.D (), you need to type ' adb shell setprop log.tag.Telecom V ' REM in your console, and Kill the process of com.android.server.telecom, then LOG.D () is enabled. REM but if you reboot your device, the LOG.D () is disabled, so we write the TAG to property systemrem to enable LOG.D () forever. If you had any questions, please feel free to let me know. REM Email: [Email protected]rem steps:rem 1. Get your device root permission. REM 2. Running the Openhidelogs.bat;echo.set NOROOTSTR=ADBD cannot run as Rootset rootstr=adbd is already Running as Rootset BUIL dtype=userfor/f "delims="%%a in (' adb shell getprop ro.build.type ') does set "Build_type=%%a" Echo Your device is%build_ty Pe% modeecho.:i senabledfor/f "delims="%%c in (' adb shell getprop log.tag.InCall ') do set "Check=%%c" if "%check%" = = "V" (Echo Hidden Lo GS has been enabled!pauseexit) Else (echo Hidden Logs hasn ' t been enabled!) echo.for/f "delims="%%b in (' adb root ') do set "Str=%%b" REM echo%str%set exists_flag=falseecho%str%|find "%rootstr%" &G T;nul&&set Exists_flag=trueif "%exists_flag%" = "true" (Echo Checking ROOT permission passping-n 5 127.0.0.1 > NULADB remountif "%build_type%" = = "%buildtype%"(adb shell" echo log.tag.incall=v >>/system/build.prop "adb shell" echo log.tag.telephony=v >>/system/buil D.prop "adb shell" echo log.tag.telecom=v >>/system/build.prop "adb shell" echo log.tag.telecomframework=v > >/system/build.prop "adb shell" echo log.tag.mms=v >>/system/build.prop "adb shell" echo Log.tag.messagetemplateprovider=v >>/system/build.prop "adb shell" echo log.tag.carriertext=v >>/system/ Build.prop ") Else (adb push local.prop/data/adb shell chmod 644/data/local.propadb Shell Chown system:system/data/local . prop) adb rebootadb wait-for-devicegoto:isenabled) Else (echo Checking root permission Failecho please get the root privi Leges for ADBD and try Againpauseexit)The contents of Local.prop are as follows:
log.tag.incall=vlog.tag.telephony=vlog.tag.telecom=vlog.tag.telecomframework=vlog.tag.mms= Vlog.tag.messagetemplateprovider=vlog.tag.carriertext=v
Scripts are updated on GitHub, and subsequent updates see GitHub
Summary
At first, see Android.util.Log.isLoggable (TAG, Android.util.Log.DEBUG) code, take it for granted that if Isloggable returns true in Userdebug version, The results show that the relevant log is not printed, and further analysis reveals the principle behind isloggable, while also realizing the flexibility of using isloggable to control the log output. For developers, it is good to use isloggable to open the hidden log in the user version of the system, thus providing a more detailed log for related issues. The important points of knowledge for isloggable are summarized as follows:
1. Isloggable default threshold value is 4 (INFO)
If log level is less than 4 (INFO), i.e. 3 (DEBUG) and 2 (VERBOSE), then Isloggable returns false;
2. Isloggable can be set to return true by setting the property value
By setting properties such as Log.tag.InCall D, you can make the corresponding isloggable return true, but be aware that you need to restart the related process after setting the properties, or you can use the ADB shell stop & adb shell Start restarts the zygote and its sub-processes, but the method fails after completely restarting the device;
3. Set the properties file to permanently return isloggable true
In the Userdebug/eng version, you can write the property value Log.tag.incall=d to the/data/local.prop file so that Isloggable returns true and remains valid after the device restarts. If the user version of the system has been obtained root permissions, you can append the property value to the/system/build.prop, you can also achieve a reboot to permanently return the isloggable to true;
Reference:
In-depth explanation of the Android property mechanism: This article analyzes the various processes of Android 4.4 Android property in detail.
Android Init process (ii): initialization language (INIT.RC) parsing: This article analyzes the parsing process of init.rc in detail, and note that Nargs parsing is performed first nargs++
Android Systemproperties set/Get System Properties Usage Summary: This article is a collection of Android property system stickers
Related Resources free Credit download: poke here
Android 5.0 How to correctly enable Isloggable (ii) __ Principle Analysis