2011-08-26 11:30

1340人阅读

评论(0)

嵌入式系统一般都有一个关机按键,长按这个按键系统会弹出关机对话框,提示关机确认,

关机动作从按键触发中断,linux kernel层给android framework层返回按键事件进入

framework层,再从framework层到kernel层执行kernel层关机任务。

长按键对应的handler代码:

private final Runnable mPowerLongPress = new Runnable() {

public void run() {

if (!mPowerKeyHandled) {

mPowerKeyHandled = true;

performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);

sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);

showGlobalActionsDialog();

}

}

};

mPowerLongPress

启动关机对话框

如果我们选择Power OFF’,会调用ShutdownThread.shutdown.

启动关机线程执行关机动作。

真正关机 流程:

(1)广播全局事件,ACTION_SHUTDOWN Intent

(2)shutdown ActivityManager 服务

(3) 停止蓝牙服务

(4) 停止 电话服务 (radio phone service)

(5)停止mount 服务

(6) 调用 Power.shutdown() 进入native

power的native实现代码:

static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)

{

sync();

#ifdef HAVE_ANDROID_OS

reboot(RB_POWER_OFF);

#endif

}

sync, reboot 为linux系统调用,进入linux内核关机流程。

完毕。

1.通过logcat找到关机流程

frameworks/base/core/java/com/android/internal/app/ShutdownThread.java

public void run() {

boolean bluetoothOff;

boolean radioOff;

BroadcastReceiver br = new BroadcastReceiver() {

@Override public void onReceive(Context context, Intent intent) {

// We don't allow apps to cancel this, so ignore the result.

broadcastDone();

}

};

Log.i(TAG, "Sending shutdown broadcast...");

// First send the high-level shut down broadcast.

mBroadcastDone = false;

mContext.sendOrderedBroadcast(new Intent(Intent.ACTION_SHUTDOWN), null,

br, mHandler, 0, null, null);

final long endTime = System.currentTimeMillis() + MAX_BROADCAST_TIME;

synchronized (mBroadcastDoneSync) {

while (!mBroadcastDone) {

long delay = endTime - System.currentTimeMillis();

if (delay <= 0) {

Log.w(TAG, "Shutdown broadcast timed out");

break;

}

try {

mBroadcastDoneSync.wait(delay);

} catch (InterruptedException e) {

}

}

}

Log.i(TAG, "Shutting down activity manager...");

final IActivityManager am =

ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));

if (am != null) {

try {

am.shutdown(MAX_BROADCAST_TIME);

} catch (RemoteException e) {

}

}

final ITelephony phone =

ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));

final IBluetooth bluetooth =

IBluetooth.Stub.asInterface(ServiceManager.checkService(

BluetoothAdapter.BLUETOOTH_SERVICE));

final IMountService mount =

IMountService.Stub.asInterface(

ServiceManager.checkService("mount"));

try {

bluetoothOff = bluetooth == null ||

bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;

if (!bluetoothOff) {

Log.w(TAG, "Disabling Bluetooth...");

bluetooth.disable(false);  // disable but don't persist new state

}

} catch (RemoteException ex) {

Log.e(TAG, "RemoteException during bluetooth shutdown", ex);

bluetoothOff = true;

}

try {

radioOff = phone == null || !phone.isRadioOn();

if (!radioOff) {

Log.w(TAG, "Turning off radio...");

phone.setRadio(false);

}

} catch (RemoteException ex) {

Log.e(TAG, "RemoteException during radio shutdown", ex);

radioOff = true;

}

Log.i(TAG, "Waiting for Bluetooth and Radio...");

// Wait a max of 32 seconds for clean shutdown

for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {

if (!bluetoothOff) {

try {

bluetoothOff =

bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;

} catch (RemoteException ex) {

Log.e(TAG, "RemoteException during bluetooth shutdown", ex);

bluetoothOff = true;

}

}

if (!radioOff) {

try {

radioOff = !phone.isRadioOn();

} catch (RemoteException ex) {

Log.e(TAG, "RemoteException during radio shutdown", ex);

radioOff = true;

}

}

if (radioOff && bluetoothOff) {

Log.i(TAG, "Radio and Bluetooth shutdown complete.");

break;

}

SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);

}

// Shutdown MountService to ensure media is in a safe state

try {

if (mount != null) {

mount.shutdown();

} else {

Log.w(TAG, "MountService unavailable for shutdown");

}

} catch (Exception e) {

Log.e(TAG, "Exception during MountService shutdown", e);

}

//shutdown power

Log.i(TAG, "Performing low-level shutdown...");

Power.shutdown();

}

logcat显示到最后一步了,但是系统还没有关闭,是电源关闭有问题。

2. Power.shutdown();

找这个 android.os.Power  模块

frameworks/base/core/java/android/os/power.java 中有调用shutdown()jni接口

3. jni接口

frameworks/base/core/jni/android_os_Power.cpp

static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)

{

sync();

#ifdef HAVE_ANDROID_OS

reboot(RB_POWER_OFF);

#endif

}

其中,RB_POWER_OFF 及RB_AUTOBOOT (重启)定义bionic/libc/include/sys/reboot.h

#define RB_AUTOBOOT     LINUX_REBOOT_CMD_RESTART

#define RB_HALT_SYSTEM  LINUX_REBOOT_CMD_HALT

#define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF

