ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年7月26日 星期二

linux device open, major/minor number

device 被 open 的時候, kernel 會 call driver 的 struct file_operations { .open } function.

並且把 開啟時的參數 (major, minor number) 放在 struct inode 的
include/linux/fs.h struct inode { ... dev_t i_rdev; ... }

dev_t 定義在
include/linux/types.h typedef __u32 __kernel_dev_t; typedef __kernel_dev_t dev_t;
這個 dev_t (i_rdev) 包含 major, minor number,用以下的 MACRO 取出: include\linux\kdrv_t.h #define MINORBITS 20 #define MINORMASD ((1U << MINORBITS) -1 ) #define MAJOR(dev) ((unsigned int)((dev) >> MINORBITS) #define MINOR(dev) ((unsigned int)((dev) & MINORMASK))

所以 driver 可以靠 參數的 inode.i_rdev 知道 user program 是對哪一個 minor number 動作。

driver 的 read/write function 沒有 inode 參數,而是用 struct file *filep
同樣的
filep->f_dentry->d_inode->i_rdev 可以拿到 dev_t i_rdev


所以linux 的 dev node 最多只有 32-20 = 12 bits (4096).
每個 device 最多有 20 = 1048576 個 minor number
可以用

2011年7月22日 星期五

repo level 的 diff , patch -- worklog

repo forall -c 'git format-patch myorg; 來產生 patch 檔。 然後依照 folder structure ,把所有 patch 檔複製出來。 tar then mail to customers
解開 用 git am 上回去...
STEP: 1.複製目錄結構就好

2011年7月20日 星期三

platform_device, platform_driver

  1. platform-device 是 hardware (大概是指 hardware resource - gpio, interrupt number, memory region .. etc)
  2. platform-driver 是 software
各自和 kernel 註冊。

device 要比 driver 先註冊。

因為 driver 向 kernel 註冊時, kernel 會去 registered device list中,找出 name 和 driver 的 name 一樣的 device 和 driver 配對。

如果找不到,就 driver register 會 fail。



