Android 7.0 Settings分析

最近参加了settings的开发,由于代码还比较新, Android7.0 对Settings进行了重构,相比5.0,6.0而言,7.0的Settings有很大的不同,所以将开过程中的一些点点滴滴记录下来.此篇文章主要给大家介绍Settings相关的基础知识:代码路径,手机中相关数据库、文件的路径,等。

代码相关的路径:

android\frameworks\base\packages\SettingsLib                          7.0重构Settings后多出来的部分
android\frameworks\base\packages\SettingsProvider settings     数据库相关
android\packages\apps\Settings Settings相关
android\frameworks\base\core\java\android\provider settings     数据库字段定义相关
android\packages\providers\MediaProvider                                 铃声相关
android\packages\screensavers                                                   屏保相关
android\packages\inputmethods                                                   输入法相关

源码编译后apk生成目录:

android\out\target\product\****\system\priv-app\Settings\Settings.apk
android\out\target\product\****\system\priv-app\MediaProvider\MediaProvider.apk
android\out\target\product\****\system\priv-app\SettingsProvider\SettingsProvider.apk

cmd下,adb shell
system/priv-app/Settings/Settings.apk
system/priv-app/MediaProvider/MediaProvider.apk
system/priv-app/SettingsProvider/SettingsProvider.apk

Settings数据库

Android L (5.1)及以前版本Settings相关的数据库在
/data/data/com.android.providers.settings/databases/settings.db里,里面有三个表global, system, secure.
查看数据库方式:
(1)cmd下(不确认是否需配置sqlite3环境变量,如果不能使用sqlite3命令,请百度)
adb shell sqlite3 data/data/com.android.providers.settings/databases/settings.db “select * from system”
(2)或者
adb pull data/data/com.android.providers.settings/databases/settings.db D:\xx 到本地,然后用SQLite Expert Professional 软件打开即可

Android M (6.0)之后的谷歌对SettingsProvider进行了重构,所以Settings数据库的路径有了变化
在手机目录/data/system/users/0路径下,以xml的形式存储数据,有settings_global.xml, settings_system.xml, settings_secure.xml
其中不同用户的数据库放不同的用户路径下,如果没有创建新用户,则在/data/system/users/0下。
修改数据库中的字段使用命令
adb shell settings get global captive_portal_server
adb shell settings put global captive_portal_server 0

注:这里虽然手机目录中数据库存储是以xml的形式,但是代码中操作时操作的仍然是数据库。系统会先生成Settings.db数据库,然后将其中的内容保存到xml文件中,最后删除Settings.db数据库(SettingsProvider的功能,后续会讲到)。
这里为何先生成数据库后又删除,主要是为了兼容之前的版本。
为什么以xml的形式保存字段:节省资源,简单,安全(xml保存的路径相对于之前的数据库路径比较安全,大概是考虑到多用户吧)

目录结构

SettingsLib和Settings结构目录分工比较明确,目录一般都可以见名知意,如果你了解的话,看英文目录名就可以知道代码中的大概功能了,希望大家也养成良好的习惯,目录功能分工明确。

1、Settings目录结构

android\packages\apps\Settings
- src
- - com.android.settings Settings应用整体所用的java文件
- - com.android.settings.accessibility 辅助功能相关
- - com.android.settings.accounts 账户相关
- - com.android.settings.application 应用管理相关
- - com.android.settings.backup 备份相关
- - com.android.settings.bluetooth 蓝牙相关
- - com.android.settings.dashboard Settings主界面相关
- - com.android.settings.datausage 数据流量相关
- - com.android.settings.deletionhelper
- - com.android.settings.deviceinfo 关于手机相关
- - com.android.settings.display 显示相关
- - com.android.settings.drawable 菜单图片相关
- - com.android.settings.fingerprint 指纹相关
- - com.android.settings.fuelgauge
- - com.android.settings.gestures 手势相关
- - com.android.settings.inputmethod 输入法相关
- - com.android.settings.localepicker 语言相关
- - com.android.settings.location 位置相关
- - com.android.settings.nfc nfc相关
- - com.android.settings.notification 通知相关相关
- - com.android.settings.overlay
- - com.android.settings.password 密码相关
- - com.android.settings.print 打印相关
- - com.android.settings.qstile
- - com.android.settings.search 快速搜索相关
- - com.android.settings.sim SIM卡相关
- - com.android.settings.support
- - com.android.settings.tts tts播报相关
- - com.android.settings.users 用户相关
- - com.android.settings.utils 工具类
- - com.android.settings.voice
- - com.android.settings.vpn2
- - com.android.settings.wfd
- - com.android.settings.widget 小部件相关
- - com.android.settings.wifi wifi相关
- AndroidManifest.xml 清单文件