系统最后会执行系统调用sys_reboot(reboot)。reboot通常定义在内核kernel/kernel/sys.c

4 。内核部分。 kernel/sys.c

其中,

if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)

cmd = LINUX_REBOOT_CMD_HALT;

lock_kernel();

switch (cmd) {

case LINUX_REBOOT_CMD_RESTART:

kernel_restart(NULL);

break;

case LINUX_REBOOT_CMD_CAD_ON:

C_A_D = 1;

break;

case LINUX_REBOOT_CMD_CAD_OFF:

C_A_D = 0;

break;

case LINUX_REBOOT_CMD_HALT:

kernel_halt();

unlock_kernel();

do_exit(0);

break;

case LINUX_REBOOT_CMD_POWER_OFF:

printk("test powe down in %s(%d)\n", __FILE__, __LINE__);

kernel_power_off();

unlock_kernel();

do_exit(0);

break;

当pm_power_off为空时,

由上层传入的命令LINUX_REBOOT_CMD_POWER_OFF会变为LINUX_REBOOT_CMD_HALT,从而执行

kernel_halt()函数。在该函数中,会执行函数machine_halt()。错误原因就在这儿(pm_power_off为空)。

5.

函数指针pm_power_off是与平台相关的指针,

添加函数

static void lpc32xx_power_off(void)

{

__raw_writel((0x1<<9),GPIO_P2_OUTP_CLR(GPIO_IOBASE));

}

在ea3250_board_init中添加

pm_power_off = lpc32xx_power_off;

编译内核 ,OK

android层可以正常关闭电源了。。,

android 关机 流程_android 关机 流程分析相关推荐

  1. android 关机 流程_android系统关机流程分析

    关机动作从按键触发中断,linux kernel层给android framework层返回按键事件进入  framework层,再从 framework层到kernel层执行kernel层关机任务. ...

  2. android 关机 流程_Android系统关机的全流程解析

    在PowerManager的API文档中,给出了一个关机/重启接口: public void reboot (String reason) 对于这个接口的描述很简单,就是几句话. 接口的作用就是重启设 ...

  3. Android 4.4KK系统关机流程分析

    在PowerManager的API文档中,给出了一个关机/重启接口 public void reboot (String reason) 对于这个接口的描述很简单,就是几句话. 接口的作用就是重启设备 ...

  4. (转)CentOS 7系统详细开机启动流程和关机流程

    CentOS 7系统详细开机启动流程和关机流程 原文:http://blog.csdn.net/yuesichiu/article/details/51350654 名称 bootup - 系统启动流 ...

  5. Android内存泄漏的检测流程、捕捉以及分析

    https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...

  6. Android 系统(78)---《android framework常用api源码分析》之 app应用安装流程

    <android framework常用api源码分析>之 app应用安装流程 <android framework常用api源码分析>android生态在中国已经发展非常庞大 ...

  7. Android OTA升级原理和流程分析(五)---update.zip包从上层进入Recovery服务

    转载自:http://blog.chinaunix.net/uid-22028566-id-3533854.html 文章开头我们就提到update.zip包来源有两种: 一个是OTA在线下载(一般下 ...

  8. Android原生音频变调代码流程分析

    会说话的Tom猫是一款非常经典的终端游戏,可爱的Tom猫可以发出不同音调的声音. 之前用过一个非常著名的开源库SoundTouch可以实现音频的变速变调功能,具体可参考: https://blog.c ...

  9. 【SemiDrive源码分析】【X9芯片启动流程】30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一)

    [SemiDrive源码分析][X9芯片启动流程]30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一) 一.Android Kernel 启动流程分析 ...

最新文章

  1. openresty开发系列33--openresty执行流程之2重写赋值阶段
  2. ubuntu首次给root用户设置密码和root用户登录设置
  3. 步步为营-11-ListT泛型的简单练习
  4. 江苏省计算机学会博士论文,江苏学会网 欢迎您成为江苏省计算机学会会员
  5. 横幅新年促销海报PSD模板,拯救年底节日忙
  6. 诊所 金卫系统 青岛_金卫体检信息管理系统
  7. 收集最全的工业软件大集合
  8. 错误代码 insufficient-isv-permissions 错误原因: ISV权限不足
  9. Nvivo 12 安装包可自动编码
  10. 南阳oj入门题-cigarettes
  11. 友盟分享,极光推送Demo
  12. 关于Win10创意者更新之后蓝屏的修复办法
  13. 黑客全票打飞服务器,《鹅鸭杀》停服三天!更有游戏首发被冲下架
  14. Kotlin ListView设置Adapter
  15. 工业数字化转型中的数据治理
  16. CSS学习笔记(二十一)CSS变量var()
  17. 使用scrapy框架抓取手机商品信息(2)
  18. 设计owllook网络小说推荐系统
  19. linux复制文件夹及赋予权限
  20. 教科书范本级:银行容错容灾体系建设与实操性演练设计

热门文章

  1. Android 进程间通信方式
  2. Raw Socket和Socket编程
  3. Unity Animator入门:使用Animator和trigger参数做简单的UI动画
  4. 2022-05-19 列式数据库-Clickhouse
  5. 【报错】win键被锁怎么解锁
  6. docker创建容器一直restart解决
  7. Unity:锚点详解
  8. 数论的基础入门(初读数论概论有感)(acm知识储备)
  9. Drools简单入门
  10. 大学生当裁缝专做西服 一年收入100万