2011年11月28日 星期一

android - 電源管理 與 飛航模式控制

這次研究的是在android 進S3時要切到飛模式(Airplane Mode)避免耗電,而這個自動切換又不受使用者自行啟用飛模式影響,也就是如果是使用者自行開啟,不自動去開關。

●何謂S3
以電源管來說主要區分S0->S5 下面逐一說明

S0:正常狀態,即為RUNTIME模式

S1:CPU停止工作,即為待機(Standby)

S2:CPU關閉,和S1相同(Power Standby)

S3:Suspend to RAM,即為「睡眠」,將所有狀態資料儲存在記憶體中,進入「假關機」,
         所有設備除了記憶體之外都斷電了。

S4:Suspend to Disk,將所有狀態資料儲存至硬碟中,即為「休眠」。

S5:Shutdown...就是關機的意思啦。

在Embedded中,可以對下列路徑下命令系統進入各種狀態
# echo standby > /sys/power/state

用cat 可取得kenerl支持哪些休眠方式
# cat /sys/power/state


●Airplane Mode
這次是以修改 PowerManagerService,來進飛模式,因應S3狀態即要自動開始
首先先暸解如何切換飛模式,範例程式如下:

import android.content.Context;
import android.provider.Settings;
 
public static boolean isAirplaneModeOn(Context context){
 return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}


import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
 
public static void setAirplaneMode(Context context, boolean status){
 // 先判斷目前是已否開啟飛航模式
 boolean isAirplaneModeOn = isAirplaneModeOn(context);
 
 if((status && isAirplaneModeOn) || (!status && !isAirplaneModeOn)){
  return;
 }
 
 int mode = status ? 1 : 0;
 // 設定飛航模式的狀態並廣播出去
 Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, mode);
 Intent i = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
 i.putExtra("state", mode);
 context.sendBroadcast(i);
}

記得在AndroidManifest.xml 加上權限


●PowerManagerService
在需要設定切換飛模式增加程式,增加地方如下:
SCREEN_BRIGHT:
SCREEN_OFF:
reallyTurnScreenOn = true;


我們主要是在android 原始碼的service加上我們的切換程式,這樣在重新build image前,要記得 api也重新再make一次,避免發生android辨示不出我們增加的副程式 (正確應該避免修改android service,要將我們的副程式獨立出來用import方式處理。)

# export TARGET_PRODUCT=xxxxxx  ==>xxxxxx為產品代碼

# make update-api



另外該如何去區分何時該自動開啟飛模式呢?
我採用的方式是利用android frameworks中的providers,來儲存是否為USER自行開啟,這樣在進入休眠時會一並存入記憶體中,並在PowerManagerService 內增加判斷。

路徑如下
frameworks/base/packages/SettingProvider/src/com/android/providers/settings/DatabaseHelper.java

增加provider
loadBooleanSetting(stmt, Settings.System.AIRPLANE_USER_MODE_ON,R.bool.def_airplane_mode_on);



●補充說明,android 是如何呼叫進入suspend流程。
上層 → goToSleep() → goToSleepLocked() →setPowerState() → setScreenStateLocked() → Power.setScreenstate(on) //android_os_power.cpp →Power.c



http://www.thinksrc.com/2010/04/18/suspend-cn.html

http://abgne.tw/android/android-code-snippets/android-control-airplane-mode-enabled.html

沒有留言:

張貼留言