Android 5.0 How to correctly enable Isloggable (ii) __ Principle Analysis

Source: Internet
Author: User

Predecessor articles

Android 5.0 How to correctly enable Isloggable (a) __ Use specific explanations

Profile

In the above "How does Android 5.0 correctly enable Isloggable (a) __ use specific explanation" in the analysis of isloggable usage, this article mainly analyzes the isloggable implementation principle and the user version of the system root permanent enable Isloggable, and use the script to set the Isloggable related properties on its own initiative.

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;} 
Can be seen 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;}
Isloggable () in android_util_log.cpp first gets the value of the Log.tag.<your_tag> property by Property_get (). If you do not set this property, Buf[0] is set to null. The value of LogLevel is obtained by the Tolevel () method, and finally the return value is determined by loglevel >= 0 && level >=loglevel. Tolevel () method contents such as the following:
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 and is assigned at the end of the Register_android_util_log () method, while the Register_android_util_log () The method is called at system startup through Reg_jni (Register_android_util_log) in AndroidRuntime.cpp. The code is as follows:
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. Assuming that the character array value[0] matches v/d/i/w/e/a/s returns the corresponding int value, assuming value[0] is empty, the default value levels.info that is 4 is returned.

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 structure 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 is inferred 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. Assuming that the value of the property value Log.tag.InCall is not set, the default return for LogLevel is 4 (INFO), so 3 >= 4 does not return false, so loglevel >=0 && level >= LogLevel returns false, assuming that the value of the set Log.tag.InCall is D or v. The LogLevel returns 3 or 2, so the level >= loglevel is set up, which makes isloggable return true.

Android Property System Brief Introduction

The read of the property value is involved in the isloggable invocation process. Here's a quick overview of the workflow of the Android property system. For example, as seen in:


Figure 1 Android Property system (Pic from @rxwen)

Blue indicates an independent process. Orange indicates shared memory, and white indicates a property file.

The acquisition of the property value is completed by the property consumer, and the value of the attribute in the persistent file is loaded into the shared memory when the system starts. Given the need to set the property value, the property setter submits the requirement through the socket to the properties service, which writes the attribute value to the shared memory.

Because the settings property, such as Log.tag.InCall D, is written to shared memory, the device restarts and then requests the shared memory again and loads the properties file. The properties that are set manually are not written to the properties file. Therefore, the Log.tag.InCall property is invalidated after restarting the device.

Local. prop file loading process

In the previous article "How does Android 5.0 correctly enable Isloggable (a) __ use specific explanations" mentioned. Assuming that the Log.tag.<your_tag> property that you want to set after restarting is still valid, you need to write log.tag.incall=d to the/data/local.prop file. After you restart the device, the system loads the properties file under that path.

So how is this step finished? 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. The loading process is, for example, what you see:


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

The init process starts with the main () method running first. The init.rc file is then loaded via Init_parse_config_file () and the init.rc file is parsed, and the parsed service, action, and command are then saved in the linked list. After Init.rc parsing, the Execute_one_command () method is used to remove the command from the linked list and run.

Properties related action in init.rc such as the following:

# 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
Finally 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"
But it needs to be noted here. /system/build.prop,/vendor/build.prop,/factory/factory.prop These documents assume the existence will be loaded, and/data/ Local.prop this file, only in the ro.debuggable=1 when the load, that is/data/local.prop only in the case of Userdebug/eng, will be loaded into 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 the specific explanation", has given the method to be able to isloggable and the pros and cons of the various methods. Of Assume that the current device is a user version, but you can permanently turn on isloggable after you get root permissions. As you can see from the previous analysis, in the user version of the system. The/data/local.prop properties file is not read by the property service. However, the/system/build.prop property file will be read regardless of the user or Userdebug/eng version number, 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 the value of the Isloggable property (you can use the 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)
Among the Local.prop contents 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 if you have updates, see GitHub

Summary

At first, see the Android.util.Log.isLoggable (TAG, Android.util.Log.DEBUG) code and assume that isloggable will return true in the Userdebug version number. Results after viewing found that the relevant log is not printed, further analysis of the isloggable behind the implementation of the principle, at the same time also realized the use of isloggable control log output flexibility. For developers. Very good use of isloggable to open the hidden log in the user version of the system, so as to provide more specific log for related issues. For the important points of knowledge of the isloggable, a summary such as the following:

1. Isloggable default threshold value is 4 (INFO)

Suppose the log level is less than 4 (INFO), which is 3 (DEBUG) and 2 (VERBOSE). Then Isloggable returns FALSE.

2. Isloggable is able 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 it is important to note that you need to restart the related process after setting the property. You can also restart Zygote and its child processes via adb shell stop & adb shell start. Only the method fails after completely restarting the device;

3. Setting the property file to permanently return isloggable true

In the Userdebug/eng version number, you can write the property value Log.tag.incall=d to the/data/local.prop file so that Isloggable returns true and remains in effect after the device restarts.

Assume that root privileges have been obtained in the user version of the system. The ability to append attribute values to/system/build.prop, and also to achieve the purpose of permanently returning isloggable to true after a restart;

References:

In-depth commentary on the Android property mechanism: This article specifically analyzes the various processes of Android 4.4 Android property

The Init process of Android (ii): initialization language (INIT.RC) parsing: This paper analyzes the parsing process of init.rc in detail. Note that Nargs will run nargs++ before parsing

Android Systemproperties set/Get System Properties Usage Summary: This article is a collection of Android property system paste


Related Resources free Credit download: poke here

Android 5.0 How to correctly enable Isloggable (ii) __ Principle Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.