要改用 platform device, driver 的方式,大概是因為要有 suspend, resume callback 的機會。
include/linux/platform_device.h struct platform_driver { int (*probe) (struct platform_device *); int (*remove) (struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend) (struct platform_device *, pm_message_t state); int (*resume) (struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; }; 填好這個 struct 後,kernel 註冊 (platform_driver_register),kernel 就會在 suspend , resume 時,call 對應的 callback function.
* 其中 的
struct device_driver driver.name 就是用來找對應的 platform_device 的 name device_driver 宣告在 include/linux/device.h
又是一個很大的 階層 式結構..



platform_device_XXX 和 platforma_driver_XXX 的 function 都 implement 在 driver/base/platform.c platform_add_devices -- call platform_device_register int platform_add_devices(struct platform_device **devs, int num) { int i, ret = 0; for (i = 0; i < num; i++) { ret = platform_device_register(devs[i]); if (ret) { while (--i >= 0) platform_device_unregister(devs[i]); break; } } return ret; }
platform_device_register-- call platform_device_add.
int platform_device_register(struct platform_device *pdev) { device_initialize(&pdev->dev); return platform_device_add(pdev); }
還有動態 alloc 的 device 用:
  1. platform_device_alloc 取得一塊記憶體,工作 platform_device 的資料存放



並不是從此以後 driver 都要用 platform_device, platform_driver 這樣的方式來作。
舊的 module 實作方式還是可以用,只是沒有 suspend/resume 的 callback 機制了 (還是我找不到?)

把原來的 driver moduel 方式改為 platform_device, platform_driver ,大概就是..
  1. 把 mod_init 改為 mod_probe -- 主要是內容,原來 init 做的事,改在 probe 作
  2. 增加 remove, suspend, resume 這幾個 function
  3. 填寫一個 platform_driver structure
  4. 新增一個 init,內容就是註冊 platform_driver 和 platform_device
  5. 修改 exit,作 unregister platform_driver 和 platform_device
* kernel 提供一個 platform_device_register_simple( ) function call,讓 legacy module 方便改為 platform model. mydevicep = platform_device_register_simple("mydriver",0,NULL,0); 這個 mydevicep 要存起來,exit 作 unregister 時藥用。


platform, device, driver model 相關的 code 都在 drivers/base: bus.c driver.c platform.c

2011年7月18日 星期一

capture , output 都是 /dev/video? 只是 index 不一樣。 capture 是 video0, output 是 video16. 在 v4l2-dev.c 的 video_register_device 有 /dev 下名字的分類: /** * video_register_device - register video4linux devices * @vdev: video device structure we want to register * @type: type of device to register * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ... * -1 == first free) * @warn_if_nr_in_use: warn if the desired device node number * was already in use and another number was chosen instead. * * The registration code assigns minor numbers and device node numbers * based on the requested type and registers the new device node with * the kernel. * An error is returned if no free minor or device node number could be * found, or if the registration of the device node failed. * * Zero is returned on success. * * Valid types are * * %VFL_TYPE_GRABBER - A frame grabber * * %VFL_TYPE_VTX - A teletext device * * %VFL_TYPE_VBI - Vertical blank data (undecoded) * * %VFL_TYPE_RADIO - A radio card */ capture 和 output 的 type 都是 VFL_TYPE_GRABBER. capture device 的 register function , nr 是 -1 . output device 的 register function, nr 是

2011年7月15日 星期五

frameworks/base/core/java/android/view/SurfaceHolder.java 是一個 interface: public interface SurfaceHolder {

2011年7月14日 星期四

Android Sample code : CameraPreview

這一篇:
http://www.devdaily.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java.shtml
的 example 比 google 的
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html
簡單.

但是有點問題,所以改一下,source code 放在 github
https://github.com/checko/CameraPreview

大概就是
  1. try catch on setDisplaySize
  2. 加上 Camera.release( ) , 這樣 overlay 才會 call V4L_STREAM_OFF. -- 下次啟動才不會有 exception.

About Camera Preview :

簡單的說,就是原來 的, onCreate( ),設定 application Content View 的 code,改為把 CameraPreview 的 Surface 設為 Content View: mPreview = new Preview(this); setContentView(mPreview); Preview 這個 class, 負責 包裝 camera,和 output.:
class Preview extends SurfaceView implements SurfaceHolder.Callback { 繼承 SurfaceView, 所以可以被設為 application Context View.

然後把 Camera 的控制加在 class 生成,與 View 的 eventHandler 中。


ref

2011年7月13日 星期三

Application Name : 沒什麼用。
package name : 最後 build 出來的 apk, class 的名字 -- 整個都要實做
Activity : Activity class 的名字 --- 要實做。

2011年7月11日 星期一

Android suspend -- worklog - usb wakeup

經過以上修改,系統已經可以 suspend/wakeup,
但是suspend 後把週邊 power 關掉後,會有 usb wakeup here 的 message
-- 大概是 usb host 認為有 wakeup 吧..

把 usb 的 wakeup driver handler 拿掉
--
結果 , suspend 後反而出現 unhandled irq。
只好把 usb host 的 registeration function 拿掉,, 這樣就 OK 了,
suspend current 也由 300mA降掉 150mA--- 因為以前根本沒 suspend ..

要disable 的話..
arch/arm/plat-mxc/usb_common.c
static int usb_register_remote_wakeup(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct resource *res; int irq; pr_debug("%s: pdev=0x%p \n", __func__, pdev); if (!(pdata->wake_up_enable)) return -ECANCELED; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", dev_name(&pdev->dev)); return -ENODEV; } irq = res->start; pdev->dev.power.can_wakeup = 1; enable_irq_wake(irq); return 0; } 讓這個 return 0 就可以

其實比較好的作法是在 kenel menuconfig 中拿掉 usb suspend 的功能。

Android -- power button operation -- pluse 改 level

原來設計的 Power Button 動作是在 button up 時動作。 -- 因為需要判斷 long-press or click (short press)。 但是現在改為 hardware,應該就是:
  • down -- suspend
  • up -- wakeup

原來的 "兩用" power button,用這樣的方法 detect longpress - private void interceptPowerKeyDown(boolean handled) { Log.v(TAG,"InterceptPowerKeyDown"); mPowerKeyHandled = handled; if (!handled) { Log.v(TAG,"...postDelay..."); mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); } } 在 keydown 時,設定一個 5 sec 啟動的 call back function ... 然後在 key up 時移除他: private boolean interceptPowerKeyUp(boolean canceled) { Log.v(TAG,"interceptPowerKeyUp"); if (!mPowerKeyHandled) { Log.v(TAG,"...remove..."); mHandler.removeCallbacks(mPowerLongPress); return !canceled; } else { mPowerKeyHandled = true; return false; } } 所以如果在 5sec 內,call back function 還沒被 launch 前 relase key 的話, call back function 就會被 remove.. 也就不會執行了。
改為 level 動作 .. 一樣,利用 這種 delay-remove 的方法: private final Runnable mGoToSleep = new Runnable() { public void run() { Log.v(TAG,"mGoToSleep"); mPowerManager.goToSleep(SystemClock.uptimeMillis() + 1); } }; 然後按下 powerdown 的時候.. private void interceptPowerKeyDown(boolean handled) { Log.v(TAG,"InterceptPowerKeyDown"); mPowerKeyHandled = handled; if (!handled) { Log.v(TAG,"...postDelay..."); mHandler.postDelayed(mGoToSleep,1000); } } private boolean interceptPowerKeyUp(boolean canceled) { Log.v(TAG,"interceptPowerKeyUp"); if (!mPowerKeyHandled) { Log.v(TAG,"...remove..."); mHandler.removeCallbacks(mGoToSleep); return !canceled; } else { mPowerKeyHandled = true; return false; } } 另外,interceptKeyBeforeQueueing ( ) 也要改一下.. 原來,只有在 'down' 時,才會加入 wakeup ..改成不用了 if (isWakeKey /* && down */) { if (keyguardActive) { // If the keyguard is showing, let it decide what to do with the wake key. mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode); Log.d(TAG,"Keyguard"); } else { // Otherwise, wake the device ourselves. result |= ACTION_POKE_USER_ACTIVITY; result |= ACTION_WAKE_TO_SLEEP; Log.d(TAG,"ADD WAKE"); } } 這樣在 keyup 時,也會有 WAKE_TO_SLEEP 動作。
result 沒有 WAKE_TO_SLEEP flag 的話, system resume 後又會馬上suspend..
其實還有一點是 系統的 pwrbutton level 改成:
  • low -- suspend
  • high -- resume
但是原來的 key operation 是:
  • low -- key up
  • high -- key down
加上 keyboard manager 有 check down action 後才會認可 up 動作,所以必須要反向 -- 這個改 kernel driver.

2011年7月8日 星期五

Android : call back function for native code

就是 C code call java code.

從 InputManager.java 看到
/* * Callbacks from native. */ private class Callbacks { static final String TAG = "InputManager-Callbacks"; private static final boolean DEBUG_VIRTUAL_KEYS = false; private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; private static final String CALIBRATION_DIR_PATH = "usr/idc/"; @SuppressWarnings("unused") public void notifyConfigurationChanged(long whenNanos) { mWindowManagerService.sendNewConfiguration(); } .... @SuppressWarnings("unused") public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags, int keyCode, int scanCode, int policyFlags, boolean isScreenOn) { return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing( whenNanos, action, flags, keyCode, scanCode, policyFlags, isScreenOn); } 然後 class InputManager 就有
private final Callbacks mCallbacks; 和 class Init 時..
nativeInit(mCallbacks); nativeInit 實際上是 implement 在 C code :
./base/services/jni/com_android_server_InputManager.cpp:1300: { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V", ..... static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz, jobject callbacks) { if (gNativeInputManager == NULL) { gNativeInputManager = new NativeInputManager(callbacks); } else { LOGE("Input manager already initialized."); jniThrowRuntimeException(env, "Input manager already initialized."); } }
這樣切開,看 com_android_server_InputManager.cpp 的 code .. 裡面都是 call InputManager.java 的 callback function。
--- 為什麼不都用 java 作算了呢?

com_android_server_InputManager.cpp 的 register_android_server_InputManager(JNIEnv*) 是由 onload.cpp 的 JNI_OnLoad( ) 呼叫的。
這個 (/frameworks/base/services/jni) Android.mk 的 target module name 是 libandroid_servers。

是由 ./frameworks/base/services/java/com/android/server/SystemServer.java:634: System.loadLibrary("android_servers"); load 進來的。
也就是 service.


亂入一下,設定系統時間是...
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);

Android, code trace -- power button up/down

trace 一下 ENDCALL 之後的動作。 result &= ~ACTION_PASS_TO_USER : 不用把 key 傳給 user program. if(down) {偵測到 keydown.. 之後就把 TelephonyService 關掉 然後 交給 PowerKeyDown. interceptPowerKeyDown(!isScreenOn || hungUp) 如果是 keyup 的話... if(interceptPowerKeyUp(canceled){交給 PowerKeyUp.. 確認要處理的話,由 mEndcallBehavior 決定動作.. --- 大概改成這樣會比較好看吧: if(mEndcallBehavior) { if(Setting.System.END_BUTTON_BEHAVIOR_HOME){ goHome(); }else if(Setting.System.END_BUTTON_BEHAVIOR_SLEEP){ result = (result & ~ ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP; } }

2011年7月7日 星期四

Android : log - suspend/wakeup

正確的log: suspend pwrkey_event_handler_Keydown V/WindowManager( 2253): InterceptPowerKeyDown pwrkey_event_handler_Keyup V/WindowManager( 2253): interceptPowerKeyUp request_suspend_state: mem (0->3) at 148562587628 (2011-07-01 13:02:24.267737500 UTC) I/power ( 2253): *** set_screen_state 0 D/SurfaceFlinger( 2253): About to give-up screen, flinger = 0x11b450 PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.01 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done. PM: suspend of devices complete after 1237.362 msecs suspend wp cpu=800000000 PM: late suspend of devices complete after 0.625 msecs resume PM: early resume of devices complete after 0.511 msecs pwrkey_event_handler_Keyup IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7) mmc0: error -110 during resume (card was removed?) mmc0: card 0001 removed wakeup wake lock: mmc_delayed_work pwrkey_event_handler_Keydown PM: resume of devices complete after 257.948 msecs Restarting tasks ... request_suspend_state: on (3->0) at 150510488058 (2011-07-01 13:05:39.060255538 UTC) V/WindowManager( 2253): InterceptPowerKeyDown done. I/power ( 2253): *** set_screen_state 1 I/dalvikvm( 2322): Total arena pages for JIT: 11 suspend: exit suspend, ret = 0 (2011-07-01 13:05:39.431860787 UTC) mxc_ipu mxc_ipu: Channel already disabled 9 mxc_ipu mxc_ipu: Channel already uninitialized 9 D/SurfaceFlinger( 2253): Screen about to return, flinger = 0x11b450 mmc1: Starting deferred resume mmc1: Deferred resume completed W/KeyCharacterMap( 2326): Can't open keycharmap file W/KeyCharacterMap( 2326): Error loading keycharmap file '/system/usr/keychars/mxc_power_key.kcm.bin'. hw.keyboards.65538.devname='mxc_power_key' W/KeyCharacterMap( 2326): Using default keymap: /system/usr/keychars/qwerty.kcm.bin processpacket: 24 08 17 0A 43 72 0D 0A >>value= 0x0A43 [mcustub] button0, scan code= [mcustub] keyi = 0 don't send!! PM: early resume of devices complete after 0.511 msecs
另一個加上 debug msg 的 suspend log: pwrkey_event_handler_Keyup pwrkey_event_handler_Keyup pwrkey_event_handler_Keydown V/WindowManager( 2259): KEYCODE_ENDCALL V/WindowManager( 2259): InterceptPowerKeyDown V/WindowManager( 2259): ...postDelay... pwrkey_event_handler_Keyup V/WindowManager( 2259): KEYCODE_ENDCALL V/WindowManager( 2259): interceptPowerKeyUp V/WindowManager( 2259): ...remove... D/InputManager-JNI( 2259): interceptpwrkey_event_handler_Keyup KeyBeforeQueueing, GO_TO_SLEEP D/PowerManagerService-JNI( 2259): android_server_PowerManagerService_goToSleep request_suspend_state: mem (0->3) at 148702204627 (2011-07-01 13:02:23.578792624 UTC) I/power ( 2259): *** set_screen_state 0 D/SurfaceFlinger( 2259): About to give-up screen, flinger = 0x2542c8 D/dalvikvm( 2334): GC_CONCURRENT freed 242K, 51% free 2860K/5767K, external 1527K/1559K, paused 3ms+3ms resume pwrkey_event_handler_Keyup pwrkey_event_handler_Keydown request_suspend_state: on (3->0) at 480581041834 (2011-07-01 13:07:55.457631706 UTC) V/WindowManager( 2259): InterceptPowerKeyDown I/power ( 2259): *** set_screen_state 1 V/WindowManager( 2259): KEYCODE_ENDCALL mxc_ipu mxc_ipu: Channel already disabled 9 mxc_ipu mxc_ipu: Channel already uninitialized 9 D/SurfaceFlinger( 2259): Screen about to return, flinger = 0x2542c8 W/KeyCharacterMap( 2342): Can't open keycharmap file W/KeyCharacterMap( 2342): Error loading keycharmap file '/system/usr/keychars/mxc_power_key.kcm.bin'. hw.keyboards.65538.devname='mxc_power_key' W/KeyCharacterMap( 2342): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
另外,查到是 ENDCALL ..還有修改了 power key up/down 的 high/low 對應後的suspend: pwrkey_event_handler_Keydown power_key_int:RISING D/InputReader( 2256): Input event: device=0x10002 type=0x1 scancode=62 keycode=6 value=1 D/WindowManager( 2256): interceptKeyTq keycode=6 screenIsOn=true keyguardActive=false V/WindowManager( 2256): KEYCODE_ENDCALL V/WindowManager( 2256): InterceptPowerKeyDown V/WindowManager( 2256): ...postDelay... pwrkey_event_handler_Keyup power_key_int:FALLING D/InputReader( 2256): Input event: device=0x10002 type=0x1 scancode=62 keycode=6 value=0 D/WindowManager( 2256): interceptKeyTq keycode=6 screenIsOn=true keyguardActive=false V/WindowManager( 2256): KEYCODE_ENDCALL V/WindowManager( 2256): interceptPowerKeyUp V/WindowManager( 2256): ...remove... D/InputManager-JNI( 2256): interceptKeyBeforeQueueing, GO_TO_SLEEP D/PowerManagerService-JNI( 2256): android_server_PowerManagerService_goToSleep request_suspend_state: mem (0->3) at 54372444002 (2011-07-01 13:00:49.350592499 UTC) I/power ( 2256): *** set_screen_state 0 D/SurfaceFlinger( 2256): About to give-up screen, flinger = 0x11b448 PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.01 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done. PM: suspend of devices complete after 1237.164 msecs suspend wp cpu=800000000 PM: late suspend of devices complete after 0.614 msecs ....可以看到,一樣是在 up 時進入 suspend. 下面是 resume ... PM: early resume of devices complete after 0.509 msecs pwrkey_event_handler_Keydown power_key_int:RISING IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7) mmc0: error -110 during resume (card was removed?) mmc0: card 0001 removed wakeup wake lock: mmc_delayed_work pwrkey_event_handler_Keyup power_key_int:FALLING PM: resume of devices complete after 260.198 msecs Restarting tasks ... D/InputReader( 2256): Input event: device=0x10002 type=0x1 scancode=62 keycode=6 value=1 D/WindowManager( 2256): interceptKeyTq keycode=6 screenIsOn=false keyguardActive=false D/WindowManage request_suspend_state: on (3->0) at 56324691776 (2011-07-01 13:05:43.144466699 UTC) r( 2256): ADD WAKE V/WindowManager( 2256): KEYCODE_ENDCALL V/WindowManager( 2256): InterceptPowerKeyDown I/power ( 2256): *** set_screen_state 1 D/InputReader( 2256): Input event: device=0x10002 type=0x1 scancode=62 keycode=6 value=0 D/WindowManagerdone. ( 2256): interceptKeyTq keycode=6 screenIsOn=true keyguardActive=false V/WindowManager( 2256): KEYCODE_ENDCALL V/WindowManager( 2256): interceptPowerKeyUp suspend: exit suspend, ret = 0 (2011-07-01 13:05:43.501921450 UTC) mxc_ipu mxc_ipu: Channel already disabled 9 mxc_ipu mxc_ipu: Channel already uninitialized 9 D/SurfaceFlinger( 2256): Screen about to return, flinger = 0x11b448

2011年7月5日 星期二

Android Power Button Dialog -- code trace

要找一下長按 Power Button 會出現的 dialog 畫面..

原來以為是
frameworks/base/policy/src/com/android/internal/policy/impl/PowerDialog.java,
結果重點是source code 的開頭....
* @deprecated use {@link GlobalActions} instead ......

所以去找 GlobalActions.java。

這個是畫出 PowerDialog 的 class。

最後是在 frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 找到啟動的地方..
public int interceptKeyBeforeQueueing( )... ... case KeyEvent.KEYCODE_POWER: { result &= ~ACTION_PASS_TO_USER; if (down) { ITelephony telephonyService = getTelephonyService(); boolean hungUp = false; if (telephonyService != null) { try { if (telephonyService.isRinging()) { // Pressing Power while there's a ringing incoming // call should silence the ringer. telephonyService.silenceRinger(); } else if ((mIncallPowerBehavior & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 && telephonyService.isOffhook()) { // Otherwise, if "Power button ends call" is enabled, // the Power button will hang up any current active call. hungUp = telephonyService.endCall(); } } catch (RemoteException ex) { Log.w(TAG, "ITelephony threw RemoteException", ex); } } interceptPowerKeyDown(!isScreenOn || hungUp); if((result & ACTION_WAKE_TO_SLEEP) !=0 && mPowerManager.getSystemState()==2) { // only try to turn off the screen if we didn't already hang up mPowerKeyHandled = false; mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); result &= ~ACTION_PASS_TO_USER; } } else { if (interceptPowerKeyUp(canceled)) { result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP; } } break; }
在 PowerButton 按下 (Down)的部份..有 call private void interceptPowerKeyDown(boolean handled) { mPowerKeyHandled = handled; if (!handled) { mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); } } 大概就是設定一個 5 sec(getGlobalActionKeyTimeout) 後啟動的 function (mPowerLongPress)..

這個 delayed callback function : mPowerLongPress 是 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(); } } }; 的最後是 showGlobalActionsDialog( ) -- 把 GlobalActions new 出來 void showGlobalActionsDialog() { if (mGlobalActions == null) { mGlobalActions = new GlobalActions(mContext); } final boolean keyguardShowing = mKeyguardMediator.isShowingAndNotHidden(); mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); if (keyguardShowing) { // since it took two seconds of long press to bring this up, // poke the wake lock so they have some time to see the dialog. mKeyguardMediator.pokeWakelock(); } }


原來早就有人寫了,只是google keyword 不對,所以沒找到..

http://my.unix-center.net/~Simon_fu/?p=592

Android Power Button Dialog -- code trace

要找一下長按 Power Button 會出現的 dialog 畫面..
原來以為是 frameworks/base/policy/src/com/android/internal/policy/impl/PowerDialog.java,結果重點是source code 的開頭....
* @deprecated use {@link GlobalActions} instead ......
所以去找 GlobalActions.java。
這個是畫出 PowerDialog 的 class。
最後是在 frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 找到啟動的地方..
public int interceptKeyBeforeQueueing( )... ... case KeyEvent.KEYCODE_POWER: { result &= ~ACTION_PASS_TO_USER; if (down) { ITelephony telephonyService = getTelephonyService(); boolean hungUp = false; if (telephonyService != null) { try { if (telephonyService.isRinging()) { // Pressing Power while there's a ringing incoming // call should silence the ringer. telephonyService.silenceRinger(); } else if ((mIncallPowerBehavior & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 && telephonyService.isOffhook()) { // Otherwise, if "Power button ends call" is enabled, // the Power button will hang up any current active call. hungUp = telephonyService.endCall(); } } catch (RemoteException ex) { Log.w(TAG, "ITelephony threw RemoteException", ex); } } interceptPowerKeyDown(!isScreenOn || hungUp); if((result & ACTION_WAKE_TO_SLEEP) !=0 && mPowerManager.getSystemState()==2) { // only try to turn off the screen if we didn't already hang up mPowerKeyHandled = false; mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); result &= ~ACTION_PASS_TO_USER; } } else { if (interceptPowerKeyUp(canceled)) { result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP; } } break; } 在 PowerButton 按下 (Down)的部份..有 call
private void interceptPowerKeyDown(boolean handled) { mPowerKeyHandled = handled; if (!handled) { mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); } } 這個 delayed callback function : mPowerLongPress 是
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(); } } }; 的最後是 showGlobalActionsDialog( ) -- 把 GlobalActions new 出來
void showGlobalActionsDialog() { if (mGlobalActions == null) { mGlobalActions = new GlobalActions(mContext); } final boolean keyguardShowing = mKeyguardMediator.isShowingAndNotHidden(); mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); if (keyguardShowing) { // since it took two seconds of long press to bring this up, // poke the wake lock so they have some time to see the dialog. mKeyguardMediator.pokeWakelock(); } }

2011年7月4日 星期一

am - 從 command 啟動 Android apk

frameworks/base/cmds/am 提供 am ,可以在 console (shell) 啟動 android apk. 實際上是一個 java program (am.jar),另外提供一個 shell script am,用來 invoke 這個 java class. # Script to start "am" on the device, which has a very rudimentary # shell. # base=/system export CLASSPATH=$base/framework/am.jar exec app_process $base/bin com.android.commands.am.Am "$@" 所以實際上是用 app_process 叫起來 am.jar,再由 am.jar 叫起 apk activity. app_process 主要用 AndroidRuntime 這個 class. frameworks/base/core/jni/AndroidRuntime.cpp
ref:

Android.mk -- multiple cpp to exe file

frameworks/base/libs/ui/tests的 Android.mk 是一個包含很多 execute file 的 project。 因為每一個 test application 只有一個 cpp file,所以這樣寫: $(foreach file,$(test_src_files), \ $(eval include $(CLEAR_VARS)) \ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ $(eval LOCAL_C_INCLUDES := $(c_includes)) \ $(eval LOCAL_SRC_FILES := $(file)) \ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ $(eval include $(BUILD_EXECUTABLE)) \ ) 其實就記得android 的 每個 Android.mk 最後都被 include 到一個大 Makefile 裡就可以...

標籤

網誌存檔