>安卓手機可以安裝LTE
Discovery來觀察. TSU上可以安裝LTE
Discovery來觀察嗎?
尝试下载了一个
LTE Discovery apk
Adb install XXX.apk
然后怎么启动? 能给一个 adb shell start am -n Packagename/ActivityName
的命令吗?ActivityName不知道。
>安卓手機可以安裝LTE
Discovery來觀察. TSU上可以安裝LTE
Discovery來觀察嗎?
尝试下载了一个
LTE Discovery apk
Adb install XXX.apk
然后怎么启动? 能给一个 adb shell start am -n Packagename/ActivityName
的命令吗?ActivityName不知道。
Android Version |API Level |Linux Version in AOSP |Header Version
----------------------------------------------------------------------------------------
1.5 Cupcake |3 |(2.6.27) |
1.6 Donut |4 |(2.6.29) |2.6.18
2.0/1 Eclair |5-7 |(2.6.29) |2.6.18
2.2.x Froyo |8 |(2.6.32) |2.6.18
2.3.x Gingerbread |9, 10 |(2.6.35) |2.6.18
3.x.x Honeycomb |11-13 |(2.6.36) |2.6.18
4.0.x Ice Cream San|14, 15 |(3.0.1) |2.6.18
4.1.x Jelly Bean |16 |(3.0.31) |2.6.18
4.2.x Jelly Bean |17 |(3.4.0) |2.6.18
4.3 Jelly Bean |18 |(3.4.39) |2.6.18
4.4 Kit Kat |19, 20 |(3.10) |2.6.18
5.x Lollipop |21, 22 |(3.16.1) |3.14.0
6.0 Marshmallow |23 |(3.18.10) |3.18.10
7.0 Nougat |24 | 3.18.48 4.4.0 |4.4.1
7.1 Nougat |25 | ? |4.4.1
8.0 Oreo |26 | 3.18.72 4.4.83 4.9.44 |4.10.0
8.1 Oreo |27 | 3.18.70 4.4.88 4.9.56 |4.10.0
9.0 Pie |28 | 4.4.146 4.9.118 4.14.61 |4.15.0
10.0 Q |29 | 4.9.191 4.14.142 4.19.71|5.0.3
One aspect that has been up to the OEM is the Linux kernel version but this is changing with Android Oreo.As long as the OEM was able to pass the certification tests that Google lays out, then they didn’t care what kernel version was used in a new device. This generally wasn’t an issue as most OEMs would use the same version of the kernel for that generation that other OEMs were using, as it is tied heavily to what the hardware drivers support. However, some had been falling through the cracks and this started to cause security issues. This is something that Google has been taking seriously lately so it makes sense that they would want to start mandating this.Starting this year with smartphones which ship with Android Oreo, Google is requiring that all SoCs productized in 2017 must launch with kernel 4.4 or newer.Currently existing devices that are upgraded to Android Oreo are only required to run kernel version 3.18 or newer, and will not have to be upgraded to support Project Treble.
ro.product.model
是對應設備的型號。如果我在Samsung 的S5 手機上,它的值是SM-G900F
這些系統屬性是在/system/build.prop 這個文件中,需要你有Root 權限才能修改。
cat /system/build.prop

ro.product.model
ro.build.id
ro.product.board
等等。當然了,這些ro開頭的屬性也不是不能修改,你可以通過一些方式來修改。修改的後果自負。adb 的眾多命令中有一個命令叫做setprop,是set property(設置屬性)的簡寫,用於為系統設置屬性的值,就是類似鍵值對的概念。
你可以自行Google搜索,或者參考這篇StackOverFlow的文章,或者這篇文章,不過不在本課討論之列。
setprop 属性名称 属性的值
既然有setprop 命令,Android 也提供了getprop 命令,用於顯示屬性的值。getprop 属性名称
用setprop 設置了設備的屬性之後,在Android 的代碼中就可以獲取到屬性的值。setprop media.enable-commonsource false
把它的值改為false。然後用getprop 來查看它新的值:getprop media.enable-commonsource