2、SettingsLib目录结构

android\frameworks\base\packages\SettingsLib\src\com\android\settingslib
- src
- - com.android.settingslib.accessibility 辅助功能相关
- - com.android.settingslib.accounts 账户相关
- - com.android.settingslib.animation 动画相关
- - com.android.settingslib.application 应用管理相关
- - com.android.settingslib.bluetooth 蓝牙相关
- - com.android.settingslib.datetime 日期相关
- - com.android.settingslib.deviceinfo 关于手机相关
- - com.android.settingslib.display 显示相关
- - com.android.settingslib.drawable 菜单图片相关
- - com.android.settingslib.drawer 侧滑菜单相关
- - com.android.settings.dream 休眠相关
- - com.android.settings.graph
- - com.android.settings.location 位置相关
- - com.android.settings.net 网络相关
- - com.android.settings.users 用户相关
- - com.android.settings.widget 小部件相关
- - com.android.settings.wifi wifi相关
- AndroidManifest.xml 清单文件

以下是FAQ,来自MTK:

how to modify the maximum connections of hotspot from frameworks?
[DESCRIPTION]
   In general,hotspot's maximam connection is limited by hardware,so if you want to modify the number,must to make sure the performance of hardware is enough;
[SOLUTION]
To change the number to 10 as an example:
/packages/apps/Settings/res_ext/values/mtk_arrays.xml
<string-array name="wifi_ap_max_connection_entries">
73 <item>1 user</item>
74 <item>2 users</item>
75 <item>3 users</item>
76 <item>4 users</item>
77 <item>5 users</item>
78 <item>6 users</item>
79 <item>7 users</item>
80 <item>8 users</item>
//add to ten
<item>9 users</item>
<item>10 users</item>
//add
81 </string-array>
so you can choose "10 users " when you setup hotspot;

 ============================================================

如何预置一个WIFI热点
 在此文档中会描述下面几个问题: 如何预置一个WIFI热点 — WIFI Setting界面默认就加入一个热点。
[SOLUTION]
JB版本:
请在alps/external/wpa_supplicant_8/mtk-wpa_supplicant.conf 这个文件中增加
networ={} 即可。
network需要字段的含义可以查看wpa_supplicant_8/wpa_supplicant.conf文件中的注释“
network block fields:”后的说明即可。
KK&L版本:
请在/hardware/mediatek/wlan/config/mtk-wpa_supplicant-overlay.conf文件中增加networ={} 即可。
M 版本路径
/vendor/mediatek/proprietary/hardware/connectivity/wlan/config/mtk-wpa_supplicantoverlay.
conf
如下面的例子,预置一个OPEN 和WPA2-PSK的网络:
ctrl_interface=/data/misc/wpa_supplicant
update_config=1
device_name=rk30sdk
manufacturer=rockchip
model_name=ONE TOUCH EVO8HD
model_number=ONE TOUCH EVO8HD
serial_number=0123456789
device_type=10-0050F204-5
config_methods=physical_display virtual_push_button keypad
network={
     ssid="aaaa"
     scan_ssid=1
     key_mgmt=NONE
}
network={
     ssid="bbbbb"
     scan_ssid=1
     psk="12345678"
     key_mgmt=WPA-PSK
}

====================================================================

how to set max bandwidth in 2G and 5G
[DESCRIPTION]
customer want to limit the bandwidth in different band as below: Maximum bandwidth : 40MHz for 2.4G, 20MHz for 5G

[SOLUTION]
    1. find out the flie(wlan_lib.c)
    2. find out the function (wlanInitFeatureOption)
    3. modify codes and set those as you needs:
