一、SystemUI启动流程
路径:/frameworks/base/services/java/com/android/server/SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
可以看到main()中生成了SystemServer对象并执行了run方法。
SystemServer.run():
private void run() {
...
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class,
mSystemServiceManager);
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
...
}
...
}
进入startOtherServices():
private void startOtherServices() {
...
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
...
}
进入startSystemUi(context):
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui","com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}
进入SystemUIService:
/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
进入startServicesIfNeeded方法:
public void startServicesIfNeeded() {
...
Log.v(TAG, "Starting SystemUI services.");
final int N = SERVICES.length;
for (int i=0; i<N; i++) {
Class<?> cl = SERVICES[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
try {
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
mServices[i].start();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
可以看到startServicesIfNeeded()循环start了很多Services.
数组SERVICES的定义如下:
private final Class<?>[] SERVICES = new Class[] {
com.android.systemui.tuner.TunerService.class,
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recents.Recents.class,
com.android.systemui.volume.VolumeUI.class,
com.android.systemui.statusbar.SystemBars.class,
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
com.android.systemui.keyboard.KeyboardUI.class,
};
进入SystemBars.Java:
Frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
public void start() {
if (DEBUG) Log.d(TAG, "start");
mServiceMonitor = new ServiceMonitor(TAG, DEBUG, mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); // will call onNoService if no remote service is found
}
进入onNoService ():
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig(); // fallback to using an in-process implementation
}
进入createStatusBarFromConfig():
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
final String clsName = mContext.getString(R.string.config_statusBarComponent);
if (clsName == null || clsName.length() == 0) {
throw andLog("No status bar component configured", null);
}
Class<?> cls = null;
try {
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
mStatusBar = (BaseStatusBar) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
其中根据R.string.config_statusBarComponent找到定义位置:
res/values/config.xml
<!-- Component to be used as the status bar service. Must implement the IStatusBar
interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
进入PhoneStatusBar.java:
Frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
public void start() {
...
super.start(); // calls createAndAddWindows()
...
}
进入createAndAddWindows():
public void createAndAddWindows() {
addStatusBarWindow();
}
进入addStatusBarWindow():
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
进入makeStatusBarView():
protected PhoneStatusBarView makeStatusBarView() {
...
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,R.layout.super_status_bar, null);
...
mStatusBarView = (PhoneStatusBarView)
mStatusBarWindow.findViewById(R.id.status_bar);
mStatusBarView.setBar(this);
...
}
在Android中,SystemUI上显示信号状态栏的地方主要由三处,分别是状态栏、锁屏界面下的状态栏以及下拉通知栏的快捷设置区域。这三个引用处分别是status_bar.xml、keyguard_status_bar.xml、status_bar_expanded_header.xml;而这三个布局文件都会去include一个system_icons.xml布局,
这个布局就是所要寻找的网络信号栏显示和电池图标显示view的地方
进入res/layout/super_status_bar.xml:
<com.android.systemui.statusbar.phone.PanelHolder
android:id="@+id/panel_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent" >
<include layout="@layout/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</com.android.systemui.statusbar.phone.PanelHolder>
进入res/layout/status_bar_expanded.xml:
<include layout="@layout/status_bar_expanded_header" />
进入res/layout/status_bar_expanded_header.xml:
<FrameLayout android:id="@+id/system_icons_container"
android:layout_width="wrap_content"
android:layout_height="@dimen/status_bar_height"
android:layout_gravity="center_vertical"
>
<include layout="@layout/system_icons" />
</FrameLayout>
进入res/layout/system_icons.xml:
<include layout="@layout/signal_cluster_view"
android:id="@+id/signal_cluster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2.5dp"/>
进入res/layout/signal_cluster_view.xml:
进入frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
更新SIM卡、飞行模式、WIFI、有线网络四种状态
进入PhoneStatusBarView.java:
Frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
二、修改系统默认语言环境
路径:/libcore/luni/src/main/java/java/util/Locale.java
/**
* Returns the default locale from system properties.
*
* @hide visible for testing.
*/
public static Locale getDefaultLocaleFromSystemProperties() {
final String languageTag = System.getProperty("user.locale", "");
final Locale defaultLocale;
if (!languageTag.isEmpty()) {
defaultLocale = Locale.forLanguageTag(languageTag);
} else {
String language = System.getProperty("user.language", "en");
String region = System.getProperty("user.region", "US");
String variant = System.getProperty("user.variant", "");
defaultLocale = new Locale(language, region, variant);
}
return defaultLocale;
}
三、系统APK裁剪
路径device/fsl/imx6/imx6.mk
四、修改系统硬件和产品架构配置
路径:device/fsl/sabresd_6dq/overlay/frameworks/base/core/res/res/values/config.xml
USB支持配置
<!-- List of regexpressions describing the interface (if any) that represent tetherable
USB interfaces. If the device doesn't want to support tething over USB this should
be empty. An example would be "usb.*" -->
<string-array translatable="false" name="config_tether_usb_regexs">
<item>usb0</item>
</string-array>
WIFI支持配置
<!-- List of regexpressions describing the interface (if any) that represent tetherable
Wifi interfaces. If the device doesn't want to support tethering over Wifi this
should be empty. An example would be "softap.*" -->
<string-array translatable="false" name="config_tether_wifi_regexs">
<item>"wlan0"</item>
</string-array>
蓝牙支持配置
<!-- List of regexpressions describing the interface (if any) that represent tetherable
bluetooth interfaces. If the device doesn't want to support tethering over bluetooth this
should be empty. -->
<string-array translatable="false" name="config_tether_bluetooth_regexs">
<item>"bt-pan"</item>
</string-array>
自动亮度配置
<!-- Flag indicating whether we should enable the automatic brightness in Settings.
config_hardware_automatic_brightness_available is not set, so we will use software implementation -->
<bool name="config_automatic_brightness_available">false</bool>
网络共存配置
<!-- An Array of "[ConnectivityManager connectionType],
[# simultaneous connection types]" -->
<string-array translatable="false" name="radioAttributes">
<item>"1,1"</item>
<item>"0,1"</item>
<item>"7,1"</item>
<item>"9,1"</item>
</string-array>
frameworks\base\core\java\android\net\ConnectivityManager.java
public static final int TYPE_MOBILE = 0;
public static final int TYPE_WIFI = 1;
public static final int TYPE_MOBILE_MMS = 2;
public static final int TYPE_MOBILE_SUPL = 3;
public static final int TYPE_MOBILE_DUN = 4;
public static final int TYPE_MOBILE_HIPRI = 5;
public static final int TYPE_WIMAX = 6;
public static final int TYPE_BLUETOOTH = 7;
public static final int TYPE_DUMMY = 8;
public static final int TYPE_ETHERNET = 9;
public static final int TYPE_MOBILE_FOTA = 10;
public static final int TYPE_MOBILE_IMS = 11;
public static final int TYPE_MOBILE_CBS = 12;
frameworks\base\core\java\android\net\NetworkConfig.java
网络优先级配置
<!-- An Array of "[Connection name],[ConnectivityManager.TYPE_xxxx],[associated radio-type],[priority],[restoral-timer(ms)],[dependencyMet] -->
<!-- the 5th element "resore-time" indicates the number of milliseconds to delay
before automatically restore the default connection. Set -1 if the connection
does not require auto-restore. -->
<!-- the 6th element indicates boot-time dependency-met value. -->
<string-array translatable="false" name="networkAttributes">
<item>"wifi, 1, 1, 1, -1, true"</item>
<item>"mobile, 0, 0, 0, -1, true"</item>
<item>"mobile_mms, 2, 0, 3, 60000, true"</item>
<item>"mobile_supl, 3, 0, 3, 60000, true"</item>
<item>"mobile_hipri,5, 0, 4, 60000, true"</item>
<item>"mobile_fota, 10, 0, 3, 60000, true"</item>
<item>"mobile_ims, 11, 0, 3, 60000, true"</item>
<item>"mobile_cbs, 12, 0, 3, 60000, true"</item>
<item>"bluetooth, 7, 7, 2, -1, true"</item>
<item>"ethernet, 9, 9, 2, -1, true"</item>
</string-array>
熄屏配置
<!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
The N entries of this array define N + 1 zones as follows:
Zone 0: 0 <= LUX < array[0]
Zone 1: array[0] <= LUX < array[1]
...
Zone N: array[N - 1] <= LUX < array[N]
Zone N + 1: array[N] <= LUX < infinity
Must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLevels">
<item>5</item>
<item>15</item>
<item>50</item>
<item>100</item>
<item>200</item>
<item>400</item>
<item>1000</item>
<item>2000</item>
<item>3000</item>
<item>5000</item>
<item>10000</item>
<item>30000</item>
</integer-array>
熄屏LCD背光值配置
<!-- Array of output values for LCD backlight corresponding to the LUX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLcdBacklightValues">
<item>5</item> <!-- 0-5 -->
<item>20</item> <!-- 5-15 -->
<item>30</item> <!-- 15-50 -->
<item>40</item> <!-- 50-100 -->
<item>50</item> <!-- 100-200 -->
<item>60</item> <!-- 200-400 -->
<item>70</item> <!-- 400-1000 -->
<item>80</item> <!-- 1000-2000 -->
<item>130</item> <!-- 2000-3000 -->
<item>180</item> <!-- 3000-5000 -->
<item>255</item> <!-- 5000-10000 -->
<item>255</item> <!-- 10000-30000 -->
<item>255</item> <!-- 30000+ -->
</integer-array>
熄屏按钮背光值配置
<!-- Array of output values for button backlight corresponding to the LUX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessButtonBacklightValues">
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
</integer-array>
熄屏键盘背光值配置
<!-- Array of output values for keyboard backlight corresponding to the LUX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessKeyboardBacklightValues">
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
<item>0</item>
</integer-array>
导航栏显示配置
<!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
autodetected from the Configuration. -->
<bool name="config_showNavigationBar">true</bool>
五、修改系统init.rc
路径:device/fsl/sabresd_6dq/init.rc
可修改系统文件权限
六、修改系统root权限
#define CUSTOM_ROOT
1、修改/system/extras/su/su.c
int main(int argc, char** argv) {
uid_t current_uid = getuid();
#ifndef CUSTOM_ROOT
if (current_uid != AID_ROOT && current_uid != AID_SHELL) error(1, 0, "not allowed");//kang
#endif
...
}
2、修改/system/core/libcutils/fs_config.c
static const struct fs_path_config android_files[] = {
...
/* the following five files are INTENTIONALLY set-uid, but they
* are NOT included on user builds. */
#ifdef CUSTOM_ROOT
{ 06755, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
#else
{ 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
#endif
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/librank" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procrank" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
{ 04770, AID_ROOT, AID_RADIO, 0, "system/bin/pppd-ril" },
/* the following files have enhanced capabilities and ARE included in user builds. */
{ 00750, AID_ROOT, AID_SHELL, (1ULL << CAP_SETUID) | (1ULL << CAP_SETGID), "system/bin/run-as" },
{ 00700, AID_SYSTEM, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND), "system/bin/inputflinger" },
{ 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" },
{ 00750, AID_ROOT, AID_ROOT, 0, "system/bin/install-recovery.sh" },
#ifdef CUSTOM_ROOT
{ 06755, AID_ROOT, AID_ROOT, 0, "system/bin/su" },
#endif
{ 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },
...
};
3、修改/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
#ifndef CUSTOM_ROOT
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
// Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
// EINVAL. Don't die on such kernels.
if (errno != EINVAL) {
LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
return 12;
}
}
#endif
...
}
4、修改/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static void DropCapabilitiesBoundingSet(JNIEnv* env) {
#ifndef CUSTOM_ROOT
for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
if (rc == -1) {
if (errno == EINVAL) {
ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
"your kernel is compiled with file capabilities support");
} else {
ALOGE("prctl(PR_CAPBSET_DROP) failed");
RuntimeAbort(env);
}
}
}
#endif
}
5、修改/system/core/adb/adb_main.cpp
static bool should_drop_privileges() {
#ifdef CUSTOM_ROOT
return false;
#endif
...
}
6、修改/system/core/init/init.cpp
static bool selinux_is_disabled(void)
{
#ifdef CUSTOM_ROOT
return true;
#endif
if (ALLOW_DISABLE_SELINUX) {
if (access("/sys/fs/selinux", F_OK) != 0) {
// SELinux is not compiled into the kernel, or has been disabled
// via the kernel command line "selinux=0".
return true;
}
return selinux_status_from_cmdline() == SELINUX_DISABLED;
}
return false;
}
七、屏蔽系统开机文字LOGO
路径:/system/core/init/init.cpp
static int console_init_action(int nargs, char **args)
{
char console[PROP_VALUE_MAX];
if (property_get("ro.boot.console", console) > 0) {
snprintf(console_name, sizeof(console_name), "/dev/%s", console);
}
int fd = open(console_name, O_RDWR | O_CLOEXEC);
if (fd >= 0)
have_console = 1;
close(fd);
/*
fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
if (fd >= 0) {
const char *msg;
msg = "\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n" // console is 40 cols x 30 lines
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
" A N D R O I D ";
write(fd, msg, strlen(msg));
close(fd);
}
*/
return 0;
}
八、修改系统U盘挂载
1、修改/system/core/rootdir/init.rc
...
mkdir /mnt/secure 0700 root root
mkdir /mnt/secure/asec 0700 root root
mkdir /mnt/asec 0755 root system
mkdir /mnt/obb 0755 root system
mkdir /mnt/media_rw 0750 root media_rw
mkdir /mnt/user 0755 root root
mkdir /mnt/user/0 0755 root root
mkdir /mnt/expand 0771 system system
mkdir /mnt/udisk 0755 system system #添加U盘挂载
# Storage views to support runtime permissions
mkdir /storage 0755 root root
mkdir /mnt/runtime 0700 root root
mkdir /mnt/runtime/default 0755 root root
mkdir /mnt/runtime/default/self 0755 root root
mkdir /mnt/runtime/read 0755 root root
mkdir /mnt/runtime/read/self 0755 root root
mkdir /mnt/runtime/write 0755 root root
mkdir /mnt/runtime/write/self 0755 root root
# Symlink to keep legacy apps working in multi-user world
symlink /storage/self/primary /sdcard
symlink /mnt/user/0/primary /mnt/runtime/default/self/primary
symlink /mnt/udisk /udisk #添加U盘挂载
2、修改/frameworks/base/core/res/res/xml/storage_list.xml
<StorageList xmlns:android="http://schemas.android.com/apk/res/android">
<!-- removable is not set in nosdcard product -->
<storage
android:mountPoint="/storage/sdcard"
android:storageDescription="@string/storage_usb"
android:primary="true" />
<!-- 添加U盘挂载 -->
<storage android:mountPoint="/mnt/udisk"
android:storageDescription="@string/storage_usb"
android:removable="true"
android:primary="false" />
</StorageList>
九、修改系统默认配置
方式一:
路径:/frameworks/base/core/res/res/values/config.xml
关闭双击开机键启动照相机功能
<!-- Allow the gesture to double tap the power button twice to start the camera while the device
is non-interactive. -->
<bool name="config_cameraDoubleTapPowerGestureEnabled">false</bool>
方式二:
1、添加新字段
路径:\frameworks\base\core\java\android\provider\Settings.java
public static final class System extends NameValueTable {
public static final String SYS_PROP_SETTING_VERSION = "sys.settings_system_version";
//在此处添加
/**
* @hide
*/
public static interface Validator {
public boolean validate(String value);
}
...
}
2、添加新字段默认值
路径:/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
3、加载默认值到数据库
路径:\frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
private void loadSystemSettings(SQLiteDatabase db) {
loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
R.bool.def_notification_pulse);
loadUISoundEffectsSettings(stmt);
loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
R.integer.def_pointer_speed);
//在此处添加
...
}
十、修改系统默认风格
路径:/frameworks/base/core/res/res/values/styles_material.xml
十一、修改系统默认Size
路径:frameworks/base/core/res/res/values/dimens.xml
...
<!-- Height of the status bar -->
<dimen name="status_bar_height">32dp</dimen>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
<!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
<dimen name="navigation_bar_height_landscape">62dp</dimen>
<!-- Width of the navigation bar when it is placed vertically on the screen -->
<dimen name="navigation_bar_width">160dp</dimen>
...
十二、修改系统默认音量配置
修改默认值:/frameworks/base/media/java/android/media/AudioSystem.java
public static int[] DEFAULT_STREAM_VOLUME = new int[] {
4, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
5, // STREAM_RING
11, // STREAM_MUSIC
6, // STREAM_ALARM
5, // STREAM_NOTIFICATION
7, // STREAM_BLUETOOTH_SCO
7, // STREAM_SYSTEM_ENFORCED
11, // STREAM_DTMF
11 // STREAM_TTS
};
修改最大值:/frameworks/base/services/core/java/com/android/server/audio/AudioService.java
private static int[] MAX_STREAM_VOLUME = new int[] {
5, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
7, // STREAM_RING
15, // STREAM_MUSIC
7, // STREAM_ALARM
7, // STREAM_NOTIFICATION
15, // STREAM_BLUETOOTH_SCO
7, // STREAM_SYSTEM_ENFORCED
15, // STREAM_DTMF
15 // STREAM_TTS
};
十三、修改系统打印程序
路径:/frameworks/base/packages/PrintSpooler
十四、修改系统状态栏
路径:/frameworks/base/packages/SystemUI
十五、修改系统WindowManagerService
路径:/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
十六、修改系统PackageManagerService
路径:/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
十七、修改系统权限申请
1、修改/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
//源码
...
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
...
if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
p.group = mPermissionGroups.get(p.info.group);
...
if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
// For legacy apps dangerous permissions are install time ones.
grant = GRANT_INSTALL_LEGACY;
...
if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_PRE23) != 0
&& pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
// If this was a previously normal/dangerous permission that got moved
// to a system permission as part of the runtime permission redesign, then
// we still want to blindly grant it to old apps.
allowed = true;
}
...
if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
&& newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
"Package " + pkg.packageName + " new target SDK " + newTargetSdk
+ " doesn't support runtime permissions but the old"
+ " target SDK " + oldTargetSdk + " does.");
return;
}
...
//修改
...
mPromoteSystemApps =
mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.M;
...
if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.M) {
p.group = mPermissionGroups.get(p.info.group);
...
if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.M) {
// For legacy apps dangerous permissions are install time ones.
grant = GRANT_INSTALL_LEGACY;
...
if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_PRE23) != 0
&& pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.M) {
// If this was a previously normal/dangerous permission that got moved
// to a system permission as part of the runtime permission redesign, then
// we still want to blindly grant it to old apps.
allowed = true;
}
...
if (oldTargetSdk > Build.VERSION_CODES.M
&& newTargetSdk <= Build.VERSION_CODES.M) {
res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
"Package " + pkg.packageName + " new target SDK " + newTargetSdk
+ " doesn't support runtime permissions but the old"
+ " target SDK " + oldTargetSdk + " does.");
return;
}
...
2、修改/frameworks/support/v4/java/android/support/v4/app/ActivityCompat.java
public static void requestPermissions(final @NonNull Activity activity,
final @NonNull String[] permissions, final int requestCode) {
//源码 if (Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT > 23) {
ActivityCompatApi23.requestPermissions(activity, permissions, requestCode);
} else if (activity instanceof OnRequestPermissionsResultCallback) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
final int[] grantResults = new int[permissions.length];
PackageManager packageManager = activity.getPackageManager();
String packageName = activity.getPackageName();
final int permissionCount = permissions.length;
for (int i = 0; i < permissionCount; i++) {
grantResults[i] = packageManager.checkPermission(
permissions[i], packageName);
}
((OnRequestPermissionsResultCallback) activity).onRequestPermissionsResult(
requestCode, permissions, grantResults);
}
});
}
}
public static boolean shouldShowRequestPermissionRationale(@NonNull Activity activity,
@NonNull String permission) {
//源码 if (Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT > 23) {
return ActivityCompatApi23.shouldShowRequestPermissionRationale(activity, permission);
}
return false;
}
3、修改/frameworks/support/v4/java/android/support/v4/app/AppOpsManagerCompat.java
static {
//源码 if (Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT > 23) {
IMPL = new AppOpsManager23();
} else {
IMPL = new AppOpsManagerImpl();
}
}
十八、修改系统首次启动安装指定APP
路径:/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public void systemReady() {
...
//添加
if(isFirstBoot()){
//TODO
}
}
十九、修改系统Settings
路径:/packages/apps/Settings
二十、关闭系统底部导航栏
路径:device\fsl\sabresd_6dq\overlay\frameworks\base\core\res\res\values\config.xml
<!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
autodetected from the Configuration. -->
<bool name="config_showNavigationBar">false</bool>
二十一、禁止系统状态栏下拉
路径:Frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
public boolean onInterceptTouchEvent(MotionEvent ev) {
//直接return true
return true;
}
二十二、实现WLAN、以太网共存
1、路径:/frameworks/base/services/core/java/com/android/server/ConnectivityService.java
private void teardownUnneededNetwork(NetworkAgentInfo nai) {
for (int i = 0; i < nai.networkRequests.size(); i++) {
NetworkRequest nr = nai.networkRequests.valueAt(i);
// Ignore listening requests.
if (!isRequest(nr)) continue;
loge("Dead network still had at least " + nr);
break;
}
//nai.asyncChannel.disconnect(); //屏蔽此行代码
}
2、路径:/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
public synchronized void start(Context context, Handler target) {
// The services we use.
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
// Interface match regex.
mIfaceMatch = context.getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);
// Create and register our NetworkFactory.
mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper());
mFactory.setCapabilityFilter(mNetworkCapabilities);
//源码 mFactory.setScoreFilter(-1); // this set high when we have an iface
mFactory.setScoreFilter(110);
mFactory.register();
mContext = context;
...
}