private int readProp(String prop) {
try {
Process process = Runtime.getRuntime().exec("getprop " + prop);
InputStreamReader ir = new InputStreamReader(process.getInputStream());
BufferedReader input = new BufferedReader(ir);
return Integer.parseInt(input.readLine());
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
}
在你的代碼中調用int delay = readProp("delay");
int filter = readProp("filter");
Log.i(TAG, "Echo_delay = " + delay + ", filter_length = " + filter);
然後把代碼編譯,燒寫到Android 設備中,再用setprop 命令開始測試。setprop delay 250
可以用getprop 命令看看設置的值是否正確:getprop delay

setprop filter 100
getprop filter


public static String get(String key){...}
public static String get(String key, String def){...}
public static int getInt(String key, int def){...}
public static long getLong(String key, long def){...}
public static boolean getBoolean(String key, boolean def){...}
public static void set(String key, String val){...}int property_set(const char *key, const char *value) {...}
int property_get(const char *key, char *value, const char *default_value) {...}
int8_t property_get_bool(const char *key, int8_t default_value) {...}
static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
intmax_t default_value) {...}
int64_t property_get_int64(const char *key, int64_t default_value) {...}
int32_t property_get_int32(const char *key, int32_t default_value){...}
void property_init() {
if (__system_property_area_init()) {
LOG(ERROR) << "Failed to initialize property area";
exit(1);
}
}...
sys.usb.config u:object_r:system_radio_prop:s0
ril. u:object_r:radio_prop:s0
ro.ril. u:object_r:radio_prop:s0
gsm. u:object_r:radio_prop:s0
...static bool initialize_properties() {
// If we do find /property_contexts, then this is being
// run as part of the OTA updater on older release that had
// /property_contexts - b/34370523
if (initialize_properties_from_file("/property_contexts")) {//加载"/property_contexts"
return true;
}
// Use property_contexts from /system & /vendor, fall back to those from /
if (access("/system/etc/selinux/plat_property_contexts", R_OK) != -1) {
//如果可以访问/system/etc/selinux/plat_property_contexts,就去加载解析文件。
if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
return false;//这里如果解析失败就直接返回了,不再加载其他路径下的文件。
}
// Don't check for failure here, so we always have a sane list of properties.
// E.g. In case of recovery, the vendor partition will not have mounted and we
// still need the system / platform properties to function.
//这里去加载/vendor/etc/selinux/nonplat_property_contexts, 但是不care结果。
initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts");
} else {
//如果/system没有配置property_contexts文件,那么加载//plat_property_contexts
if (!initialize_properties_from_file("/plat_property_contexts")) {
return false;
}
initialize_properties_from_file("/nonplat_property_contexts");
}
return true;
}
/*initialize_properties_from_file负责解析property_contexts文件中的内容,
*将property前缀存在prefixes指向的链表中,将context存在contexts指向的链表中。
*/
static bool initialize_properties_from_file(const char* filename) {
FILE* file = fopen(filename, "re");
if (!file) {
return false;
}
char* buffer = nullptr;
size_t line_len;
char* prop_prefix = nullptr;
char* context = nullptr;
while (getline(&buffer, &line_len, file) > 0) {
int items = read_spec_entries(buffer, 2, &prop_prefix, &context);
if (items <= 0) {
continue;
}
if (items == 1) {
free(prop_prefix);
continue;
}
/*
* init uses ctl.* properties as an IPC mechanism and does not write them
* to a property file, therefore we do not need to create property files
* to store them.
*/
if (!strncmp(prop_prefix, "ctl.", 4)) {
free(prop_prefix);
free(context);
continue;
}
auto old_context =
list_find(contexts, [context](context_node* l) { return !strcmp(l->context(), context); });
if (old_context) {
list_add_after_len(&prefixes, prop_prefix, old_context);
} else {
list_add(&contexts, context, nullptr);
list_add_after_len(&prefixes, prop_prefix, contexts);
}
free(prop_prefix);
free(context);
}
free(buffer);
fclose(file);
return true;
}int __system_property_area_init() {
free_and_unmap_contexts();
//property_filename所指的路径为/dev/__properties__; #define PROP_FILENAME "/dev/__properties__"
mkdir(property_filename, S_IRWXU | S_IXGRP | S_IXOTH);
if (!initialize_properties()) {
return -1;
}
bool open_failed = false;
bool fsetxattr_failed = false;
/*从property_contexts中解析的context全在contexts指向的链表中,下面这段代码就是遍历链表,
*open函数将每个context_node节点对应的文件都打开,并映射到一块share memory中。
*并在这块memory上构造一个prop_area指针存在context_node节点中。
*/
list_foreach(contexts, [&fsetxattr_failed, &open_failed](context_node* l) {
if (!l->open(true, &fsetxattr_failed)) {
open_failed = true;
}
});
if (open_failed || !map_system_property_area(true, &fsetxattr_failed)) {
free_and_unmap_contexts();
return -1;
}
initialized = true;
return fsetxattr_failed ? -2 : 0;
}static bool map_system_property_area(bool access_rw, bool* fsetxattr_failed) {
char filename[PROP_FILENAME_MAX];
//经过下面的格式化之后filename指向的文件为/dev/__properties__/properties_serial
int len =
__libc_format_buffer(filename, sizeof(filename), "%s/properties_serial", property_filename);
if (len < 0 || len > PROP_FILENAME_MAX) {
__system_property_area__ = nullptr;
return false;
}
if (access_rw) {
/*map_prop_area_rw函数会打开filename,映射一块共享内存,然后将地址返回。
*地址将保存在 __system_property_area__中, 这个是一个全局变量,property
*相关的操作还会用到这个变量。
*/
__system_property_area__ =
map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
} else {
__system_property_area__ = map_prop_area(filename);
}
return __system_property_area__;
} {"load_persist_props", {0, 0, do_load_persist_props}},
{"load_system_props", {0, 0, do_load_system_props}},
{"loglevel", {1, 1, do_loglevel}},on post-fs
# Load properties from
# /system/build.prop,
# /odm/build.prop,
# /vendor/build.prop and
# /factory/factory.prop
load_system_props
...
on load_persist_props_action
load_persist_props
start logd
start logd-reinit
...
on property:vold.decrypt=trigger_load_persist_props
load_persist_props
start logd
//下面是system property
static int do_load_system_props(const std::vector<std::string>& args) {
load_system_props();
return 0;
}
void load_system_props() {
load_properties_from_file("/system/build.prop", NULL);
load_properties_from_file("/odm/build.prop", NULL);
load_properties_from_file("/vendor/build.prop", NULL);
load_properties_from_file("/factory/factory.prop", "ro.*");
load_recovery_id_prop();
}
//下面是persist properties
static int do_load_persist_props(const std::vector<std::string>& args) {
load_persist_props();
return 0;
}
void load_persist_props(void) {
load_override_properties();
/* Read persistent properties after all default values have been loaded. */
load_persistent_properties();
property_set("ro.persistent_properties.ready", "true");
}
static void load_override_properties() {
if (ALLOW_LOCAL_PROP_OVERRIDE) {
load_properties_from_file("/data/local.prop", NULL);
}
}void property_load_boot_defaults() {
if (!load_properties_from_file("/system/etc/prop.default", NULL)) {
// Try recovery path
if (!load_properties_from_file("/prop.default", NULL)) {
// Try legacy path
load_properties_from_file("/default.prop", NULL);
}
}
load_properties_from_file("/odm/default.prop", NULL);
load_properties_from_file("/vendor/default.prop", NULL);
update_sys_usb_config();
}| 文件/屬性 | 註釋 |
|---|---|
| /system/etc/prop.default | |
| /prop.default | |
| /default.prop | |
| /odm/default.prop | |
| /vendor/default.prop | |
| /system/build.prop | |
| /odm/build.prop | |
| /vendor/build.prop | |
| /factory/factory.prop | 只加載ro.* |
| ro.recovery_id | |
| /data/local.prop | |
| /數據/屬性 | 這個路徑下只加載persist開頭的property |
/*
* Properties are stored in a hybrid trie/binary tree structure.
* Each property's name is delimited at '.' characters, and the tokens are put
* into a trie structure. Siblings at each level of the trie are stored in a
* binary tree. For instance, "ro.secure"="1" could be stored as follows:
*
* +-----+ children +----+ children +--------+
* | |-------------->| ro |-------------->| secure |
* +-----+ +----+ +--------+
* / \ / |
* left / \ right left / | prop +===========+
* v v v +-------->| ro.secure |
* +-----+ +-----+ +-----+ +-----------+
* | net | | sys | | com | | 1 |
* +-----+ +-----+ +-----+ +===========+
*/