example:
    prWifiVar->ucSta2gBandwidth = (UINT_8) wlanCfgGetUint32(prAdapter, "Sta2gBw",
    MAX_BW_20MHZ);
    prWifiVar->ucSta5gBandwidth = (UINT_8) wlanCfgGetUint32(prAdapter, "Sta5gBw",
    MAX_BW_80MHZ);
    prWifiVar->ucAp2gBandwidth = (UINT_8) wlanCfgGetUint32(prAdapter, "Ap2gBw",
    MAX_BW_20MHZ);
    prWifiVar->ucAp5gBandwidth = (UINT_8) wlanCfgGetUint32(prAdapter, "Ap5gBw",
    MAX_BW_40MHZ);
    prWifiVar->ucP2p2gBandwidth = (UINT_8) wlanCfgGetUint32(prAdapter, "P2p2gBw",
    MAX_BW_20MHZ);
    prWifiVar->ucP2p5gBandwidth = (UINT_8) wlanCfgGetUint32(prAdapter, "P2p5gBw",
    MAX_BW_40MHZ);
    typedef enum _ENUM_MAX_BANDWIDTH_SETTING_T {
    MAX_BW_20MHZ = 0,
    MAX_BW_40MHZ,
    MAX_BW_80MHZ,
    MAX_BW_160MHZ,
    MAX_BW_80_80_MHZ
}

=========================================================

MTK wifi Roaming conditions
[Question]
Customer want to know machanism of roam between same SSID and different SSID
[Answer]
   if the RCPI of signal lower than -70dbm. wifi will choice the best one(scores higher and better) from Condidates.
and thescores of AP is decided by elements as those(u2ScoreBandwidth + u2ScoreChnlInfo + u2ScoreDeauth + u2ScoreProbeRsp+u2ScoreScanMiss + u2ScoreSnrRssi + u2ScoreStaCnt + u2ScoreSTBC + u2ScoreBand + u2BlackListScore) and the additional sroces will
be added by 5G band or Current connected AP.

============================================================

每次连接上网络会提示“已连接无法访问互联网”几秒钟后消失
[DESCRIPTION]
   每次连接上网络会提示“已连接无法访问互联网”几秒钟后消失
   
[SOLUTION]
   M版本开始连接WIFI AP,提示“已连接,没有网络”,约过5s左右切成“已连接”
  在L版時多了一個NetworkMonitor的module,負責當Wi-Fi連上後檢查該AP是否有captive portal能力,
  - 如果有, 提醒user在browser輸入username/password (如同mtkguest)
  - 如果沒有, 又區別分兩種case, 該AP有Internet or 該AP沒有Internet(意即validated = true/false)
 接著M版在networkCapability多了NET_CAPABILITY_VALIDATED的欄位將L版的validated結果帶入capability, 讓別的module更容易知道此Network是否有支援Internet
如同L版本流程
Wifi連上 WifiNetworkAgent的NetworkMonitor嘗試連connectivitycheck.gstatic.com如果有得到200, 代表有Internet能力
ConnectivityService WifiNetworkAgent.networkCapability添加NET_CAPABILITY_VALIDATED的欄位如果沒得到response, 或者response延遲(大陸地區常遇到),延後networkCapability添加NET_CAPABILITY_VALIDATED的欄位

===============================================================================

为什么add network 时点击security不显示密码输入框
[DESCRIPTION]
    how to reproduce the problem?
    wifisettings -->add network--->choose different security ,but the password did not show;
[SOLUTION]
    change code as follow:
    /packages/apps/Settings/src/com/android/settings/wifi/WifiConfigController.java
    public void onItemSelected(AdapterView<?> parent, View view, int position,long id)
   if (parent == mSecuritySpinner)
     change to
    if (parent == mSecuritySpinner || parent.getId() == R.id.wpa_security) reason: the cause of this problemis the id of "mSecuritySpinner" will be set to
    "R.id.wpa_security" when the software did not support WAPI ;
    int viewId = R.id.security;
    if (FeatureOption.MTK_WAPI_SUPPORT) {
        String type = SystemProperties.get(WLAN_PROP_KEY, DEFAULT_WLAN_PROP);
    if (type.equals(WIFI_WAPI)) {
    if (AccessPointExt.isWFATestSupported()) {
        viewId = R.id.security_wfa; // WIFI + WAPI, support // separate WPA2 PSK  security
    } else {
        viewId = R.id.security; // WIFI + WAPI
    }
    } else if (type.equals(WIFI)) {
        if (AccessPointExt.isWFATestSupported()) {
        viewId = R.id.wpa_security_wfa; // WIFI only, support
        // separate WPA2 PSK   // security
    } else {
        viewId = R.id.wpa_security; // WIFI only
    }
    } else if (type.equals(WAPI)) {
        viewId = R.id.wapi_security; // WAPI only
    }
    } else {
    if (AccessPointExt.isWFATestSupported()) {
        viewId = R.id.wpa_security_wfa; // WIFI only, support
        // separate WPA and WPA2 PSK // security
    } else {
        viewId = R.id.wpa_security; // WIFI only
    }
    }
    switchWlanSecuritySpinner((Spinner) mView.findViewById(viewId));

