ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2012年2月7日 星期二

ViewRoot 的 getpermission 用到 ActivityManagerNative: return ActivityManagerNative.getDefault().checkPermission( permission, Binder.getCallingPid(), Binder.getCallingUid());

getTopActivity & GET_TASKS permission check

要知道目前 最前面的 activity 是什麼,可以用: import java.util.List; import android.app.ActivityManager; ... ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); Log.d("current task:", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName()); Log.d("Package Name:", " " + taskInfo.get(0).topActivity.getPackageName());
但是 getRunningTasks( ) 需要 GET_TASKS 權限 android.permission.GET_TASKS

getRunningTasks( ) 實際上是 call IActivityManager 的 getTasks(): public List<RunningTaskInfo> getRunningTasks(int maxNum, int flags, IThumbnailReceiver receiver) throws SecurityException { try { return ActivityManagerNative.getDefault().getTasks(maxNum, flags, receiver); } catch (RemoteException e) { // System dead, we will be dead too soon! return null; } }


配合 Hotkey 的動作,如果要作到:依照目前操作的 程式,決定 Hotkey 要 launch 的程式,就要改 framework 裡,hotkey 的 code。

因為這段 code 實際上是在每一個 vm 中 run 的,
所以,要是 這個 package 沒有 GET_TASKS 權限, framework 的 getRunningTasks 就會 fail。

只好.... bypass GET_TASKS 的 permission check!!

修改 ActivityManagerService.java: public List getTask(int maxNum .... ... if (checkCallingPermission(android.Manifest.permission.GET_TASKS) != PackageManager.PERMISSION_GRANTED) { .. 把這段 check comment 掉..



ref:
  1. http://qtcstation.com/2011/01/getting-info-about-your-currently-running-activities/

2012年2月6日 星期一

shortcut - Camera

CAMERA 按鍵在 android framework 中,要長按才會啟動,

順便可以看一下 LongPress 的 detection: if (event.getRepeatCount() == 0) { dispatcher.startTracking(event, this); } else if (event.isLongPress() && dispatcher.isTracking(event)) { dispatcher.performedLongPress(event); mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); sendCloseSystemWindows(); Broadcast an intent that the Camera button was longpressed Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null); intent.putExtra(Intent.EXTRA_KEY_EVENT, event); getContext().sendOrderedBroadcast(intent, null); } 大概就是... 第一次 down event (repeat()=0) 時,call startTracking( ) 叫 Input manager(?) tracking 這個 key。
這樣 input manager 就會持續嗔測 CAMERA Key, timeout 時 再送一個 down event,並且 event.isLongPress() 會是 1



在 ViewRoot.java 有關 CAMERA Key 的一段 code: private void dispatchKey(KeyEvent event, boolean sendDone) { //noinspection ConstantConditions if (false && event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) { if (Config.LOGD) Log.d("keydisp", "==================================================="); if (Config.LOGD) Log.d("keydisp", "Focused view Hierarchy is:"); debug(); if (Config.LOGD) Log.d("keydisp", "==================================================="); } } .... 如果把 false 拿掉,會印出有趣的 debug message,,,
D/keydisp ( 2642): =================================================== D/keydisp ( 2642): Focused view Hierarchy is: D/View ( 2642): + com.android.internal.policy.impl.PhoneWindow$DecorView@2ac72cc0 D/View ( 2642): frame={0, 0, 800, 480} scroll={0, 0} D/View ( 2642): mMeasureWidth=800 mMeasureHeight=480 D/Debug ( 2642): Contents of WM.LayoutParams{(0,0)(fillxfill) ty=1 fl=#790303 fmt=-2 wanim=0x1030001}: D/Debug ( 2642): ViewGroup.LayoutParams={ width=match-parent, height=match-parent } D/Debug ( 2642): WindowManager.LayoutParams={title=com.android.deskclock/com.android.deskclock.DeskClock} D/View ( 2642): flags={} D/View ( 2642): privateFlags={IS_ROOT_NAMESPACE HAS_BOUNDS DRAWN} D/View ( 2642): { D/View ( 2642): + android.widget.FrameLayout@2ac73900 (id=16908290) D/View ( 2642): frame={0, 0, 800, 480} scroll={0, 0} D/View ( 2642): mMeasureWidth=800 mMeasureHeight=480 D/View ( 2642): ViewGroup.LayoutParams={ width=match-parent, height=match-parent } D/View ( 2642): flags={} remain 0 unprocessed. D/View ( 2642): privateFlags={HAS_BOUNDS DRAWN} D/View ( 2642): { D/View ( 2642): + android.widget.FrameLayout@2ac74548 D/View ( 2642): frame={0, 0, 800, 480} scroll={0, 0} D/View ( 2642): mMeasureWidth=800 mMeasureHeight=480 D/View ( 2642): ViewGroup.LayoutParams={ width=match-parent, height=match-parent } D/View ( 2642): flags={} D/View ( 2642): privateFlags={HAS_BOUNDS DRAWN} D/View ( 2642): { D/View ( 2642): + android.widget.LinearLayout@2ac74bc0 (id=2131492882) D/View ( 2642): frame={0, 0, 800, 480} scroll={0, 0} D/View ( 2642): padding={0, 38, 0, 0} D/View ( 2642): mMeasureWidth=800 mMeasureHeight=480 D/View ( 2642): ViewGroup.LayoutParams={ width=match-parent, height=match-parent } 可以出來,目前的 Focuse App 是 com.android.deskclock/com.android.deskclock.DeskClock

2012年2月3日 星期五

Task :
A task is a collection of activities that users interact with when performing a certain job. 
http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html 所以task 是一堆 activity 的集合。
Application 是 apk.
application 裡面是一堆 component (Activity, Service, BroadcastReceiver...)。
當這個 application 的 component 被叫起來時, android 就會啟動這個 application。
做出 Launcher 長壓 HOME Key 的動作:
列出 N 個 recent task,按下後開啟該 task。

或先測試一下這用 "長按 HOME" 來切換 task 的方式,和不合用。
再作決定。


HomeLongPress 在 PhoneWindowManager.java Runnable mHomeLongPress = new Runnable() { public void run() { mHomePressed = false; performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS); showRecentAppsDialog(); } };
的 showRecentAppsDialog: void showRecentAppsDialog() { if (mRecentAppsDialog == null) { mRecentAppsDialog = new RecentApplicationsDialog(mContext); } mRecentAppsDialog.show(); }
所以實做就是在 RecentApplicationDialog( )


2012年2月2日 星期四

3g modem, rild & pppd

init.rc 啟動 rild 和 pppd: service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so socket rild stream 660 root radio socket rild-debug stream 660 radio system socket rild-ppp stream 660 radio system user root group radio cache inet misc audio service pppd_gprs /etc/init.gprs-pppd user root group radio cache inet misc disabled oneshot rild 的部份是直接 run rild (實際是去 run libreference-ril.so 的 Init)

rild 負責 modem 的初始化,語音撥撥號,接聽,modem 連線狀態維護 (連線中, operator, signal strength.. etc)。
pppd 則負責 ppp protocol,並形成 ppp0 這個 network interface

pppd 是 run script : /etc/init.gprs-pppd: PPPD_PID= /system/bin/setprop "net.gprs.ppp-exit" "" /system/bin/log -t pppd "Starting pppd" #/system/xbin/pppd $* # pppd was put into /system/bin instead of /system/xbin after SDK1.6 if ls /dev/ttyUSB0 > /dev/null 2>&1; then /system/bin/pppd connect 'chat -f "/etc/3gdata.conf"' /dev/ttyUSB3 115200 mru 1280 mtu 1280 nodetach debug dump defaultroute usepeerdns novj novjccomp noipdefault ipcp-accept-local ipcp-accept-remote connect-delay 5000 linkname ppp0 else /system/bin/pppd ttyACM0 921600 nodetach noauth noipdefault defaultroute usepeerdns linkname ppp0 connect "chat -v '' AT OK ATD*99***1# CONNECT" debug fi PPPD_EXIT=$? PPPD_PID=$! /system/bin/log -t pppd "pppd exited with $PPPD_EXIT" /system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT" .. 這個 file 在 /system/core/rootfs/etc/

script 是啟動 pppd ,在參數指定連接的動作,使用 chat: connect 'chat -f "/etc/3gdata.conf" ' 這樣寫是要 chat 使用 3gdata.conf 作 連線參數。
connect "chat -v ''AT OK ATD*99***1# CONNECT" 這樣寫是使用簡單是 chat 設定,所以直接寫出來。

chat 是一種 send - reply 對應的程式,會依照config 送 string,並且依照 config 檢查回應的string。

pppd 的 help 中,connet 的說明是: connect <p> Invoke shell command <p> to set up the serial line 就是另外 run script 'p' 來作建立連線的動作 (撥號)。

啟動 pppd 還要給的就是 pppd 對應的 3g modem data port number,一般會是 /dev/ttyUSB?

3g modem 會提供很多 ttyUSB port,每個有不同的功能
  1. AT Command 語音撥號
  2. ppp 資料
  3. AT Command 系統狀態
每一個廠家的port 對應都不一樣,所以要告訴 pppd 對哪一個 port 動作。

同理,撥號也一樣,如果撥號和 ppp 通訊在同一個,就可以寫在 這裡,叫 pppd 撥號。
如果 撥號 和 ppp 通訊在不同的 port,就不能請 pppd 做了 (也就沒有 connect 這個 參數)



port 是 支援 3g modem 時最麻煩的東西。
不同的 modem 有不同的 port 指定。
不僅 pppd 要知道對哪一個 port 動作, rild 也要知道。

舊版的 android,是把 port number 直接寫在 init.rc 的 啟動命令參數,所以要同時支持多個 3g modem 是不可能的。

新版修改了 rild reference-ril,會由 3g modem 的 vid, pid 知道是哪一個 modem,然後有一個內建的 table,決定 port。
所以只要有在 vid. pid table 中的 3g modem, rild 都可以正確動作。

* 但是這樣只有作半套...
pppd 的 port 還是由 init.rc 寫死,所以沒辦法依照 vid.pid 來決定。

iMX51 的 DDR D0-D31 driving strength setting

  1. IOMUXC_SW_PAD_CTL_GRP_DRAM_B0 (08A4) : DRAM_D0-- D7
  2. IOMUXC_SW_PAD_CTL_GRP_DRAM_B1 (08AC) : DRAM_D8-- D15
  3. IOMUXC_SW_PAD_CTL_GRP_DRAM_B2 (08B8) : DRAM_D16- D23
  4. IOMUXC_SW_PAD_CTL_GRP_DRAM_B4 (082C) : DRAM_D25- D31
最後 bit 2.1 是 driving strength
  1. 0.0 : Low
  2. 0.1 : Medium
  3. 1.0 : High
  4. 1.1 : Max
memory 的相關設定都是在 bootloader 做的,所以是在 board/freescale/imx51_bbg/flash_header.S MXC_DCD_ITEM(11,4, IOMUXC_BASE_ADDR + 0x8a4, 0x004) MXC_DCD_ITEM(12,4, IOMUXC_BASE_ADDR + 0x8ac, 0x004) MXC_DCD_ITEM(13,4, IOMUXC_BASE_ADDR + 0x8b8, 0x004) MXC_DCD_ITEM(14,4, IOMUXC_BASE_ADDR + 0x82c, 0x004) 都改最小的話,就是 0x000

標籤

網誌存檔