(android 关机/重启)Android关机/重启流程解析 (2)-----实例解析(多种实现方式)
来源:互联网 发布:java基础教程 pdf 编辑:程序博客网 时间:2024/05/29 15:24
介入方法1(java)接口:java实现的方式
--------------------------------上层空间--------------------------------
1.frameworks/base/core/java/android/os/PowerManager.java
////在PowerManager的API文档中,给出了一个关机/重启接口:
public void reboot (String reason)
////接口的作用就是重启设备,而且,就算重启成功了也没有返回值。需要包含REBOOT权限,也就是android.permission.REBOOT
唯一参数reason代表需要的特定重启模式,比如recovery,当然也可以为null
介入方法2(java)接口:java实现的方式
(adb: adb shell setprop sys.powerctl reboot,handoff_resolution_enable)
SystemProperties.set("ctl.start", "shutdown");///关机
&& SystemProperties.set("sys.powerctl", "reboot," + reason);///重启
((具体实现例子详见附页2))
4.frameworks/base/services/java/com/android/server/pm/ShutdownThread.java
public static void rebootOrShutdown(boolean reboot, String reason) {
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
if ( (reason != null) && reason.equals("recovery") ) {
delayForPlayAnimation();
}
try {
PowerManagerService.lowLevelReboot(reason);
} catch (Exception e) {
Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
}
} else if (SHUTDOWN_VIBRATE_MS > 0) {
// vibrate before shutting down
Vibrator vibrator = new SystemVibrator();
try {
vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
} catch (Exception e) {
// Failure to vibrate shouldn't interrupt shutdown. Just log it.
Log.w(TAG, "Failed to vibrate during shutdown.", e);
}
// vibrator is asynchronous so we need to wait to avoid shutting down too soon.
try {
Thread.sleep(SHUTDOWN_VIBRATE_MS);
} catch (InterruptedException unused) {
}
}
delayForPlayAnimation();
// Shutdown power
// power off auto test, don't modify
Log.i(TAG, "Performing low-level shutdown...");
//PowerManagerService.lowLevelShutdown();////已经注释掉了
//add your func: HDMI off
//add for MFR
try {
if (ImHDMI == null)
ImHDMI=MediatekClassFactory.createInstance(IHDMINative.class);
} catch (Exception e) {
e.printStackTrace();
}
ImHDMI.hdmiPowerEnable(false);
//unmout data/cache partitions while performing shutdown
SystemProperties.set("ctl.start", "shutdown");////直接关机shutdown操作
/* sleep for a long time, prevent start another service */
try {
Thread.currentThread().sleep(Integer.MAX_VALUE);
} catch ( Exception e) {
Log.e(TAG, "Shutdown rebootOrShutdown Thread.currentThread().sleep exception!");
}
}
public static void lowLevelShutdown() {
SystemProperties.set("sys.powerctl", "shutdown");////直接关机
}
/**
* Low-level function to reboot the device. On success, this function
* doesn't return. If more than 5 seconds passes from the time,
* a reboot is requested, this method returns.
*
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
*/
public static void lowLevelReboot(String reason){
if (reason == null) {
reason = "";
}
SystemProperties.set("sys.powerctl", "reboot," + reason);///重启
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
【注解:】
关机流程中最后是通过修改Android属性进行关机操作(SystemProperties.java通过JNI调用访问系统属性)。
当然我们也可以通过adb命令修改Android系统属性执行关机操作,例如adb shell setpro sys.powerctl shutdown。
这里我们简单介绍下修改Android属性关机的原理或流程。
native_set()<SystemProperties.java>--->SystemProperties_set()<android_os_SystemProperties.cpp>
这是SystemProperties.java类中设置系统函数的方法。
介入方法3(JNI-ndk)接口:java实现的方式
5.frameworks/base/services/jni/com_android_server_PowerManagerService.cpp
- static JNINativeMethod gPowerManagerServiceMethods[] = {
- /* name, signature, funcPtr */
- ...
- { "nativeShutdown", "()V",
- (void*) nativeShutdown },
- { "nativeReboot", "(Ljava/lang/String;)V",
- (void*) nativeReboot },
- ...
- };
这两个好哥俩的实现也是在一起的:(定义如下)
- static void nativeShutdown(JNIEnv *env, jobject clazz) {
- android_reboot(ANDROID_RB_POWEROFF, 0, 0); ////直接关机
- }
-
- static void nativeReboot(JNIEnv *env, jobject clazz, jstring reason) {
- if (reason == NULL) {
- android_reboot(ANDROID_RB_RESTART, 0, 0); //////无reboot reason的重启
- } else {
- const char *chars = env->GetStringUTFChars(reason, NULL);
- android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars); //////有reboot reason的重启
- env->ReleaseStringUTFChars(reason, chars); // In case it fails.
- }
- jniThrowIOException(env, errno);
- }
可以看到无论是关机还是重启,都是调用android_reboot来实现的,只是参数不一样而已。
6.system/core/libcutils/android_reboot.c
int android_reboot(int cmd, int flags, char *arg)
{
int ret;
sync();
remount_ro();
switch (cmd) {
case ANDROID_RB_RESTART://普通重启
ret = reboot(RB_AUTOBOOT);
break;
case ANDROID_RB_POWEROFF://///直接关机
ret = reboot(RB_POWER_OFF);
break;
case ANDROID_RB_RESTART2:
ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,///有参数的重启直接走这里
LINUX_REBOOT_CMD_RESTART2, arg);
break;
default:
ret = -1;
}
return ret;
}
介入方法4(kernel)接口(或者是adb 入口方法:adb reboot xx,etc)
(具体实现例子详见附页4)
7.bionic/libc/unistd/reboot.c ///A:\v387-debug\my-ap\bionic\libc\bionic\reboot.c:
- int reboot (int mode)
- {
- return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL );
- }
--------------------------------KERNEL域--------------------------------
8.__reboot通过syscall来到内核
这里用一些篇幅简要介绍syscall,以后遇到类似的东西更好追踪一些。
第七步中的__reboot在arm架构的实现是这样的(bionic/libc/arch-arm/syscalls/__reboot.S)
/////home/tonylau/tony-workspace/v387-debug/my-ap/bionic/libc/arch-arm/syscalls/__reboot.S
9.kernel/sys.c
在进入这个文件前,我们先去include/linux/syscalls.h中查看一下sys_reboot的定义:
- asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd,
- void __user *arg);
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg)就是sys_reboot
xx.最终调用@@@@kernel/meditek/kernel/kernel/system.c:
void arch_reset(char mode, const char *cmd)
{
char reboot = 0;
int res=0;
struct wd_api*wd_api = NULL;
res = get_wd_api(&wd_api);
printk("arch_reset: cmd = %s\n", cmd ? : "NULL");
if (cmd && !strcmp(cmd, "charger")) {//////
/* do nothing */
} else if (cmd && !strcmp(cmd, "recovery")) {/////如果传下来的字符串是recovery=>就在RTC寄存器里设置某个特定值,
当uboot里读取RTC寄存器的时候如果获取了这个特定值,那就可以起recovery这个动作了
rtc_mark_recovery();
} else if (cmd && !strcmp(cmd, "bootloader")){//////////
rtc_mark_fast();
}
#ifdef MTK_KERNEL_POWER_OFF_CHARGING
else if (cmd && !strcmp(cmd, "kpoc")){ rtc_mark_kpoc(); }///////
#endif
else {
reboot = 1;
}
printk("arch_reset, get wd api error %d\n",res);
} else {
wd_api->wd_sw_reset(reboot);
}
}
附页2:
private OnClickListener ButtonSetResolution = new OnClickListener(){ @Override public void onClick(View view) { try { Class<?> c = Class.forName("android.os.SystemProperties"); Object object1 = c.newInstance(); java.lang.reflect.Method getmethod = c.getDeclaredMethod("get", String.class); java.lang.reflect.Method setmethod = c.getDeclaredMethod("set", String.class, String.class); setmethod.invoke(object1, "sys.powerctl", "reboot,handoff_resolution_enable"); ////2015-06-03 //setmethod.invoke(object1, "sys.lucid.PowerXtend.loglevel", Integer.toString(1)); } catch (Exception e) { e.printStackTrace(); } } };
附页4:refer http://blog.sina.com.cn/s/blog_474928c90100zxkb.html
1、在Android源码目录中的packages/apps/下创建一个目录,例如:Hello。2、编写Android.mk文件:LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= shutdown.cLOCAL_MODULE:= shutdownLOCAL_PRELINK_MODULE:= falseLOCAL_SHARED_LIBRARIES:= libutilsinclude $(BUILD_EXECUTABLE)3、编写shutdown.c源文件,如下:
#include <stdio.h>#include <stdlib.h>#include <utils/Log.h>#include <sys/reboot.h>#ifndef LOG_TAG#define LOG_TAG "dxyh"#endifint main(int argc, char **argv){int retval;if ((retval = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,RB_POWER_OFF, NULL)) < 0) {LOGE("Try to shutdown the machine failed!");exit(EXIT_FAILURE);}return 0;}
<span style="color:#000000;"><span style="font-size:16px"><span style="background:none repeat scroll 0% 0% transparent">4</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">、</span><span style="font-size:16px">mm</span></span></span><span style="color:#000000;"><span style="font-size:16px"><span style="background:none repeat scroll 0% 0% transparent">5</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">、将生成的</span><span style="font-size:16px">shutdown</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">可执行程序推入到</span><span style="font-size:16px">pad</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">中的</span><span style="font-size:16px">/system/bin</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">下即可。</span></span></span><span style="color:#000000;"><span style="font-size:16px"><span style="background:none repeat scroll 0% 0% transparent">6</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">、然后就可以和其他命令一样运行了,例如</span><span style="font-size:16px">adb shell shutdown</span></span><span style="background:none repeat scroll 0% 0% transparent"><span style="font-size:16px">。</span></span></span>
- (android 关机/重启)Android关机/重启流程解析 (2)-----实例解析(多种实现方式)
- (android 关机/重启)Android关机/重启流程解析
- (android 关机/重启)Android关机/重启流程解析
- Android实现关机/重启
- Android关机重启实现
- android 系统重启关机流程分析
- android 系统重启关机流程分析
- android 系统重启关机流程分析
- android 系统重启关机流程分析
- android关机重启流程代码
- android usb adb流程,Android系统关机或重启的几种实现方式
- Android实现关机和重启的几种方式
- android编程如何实现关机和重启(1)
- Android关机流程解析
- Android关机流程解析
- Android关机流程解析
- Android关机流程解析
- Android关机流程解析
- 关于安装ACCESS 2007 精简版(云端版)出现错误的解决方案
- 浅析Oracle数据恢复操作
- Word Break II -- leetcode
- velocity基本语法
- 启动smb服务器的小技巧
- (android 关机/重启)Android关机/重启流程解析 (2)-----实例解析(多种实现方式)
- JQuery 常用方法经典总结
- PuTTY+Xming实现X11的ssh转发
- 理解OAuth 2.0
- 在你步入职业软件开发生涯那天起就该知道的五件事
- Matlab 的reshape函数
- ListView尖括号参数的比较
- 算法导论中《图论的单源最短路径》思考
- Python challenge攻关6-11