=-==============================================================================

应用如何定制ActionBar的背景颜色?
[DESCRIPTION]
    应用如何定制ActionBar的背景颜色?
[SOLUTION]
    ActionBar 默认使用的背景颜色是取自Style Widget.AppCompat.ActionBar,如果需要定制自己的应用的ActionBar的背景颜色,可以自定义一个Style文件,并将Widget.AppCompat.ActionBar设置
为Parent, 然后再设定item background 为需要的值即可。参考例子如下:
<?xml version="1.0" encoding="utf-8"?>
    <resources>
    <!-- the theme applied to the application or activity -->
    <style name="CustomActionBarTheme" parent="@style/Theme.AppCompat.Light">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <item name="android:actionBarTabTextStyle">@style/TabTextStyle</item>
        <item name="android:actionMenuTextColor">@color/actionbar_text</item>
        <!-- Support library compatibility -->
        <item name="actionBarStyle">@style/MyActionBar</item>
        <item name="actionBarTabTextStyle">@style/TabTextStyle</item>
        <item name="actionMenuTextColor">@color/actionbar_text</item>
    </style>
    
    <!-- general styles for the action bar -->
    <style name="MyActionBar" parent="@style/Widget.AppCompat.ActionBar">
        <item name="android:titleTextStyle">@style/TitleTextStyle</item>
        <item name="android:background">@drawable/actionbar_background</item>
        <item name="android:backgroundStacked">@drawable/actionbar_background</item>
        <item name="android:backgroundSplit">@drawable/actionbar_background</item>
        <!-- Support library compatibility -->
        <item name="titleTextStyle">@style/TitleTextStyle</item>
        <item name="background">@drawable/actionbar_background</item>
        <item name="backgroundStacked">@drawable/actionbar_background</item>
        <item name="backgroundSplit">@drawable/actionbar_background</item>
    </style>
    <!-- action bar title text -->
    <style name="TitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
        <item name="android:textColor">@color/actionbar_text</item>
    </style>
    <!-- action bar tab text -->
    <style name="TabTextStyle" parent="@style/Widget.AppCompat.ActionBar.TabText">
        <item name="android:textColor">@color/actionbar_text</item>
    </style>
</resources>

在您的app manifest file, 可以让整个app使用客制化的Theme <application android:theme="@style/CustomActionBarTheme" ... />
或者让 activity 使用客制化的Theme<activity android:theme="@style/CustomActionBarTheme" ... />
ActionBar的其他属性修改,也可以参考该方法,具体可以参考Android developer上的说明。
http://developer.android.com/guide/topics/ui/actionbar.html#Style

==================================================================================

如何将一个app 设置为持久app, 不被
low memory kill 关闭
[Description]
如何将一个app 设置为常住app, 不被low memory kill 关闭
[Keyword]
app 持久 persistent
[Solution]
1. 将app 的manifest.xml 中的 application 中添加属性
android:persistent="true"
2. 对这个APP 使用platform 的签名
3. 放置在system/app 下面
注: 一个app 被设置为 persistent 后,将很难被low memory kill 杀掉(oom_adj=-
12),请在设置之前仔细确认是否必须,否则将浪费掉memory。

=========================================================================

如何设置进程/线程 的调度模式
(sched policy),优先级(priority)
[Title]
如何设置进程/线程 的调度模式,优先级
[Description]
如何将进程的优先级调整,提高,降低;如何将设置进程进程的调度模式,如实时进程(实时轮转RR,实时FIFO)
linux 中调度模式有: SCHED_OTHER, SCHED_IDLE, SCHED_BATCH 以及 SCHED_FIFO,SCHED_RR; 前
3种为CFS 调度模式,后2种为实时调度模式
[Keyword]
进程优先级 进程调度 实时进程 实时线程 rt thread process setpriority sched_setscheduler
SCHED_FIFO SCHED_RR
[Solution]
Java API:
在java 层,
设置线程优先级:
* 使用java 默认的Thread.setPriority(int priority); priority 的值为[1,10], 即此priority
为java spec 定义, 可参考Thread.java
java property : 1 2 3 4 5 6 7 8 9 10
linux nice: 19 16 13 10 0 -2 -4 -5 -6 -8
* 使用android.os.Process 的API:
public static final native void setThreadPriority(int tid, int priority);
public static final native void setThreadPriority(int priority)
两个API 中的priority 为标准的linux nice 值 [-20,19]
* @param tid The identifier of the thread/process to change.
* @param priority A Linux priority level, from -20 for highest scheduling
设置线程调度模式:
* 标准java Spec 中并没有直接的API 可供使用,在android 中, android.os.Process 提供API:
public static final native void setThreadScheduler(int tid, int policy, int priority)
throws IllegalArgumentException;
对应它的三个参数分别为:
* @param tid The identifier of the thread/process to change.
* @param policy A Linux scheduling policy such as SCHED_OTHER etc.
* @param priority A Linux priority level in a range appropriate for the given policy.
在native 层:
设置线程优先级:
* setprority(int which, int who, int niceval);
@which 为PRIO_PROCESS, PRIO_PGRP, PRIO_USER; 默认一般使用PRIO_PROCESS 即只设置单个
thread, 如果是PRIO_PGRP 即整个进程, 如同是PRIO_USER 则所有USER 都为此进程USER 的进程。
@who 为对应的线程, 如果为0 即当前线程
@niceval 为对应的nice 值[-20,19]
设置线程调度模式:
#include <sched.h>
struct sched_param {
...
int sched_priority;
...
};
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
@pid 为对应的线程, 如果为0, 即当前的线程
@policy 为SCHED_OTHER, SCHED_IDLE, SCHED_BATCH 以及 SCHED_FIFO,SCHED_RR 中的一种
@param 目前唯一需要设置的就是这个param 里面的sched_priority,为实时进程优先级[1,99] 如
果是SCHED_OTHER, SCHED_IDLE, SCHED_BATCH, 那么sched_priority 必须为0.
具体的相关约束可以参考linux man: 如: http://man7.org/linux/manpages/
man2/sched_setscheduler.2.html

========================================================================================

如何在编译的时候修改xlog选项
[DESCRIPTION]
当希望过滤某些log时,可以通过在编译的时候,修改xlog选项来实现
[SOLUTION]
修改mediatek/external/xlog/tools/tag-setting.xlog 或tag-default.xlog. 会优
先考虑/tag-setting.xlog
的设置.
(ICS/ICS2版本,在这里:mediatek/source/external/xlog/tools/tagsetting.
xlog )
available level:
verbose debug

available level:
verbose debug info warn error assert on off

例如:如果需要关闭所有的log做法如下:
修改merge-xlog-filter-tags.py
default_level =None => default_level = "off"

====================================================================

如何确认故障机的system分区是否被
破坏或者刷机
[DESCRIPTION]
当故障机 发生随机乱死(NE或者KE),则一个排查重点就是手机中的system分区中的档案是否有被
刷过或者破坏。因此,需要通过Flash Tool把system.img从故障机中readback回来,并且用
ext2explore解开,然后用工具(Beyond Compare)比较system分区中的任何档案是否有被刷过或者
破坏。
[KEY WORDS]
system分区 readback 刷机
[SOLUTION]
步骤一:分别从故障机和正常机器中readback并解开system.img档案。该步骤可参考如下的FAQ:
《FAQ10664 如何在windows下解开readback回来的ext image》
步骤二:用Beyond Compare工具打开 正常机器与故障机器的system分区档案
步骤三:在Beyond Compare图形界面上选中 待比较的所有folder/file,然后点击鼠标右键,并在
弹出的选项中 选中Compare Contents。该步骤如下图所示:

步骤四:选中 Binary Comparison,然后点击Start,则执行compare动作。该步骤如下图所示:

 

假如所有档案内容完全一致,则说明system分区没有被破坏或者刷过,参考下图所示:

 

猜你喜欢

转载自blog.csdn.net/u011694328/article/details/81220583