2010/12/30

android 遠端搖控 remote control -- keyevent

android 要遠端控制的話,大抵上是用 adb 來實作,這邊的遠端其實不是網路理論上的那種 client server....

話說回來,光看 adb 的說明,可能還感覺不出遠端控制的效用,但是底下資訊幫著看的話,效果就大不同:

adb shell input text wirelessadb
adb shell input keyevent 66

上面是會讓 android 輸入 wirelessadb 然後送 "enter" 鍵,通常輸入文字是搜尋,所以代表可以查 wirelessadb
為了幫助我那可憐的有限記憶,底下把 keyevent 中能用的 key code 簡單的列下來,有篇非常好的文章值得有興趣的人進一步去研讀:
0 --> "KEYCODE_UNKNOWN"
1 --> "KEYCODE_MENU"
2 --> "KEYCODE_SOFT_RIGHT"
3 --> "KEYCODE_HOME"
4 --> "KEYCODE_BACK"
5 --> "KEYCODE_CALL"
6 --> "KEYCODE_ENDCALL"
7 --> "KEYCODE_0"
8 --> "KEYCODE_1"
9 --> "KEYCODE_2"
10 --> "KEYCODE_3"
11 --> "KEYCODE_4"
12 --> "KEYCODE_5"
13 --> "KEYCODE_6"
14 --> "KEYCODE_7"
15 --> "KEYCODE_8"
16 --> "KEYCODE_9"
17 --> "KEYCODE_STAR"
18 --> "KEYCODE_POUND"
19 --> "KEYCODE_DPAD_UP"
20 --> "KEYCODE_DPAD_DOWN"
21 --> "KEYCODE_DPAD_LEFT"
22 --> "KEYCODE_DPAD_RIGHT"
23 --> "KEYCODE_DPAD_CENTER"
24 --> "KEYCODE_VOLUME_UP"
25 --> "KEYCODE_VOLUME_DOWN"
26 --> "KEYCODE_POWER"
27 --> "KEYCODE_CAMERA"
28 --> "KEYCODE_CLEAR"
29 --> "KEYCODE_A"
30 --> "KEYCODE_B"
31 --> "KEYCODE_C"
32 --> "KEYCODE_D"
33 --> "KEYCODE_E"
34 --> "KEYCODE_F"
35 --> "KEYCODE_G"
36 --> "KEYCODE_H"
37 --> "KEYCODE_I"
38 --> "KEYCODE_J"
39 --> "KEYCODE_K"
40 --> "KEYCODE_L"
41 --> "KEYCODE_M"
42 --> "KEYCODE_N"
43 --> "KEYCODE_O"
44 --> "KEYCODE_P"
45 --> "KEYCODE_Q"
46 --> "KEYCODE_R"
47 --> "KEYCODE_S"
48 --> "KEYCODE_T"
49 --> "KEYCODE_U"
50 --> "KEYCODE_V"
51 --> "KEYCODE_W"
52 --> "KEYCODE_X"
53 --> "KEYCODE_Y"
54 --> "KEYCODE_Z"
55 --> "KEYCODE_COMMA"
56 --> "KEYCODE_PERIOD"
57 --> "KEYCODE_ALT_LEFT"
58 --> "KEYCODE_ALT_RIGHT"
59 --> "KEYCODE_SHIFT_LEFT"
60 --> "KEYCODE_SHIFT_RIGHT"
61 --> "KEYCODE_TAB"
62 --> "KEYCODE_SPACE"
63 --> "KEYCODE_SYM"
64 --> "KEYCODE_EXPLORER"
65 --> "KEYCODE_ENVELOPE"
66 --> "KEYCODE_ENTER"
67 --> "KEYCODE_DEL"
68 --> "KEYCODE_GRAVE"
69 --> "KEYCODE_MINUS"
70 --> "KEYCODE_EQUALS"
71 --> "KEYCODE_LEFT_BRACKET"
72 --> "KEYCODE_RIGHT_BRACKET"
73 --> "KEYCODE_BACKSLASH"
74 --> "KEYCODE_SEMICOLON"
75 --> "KEYCODE_APOSTROPHE"
76 --> "KEYCODE_SLASH"
77 --> "KEYCODE_AT"
78 --> "KEYCODE_NUM"
79 --> "KEYCODE_HEADSETHOOK"
80 --> "KEYCODE_FOCUS"
81 --> "KEYCODE_PLUS"
82 --> "KEYCODE_MENU"
83 --> "KEYCODE_NOTIFICATION"
84 --> "KEYCODE_SEARCH"
85 --> "TAG_LAST_KEYCODE"

2010/12/28

svn server on win-xp

自從兩年多前寫過一篇 svn 至今,終於「穩定」下來了,現在來寫一下 subversion server 安裝的部份。

先轉述一篇好文章的話:
匪夷所思的是國內資訊軟體公司中的資訊工程師似乎對其非常陌生」,
沒有 CVS/SVN 這類版本控制工具,任何修改程式碼的動作都會增加 programmer 大腦記憶體的負擔, programmer 將會浪費許多時間在搜尋與比對程式碼的工作之上』


subversion 原先由 CollabNet 維護,目前由 Apache 納入其專案中,可以至 Apache Subversion 專案查詢相關資訊。


---server---


1. 下載: 自 VisualSVN 下載最新的 binary, 我目前抓到的是 2.1.5
2. 執行它....這不必我多說,它是個 MSI 檔,可以自動進行大部份自動安裝工作,內含 svn server 2.1.5, 及 apache 2.2.17, svn client 1.6.15
3. 在安裝中,我選的是『Use Windows authentication』,畫面如下

4. 安裝之後,會問你要不要執行 VisualSVN Server Manager, 可以不執行,也可以叫出來看,當然看完可以按右上角的叉叉關掉,背景的 server 仍然會一直跑。畫面如下:
5. 接下來算是要維持日常的 server 維護工作,第一件事當然就是準備倉庫給 client 使用。做法很簡單,透過上面的管理界面跟檔案總管非常相像的按右鍵新增即可,畫面如下。仔細看的話,其實我是在最上層用『Create New Repository」新增了 EE1 這個倉庫,並在其下用『新增』『Project Structure』的方式新增了 android-testsuite 及 mfg-dll 兩個專案:
6. 檢查一下硬碟。根據上面的設定,我是把倉庫(Repository)放在 D:\SVN, 會發現 D:\SVN 確實有 EE1, 可是 D:\SVN\EE1\ 卻沒有 android-testsuite, 或是 mfg-dll 兩個目錄!!! 這是為什麼?原因是 EE1 是倉庫,而 android-testsuite, mfg-dll 兩個只是倉庫中的存貨。所有存貨都是在版本控制內的實體,而 subversion 並不是依靠存實體檔案的方式來控管,因此,請勿自行處理 D:\SVN\ 下面的目錄或檔案,這樣很容易損毀 subversion server system.

7, 接下來就是 client 端的操作了,可以看我那篇 svn 裡面的『TortoiseSVN (Client端) 使用流程』 一節。或是繼續往下看

---client---

1. 上傳新專案,通常新專案都是寫好一堆檔案了,此時可以一批次的上傳,在裝好 subversion client 之後,在要上傳的目錄按滑鼠右鍵,選擇 TortoiseSVN-->Import 即可,畫面如下

2. 在 Import 畫面照理說,應該填上面 server Manager 新增出來的倉庫網址,不過我習慣在一個倉庫裡放不同的 Project,其觀念與正統版本控制不太相符,但是帳號比較好管理。畫面如下:
  值得注意的是,我在硬碟中的目錄名稱是 SDC_FactoryDLL,而在 svn server  放的卻是 mfg-dll ,兩個可以是不一致。而完整的 subversion url 是 https://an970100770.quanta.corp:8443/svn/EE1/mfg-dll 而不是倉庫 url https://an970100770.quanta.corp:8443/svn/EE1

3. 如此一來,svn server 已經有所有檔案,而你原來上傳的目錄是在尚未管理的原始狀態。我這麼說你可能不是很懂,底下有兩個作法可以讓你體驗,看你喜歡哪一種挑選之實作一下:
  a. 刪除原來的整個目錄
  b. 選一個跟原來的目錄不同層的新工作目錄
然後.....在新工作目錄下,用滑鼠右鍵選 SVN Checkout, 在 url of repository 中填入 https://an970100770.quanta.corp:8443/svn/EE1/mfg-dll 即可完成工作,不過 Checkout Directory 則仍然會是倉庫的網址,我是另外存到相對應的目錄。畫面如下。當然第一次免不了要輸入帳號密碼。因為我在設定 svnserver 時用的是 windows 的認證機制,因此請填入你登入 windows 的帳號密碼即可。


檢查一下新下載的目錄,會發現每一層新的目錄都會多了一個 .svn 的子目錄,代表目前正受版本控制當中。

4. 若你想移除檔案的話,請不要直接刪除,而是透過 TortoiseSVN-->delete 來操作,因為這樣才會通知 server 做刪檔動作,若只是透過檔案總管操作刪檔的話,server  並不知道你要刪檔,這樣一來下次與系統同步更新時又會把你想刪除的檔抓下來。

5. 當你修改完程式之後,可以在檔案總管發現目錄變成紅色的驚嘆號,代表該目錄已經有被更動,你可以選擇馬上上傳到 server, 或是等工作到一段落後再上傳,畫面如下:



6. 所謂上傳到 svn server, 其實就是 svn commit 命令,畫面如下
7. 以上已經可以完成大部份的工作....不過最強的不是上傳檔案,否則你大概也會想說還不如直接壓縮來放就好。我們來看看一個基本的操作,跟前一版比對,畫面如下:
你可以發現右邊是新版的,它把變動的部份用黃色標註出來了

8. 若養成好習慣的話,每次上傳更新檔時都寫 log 訊息的話,這樣你可以透過 svn log 去取得上傳的 log 訊息,畫面如下:

9. 這樣一來,你知道了每次的更改,也就能隨時回到你想要的版本去,畫面中有個選項我一直沒提,就是 HEAD, 這代表最新的版本,例如我要回到「最原始」的狀態,以這邊來說是 revision 12....那就 checkout 的畫面填入 12, 要回到最新的版本,就勾選 HEAD, 勾選回到 revision 13 的畫面如下:


2010/12/27

android eclipse setup for ubuntu 10.10 64bit

寫過一篇android build on ubuntu 10.10,其實早就寫好關於 android app 的部份,只是並非寫在這兒,底下就貼一下。

* URL: http://developer.android.com/sdk/index.html
* Quick Start
  o Prepare your development computer
  o Download and install the SDK starter package
  o Install the ADT Plugin for Eclipse
  o Add Android platforms and other components to your SDK

Install Android SDK, Java, Eclipse

  * Host Environment: Ubuntu 10.04
  * Eclipse: sudo apt-get install eclipse eclipse-jdt
  * Start Eclipse:
    o 應用程式 ==> 軟體開發 ==> eclipse

Install ADT with Eclipse v3.5(Galileo)

  * URL: http://developer.android.com/sdk/eclipse-adt.html
  * Start Eclipse, then select Help > Install New Software.
  * In the Available Software dialog, click Add....
  * In the "Name" field: Android Plugin
  * In the "Location" field:
     https://dl-ssl.google.com/android/eclipse/
  * Click OK.
  * In the Available Software view:
    o Check the Developer Tools
      + Make sure check Android DDMS and Android Development Tools.
    o Click Next.
  * Click Next to read and accept the license agreement and install any dependencies, then click Finish.
  * Restart Eclipse.

Configuring the ADT Plugin

  * Select Window > Preferences
  * Select Android from the left panel.
  * SDK Location ==> click Browse ==> locate your downloaded SDK directory, such as "/home/wade/src/android/android-sdk-linux_86"
  * Click Apply, then OK.

Adding Android Platforms and Other...

  * URL: http://developer.android.com/sdk/adding-components.html
  * Windows --> Android SDK & AVD Manager

Install a Platform

  * In the Android SDK and AVD Manager, choose Available Packages in the left panel.
  * Click the repository site checkbox to display the components available for installation.
  * Select at least one platform to install, and click Install Selected. If you aren't sure which platform to install, use the latest version.

Create an AVD(做一次就好)

  * In Eclipse, choose Window > Android SDK and AVD Manager.
  * Select Virtual Devices in the left panel.
  * Click New.
     The Create New AVD dialog appears.
  * Type the name of the AVD, such as "my_avd".
  * Choose a target. The target is the platform (that is, the version of the Android SDK, such as 2.1) you want to run on the emulator.
      You can ignore the rest of the fields for now.
  * Click Create AVD.

Create a New Android Project

  * From Eclipse, select File > New > Project.
  * Select "Android" -> "Android Project" and click Next.
  * Fill in the project details with the following values:
    o Project name: HelloAndroid
    o Application name: Hello, Android
    o Package name: com.example.helloandroid (or your own private namespace)
    o Create Activity: HelloAndroid
    o Click Finish.

Construct the UI

Run the Application

  The Eclipse plugin makes it easy to run your applications:
  * Select Run > Run.
  * Select "Android Application".
    o Select Target Device
    o Project > Properties > Run/Debug Settings > Edit > Target > ....
  * For the first time to run android app, it will show "Select a way to run ...".
     Please select "Android Application"

Start Emulator(有兩個方法)

# Eclipse
  * By Project-->Run to start emulator with installation app
  * Window --> Android SDK and AVD Manager --> Virtual Devices, and then....
Select a device --> Start

# Command Line
  * $ export DISPLAY=:0.0
  $ emulator -system system.img -data userdata.img -ramdisk ramdisk.img

wifi 二三事

底下內容其實要找相關文獻很容易,我也一直懶得寫,但是剛好看到有人寫英文的,就順手翻譯下來。本文目的就是在命令列處理無線網路。底下的命令幾乎都要 root 權限,請自行取得,或是前面加上 sudo

.第一步是先透過 ifconfig -a 來查無線網路的裝置,不同的 Linux distribution 或是不同的無線網卡會有不同的命名方式,有的是 eth1, 有的是 wlan0,底下就假設是 wlan0
.再來用 iwlist wlan0 scan 來掃瞄 Access Point,舉例如下:
Cell 01 - Address: 00:11:22:33:44:55
          ESSID:"network-essid"
          Mode:Master
          Channel:11
          Frequency:2.462 GHz (Channel 11)
          Quality=100/100  Signal level:-47dBm  Noise level=-100dBm
          Encryption key:off
          .
          .
          .
.接下來可以用 iwconfig 來設定 essid, iwconfig wlan0 essid network-essid
.說穿了,就是用 iwconfig 來設定,還有很多項目可以設定,譬如頻率: iwconfig wlan0 freq 2.422G, or...
.以 channel 的方式來設定頻率相關資訊: iwconfig wlan0 channel 3,
.若在吵雜的環境中上網不良,可以試試修改「重試」次數: iwconfig wlan0 retry 16
.訊息不良的環境,甚至需要把封包切分小單位,譬如 iwconfig wlan0 frag 512
.有些網路卡不會馬上生效,必須加上這個: iwconfig wlan0 commit

以上用 iwconfig 來設定的全部選項可以放在一起,另外還有兩個命令可以用來幫助你 debug 無線網卡,一個是 iwspy 及 iwpriv

2010/12/24

monkey 又一章

寫過一篇Monkey 教學文件,不過那篇算是抄來的。

在 android /data/system/ 下有一個檔叫 packages.xml, 打開來看,會看到很多安裝的套件資訊,舉例來說,你可以找 <package 開頭的部份來看,此時你就可以知道有哪些套件可以進行 monkey 測試。

底下擷取部份內容說明一下....例如 第一個 <package name="com.android.soundrecorder" codePath="/system/app/SoundRecorder.apk"....

此時可以下 monkey -p com.android.soundrecorder -v 50 來對錄音軟體進行測試

<packages>
<package name="com.android.soundrecorder" codePath="/system/app/SoundRecorder.apk" nativeLibraryPath="/data/data/com.android.soundrecorder/lib" flags="1" ft="12d124faa98" it="12d124faa98" ut="12d124faa98" version="9" userId="10006">
<package name="android" codePath="/system/framework/framework-res.apk" flags="1" ft="12d12461578" it="12d12461578" ut="12d12461578" version="9" sharedUserId="1000">
<package name="com.android.launcher" codePath="/system/app/Launcher2.apk" nativeLibraryPath="/data/data/com.android.launcher/lib" flags="1" ft="12d124fae80" it="12d124fae80" ut="12d124fae80" version="9" userId="10023">
<package name="com.android.defcontainer" codePath="/system/app/DefaultContainerService.apk" nativeLibraryPath="/data/data/com.android.defcontainer/lib" flags="1" ft="12d124f7fa0" it="12d124f7fa0" ut="12d124f7fa0" version="9" userId="10024">
<package name="com.android.providers.contacts" codePath="/system/app/ContactsProvider.apk" nativeLibraryPath="/data/data/com.android.providers.contacts/lib" flags="1" ft="12d124f7fa0" it="12d124f7fa0" ut="12d124f7fa0" version="9" sharedUserId="10010">
<package name="com.android.settings" codePath="/system/app/Settings.apk" nativeLibraryPath="/data/data/com.android.settings/lib" flags="1" ft="12d1250bff0" it="12d1250bff0" ut="12d1250bff0" version="9" sharedUserId="1000">
<package name="com.android.quicksearchbox" codePath="/system/app/QuickSearchBox.apk" nativeLibraryPath="/data/data/com.android.quicksearchbox/lib" flags="1" ft="12d12496520" it="12d12496520" ut="12d12496520" version="110" userId="10028">
<package name="com.android.protips" codePath="/system/app/Protips.apk" nativeLibraryPath="/data/data/com.android.protips/lib" flags="1" ft="12d12547cf8" it="12d12547cf8" ut="12d12547cf8" version="1" userId="10026">
<package name="com.android.providers.applications" codePath="/system/app/ApplicationsProvider.apk" nativeLibraryPath="/data/data/com.android.providers.applications/lib" flags="1" ft="12d124f6c18" it="12d124f6c18" ut="12d124f6c18" version="9" sharedUserId="10010">
<package name="com.android.contacts" codePath="/system/app/Contacts.apk" nativeLibraryPath="/data/data/com.android.contacts/lib" flags="1" ft="12d1253b9a8" it="12d1253b9a8" ut="12d1253b9a8" version="9" sharedUserId="10010">
<package name="com.android.inputmethod.latin" codePath="/system/app/LatinIME.apk" nativeLibraryPath="/data/data/com.android.inputmethod.latin/lib" flags="1" ft="12d12548c98" it="12d12548c98" ut="12d12548c98" version="9" userId="10001">
<package name="com.android.phone" codePath="/system/app/Phone.apk" nativeLibraryPath="/data/data/com.android.phone/lib" flags="1" ft="12d12501028" it="12d12501028" ut="12d12501028" version="9" sharedUserId="1001">
<package name="com.android.calculator2" codePath="/system/app/Calculator.apk" nativeLibraryPath="/data/data/com.android.calculator2/lib" flags="1" ft="12d12549080" it="12d12549080" ut="12d12549080" version="9" userId="10014">
<package name="com.android.providers.drm" codePath="/system/app/DrmProvider.apk" nativeLibraryPath="/data/data/com.android.providers.drm/lib" flags="1" ft="12d124f8f40" it="12d124f8f40" ut="12d124f8f40" version="9" sharedUserId="10016">
<package name="com.android.htmlviewer" codePath="/system/app/HTMLViewer.apk" nativeLibraryPath="/data/data/com.android.htmlviewer/lib" flags="1" ft="12d124f9710" it="12d124f9710" ut="12d124f9710" version="9" userId="10017">
<package name="com.android.systemui" codePath="/system/app/SystemUI.apk" nativeLibraryPath="/data/data/com.android.systemui/lib" flags="1" ft="12d1254bf60" it="12d1254bf60" ut="12d1254bf60" version="9" sharedUserId="1000">
<package name="com.android.term" codePath="/system/app/Term.apk" nativeLibraryPath="/data/data/com.android.term/lib" flags="1" ft="12d124fc9d8" it="12d124fc9d8" ut="12d124fc9d8" version="9" userId="10018">
<package name="com.android.providers.calendar" codePath="/system/app/CalendarProvider.apk" nativeLibraryPath="/data/data/com.android.providers.calendar/lib" flags="1" ft="12d124f7bb8" it="12d124f7bb8" ut="12d124f7bb8" version="9" sharedUserId="10012">
<package name="com.android.bluetooth" codePath="/system/app/Bluetooth.apk" nativeLibraryPath="/data/data/com.android.bluetooth/lib" flags="1" ft="12d125459d0" it="12d125459d0" ut="12d125459d0" version="9" userId="10022">
<package name="com.android.speechrecorder" codePath="/system/app/SpeechRecorder.apk" nativeLibraryPath="/data/data/com.android.speechrecorder/lib" flags="1" ft="12d124fc208" it="12d124fc208" ut="12d124fc208" version="9" userId="10015">
<package name="com.android.development" codePath="/system/app/Development.apk" nativeLibraryPath="/data/data/com.android.development/lib" flags="1" ft="12d12544648" it="12d12544648" ut="12d12544648" version="1" userId="10000">
<package name="com.android.packageinstaller" codePath="/system/app/PackageInstaller.apk" nativeLibraryPath="/data/data/com.android.packageinstaller/lib" flags="1" ft="12d124fae80" it="12d124fae80" ut="12d124fae80" version="9" userId="10027">
<package name="com.android.calendar" codePath="/system/app/Calendar.apk" nativeLibraryPath="/data/data/com.android.calendar/lib" flags="1" ft="12d125461a0" it="12d125461a0" ut="12d125461a0" version="9" userId="10003">
<package name="com.android.providers.telephony" codePath="/system/app/TelephonyProvider.apk" nativeLibraryPath="/data/data/com.android.providers.telephony/lib" flags="1" ft="12d124fc9d8" it="12d124fc9d8" ut="12d124fc9d8" version="9" sharedUserId="1001">
<package name="com.android.browser" codePath="/system/app/Browser.apk" nativeLibraryPath="/data/data/com.android.browser/lib" flags="1" ft="12d124f8388" it="12d124f8388" ut="12d124f8388" version="9" userId="10002">
<package name="com.android.providers.subscribedfeeds" codePath="/system/app/AccountAndSyncSettings.apk" nativeLibraryPath="/data/data/com.android.providers.subscribedfeeds/lib" flags="1" ft="12d124f6c18" it="12d124f6c18" ut="12d124f6c18" version="9" sharedUserId="1000">
<package name="com.android.music" codePath="/system/app/Music.apk" nativeLibraryPath="/data/data/com.android.music/lib" flags="1" ft="12d125484c8" it="12d125484c8" ut="12d125484c8" version="9" userId="10008">
<package name="com.android.camera" codePath="/system/app/Camera.apk" nativeLibraryPath="/data/data/com.android.camera/lib" flags="1" ft="12d12546970" it="12d12546970" ut="12d12546970" version="1" userId="10011">
<package name="com.svox.pico" codePath="/system/app/PicoTts.apk" nativeLibraryPath="/data/data/com.svox.pico/lib" flags="1" ft="12d124fb268" it="12d124fb268" ut="12d124fb268" version="1" userId="10021">
<package name="com.cooliris.media" codePath="/system/app/Gallery3D.apk" nativeLibraryPath="/data/data/com.cooliris.media/lib" flags="1" ft="12d12549468" it="12d12549468" ut="12d12549468" version="30682" userId="10013">
<package name="com.android.email" codePath="/system/app/Email.apk" nativeLibraryPath="/data/data/com.android.email/lib" flags="1" ft="12d124fa6b0" it="12d124fa6b0" ut="12d124fa6b0" version="230000" userId="10020">
<package name="com.android.providers.downloads.ui" codePath="/system/app/DownloadProviderUi.apk" nativeLibraryPath="/data/data/com.android.providers.downloads.ui/lib" flags="1" ft="12d124f8f40" it="12d124f8f40" ut="12d124f8f40" version="9" sharedUserId="10016">
<package name="com.android.providers.userdictionary" codePath="/system/app/UserDictionaryProvider.apk" nativeLibraryPath="/data/data/com.android.providers.userdictionary/lib" flags="1" ft="12d124fcdc0" it="12d124fcdc0" ut="12d124fcdc0" version="9" sharedUserId="10010">
<package name="com.android.spare_parts" codePath="/system/app/SpareParts.apk" nativeLibraryPath="/data/data/com.android.spare_parts/lib" flags="1" ft="12d124fbe20" it="12d124fbe20" ut="12d124fbe20" version="9" userId="10005">
<package name="com.android.deskclock" codePath="/system/app/DeskClock.apk" nativeLibraryPath="/data/data/com.android.deskclock/lib" flags="1" ft="12d12547528" it="12d12547528" ut="12d12547528" version="202" userId="10009">
<package name="com.android.providers.settings" codePath="/system/app/SettingsProvider.apk" nativeLibraryPath="/data/data/com.android.providers.settings/lib" flags="1" ft="12d124fba38" it="12d124fba38" ut="12d124fba38" version="9" sharedUserId="1000">
<package name="android.tts" codePath="/system/app/TtsService.apk" nativeLibraryPath="/data/data/android.tts/lib" flags="1" ft="12d124fcdc0" it="12d124fcdc0" ut="12d124fcdc0" version="9" userId="10019">
<package name="com.android.mms" codePath="/system/app/Mms.apk" nativeLibraryPath="/data/data/com.android.mms/lib" flags="1" ft="12d124fbe20" it="12d124fbe20" ut="12d124fbe20" version="9" userId="10025">
<package name="com.android.provision" codePath="/system/app/Provision.apk" nativeLibraryPath="/data/data/com.android.provision/lib" flags="1" ft="12d124fb268" it="12d124fb268" ut="12d124fb268" version="9" userId="10004">
<package name="com.android.providers.media" codePath="/system/app/MediaProvider.apk" nativeLibraryPath="/data/data/com.android.providers.media/lib" flags="1" ft="12d124f9af8" it="12d124f9af8" ut="12d124f9af8" version="9" sharedUserId="10016">
<package name="com.android.providers.downloads" codePath="/system/app/DownloadProvider.apk" nativeLibraryPath="/data/data/com.android.providers.downloads/lib" flags="1" ft="12d124f8b58" it="12d124f8b58" ut="12d124f8b58" version="9" sharedUserId="10016">
<package name="com.android.certinstaller" codePath="/system/app/CertInstaller.apk" nativeLibraryPath="/data/data/com.android.certinstaller/lib" flags="1" ft="12d124f77d0" it="12d124f77d0" ut="12d124f77d0" version="9" userId="10007">
<package name="com.android.server.vpn" codePath="/system/app/VpnServices.apk" nativeLibraryPath="/data/data/com.android.server.vpn/lib" flags="1" ft="12d124fd1a8" it="12d124fd1a8" ut="12d124fd1a8" version="9" sharedUserId="1000">
</packages>

2010/11/11

android monkey 用法範例

文章原來源已遺失,好像類似情形不少,所以無法貼原文網址,原作者叫「俊傑」,感謝他:

Android 中Monkey的用法

簡介

Monkey是一個命令行工具,可以運行在模擬器裡或實際設備中。它向系統發送偽隨機的用戶事件流,實現對正在開發的應用程序進行壓力測試。Monkey包括許多選項,它們大致分為四大類:
  • 基本配置選項,如設置嘗試的事件數量。
  • 運行約束選項,如設置只對單獨的一個包進行測試。
  • 事件類型和頻率。
  • 調試選項。
在Monkey運行的時候,它生成事件,並把它們發給系統。 同時,Monkey還對測試中的系統進行監測,對下列三種情況進行特殊處理:
  • 如果限定了Monkey運行在一個或幾個特定的包上,那麼它會監測試圖轉到其它包的操作,並對其進行阻止。
  • 如果應用程序崩潰或接收到任何失控異常,Monkey將停止並報錯。
  • 如果應用程序產生了應用程序不響應(application not responding)的錯誤,Monkey將會停止並報錯。
按照選定的不同級別的反饋信息,在Monkey中還可以看到其執行過程報告和生成的事件。 Monkey基本用法 可以通過開發機器上的命令行或腳本來啟動Monkey。 由於Monkey運行在模擬器/設備環境中,所以必須用其環境中的shell來進行啟動。 可以通過在每條命令前加上adb shell來達到目的,也可以進入Shell後直接輸入Monkey命令。 基本語法如下: $ adb shell monkey [options] 如果不指定 options,Monkey將以無反饋模式啟動,並把事件任意發送到安裝在目標環境中的全部包。 下面是一個更為典型的命令行示例,它啟動指定的應用程序,並向其發送500個偽隨機事件: $ adb shell monkey -p your.package.name -v 500 命令選項參考 下表中列出了Monkey命令行可用的全部選項。
  • --help
    列出簡單的用法。
  • -v
    命令行的每一個-v將增加反饋信息的級別。Level 0(缺省值)除啟動提示、測試完成和最終結果之外,提供較少信息。Level 1提供較為詳細的測試信息,如逐個發送到Activity的事件。Level 2提供更加詳細的設置信息,如測試中被選中的或未被選中的Activity。
    事件
  • -s
    偽隨機數生成器的seed值。如果用相同的seed值再次運行Monkey,它將生成相同的事件序列。
  • --throttle
    在事件之間插入固定延遲。通過這個選項可以減緩Monkey的執行速度。如果不指定該選項,Monkey將不會被延遲,事件將儘可能快地被產成。
  • --pct-touch
    調整觸摸事件的百分比(觸摸事件是一個down-up事件,它發生在屏幕上的某單一位置)。
  • --pct-motion
    調整動作事件的百分比(動作事件由屏幕上某處的一個down事件、一系列的偽隨機事件和一個up事件組成)。
  • --pct-trackball
    調整軌跡事件的百分比(軌跡事件由一個或幾個隨機的移動組成,有時還伴隨有點擊)。
  • --pct-nav
    調整「基本」導航事件的百分比(導航事件由來自方向輸入設備的up/down/left/right組成)。
  • --pct-majornav
    調整「主要」導航事件的百分比(這些導航事件通常引發圖形界面中的動作,如:5-way鍵盤的中間按鍵、回退按鍵、菜單按鍵)
  • --pct-syskeys
    調整「系統」按鍵事件的百分比(這些按鍵通常被保留,由系統使用,如Home、Back、Start Call、End Call及音量控制鍵)。
  • --pct-appswitch
    調整啟動Activity的百分比。在隨機間隔裡,Monkey將執行一個startActivity()調用,作為最大程度覆蓋包中全部Activity的一種方法。
  • --pct-anyevent
    調整其它類型事件的百分比。它包羅了所有其它類型的事件,如:按鍵、其它不常用的設備按鈕、等等。
    約束限制
  • -p
    如果用此參數指定了一個或幾個包,Monkey將只允許系統啟動這些包裡的Activity。如果你的應用程序還需要訪問其它包裡的Activity(如選擇取一個聯繫人),那些包也需要在此同時指定。如果不指定任何包,Monkey將允許系統啟動全部包裡的Activity。要指定多個包,需要使用多個 -p選項,每個-p選項只能用於一個包。
  • -c
    如果用此參數指定了一個或幾個類別,Monkey將只允許系統啟動被這些類別中的某個類別列出的Activity。如果不指定任何類別,Monkey將選 擇下列類別中列出的Activity: Intent.CATEGORY_LAUNCHER或Intent.CATEGORY_MONKEY。要指定多個類別,需要使用多個-c選項,每個-c選 項只能用於一個類別。
    調試
  • --dbg-no-events
    設置此選項,Monkey將執行初始啟動,進入到一個測試Activity,然後不會再進一步生成事件。為了得到最佳結果,把它與-v、一個或幾個包約 束、以及一個保持Monkey運行30秒或更長時間的非零值聯合起來,從而提供一個環境,可以監視應用程序所調用的包之間的轉換。
  • --hprof
    設置此選項,將在Monkey事件序列之前和之後立即生成profiling報告。這將會在data/misc中生成大文件(~5Mb),所以要小心使用它。
  • --ignore-crashes
    通常,當應用程序崩潰或發生任何失控異常時,Monkey將停止運行。如果設置此選項,Monkey將繼續向系統發送事件,直到計數完成。
  • --ignore-timeouts
    通常,當應用程序發生任何超時錯誤(如「Application Not Responding」對話框)時,Monkey將停止運行。如果設置此選項,Monkey將繼續向系統發送事件,直到計數完成。
  • --ignore-security-exceptions
    通常,當應用程序發生許可錯誤(如啟動一個需要某些許可的Activity)時,Monkey將停止運行。如果設置了此選項,Monkey將繼續向系統發送事件,直到計數完成。
  • --kill-process-after-error
    通常,當Monkey由於一個錯誤而停止時,出錯的應用程序將繼續處於運行狀態。當設置了此選項時,將會通知系統停止發生錯誤的進程。注意,正常的(成功的)結束,並沒有停止啟動的進程,設備只是在結束事件之後,簡單地保持在最後的狀態。
  • --monitor-native-crashes
    監視並報告Android系統中本地代碼的崩潰事件。如果設置了--kill-process-after-error,系統將停止運行。
  • --wait-dbg
    停止執行中的Monkey,直到有調試器和它相連接。
接下來看一個實例 Monkey 的用法是$ adb shell monkey -p your.package.name -v 500 首先,我們要找到應用程序在Emulator中所對應的包名,我一開始是一個個目錄找的,前7步完成了這項工作,最終發現應用程序包都在 data/data下,你可以在shell中cd data/data,然後ls查看當前Emulator中的所有應用程序包。 假如我們想對SDK中的APIDemos做壓力測試,
  1. 在Eclipse中新建工程,將

    F:\android-sdk-windows\platforms\android-2.0\samples\ApiDemos添加到工程中點擊運行,此時,他的APK應該加載到了Emulator上

  2. 在命令行輸入adb shell

  3. 輸入ls查看當前文件夾下的目錄,執行結果如下

    C:\Documents and Settings\Administrator>adb shell
    # ls
    ls
    sqlite_stmt_journals
    config
    cache
    sdcard
    d
    etc
    system
    sys
    sbin
    proc
    init.rc
    init.goldfish.rc
    init
    default.prop
    data
    root
    dev

  4. 應用程序包都在data下,我們輸入cd data進入data文件夾,如下

    # cd data
    cd data
    
  5. 輸入ls查看文件夾下的內容,如下所示:

    # ls
    ls
    misc
    local
    data
    app-private
    app
    property
    anr
    backup
    dontpanic
    dalvik-cache
    system
    lost+found

  6. 還有個data,所有的應用程序就在這個data下了,進入這個data,然後輸入ls如下:

    # cd data
    cd data
    # ls
    ls
    com.android.mms
    com.android.providers.applications
    com.android.globalsearch
    com.android.calculator2
    com.android.spare_parts
    com.android.gesture.builder
    com.android.music
    com.android.sdksetup
    com.android.packageinstaller
    com.android.fallback
    com.android.providers.settings
    com.android.providers.drm
    com.android.development
    com.android.providers.telephony
    com.android.inputmethod.pinyin
    com.android.htmlviewer
    com.android.settings
    com.android.netspeed
    com.android.providers.userdictionary
    com.android.browser
    com.android.contacts
    com.android.alarmclock
    com.android.camera
    com.android.providers.contacts
    jp.co.omronsoft.openwnn
    com.android.launcher
    com.android.phone
    com.android.soundrecorder
    com.google.android.providers.enhancedgooglesearch
    com.svox.pico
    com.android.customlocale
    com.android.term
    com.android.providers.downloads
    com.android.providers.media
    com.android.email
    android.tts
    com.android.inputmethod.latin
    com.android.server.vpn
    com.example.android.apis

  7. 最後一個就是我們剛才加載的APIDemo的應用程序包

  8. 可以直接輸入monkey -p com.example.android.apis -v 50,結果如下,也可以退出shell,在命令行輸入,adb shell monkey -p com.example.android.apis -v 50 ,運行過程中,Emulator中的應用程序在不斷地切換畫面,可以看一下,呵呵:)

    # monkey -p com.example.android.apis -v 50
    monkey -p com.example.android.apis -v 50
    :Monkey: seed=0 count=50
    :AllowPackage: com.example.android.apis
    :IncludeCategory: android.intent.category.LAUNCHER
    :IncludeCategory: android.intent.category.MONKEY
    // Event percentages:
    //   0: 15.0%
    //   1: 10.0%
    //   2: 15.0%
    //   3: 25.0%
    //   4: 15.0%
    //   5: 2.0%
    //   6: 2.0%
    //   7: 1.0%
    //   8: 15.0%
    :Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.categ
    ory.LAUNCHER;launchFlags=0x10000000;component=com.example.android.apis/.ApiDemos
    ;end
        // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.in
    tent.category.LAUNCHER] cmp=com.example.android.apis/.ApiDemos } in package com.
    example.android.apis
    :Sending Pointer ACTION_MOVE x=-4.0 y=2.0
    :Sending Pointer ACTION_UP x=0.0 y=0.0
        // Allowing start of Intent { cmp=com.example.android.apis/.ApiDemos } in pa
    ckage com.example.android.apis
    :Sending Pointer ACTION_DOWN x=207.0 y=282.0
    :Sending Pointer ACTION_UP x=189.0 y=289.0
        // Allowing start of Intent { cmp=com.example.android.apis/.app.Intents } in
    package com.example.android.apis
    :Sending Pointer ACTION_DOWN x=95.0 y=259.0
    :Sending Pointer ACTION_UP x=95.0 y=259.0
    :Sending Pointer ACTION_DOWN x=295.0 y=223.0
    :Sending Pointer ACTION_UP x=290.0 y=213.0
    :Sending Pointer ACTION_MOVE x=-5.0 y=3.0
    :Dropped: keys=0 pointers=0 trackballs=0 flips=0
    ## Network stats: elapsed time=3799ms (3799ms mobile, 0ms wifi, 0ms not connecte
    d)
    // Monkey finished

2010/11/10

windows 上跑 adb 簡介

Android 基本上都可以透過 adb 從外面跟 DUT 溝通,可以參考 http://developer.android.com/guide/developing/tools/adb.html 的說明。
adb 只是 Android SDK 的一個工具,可以從 http://dl.google.com/android/android-sdk_r07-windows.zip 下載,或是從 http://developer.android.com/sdk/index.html 查最新的版本

網頁上文件說的很複雜,因為那是教人寫 Android Application 的文件,基本上最簡單的做法就是:
0. 安裝 windows 端的 android usb driver,這一步可能你們已經安裝了,可以把 DUT 插到 PC 上看能不能抓到裝置就知道了,若是未認得的裝置,再來安裝usb driver
1. 從上面的網址下載 SDK
2. 解開壓縮檔,譬如放在 android-sdk-windows 下
3. 直接進入 android-sdk-windows\tools 下用 cmd mode 的視窗(就是執行cmd.exe) 執行adb 即可

底下簡介一下 adb 的使用,當然都是在 cmd mode 下執行, 為了方便我底下說明,把要安裝的 TestSuite.apk 放在 C:\ android-sdk-windows\tools 下,可以依實際位置修改底下的命令:
  • C:\ android-sdk-windows\tools > adb devices <-- 查連接的 android devices,請先接一台就好
  • C:\ android-sdk-windows\tools > adb shell ls / <-- 遠端在 DUT 上的命令,假設只有連接一台,這個命令範例類似 dir C:\ 之意
  • C:\ android-sdk-windows\tools > adb push .\TestSuite.apk /data/TestSuite.apk <-- 將 TestSuite 從外面放到 DUT 上
  • C:\ android-sdk-windows\tools > adb install /data/TestSuite.apk <-- 要執行過上面的命令才能執行此命令。安裝後那台 DUT 就可以看到 TestSuite 的應用程式圖示
  • C:\ android-sdk-windows\tools > adb pull /proc/meminfo <-- 這樣可以抓到 DUT 上的 /proc/meminfo 這個檔,那是抓的當時 DUT 記憶體使用狀況
  • C:\ android-sdk-windows\tools > adb logcat <-- DUT 在執行應用程式時,通常會產生一堆的 標準log, 可以用這個命令抓下來,但是這個命令不會停止,若要離開請用 Ctrl-C 中斷它
  • C:\ android-sdk-windows\tools > adb reboot recovery <-- 可以讓 DUT 重開機進入 Recovery mode


Windows 上的 usb driver, 可以自 http://dl.google.com/android/repository/usb_driver_r03-windows.zip 取得,問題是網路上很難查到這樣的網址,這邊公佈一下我找的方法:

首先,取得 http://dl.google.com/android/repository/repository.xml,這個檔就是 android 的倉庫清單,剩下的就簡單了,譬如....裡面有一筆 <sdk:url>usb_driver_r03-windows.zip</sdk:url>,這樣就可以查到剛剛上面貼的 url: http://dl.google.com/android/repository/usb_driver_r03-windows.zip

2010/11/08

一個簡單的硬碟效能測試 -- dd

dd 是一個很特別的指令,尤其在 android 中並沒有 cp 存在,只有 dd....
當然,我會這樣說,就是可以用dd 來複製檔案,大家也都會 dd if=SOURCE of=TARGET 即可,底下再說一點點它特別之處

dd if=/dev/fd0 of=/home/sam/MBRboot.image bs=512 count=2
上面這樣可以將軟碟片的前面 512x2==1024 個 byte 讀出來,寫成一個新檔案叫 MBRboot.image

dd if=/dev/sda of=/home/sam/MBR.image bs=512 count=1
上面也是一樣道理,可以把硬體的開機磁區寫到一個新檔案叫 MBR.image

所謂的硬碟開機磁區,就是一個 partition table + boot code, 若您只需要 boot code, 可以用下面的方法:
dd if=/dev/sda of=/home/sam/MBR_boot.image bs=446 count=1

那還有沒有其他用法?
dd if=/dev/uramdom bs=1024 count=1000000 of=/home/sam/1Gb.file
dd if=/home/sam/1Gb.file bs=64k | dd of=/dev/null
上面的方法可以用來簡單測試硬碟效能,也就是你搭配將上面兩行寫成一個 shell, 再搭配 time 來量時間
若不想用 /dev/uramdom 也可以用 /dev/zero 來取代

如果想弄一個空的 1G 檔案出來,一般會寫成
dd if=/dev/zero of=1G-file bs=1M count=1024
可是啊,這樣真的就要寫「很久很久」,卻又有一個很簡單的方式,一瞬間就寫完了,真的是神奇
dd if=/dev/zero of=1G-file bs=1 count=0 seek=1G

2010/11/04

Android 開機過程 boot sequence

請見The Android boot process from power on一文

全部有幾個階段:
1. Power on and boot ROM code execution
2. The boot loader
3. The Linux kernel
4. The init process
5. Zygote and Dalvik
6. The system server
7. Boot completed

在 kernel 之前還算跟一般的 embedded linux 一樣,但是在 init 之後就完全走它自己的路。先來看前面步驟的示意圖










1. Power on and boot ROM code execution




  • A. The Boot ROM code will detect the boot media using a system register that maps to some physical balls on the asic. This is to determine where to find the first stage of the boot loader.
  • B. Once the boot media sequence is established the boot ROM will try to load the first stage boot loader to internal RAM. Once the boot loader is in place the boot ROM code will perform a jump and execution continues in the boot loader.

2. The boot loader



  • A. The first boot loader stage will detect and set up external RAM.
  • B. Once external RAM is available and the system is ready the to run something more significant the first stage will load the main boot loader and place it in external RAM.
  • C. The second stage of the boot loader is the first major program that will run. This may contain code to set up file systems, additional memory, network support and other things. On a mobile phone it may also be responsible for loading code for the modem CPU and setting up low level memory protections and security options.
  • D. Once the boot loader is done with any special tasks it will look for a Linux kernel to boot. It will load this from the boot media (or some other source depending on system configuration) and place it in the RAM. It will also place some boot parameters in memory for the kernel to read when it starts up.
  • E. Once the boot loader is done it will perform a jump to the Linux kernel, usually some decompression routine, and the kernel assumes system responsibility.

3. The Linux kernel

  • A. Once the memory management units and caches have been initialized the system will be able to use virtual memory and launch user space processes.
  • B. The kernel will look in the root file system for the init process (found under system/core/init in the Android open source tree) and launch it as the initial user space process.

4. The init process

  • A. The init process in Android will look for a file called init.rc. This is a script that describes the system services, file system and other parameters that need to be set up. The init.rc script is placed in system/core/rootdir in the Android open source project.
  • B. The init process will parse the init script and launch the system service processes.

5. Zygote and Dalvik

The Zygote is launched by the init process and will basically just start executing and initialize the Dalvik VM.

6. The system server

The system server is the first java component to run in the system. It will start all the Android services such as telephony manager and bluetooth. Start up of each service is currently written directly into the run method of the system server. The system server source can be found in the file frameworks/base/services/java/com/android/server/SystemServer.java in the open source project.

7. Boot completed

Once the System Server is up and running and the system boot has completed there is a standard broadcast action called ACTION_BOOT_COMPLETED. To start your own service, register an alarm or otherwise make your application perform some action after boot you should register to receive this broadcast intent.

2010/10/31

為你的電腦降溫 cooldown CPU

請直接參考BBOY 寫的這篇 Frequency Scaling

在linux底下首先打開make menuconfig-> Power Management support --->
[*] CPU Frequency scaling --->
Default CPUFreq governor (userspace)
< > 'performance' governor
< > 'powersave' governor
-*- 'userspace' governor for userspace frequency scaling
< > 'ondemand' cpufreq policy governor
< > 'conservative' cpufreq governor

接著echo你想要的頻率到/sys底下的file node。
ex:"echo 500000000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
如果我們去查一下該目錄,可以發現
# ls -l /sys/devices/system/cpu/cpu0/cpufreq
總計 0
-r--r--r-- 1 root root 4096 2010-10-31 23:44 affected_cpus
-r-------- 1 root root 4096 2010-10-31 23:44 cpuinfo_cur_freq
-r--r--r-- 1 root root 4096 2010-10-31 21:39 cpuinfo_max_freq
-r--r--r-- 1 root root 4096 2010-10-31 23:44 cpuinfo_min_freq
-r--r--r-- 1 root root 4096 2010-10-31 23:44 cpuinfo_transition_latency
-r--r--r-- 1 root root 4096 2010-10-31 23:44 related_cpus
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_available_frequencies
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_available_governors
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_cur_freq
-r--r--r-- 1 root root 4096 2010-10-31 21:41 scaling_driver
-rw-r--r-- 1 root root 4096 2010-10-31 21:39 scaling_governor
-rw-r--r-- 1 root root 4096 2010-10-31 21:41 scaling_max_freq
-rw-r--r-- 1 root root 4096 2010-10-31 21:41 scaling_min_freq
-rw-r--r-- 1 root root 4096 2010-10-31 23:41 scaling_setspeed
drwxr-xr-x 2 root root    0 2010-10-31 23:44 stats
底下就試著....
# cd /sys/devices/system/cpu/cpu0/cpufreq
# cat cpuinfo_cur_freq
2000000
發現我的電腦目前的頻率也才 2000000, 似乎單位與原文中的不一樣。
後來我去試著用c3dl demo來衡量 CPU 速度,確實可以透過原文章中的方式調慢,我的命令如下:
# for i in 0 1; do echo 1000000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_setspeed; done

原文章有更多有用的資訊,有興趣的人請親自前往觀看

2010/10/25

cross compile busybox for android (為 android 準備 busybox)

我主要是參考cross compile busybox for android,大綱是:

1. 準備 cross compile 工具。
1. 這一項我原本試著用 ubuntu 的內建工具,也就是 xxxx-arm-linux-gnueabi 套件組,可是失敗。
2. 在文中提到可以自Download Sourcery G++ Lite Edition for ARM下載,請選『EABI』、『IA32 GNU/Linux TAR』,我下載的版本是 https://sourcery.mentor.com/public/gnu_toolchain/arm-none-linux-gnueabi/arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

3. 解壓後,我是放在 /usr/local/cross-arm 下

2. 若不想自己編譯,也可以從 busybox 網站直接下載執行檔,我試過可以執行的有 busybox-armv6l, busybox-armv5l, busybox-armv4tl

3. 下載 busybox source code, 上面執行檔最新的是 1.17.2, 但是 source code 是 1.17.3, 因此也可以自己編譯 最新的 busybox 1.17.3 source code
1. 解壓後,使用 make menuconfig 來選擇組態
2. Busybox Settings -> Build Options -> 裡面,挑下面的選項,將它編譯成靜態載入
[*] Build BusyBox as a static binary (no shared libs)
3. 在同樣的地方,挑 () Cross Compiler prefex,按 Enter 後必須填第一步安裝的 cross compile tools, 我的是:
/usr/local/cross-arm/bin/arm-none-linux-gnueabi-
確定後剛剛的選項會變成:
(/usr/local/cross-arm/bin/arm-none-linux-gnueabi-) Cross Compiler prefex
4. 在 Busybox Settings -> Installation Options-> 裡面,挑下面的選項,讓 busybox 可以不必安裝到 /usr 下
[*] Don't use /usr
註:1.19.3 版移到 Busybox Settings -> General Configuration -> 下面了
4. 上面的選項存檔、離開後,就可以用 make 來編譯
5. 放到 device 上,我是模擬機,道理一樣:
adb push busybox /data/busybox.exe
上面是故意改名字的,下一步要用到
6. adb shell:
# mkdir /data/busybox
# cd /data/busybox
# /data/busybox.exe --install .

7. 改變 PATH 環境變數
這一項比較麻煩,原則上就是要改變 system image, 所以有兩個方法,一個是自己改 ramdisk.img, 要用這一招的話請參考 busybox及bash在android中的安裝及init.rc修改
還有一個方法,就是第一點文中的方法,將系統重新掛載成 rewritable.....

su #取得root權限
mount -o remount,rw /dev/block/mtdblock6 /system #重新mount使/system可寫
mv busybox /system/bin/ #移動busybox
chmod 777 /system/bin/busybox #設為可執行
/system/bin/busybox --isntall .
mount -o remount,ro /dev/block/mtdblock6 /system #恢復/system為只讀

2010/10/12

android dynamic GUI 動態介面--範例程式

先來看看 config 檔,
$ cat Sample.xml

<?xml version="1.0" encoding="UTF-8"?>
<cmds>
<cmd text="Test1" path="Add\add" params="3 5"/>
<cmd text="Test2" path="Add\add" params="7 9"/>
</cmds>


$ cat Sample1.xml

<?xml version="1.0" encoding="UTF-8"?>
<cmds>
<cmd text="umount sdcard" path="/system/bin/umount" params="/sdcard"/>
<cmd text="top" path="/system/bin/top" params=""/>
<cmd text="reboot" path="/system/bin/reboot" params=""/>
</cmds>


範例程式如下:

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import android.view.View;
import android.widget.LinearLayout;
import android.widget.Button;
import android.widget.TextView;

public class HelloAndroid extends Activity {
/** 底下這個是放分析 xml 完的內容,資料結構要自己再想過,或是直接以 DOM 的方式存取,而不必另外放也可以
也就是在外面也是用 Document doc 這個物件來存取
**/
String[][] items;

// 底下這三個是我們的 GUI 上會有的元件的「容器」
Button cmd[];
TextView cmdPath;
TextView cmdParam;

/** Called when the activity is first created. */
/** onCreate() 是每個應用程式的入口,所以算是一般 C 裡面的 main() **/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main); // 這個是原來的 HelloAndroid 範例程式,我們不需要原來的 layout 設計,用自己的方式
// 目前以 LinearLayout 來設計,可以改成矩陣式的,不過最好是可以容許橫拿直拿動態調整,第一版可以不必有此彈性功能
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);

// 呼叫我們的 XML file 分析載入函式
GetXMLInfo();

// 底下這三個是我們的 GUI 上會有的元件的「容器」
cmd = new Button[items.length];
cmdPath = new TextView(this);
cmdParam = new TextView(this);

/** 底下就是直接把 XML 內容, 也就是 items 拿來放到 GUI 上
資料結構可以改變,整個 GUI 也可以改變設計
**/
int iCmd;
for (iCmd=0; iCmd<items.length; iCmd++)
{
cmd[iCmd] = new Button(this);
cmd[iCmd].setId(iCmd);

/** 為每個 button 加上按鍵的事件以便做出反應 **/
cmd[iCmd].setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
cmdPath.setText(items[v.getId()][1]);
cmdParam.setText(items[v.getId()][2]);
}
});
cmd[iCmd].setText(items[iCmd][0]);
layout.addView(cmd[iCmd]); // 最後真正加到我們的 layout 中
}
// 上面的 for 迴圈是加按鍵,底下只是加上顯示訊息的文字區塊
layout.addView(cmdPath);
layout.addView(cmdParam);
setContentView(layout);
}
private void GetXMLInfo()
{
try{
File f=new File("/sdcard/Sample.xml");
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("cmd");

int _cmdLength = nl.getLength();
int _cmdAttributes=3;

items = new String[_cmdLength][_cmdAttributes];

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

items[i][0]= nl.item(i).getAttributes().getNamedItem("text").getNodeValue();
items[i][1]= nl.item(i).getAttributes().getNamedItem("path").getNodeValue();
items[i][2]= nl.item(i).getAttributes().getNamedItem("params").getNodeValue();

}

//System.out.println("cmd " + RecordS.length);

}
catch(Exception e){
e.printStackTrace();
}
}
}


執行時:
$ adb push Sample.xml /sdcard/Sample.xml
----呼叫該應用執行





----換成新的 GUI, 用新的 Sample1.xml 取代原先的 Sample.xml, 記得放的檔名是一樣的
$ adb push Sample1.xml /sdcard/Sample.xml
----呼叫該應用執行

android dynamic GUI 動態介面

--動態 GUI--
寫應用程式,動態 GUI 是常常會有此需求的,原則上Dynamic Layout 的簡單概念,可以參考這篇:
http://www.dreamincode.net/forums/topic/130521-android-part-iii-dynamic-layouts/

在網路上找到一個寶庫, 一堆 Android source code 含有 test tools:
http://devdaily.com/java/jwarehouse/android/
其中有一份 DynamicLayout() 的範例:
http://devdaily.com/java/jwarehouse/android/core/java/android/text/DynamicLayout.java.shtml

或者我們可以從底下的問題開始了解我在說什麼:
1. 有人問他想要從 XML 來動態呈現 GUI,但是求問者有些功能做不到
http://efreedom.com/Question/1-2901333/Dynamic-Layout-Change-Runtime
2. 所以有人就回答他,用 setLayoutParams() 或請參考:
http://efreedom.com/Question/1-2693744/Android-Runtime-Layout-Tutorial

--執行外部命令--
至於 Dynamic Layout 之後,每個按鈕的功能,就變成要處理 button event.....再加上執行外部命令功能
http://code.google.com/p/market-enabler/wiki/ShellCommands
想要完整的 code 的話,可以參考:
http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App

還有相對簡單的方法是用 Java RunTime:
http://developer.android.com/reference/java/lang/Runtime.html
如果要使用 RunTime 的話,要能夠對外部命令做 I/O, 完整範例可以參考:
http://devdaily.com/java/edu/pj/pj010016/

2010/09/20

android adb over wifi

android adb 算是非常好用的介面,不過....預設是用 USB 來連接 Host 與 Device。有沒有方法可以透過無線網路?

首先,要能讓 Device 知道該透過 TCP/IP 或是 USB,似乎只能二選一切換,方法是:
-- 切成 TCP/IP --
setprop service.adb.tcp.port 5555
stop adbd
start adbd

-- 或切成 USB --
setprop service.adb.tcp.port -1
stop adbd
start adbd

在 Host 端,就可以用下面命令讓 adb 連線
adb tcpip 5555
adb connect WIFI.IP.ADDRESS:5555
-- 或透過 usb --
adb usb

SMART EDISON

愛迪生一向被稱讚,這邊就有一個用他的名字來取的一個新詞,用在思維、溝通、做事上很值得參考:
S.M.A.R.T E.D.I.S.O.N

全稱是:
Specific: 說話做事講究具體,不空洞
Measurable: 所有數據、問題,都應該可量測,不能太理論、抽象、高調
Accountable: 責任清楚,之前上過一堂「當責」的課,用的也是這個詞
Relevant: 切題,也就是所謂題中之意要符合目的與整體的價值
Timeline: 講究時效性,時機重於一切,等端出解決方案時黃花菜都涼了,客人跑光了,那就失去其意義

Emotional: 要能激勵人心、讓人熱情澎湃,不要澆息大夥兒的工作熱忱
Decisive: 能堅決果斷,要具備決定性的思維,做事不拖泥帶水,不做三姑六婆式的思維
Integrated: 要能整合、整體性的思維,而不是散兵游勇般的各自作戰
Sensory: 要能與別人感同身受,而不能唱獨角戲,不能自我感覺太良好而自絕於大眾之外
Optimistic: 要具樂觀思維,要影響並提升團體的樂觀氛圍,永不放棄,總要「再試一次」
Now: 立刻做

2010/09/17

Gtalk HOWTO Multi-Clients

現在因為申請 google appengine 的帳號後,就變成有多個 google 帳號,可以安裝 firefox + gmail checker....此時若想利用像 gtalk 來隨時讓人找得到,或是檢查郵件也是不錯的方式。

但是 gtalk 預設只能上一個帳號,一個非常簡單的方法:
1. 在啟動 Gtalk 的小圖示(捷徑圖示)按右鍵選內容,找到命令路徑加上 /nomutex, 以我的來說是 "C:\Program Files\Google\Google Talk\googletalk.exe" /nomutex /startmenu
2. 在 gtalk 登入畫面,不要勾選 Remember password

第二步若是來不及的話,只要在登入後的 system tray 按右鍵功能表選 Sign Out, 再按左鍵叫出登入畫面即可。注意此時不要勾選 Remember password!!! 這樣你就可以叫多個 gtalk 出來,user name 輸入全部的 email 即可。

2010/09/15

android java.util.zip.ZipException: duplicate entry: hyts_Foo.c

這個標題有點長,是因為直接貼訊息。編譯 android cts 時出現的錯誤,我的解決辦法就是把錯誤訊息中的重複檔案砍了....包括

./dalvik/libcore/support/src/test/resources/hyts_Foo.c 及
./dalvik/libcore/dom/src/test/resources/ 底下的
hc_staff.xml
staff2.xml
staffNS.dtd
xhtml1-strict.dtd
staff2.dtd
staff.dtd
staff.xml

2010/09/09

如何經營辦公室戀情

底下內容來自公司的內部文件,覺得不錯就貼上來了。老是遇到總字輩的玩辦公室戀情,底下的人總是感覺非常無奈,官位愈高,應愈謹言慎行啊!

--

隨著工作時間佔我們的生活重心愈來愈重,與同事互動的機會越來越多,在相互合作的氣氛中,也許您會發現對一些同事有不一樣的感覺,或察覺到身邊的辦公室戀情慢慢增加了。辦公室戀情處理的好,不但對工作氣氛有加分效果,更有可能促成佳偶良緣;但如果稍有不慎,卻也可能造成辦公室的災難,當事人也會身陷八卦中心,增加困擾。本月文章與您分享幾個面對辦公室戀情的方式。

Tip1.誠實的處理感情議題

請先檢視自己的心態,如果只是想尋求短期的心理安慰或是一時衝動,並沒有發展長期關係的意願,請您三思而後行。在辦公室裡,如何維持正直公平是非常重要的,如果您的身份不宜,或是只想搞曖昧增加生活刺激,是非常危險的事情,而且會為自己與組織引起非常大的危機,因此保持情感上的誠實是非常重要的。

Tip2.如果辦公室戀情的對象與您有權力關係,請想清楚再做決定

如果您的對象與您有權力關係,例如是您的客戶,廠商或是上司,部屬,您要注意,戀情可能會有兩極化的結果。特別是面臨結束關係時,您又是提出分手的一方,而且結束的過程並不夠理智成熟;那麼在分手後,有可能會面臨到工作上無理的要求,或是提出無謂的刁難,讓工作關係更加惡劣,需要極高的智慧,才能拿捏好其中的尺度。因為職場戀情與職位高低有必然的權力關係或潛在風險,因此當您面臨這個議題時,必須要更加審慎的思考所有可能後果,再做決定。

Tip3務必保持低調

如果您不希望您們的戀情受到太多的關注,或是被拿到顯微鏡下放大,那麼,請您務必保持低調,尤其是在同個辦公室裡,無心的一舉一動,如果被有意的解讀,或是只要有同事對您們其中一人有不滿或抱怨,都有可能影響工作。因此衷心的建議,除非決定要結婚了才通知大家,否則低調保守的處理這份戀情,不但能夠降低對辦公室工作的干擾,也會使感情之路省掉很多不必要的外在眼光。

Tips4享受真正認識一個人並且成熟交往的樂趣

事實上,辦公室是屬於遇見適合對象的好地點之ㄧ,因為您會透過工作互動看到身邊的人展現出他的個性、如何處理事情、面對壓力時最真實的樣子。您會是在真正了解以及認識這個人的個
性與特質之後才做出決定。在工作場合所遇到的對象,會較其他地方認識的對象,更深入且合適。所以一旦您要發展辦公室戀情,用成熟的方式去面對,您會享受到感情生活裡美好的感受。

結語:

辦公室戀情本身並無對錯,只是您一定要誠實且成熟的處理兩人感情。因此建議您如果遇到辦公室戀情或是身邊有同事正身處辦公室戀情中,您可以根據上述的幾個提醒作為感情發展的參考。若是能夠請楚了解辦公室戀情中拿捏公私關係的尺度,以及職務權力不同可能會造成的衝擊,在成熟的考慮之下發展辦公室戀情,就能夠享有愉快的心情與有效率的工作。

2010/08/17

ubuntu 10.10 將可內建支援多點觸控

詳情請見Multi-touch Support Lands in Maverick

既然有新聞,就自己去找,在 ubuntu 10.10 系統上,確實可以找到 utouch:

$sudo apt-cache search utouch
libutouch-geis-dev - Gesture engine interface support - dev files
libutouch-geis-doc - Gesture engine interface support - documentation
libutouch-geis1 - Gesture engine interface support
libutouch-grail-dev - Gesture Recognition And Instantiation Library - dev files
libutouch-grail1 - Gesture Recognition And Instantiation Library
utouch - A meta-package to install gesture libraries and tools
utouch-geis-tools - Gesture engine interface support - test tools
utouch-gesturetest - Test tool for the X Gesture extension
utouch-grail-tools - Gesture Recognition And Instantiation Library - test tools
xserver-xorg-input-mutouch - X.Org X server -- muTouch input driver


重點是,這邊感嘆一下,好像都國外廠商在玩這個,國內玩 Linux 的廠商沒半個願意搞....

2010/08/06

empathy under proxy

Empathy 是 Ubuntu 預設的 IM client, 可以支援相當多的 IM, 包括 MSN, Yahoo IM, gtalk。
敝公司會把 gtalk 的 5222/5223 擋住,此時可以用 gmail 裡面的 Port 設定值,也就是用 https在用的 443, 設定範例如下

account : username@gmail.com
encryption required TLS/ssl : (YES)
ignore ssl certificate error : (YES)
server : talk.google.com
port : 443
use old ssl : (YES)

或請參考下面的圖
.叫出帳號設定,可以在新增帳號時就設定,或是用修改的方式

.設定畫面如下,或請參考上面的設定值

2010/08/03

android build on ubuntu 10.04

Dependance
  • sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev java-common unixodbc libsdl-dev libesd0-dev
Java
  • sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
    sudo apt-get update
    sudo apt-get install sun-java6-jdk
Source Code
  • curl http://android.git.kernel.org/repo > ~/bin/repo
  • chmod a+x ~/bin/repo
  • mkdir -p ~/src/android
  • cd ~/src/android
  • repo init -u git://android.git.kernel.org/platform/manifest.git
  • repo sync
  • repo forall -c git checkout --track -b sai-master korg/master
Environment
  • export JAVA_HOME=/usr/lib/jvm/java-6-sun/
    export PATH=$PATH:${JAVA_HOME}/bin:$HOME/src/android/android-sdk-linux_86/tools:$HOME/src/android/out/host/linux-x86/bin
    export ANDROID_PRODUCT_OUT=$HOME/src/android/out/target/product/generic
  • chmod a+x build/envsetup.sh
  • source build/envsetup.sh
Build
  • make -j4
Run
  • export DISPLAY=:0.0
    #ps: 如果沒有設定 DISPLAY, 會顯示的訊息跟一般的 X app 不一樣,如下:
    SDL init failure, reason is: No available video device
  • emulator -system system.img -data userdata.img -ramdisk ramdisk.img

2010/06/04

如何加速 dd?

dd 是很常見的命令,但是在大量資料的複製時,會顯得非常慢,最簡單的範例是
dd if=/dev/zero of=/vmem.img count=2G
2G 以目前來說非常常見,例如要把一個作業系統放到隨身碟中,或是像 ChromiumOS 也差不多就這個數值。

我把我測試執行的結果貼一下:

首先用 bs=4M 來試,這個數值是 ChromiumOS 的 script 中內建的值:

$ time dd if=my-8G.img of=/dev/sdc bs=4M

1919+1 records in
1919+1 records out
8050966528 bytes (8.1 GB) copied, 1189.83 s, 6.8 MB/s

real 19m49.848s
user 0m0.030s
sys 0m18.410s


接下來用預設的來比對,預設的 block size 是 512byte

$ sudo time dd if=my-8G.img of=/dev/sdc
15724544+0 records in
15724544+0 records out
8050966528 bytes (8.1 GB) copied, 6303.21 s, 1.3 MB/s

real 105m3.254s
user 0m7.740s
sys 1m36.380s


最後,用一個更大的比較一下,用 12M

$sudo  time dd if=my-8G.img of=/dev/sdc bs=12M
639+1 records in
639+1 records out
8050966528 bytes (8.1 GB) copied, 1060.62 s, 7.6 MB/s

real 17m40.653s
user 0m0.010s
sys 0m11.730s


會發現,4M 遠比預設值快非常多,而 12M 與 4M 相差不大,但是仍然有比較快。
以上僅供參考

2010/05/21

cron 與 anacron

剛好朋友問到 crontab 怎麼不見了一事,就提醒他,現在的系統,大概都是用 anacron,因此就來說說兩個的不同。關於 anacron, 請參考 sourceforge 的說明。(我翻的也不會比較好)

首先,最主要會出現 anacron 的原因是,機器不見得會開機,所以,在原來 cron 設定的時間點過了之後,該事件就不會被觸發!也就是說,anacron 不是靠「時間點」來觸發,它是檢查要做的事在那個時間點有沒有被做,沒有?那就觸發它。

基本上兩個是互補的。例如,cron 可以設定到時、分,而 anacron 只有「天」!
又例如,anacron 並非 daemon, 通常設計成在開機時做一次.....可是又不是常常開機,所以 ubuntu 是利用 cron 來定期叫 anacron 檢查,也就是 cron 本身不再是用來設定事件,而是...

叫 anacron 替代之前的 cron, 再叫 cron 叫 anacron 起來。

什麼?疊床架屋?不是啦,要從(文章的)頭想起。這種機制最有用的地方,除了系統會掛掉或是像有的是網路的動作,剛剛好網路不通,透過 anacron 就會有機會再重做,此外,....像筆電才是它最佳的舞台,你叫它做的事,在你下次開機時,只要時間點到了(或過了),它就會幫你完成。

最後,anacron 最新的版本是 2.3, release date 是.....2000 年 06 月 22 日!!!

2010/05/19

chromiumOS 的建立與執行 -- under ubuntu-3

寫過 chromiumOS 的建立與執行 -- under ubuntu-1chromiumOS 的建立與執行 -- under ubuntu-2,一直都無法正確的在 Virtualbox 執行,後來在 ChromiumOS 論壇看到一篇討論,提到把 Virtualbox 的 Machines/下的 CHROMIUMOS.xml 內容修正如下,就可以執行了!

<Hardware version="2">
<CPU count="1">
<HardwareVirtEx enabled="true" exclusive="false"/>
<HardwareVirtExNestedPaging enabled="false"/>
<HardwareVirtExVPID enabled="false"/>
<PAE enabled="false"/>
</CPU>
......
<BIOS>
<ACPI enabled="false"/>
<IOAPIC enabled="false"/>
<Logo fadeIn="true" fadeOut="true" displayTime="0"/>
<BootMenu mode="MessageAndMenu"/>
<TimeOffset value="0"/>
<PXEDebug enabled="false"/>
</BIOS>

chromium 的測試概觀


從結構圖來看,google 企圖以 Client/Server 的架構來簡化工廠生產時的人力配置,同時提供 Web 介面以及 command line 介面。

有幾個問題先列下來:
1. 如何簡化 Server/Client 架構的建立?也就是從 server 端如何知道 client 端的 IP?
AUTOIP? ZeroConfig? DHCP?
2. 以 autotest 來說,似乎不必人力坐在電腦前面,但是,若需要 locate device 時,如何得知是哪一台?
3. 對需要 manual test 的狀況下,如何進行?


2010/05/18

chromiumOS 的建立與執行 -- under ubuntu-2

之前寫了第一篇「chromium的建立與執行-1」,不過若是要建立 virtualbox image 的話,我自己試半天都無法執行。

Running Tests一文裡,有提到另一種快速的方法來建立可供測試的影像檔。看這種文章,比較需要注意的反而是 "inside" 與 "outside" 是指有沒有 chroot, 也就是有沒有執行過 ./enter_chroot.sh。inside 就是要執行過 enter_chroot.sh, 而 outside 就是沒有執行過它,也就是一般普通的環境。

該文的後面有一節提到「Create and run a test-enabled image on your device (the easy way)」,這真的是相當方便的方式! 只要一行,對,一行命令即可。

我在我的機器終於有試出怎樣用 virtualbox 看到開機畫面,目前尚未成功,畫面如下:

首先,Virtualbox 有兩個地方要注意,一個是開啟 EFI....



but, EFI 設了只是虛擬的,目前手邊都沒有機器的 BIOS 是跑 EFI 的!!!

除了 EFI 要開啟,還要注意,我們的 CPU 都是 Intel 的,所以....AMD 的虛擬機器選項要關掉:



這樣可以看到開機畫面,心裡會爽一點,只是.....



可以發現.....一直找不到可以透過 EFI 找到的開機裝置!!!



所以,最後,就進這個維護畫面.....

2010/05/14

Seamless 使用經驗

之前在寫Hal Dbus udev automount usb device?文章提到的參考文獻已經不見了!若有興趣的話,除了我的那篇文章外,也可以自行再參考阿呆的HAL、D-bus、ivman、udev心得

會用這個標題,原因是同事提到「Gnoem與KDE兩大陣營的戰爭」這件事,似乎跟 udev, HAL, Dbus無關?在我們把話題轉回來 Seamless 之前,先讓我再說說關於 Gnome/KDE 的後續見解。

我們可以從現有狀況來思考。如果要看 Desktop 的話,現今 Linux distribution 市占率最大的仍然是 Ubuntu, 它不一定最好,譬如硬體支援恐怕還不如 SuSE, Embedded 市占恐怕還不如 MontaVista, 但是,以 Desktop 來看它卻是最大宗。我認為原因不在純粹的 Desktop 是選 Gnome or Kde, 因為 Ubuntu 還有分支是 Kubuntu 採用 KDE。

整合度、易取得、進入門檻、客製化等等都是重要考量因素。純粹就整合度來看,KDE 整合的東西較完整,問題是,KDE 太笨重了,當它變得愈來愈像微軟時,它就真的變的跟微軟一樣。

Ubuntu 採用 Debian 系統,我想也是一個它受歡迎很重要的原因之一,雖然 Redhat/Mandrake 與 Ubuntu/Debian 的套件現今要整合變得比較容易,但是畢竟我還是比較喜歡 Debian, 尤其在做嵌入式系統的時候。試想,ChromeOS 預設支援的就是 Ubuntu,而當初 Intel 在推 Moblin 第一個找的也是 Ubuntu。原因何在?

現況是,從市占來看,明顯採用 Gnome 的人比較多。至於真正的現況除了 Desktop 外,不管是 Android, Meego, ChromeOS 等等,絕對是從另一個角度切入。反倒是我們該思考的不應該是 Gnome or KDE ? 這樣的路線。就像 Meego 想通吃,ChromeOS 有沒有可能走這樣的通吃的機會?

ChomeOS 開發團隊一直被問到,ChromeOS 有沒有可能執行 Desktop Applications? 若要問答案,當然是可以,但是目前 ChomeOS 開發團隊似乎較堅持走純 WebOS 的路。我們要 followup Google 的決策呢?還是要滿足更多人的需求呢?

我想,Intel 也不是笨蛋,善用 Web 而不純粹 WebOS 的市場在目前仍然是最大的,所以,我想,似乎 Google 的堅持也會有被動搖的一天。未來潮流到底會如何走?是選擇 WebOS? 還是選擇 Gnome? KDE? or.....Meego?

接下來談談為何我會談 Seamless。udev, HAL, Dbus 是三個主題,卻也是一個主題,是連著 GNOME/KDE 來的。Ubuntu 會讓人覺得好用的一個很重要的地方,它輕量級卻有著像 Windows 那樣方便的使用經驗,這得歸功於這三者在 Gnome 中被整合的很好。DBus 不止用來取代 IPC, 它其實是各個 module, 包含底層 kernel, daemons, drivers, application, and window manager 之間的橋樑,但是它畢竟只是橋樑而已,要讓使用者覺得方便,在於一個觀念的施行: seamless。

談這麼多終於可以談 Seamless。正因為 Seamless 的緣故,早期 KDE 是比較受歡迎的,至少 Redhat 就用它,而當時 Redhat 也是最大的 linux distribution。但是 KDE 最大的問題在於它的笨重。而在 Ubuntu 的推波助瀾之下,現在 Gnome 使用率應該是最大的了,就如我前面說的,我個人認為最大的原因在於 Ubuntu 讓人有一種類似 windows 帶來的 Seamless 使用經驗。它整合好 hotplug, udev, HAL, dbus....and window manager 層,所以就打通了硬體與使用者間的無縫隙使用經驗。

把格局放大來看,iPhone 為何會流行?Android 是以什麼樣的方式來迎頭追擊?iPad 又是採取什麼策略?我個人認為背後最大的原因就是 Seamless......再把時光拉回 Netscape 與 IE 的戰爭時代,說穿了,也是同樣的原因,當IE與作業系統整合,它就贏了這場戰爭。講白話一點,就是,使用者是笨蛋,使用者是懶惰的。

沒錯!別想要打我。現在的手持裝置就夠 Seamless 了嗎?沒有!路還很長。我看好的很多技術,若有跟我常常聊天就會知道,一項一項都在實現當中,未來其實是很明顯的。

註一:我也是使用者
註二:dbus 參考文獻

2010/05/13

Open Source License Scanning tool - from Florence

一篇來自中研院葛冬梅小姐的信轉貼於此,主題是「關於原始碼版權的掃描分析工具」,在此特別感謝她。並順便協助宣導一下 OpenFoundry, 她們一直努力推廣 Open Source, 不止是版權問題的討論,還辦過非常多研討會等活動,也都有資料可以下載

【掃描原始碼】

就我所知,目前有三套系統是可以掃描軟體原始碼,來查驗原始碼是否包含自由軟 體程式碼,以及判斷這些原始碼是採用哪一份條款來授權。這三套系統為 FOSSology、Blackduck與Palamida。雖然這三套系統都可以掃描原始碼、提供授權 資訊,不過就我個人所知,這些系統掃描精確度都有需要改進之處,因此這些掃描 結果僅可以作為輔助參考之用,若真的發現有授權狀態不相容、侵權情況的時候, 還是必須要諮詢技術與法律人員,來解決不相容、侵權的問題。以下針對三個系統 分別說明。

1. Fossology

這是一套掃描原始碼檔頭授權資訊的系統,系統會將掃描到的檔頭資訊與資料庫中 的自由軟體授權資訊相比對,來確認軟體中是否有利用到自由軟體,並不會掃描所 有的原始碼。對於檔頭沒有授權資訊的原始碼檔案來說,就無法確認該檔案的授權 狀況。優點是免費、任何人都可以自由下載與安裝。您利用這套系統的方式有二:


(1) 利用現成的vdi檔。

為了方便他人利用這套系統,鑄造場將Fossology系統製作成vdi檔,只要安裝 VirtualMachine後,將這個vdi檔掛載上去,依照說明就可以掃描原始碼的授權狀態。

請您進入下列網頁,進入後點選左方選單「下載區」,進入下載區頁面後,就可以 下載vdi檔與相關說明文件

Fossology vdi from OSSF:http://of.openfoundry.org/projects/1342

(2) 自行下載與安裝。

自行到Fossology網站下載後安裝起來,網址: http://www.fossology.org/


2. Blackduck

這是美國一家專門提供自由軟體原始碼掃描比對服務的公司,收費不貲,優點是資 料庫龐大。該軟體目前在台灣有兩家代理公司分別如下:

鈦智科技:http://www.adnetwork.com.tw/pro-blackduck-cn.htm

倚碩科技:http://www.esoft.com.tw/blackduck.php


3. Palamida

這是一家提供自由軟體安全諮詢管理公司,提供服務的方式是透過系統掃描原始碼 檔案,然後針對掃描結果提供諮詢服務,這間公司並且與 OSRM合作,提供自由軟 體 風險保單供業者購買。


Palamida:http://www.palamida.com/

OSRM風險保單的頁面:http://www.osriskmanagement.com/insurance.html

【掃描目的碼】

就我目前所知,僅有一套軟體可以掃描二進位的目的碼,也就是今日講師Shane所 提過的Binary Analyzing Tool。這是自由軟體,您可以上網自行下載安裝來掃 描。網址如下:

http://www.binaryanalysis.org/en/home


由於這套軟體最近才釋出,我對於這套系統所知有限,因此無法多做評論。若是您 之後有下載來使用,非常歡迎提供您的心得給我參考。


以上每個系統各有優缺點,因此我想您還是必須就貴公司的狀況,來個案評估,採 用哪一個系統比較適合。

以上資訊供參考,希望對您有所幫助。若還有任何疑問與意見,歡迎來信討論!


祝 順心

Florence T.M. Ko 葛冬梅
Legal Specialist, OSSF
e: tmk2005@citi.sinica.edu.tw
p: +886-2-27883799 ext. 1474
w: http://www.openfoundry.org/

2010/05/10

熱門技術 3D

其實立體視覺的成像「原理」上都大同小異,也就是利用兩顆眼睛所見到的影像的微小不一樣產生的立體感來的。
早期,我在讀研究所時,曾經流行過 3D 立體書,例如這張圖片裡面是一個騎士騎著馬,右手拿著一面旗子迎風飄揚。那時候我們就想要做你的這個題目了。當然後來沒真的去做。請見 Wiki 對 Stereogram 的解釋

單一影像呈現立體視覺與戴特殊分光眼鏡看似兩種非常不同的方法,其實原理也並無不同,既然說到了,可以上網找找 SIS, SIRDS等關鍵字看看。

透過光柵來呈現立體影像的,可以參考這篇. 或是同網站的這篇。而光柵板的原理可以參考這篇

當然這樣的文獻很多,譬如這篇就將前面光柵的原理視覺化,一定要進去看看。

要談數學運算的話,可以參考這篇

看完原理之後,要用兩顆攝影機取得3d立體影像,其實不算太難,難的是後製的運算......不過,若是以立體攝影文獻來說,可以參考立體攝影這篇

working with ubuntu and XP 2 - sshfs

雖然知道 sshfs 很久,卻一直沒有用,在我提出 working ubuntu and XP 的同時,同事提到 sshfs,可以用的 tool 有兩個,一個是 Dokan,可以擁有類似網路磁碟機的無縫使用經驗,也可以用 WinSCP,這個工具也是非常好用。

搭配 sshfs 及 ssh 遠端作業,應該可以符合大部份的作業需求,剩下的,或許會希望用 svn 來實現。

2010/05/05

working with ubuntu and XP

我的環境,是因為公司(絕大多數公司都如此)是建立在微軟體系上,所以,不另行在 Ubuntu 上建 Samba server,在讀本文時也請參考Mount samba shares with utf8 encoding using cifs一文,及Share Ubuntu Home Directories using Samba一文。

☆ Ubuntu 端看到 PC 上的目錄 ☆
1. 在 PC 上選定目錄,並按右鍵開啟分享,請注意,一般預設是沒寫入權,要在 Ubuntu 端能寫入的話,必須手動打開權限
2. 在 Ubuntu 上,有兩種方式,一個是手動掛載,一個是放在 /etc/fstab 讓系統自動掛載

a. sudo mount -t cifs //你的工作電腦位址/你分享的名稱(分享名稱不見得剛好就是目錄名稱) 掛載點 -o credentials=/你的HOME路徑/.smbcredentials,iocharset=utf8,file_mode=0777,dir_mode=0777
舉例來說是 sudo mount -t cifs //10.20.30.40/wade_share /home/wade/share -o credentials=/home/wade/.smbcredentials,iocharset=utf8,file_mode=0777,dir_mode=0777
上面的 .smbcredentials 權限設成唯讀(0400), 內容是工作PC 上的帳號,如:
username=wade
password=iamwade


b. /etc/fstab 仿上面執行例的相對內容如下:
//10.20.30.40/wade_share /home/wade/share cifs credentials=/home/wade/.smbcredentials,iocharset=utf8,file_mode=0777,dir_mode=0777 0 0


☆ PC 端看到 ubuntu 上的目錄 ☆

1. 安裝 samba
2. 修改 /etc/samba/smb.conf, 找到 [homes] 這一區段,內容如下:

[homes]
comment = Home Directories
browseable = yes
writable= yes
create mask = 0775
directory mask = 0775
valid users = %S


上面原來的設定當然有很多註解,並沒說一定要刪除註解。重點是 valid users = %S 及 writable = yes
3. sudo service smbd restart
4. sudo service nmbd restart
5. 在 PC 端,「開始」「執行」輸入 \\你的 ubuntu 位址\你的帳號 即可跳出帳號密碼畫面,請輸入在 ubuntu 上的帳號密碼,實際輸入例如下:
\\10.20.30.39\wade

2010/04/28

CHT8000 如何省電

上次寫了一篇我的3G手機 CHT8000 使用心得,再來貢獻一篇。

是有發現3G手機一下子就沒電了,所謂的一下子,就是撐不到一天。哦?那應該沒人敢用了吧。當然是有發現若用 3G 功能,會耗電很兇,一開始我在晚上睡覺時是直接關機,後來發現開網頁時若把螢幕關閉(輕按左上外側按鈕)的話也會背景抓網頁,所以就沒事關螢幕。

現在則是發現,「飛航模式」下(長按左上外側按鈕))非常省電。若是只是要玩遊戲,請記得把飛航模式開啟。

另外,常常背景有應用程式在執行,我是一開始就去抓了一個軟體,叫 Process Manager, 也下載一個移除軟體叫 AppRemover。前者可以很容易讓我看哪些應用程式在背景跑,沒什麼在用就刪了。

講這議題,就得說說我另一個軟體,叫 fring, 可以讓我用手機上 skype, msn, 目前猜測它會常常三不五時上網,因此沒事我還是得把它關閉。總之總之,沒要上網時開啟飛航模式,不過,這飛航模式也會讓你的手機無法接收來電,對我是沒差,要用此招時請自行評估

遠端桌面 remote desktop

遠端桌面當然有各種協定,有各種工具,底下來講一下兩種方法。

一、用 Ubuntu 的設定:
a. 用GUI 設定:「系統」->「管理」->「登入畫面」,切換到「遠端」的Tab,將「風格」改成「當成本地端」
b. 或是編輯 /etc/gdm/gdm.schemas, 確認一下是不是有把 xdmcp 設成 Enable, 或是看看是不是有這行<key>xdmcp/Enable</key>,若是 Disable 請改成 Enable
c. 「系統」->「偏好設定」->「遠端桌面」, 勾選「允許其他使用者觀看您的桌面」、「允許其他使用者控制您的桌面」、「使用者需要輸入密碼」,並且輸入密碼,而「詢問您以確認」則不要勾選,不過若基於安全考量,你想手動決定別人是否可以用遠端桌面的話,這項反而要勾選。這邊的密碼,是用 vnc viewer 從遠端要連線時輸入用的,可以的話最好不要跟登入密碼相同。

這個方法會讓你從遠端與你的桌面共用。這句話是要仔細看的,也就是兩個人的桌面是相同的,有點像早期我用過的 PC anywhere。也就是,因為一次只能有一個人登入到桌面,所以一次也就只有一個人可以用此方法連線,相較於下面的方法而言,也就不必設定 Port 號,只需要在連線軟體填入該機器的網址即可。

二、用 vnc4server
a. 確定有安裝 vnc4server
b. 用你的帳號執行 vnc4server, 第一次執行的話,它會讓你輸入密碼,說明同上。這個動作會在 $HOME 建立一個 .vnc 目錄,裡面會放個檔案叫 passwd。若需要更改密碼,也可以透過 vncpasswd 來修改。
c. 請注意上面執行的結果訊息,我的如下:
$ vnc4server

New 'wade-laptop:1 (wade)' desktop is wade-laptop:1

Starting applications specified in /home/wade/.vnc/xstartup
Log file is /home/wade/.vnc/wade-laptop:1.log

d. 此時在 PC 端,我是下載 tightvnc,連線時要搭配執行 vnc4server 的訊息,注意到上面是 wade-laptop:1 嗎?如果網路環境設定好,當然可以在 vnc viewer 中填這個值,不過我懶得設,所以直接填 XXX.XXX.XXX.XXX:1

這個方法當然比較麻煩,若重新開機過,你就得自己再下一次 vnc4server 命令,而且每次的 Port 都不見得一樣。要注意的是,若這台機器是多人使用的話,而且大家有在用這種方式連線的話,port 大於 1 是正常的,但是若只有你用,而你看到 port 大於 1, 那代表你執行了兩次,看是要刪掉哪一個,命令是 vnc4server -kill :1

2010/04/27

跨平台環境的建立 .... 你會怎麼用?

這一篇文章簡述了幾種可能用來 cross compile 的選項。另外,我個人很喜歡 scrachbox 的方式,其中經典之作就是 GeeXboX,不過 GeeXboX 你不能只是看首頁,一定要照著下載 source code 來編譯過後才會知道其精神。

乾淨的貓 netcat

貓,通常是有靈性的。嗯嗯,有點太抽象了,netcat 有如 busybox 一樣的萬用特性,在網路上它扮演著非常強的功能,只是一般人都不會用。這一篇文章講解怎樣用 netcat 來發信。該文講的很認真,我就不多說了

2010/04/26

我的3G手機 CHT8000 使用心得

我原本有在用台灣大哥大的 3G 上網,可是啊,台灣大哥大費用800不說,當初只送了一張 usb 3G上網小老鼠,合約到了又不主動給我降價,一氣之下,就跑去中華電信,把我的 3G 上網跟我的手機結合。我家很久沒在用寬頻上網了,將來小孩長大後就再來研究吧,目前是我的手機跟 3G 結合,感覺就很方便。

在還沒談之前,先說說分開與合併的優缺點。
合併優:隨時可以上網,缺:老婆要上網必須要我的手機在她身邊
為了鼓勵大家愛用 Android, 再說一下,最方便的是,非常非常多好玩的遊戲也好、應用也好、輸入法也好,統統是免費的!當然,開發 android 軟體,據說只要得到5星評價夠多,還可以得到免費的 Google Nexus One 手機一台。最需要鼓勵的是,Android 軟體非常自由,不必破解就可以滿足我絕大部份需求,何況,上面還有我要的所有 google 應用。
還有一項要長久才看得出功效的,就是電池可以更換!大家都知道手機一、兩年後就很難待機,而3G手機更是如此,常常要充電,那如果,連基本的電力都保持不住,又要怎麼用?

我到中華電信,選了 CHT8000, 之所以選這個,純粹是因為 Android 手機,竟然只有兩款!好吧,至少這款不必再負擔手機的錢,費用上,也跟我原本的組合式用法差不多,雖然要預繳12000元,但是可以分12期繳,感覺並沒有增加負擔任何費用。

CHT8000要上網,不管是在 WinXP or Ubuntu, 也都很方便。在 XP 有隨附的光碟可以安裝,叫 CHT DialUp, 不過若要在 Win7 的話,千萬千萬不要用隨附的光碟安裝,請參考 http://5i01.com/topicdetail.php?f=423&t=1410153&last=18261051,或下載這個網址下的撥接程式,或是適用 Win7 版的安裝軟體,後者的解壓密碼是小寫的 hw 兩個字,我猜測是「華為」的縮寫。比較常見的情況是,已經在 win7 裝了光碟版的軟體,我試過這樣做的話,想用前面提到的軟體來更新,結果是 FAILED! 不過,還好的是,簡單的去控制台新增移除軟體將原來的(或更新失敗的)的軟體移除後,再重新安裝即可。

至於 Ubuntu 下,只需要在掛載內建 driver 時指定 pid/vid 即可,例如:
$ sudo modprobe usbserial vendor=0x12d1 product=0x1502

若要系統自動認得的話,可以增加 /etc/modprobe.d/usbserial.conf 把上述資料加進去即可。
options usbserial vendor=0x12d1 product=0x1502

最後,我是愛用嘸蝦米沒錯,也喜歡自己修改對應按鍵,剛好 Android 上有一套 LIME 輸入法可以容易做到,請參考 LIME 網站自創對應表,或是參考這邊

最後補充,我的 CHT8000 上用 LIME 時,一開始一直還是出現手寫輸入法,後來利用 gmail 的寫信畫面來當輸入框,才有辦法照文件上的「長按」叫出更改輸入的畫面出來。

2010/04/24

accountability 當責.問責.負責




這是憲哥的一堂課,請見當責

課堂上,老師,也就是憲哥,一直在講什麼叫「負責」什麼叫「當責」,也一直在講「授權」與「賦權」的差異。其實,照我的理解,很多主管根本連什麼叫負責都不知道,完全做不到授權,要跟這些人談當責與賦權,我覺得有點對牛彈琴,只是多舉辦這種課,想必能觸發更多人的神經吧。

先說說我自己,這堂課我很想上,可是朋友剛離開廣達,難得回來跟我吃午餐,害我忘了上課時間,請見諒。三點時又跑去面試了一個小時,為了上這堂課,害我面試時不專心,沒問到對方重點。可見我是真的很重視這課的。現在就來稍微把理解中的當責講講。以下大部份來自上課心得(與講義),不過別以為看了我的文章,你的功力就大增,還是得多上這類的課才有用,親身體驗絕對不一樣的學習成就。

當責的核心精神:
.挹注成果(從頭到尾講的重點就是成果)
.執行力(講成果本來就要靠執行力)
.紀律(這一點非常難解釋,舉個例,公司一直在講要節約,多走樓梯,但是有多少人真的是走樓梯的?)

因為要講執行力,有四項執行力的特質:
.首先要有當責的觀念(要將當責精神深植內心是非常難的)
.能激發同仁活力(自己不先死掉就很高興了,所以真的是很難)
.擅於後續追蹤(不會五分鐘熱度)
.面對棘手問題能迅速做出決定(通常能避則避,或常見猶豫不決)

當然課堂講了很多其他的重點,不過先來談談當責與負責:(常常我們在講負責任的人時,是很貼近當責的,只是當責不止是負責這麼簡單而已)
當責是:
.對別人所訂下的承諾並交出符合的結果
.在責任、在成果上達成目標
.體認與接受並負起發生在管轄範圍內任何活動的全部責任,無論原因為何(是個經理人)
.做對的事
負責是:
.對自己所訂下的承諾並交出符合自己預期的結果(這一點定義我不是很認同)
.有責任感的確實執行被交付的任務
.執行特定任務或上級分派的工作,或圓滿達成被授權的職務內容(是個專業者)
.把事情做對

從上面,可以見到老師企圖把當責引導到更具「成果導向」的路上。上面也提到授權一事,現在再來談談這兩個的差異。(同樣的,這邊對賦權的定義,有時我也是以授權來理解的,有點硬要分成兩個詞的感覺)

授權(Delegation)是:(我發現我之前一直只做到這一階段而已)
.分身分勞
.工作下屬去做,責任上司承擔
.獲授權者揣摩上意,依規依約行事,缺乏獨立思考及判斷(這一點我是有企圖不讓它發生)
.講責任(responsibility)
賦權(Empowerment)是:(我一直很希望遇到這樣的上司,我的前上司或許也這麼自認為)
.全權處理(看似全權處理,很容易變成放羊吃草的境地)
.下屬一併承擔責任(這一點要有同舟共濟的精神,很難做到)
.需有充分資訊,充分能力,充分訓練,充分溝通,要下屬成長,獲賦權者有決策能力,要完成目標(這一點就是我與前主管間缺乏的部份)
.當責(accountability)

課堂上,老師一直在講,當責精神是要給下面的句子加上問號,要大家去質疑:
.雖敗猶榮?
.沒有功勞也有苦勞?
.重視過程而不重視成果?
.志在參加不在得獎?
.只問耕耘不問收獲?
==>當責的精神是,不僅要努力耕耘,更要有收獲,還要將本求利

老師把員工依X(被動-->主動)及Y(負面-->正面)分成四種人:
  .囚犯:就是那種等死的人,一切都在等待
  .過客:就是參與感不重的,叫他做事做的好好的,我稱這種人為混吃的人
  .抱怨者:這種人很積極參與,卻常抱怨。我反省一下,我很常落入這種狀態,不過有點像關起門來抱怨。也很應該改進。
  .玩家:就是積極又正向的當責精神

課堂上,老師講了兩個詞,很值得玩味:
  .分工合作。從小我們就在聽這個詞,但是分工了,就能合作嗎?這也是我一直在懷疑的,老師用下面的詞來說明
  .合作分工。有了共同的目標,再來看怎樣分工。這樣做事才會有「共識」,才能真正犧牲小我完成大我。可是很難,就算危機意識夠強也不見得能做到。就像即使要亡國了,仍然會有漢奸一樣。在講這一點的時候,老師提到賽局理論裡面很有名的「犯人的困局」,若是多人犯案被抓到,警察通常分開問訊,而且,許諾問案對象坦白從寬,抗拒從嚴,通常通常,人在「人不為己天誅地滅」的想法下,都會替自己求最大利益,因此坦白。

所以,來看看當責的七個重要行為:
  .了解公司與您的工作夥伴(嗯嗯,我們常自掃門前雪)
  .設定明確的目標與優先順序
  .實事求是
  .後續追蹤
  .論功行賞(很難,常常是做的要死被念的半死)
  .傳授經驗(也常常被忽略,都有藉口說很忙,或是自己學比較快)
  .了解自我的情緒韌性(不要只會抱怨)

最後最後,來講講 X-Y game

  明明,大家都知道要追求團體最大利益,可惜,這堂課一直到最後,都還是有人只追求自己的最大利益。明明大家都發誓的。遊戲過程我很難在這邊講清楚,我只能說,當考量到私人利益時,團體利益常常是被擺在最後的,殊不知,船沉了,就自己也活不了。當然,職場上,常常大家都會說,此處不留爺,自有留爺處。唉。難矣哉。

剛剛有空跟朋友聊天,把遊戲講過一遍,所以就貼下來,憲哥別罵我(不過我也知道這遊戲其實也是他抄來的,我以前就看過了)。

先說說遊戲規則,要看好哦:
  .整堂課,學員們分六個組
  .每個組,只能選擇X或是選擇Y之一,就是說,你可以選X,也可以選Y,但是不能同時選X及Y
  .我這麼囉嗦的說,只是在說,每一組有選擇權,可以自由選X或是選Y,但是事先你不知道別組選 X or Y
  .所以,最後若六組的結果如下的話,其獎懲也列在下面:
   ○ 6X: 則每一組都扣100元
   ○ 5X1Y: 則選X的組各得100元,選Y的組扣500元
   ○ 4X2Y: 則選X的組各得200元,選Y的組扣400元
   ○ 3X3Y: 則選X的組各得300元,選Y的組扣300元
   ○ 2X4Y: 則選X的組各得200元,選Y的組扣200元
   ○ 1X5Y: 則選X的組各得100元,選Y的組扣100元
   ○ 6Y: 則各組各得100元

我把題目寫在最後,請看的朋友們自己好好看清楚題目:
請你們各盡所能,求獲得最多的錢

其實不管題目如何,如果,如果能大家都投 Y, 就從頭到尾大家都會是贏的。可是拿我的組來說好了,就有組員一直在講,萬一別人投X呢?我說又說不過,一直在第五局之後才說服了大家,堅持從第5局到第10局都投Y。這已經很難了。但是但是,我前面也說了,一直到最後,也沒出現過6Y。這,就是廣達,嗎?

再來補充一點,在個人利益與團體利益的兩難情況下,你會如何選擇?
最後再說一點,題目,其實是求團體的最大利益,選 6X 就是負的,選 6Y 就是正的,其他都是 0, 答案很明顯。
最後最後再說一點,課堂上,根本都沒「錢」,何必一直有人跑票選X,這一點讓我苦悶到現在。
最後最後的最後,上面的那個問句,希望有人能看懂。(這,就是廣達,嗎?)

2010/04/20

shell script 處理空白字元

請參考這篇

一個方法是用 find 來解決,另一個是透過更改 IFS 的環境變數來解決,底下直接列範例:


#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in *
do
echo "$f"
done
IFS=$SAVEIFS




#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
# set me
FILES=/data/*
for f in $FILES
do
echo "$f"
done
IFS=$SAVEIFS


或直接拿來分析 /etc/passwd


while IFS=: read userName passWord userID groupID geCos homeDir userShell
do
echo "$userName -> $homeDir"
done < /etc/passwd


用 find 也行

find . -print0 | while read -d $'\0' file
do
echo -v "$file"
done

2010/04/14

chromium 的建立與執行...under ubuntu -1

我在摸索階段,是完全根據 Chromium OS上的說明來玩的,有些措詞會讓人看不懂。若你的目的是,下載 source code, 自己編譯, 進行「測試」,的話,那麼希望我的文章可以減少您摸索的時間。

一、開發環境的建立

我是直接把我的電腦安裝成 Ubuntu 64, 請見我的前一篇文章。我不想去解決 x86-32 環境是否可以 build, 反正改變自己的系統比較簡單些。

安裝套件:
$ sudo apt-get install bison fakeroot flex g++ g++-multilib gperf \
libapache2-mod-php5 libasound2-dev libbz2-dev libcairo2-dev \
libdbus-glib-1-dev libgconf2-dev libgl1-mesa-dev libglu1-mesa-dev \
libglib2.0-dev libgtk2.0-dev libjpeg62-dev libnspr4-dev libnss3-dev \
libpam0g-dev libsqlite3-dev libxslt1-dev libxss-dev \
mesa-common-dev msttcorefonts patch perl pkg-config python \
python2.5-dev rpm subversion apache2 wdiff lighttpd php5-cgi sun-java6-fonts \
msttcorefonts ttf-dejavu-core ttf-kochi-gothic ttf-kochi-mincho \
  lib32asound2-dev lib32bz2-dev git-core

甚至我還安裝了 virtualbox, qemu 等套件

二、取得原始碼

取得原始碼的話,我是遵照這一篇裡面的安裝 depot_tools來做,把 gclient 放在自己的家目錄中。

有了 gclient, 可以透過 gclient config http://src.chromium.org/svn/trunk/src 來設定 gclient 的環境,不過,請確定你要放 source code 的目錄位置再做此動作。以文件中的方式先放別的地方,再用 link 的方式也是可行。底下講的都是指這個放 source code 的目錄而言。

接下來就是抓 source code, 命令很簡單,就是 $ gclient sync

當然要抓很久很久....建議你去休息看個書,明天再來看。不過,沒理解錯的話(還需要確認),browser 的部份是採用 binary 的這種已編譯好的,若還需要另行編譯 browser 的話,需要參考編譯 Chromium OS裡面的 Option 說明。

三、建立開發系統

在編譯前,我建議一定要有一個認知再去讀原始文件,那就是建立 chromium os 的整個動作,它是建立一個新檔案系統,然後是用 chroot 進去執行的,所以,文件中有 "Inside", "Outside" 分別指的就是在 chroot 裡面,還是外面。換言之,Outside 就是一般你開機後的環境,也就是開發環境。而 Inside 是要透過 ./enter_chroot.sh 之後的環境。這一點尤其在看Running Tests一文時特別要注意。

有了上面的理解之後,當然要先來建立 chroot 的環境,請執行
$ ./make_chroot

建好環境後可以透過下面的方式進入,注意 chroot 環境不必常常重建,以後想要用,也只需要直接執行下面的步驟:
$ ./enter_chroot.sh

四、設定開發對象

接下來是設定環境,首先是設定要給什麼樣的平台使用,這邊只有兩種選擇,一個是 x86-genenric, 一個是 arm-generic,這只是開發環境,因此這兩類也就夠了。我是選 x86-generic
cd ~/trunk/src/scripts
./setup_board --board=x86-generic
echo x86-generic > ~/trunk/src/scripts/.default_board


五、建立測試帳號

ChromiumOS 開機後會需要以 google 帳號登入,或是 ssh 登入,此時請透過底下的方式建立此測試帳號:
./enable_localaccount.sh TEST_ACCOUNT
./set_shared_user_password.sh


六、編譯

就不多說了,直接用下面的命令建立套件及產生影像檔
./build_packages --board=x86-generic
./build_image --board=x86-generic


七、轉換成 virtualbox 或 vmware 虛擬機器環境的影像檔:

./image_to_virtualbox.sh --from=../build/images/x86-generic/0.7..... 這命令會產生一個 os.vdi 在 ../build/images/x86-generic 目錄下

2010/04/08

Chromium OS -- initialize

不知道為什麼,我似乎跟 chromium 脫不了關係,原因就不多說了,現在則要專心來讀讀這個流行的東西。

首先要說的是,chrome、chromium、chrome OS 與 chromium OS 的關係,我底下的認知不見得正確。

一、google 推出的,才叫 chrome, 才叫 chrome OS, 其他人推出的,都只能叫 Chromium 及 Chromium OS
二、Chrome OS 想當然,就是一個極類似 ubuntu or special for qualcomm 的 linux 加上 chrome
三、上面這說法還不見得正確,比較正確的是 Chromium OS 想當然,就是一個極類似 ubuntu or special for qualcomm 的 linux 加上 chromium
四、在編譯上,chromium os 需要 x86_64 的環境,這就導致下面的需求

若你想自己編譯 chromium os, 最好的方式是去 http://cdimages.ubuntu.com/ 找 amd64 的 iso 檔 來安裝。

若想拿到比較新的資訊,可以至 chromium查閱文件。

2010/03/21

致勝讀後心得-winning by Jack Welch

最近在讀致勝,傑克威爾許的中文版,非常值得所有人花點時間閱讀,我相信,在職場上的問題,或多或少都可以在這本書找到答案。

我很慶幸,在家裡,跟老婆相處,我能做到坦誠,書中非常重要的觀念。至於職場?若有看我前面的心得就會知道,我何其不幸。不過,永不言敗,我還是努力的去做好我的角色。

跟過我的人就會知道,我一向有話會直接跟他們說,有時我也會反省,我會不會講太多反而有傷害?我一直在跟我帶的伙伴們說,就算會有擔憂,我還是寧可選擇坦誠。

先講點簡單的,我認為,坦誠是雙向的,甚至是全面的,若只是上對下的坦誠,會變成比較接近溺愛,甚至是包疪,若只是下對上坦誠,會變成愚忠。只有雙向的坦誠,才是健康的環境。

2010/03/19

態度決定一切心得摘要 Attitude is everything

這一本書很久以前讀的,書也不知道被我放到哪兒了,甚至心得也寫下很久了,卻懶得查作者什麼的,請有興趣的人自行翻查。請參考簡報版本


  • 態度決定一切:永不放棄,無欲則剛,除死無大事
    • 工作就意味著責任:
      • 人人應把工作視為使命,負責任做到好。
      • 負責=信任
    • 勇敢地承認錯誤:
      • 能承認錯誤並負起責任者,方能委以重任。
      • 認錯=戰勝自己
    • 工作中無小事:
      • 人人都是螺絲釘。
      • 勿以善小而不為,勿以惡小而為之。
    • 像水牛一樣勤奮:
      • 只有勤奮才能與老闆獲得雙贏。
      • 滾石不生苔
      • 把工作當成自己的事業:
        • 從工作中實現夢想
      • 用心去工作:
        • 勤奮並非把工作當成機械性工作
      • 勞與逸的結合:
        • 最神秘的力量來自日夜交替,四季更替。
        • 終點是再出發的好地方
      • 繼續努力:
        • 鬆懈、安逸與放棄,永遠到不了終點
    • 盡職盡責才能盡善盡美:
      • 盡職只是本分,盡責把工作做好才能完美自己
  • 不要為自己找藉口:別學陳水扁
    • 藉口就是推卸責任:
      • 積極樂觀,持之以恆
    • 沒有任何藉口:
      • 服從、負責、榮譽、貫徹上級意志
      • ☆藉口:不關我事、我很忙、以前不是這樣的、這件事我不會、他比我適合
    • 服從是美德:
      • 覆誦命令、然後守紀律、盡己所能做好它
    • 不要成為藉口的奴隸:
      • 藉口是一種習慣,養成讓藉口遠離的習慣(工作文化)
      • 當老闆需要你時,為他加班、主動承擔任務、對工作表現興趣與熱忱、不做與工作無關的事
  • 這種事不用老闆交待:主動直接的行動為自己為公司爭利益
    • 主動與老闆溝通:
      • 只有學會與老闆溝通,才能把事情做好
      • 學會與老闆溝通才能與他的思想同步
      • 溝通時的態度:
        • 簡潔、不卑不亢、傾聽、勿貶低他人、勿踩在他人頭上
      • 養成注意小細節的習慣
      • 找到溝通的方式:每個人都有不同的溝通方式
      • 替他人留面子
    • 做好自己的工作,不需要老闆分咐:
      • 做好自己的工作是基本要求,卻是成功要素
      • 公司的工作都是自己的工作
      • 主動了解老闆與公司有助於自己工作的推展
    • 為老闆分憂解勞:
      • 這樣的人,誰都喜歡
      • 充實自己,隨時為上級分憂解勞
      • 正確看待工作,設法自己創造職位
    • 自動自發地工作:
      • 別在上級看不到時放鬆自己
      • 君子不欺暗室。
        • 禮記:莫見乎隱,莫顯乎微,故君子慎其獨也
      • 去發現需要的工作,哪怕那不是你的工作
  • 養成積極主動的習慣
    • 每天多做一點點:
      • 不止盡職盡責,不懈怠,成就自己與別人
    • 不要只為薪水工作:
      • 經驗的累積,從工作中創造自己的價值
      • ☆指的是對工作敷衍了事、到處兼職、隨時準備跳槽
    • 公司的每一件事,都值得我們去做:
      • 做好每件事者,方對公司最有價值
      • 即使日常生活中最平凡的事,也值得全神貫注地完成
      • 不積跬步無以至千里之外,不積小流無以成江海之大
    • 向老闆積極表現自己:
      • 不要以為這樣會踐踏別人,也別嫉妒別人
      • 提高自己的悟性,多用心體會上級的用心與用意
      • 設法讓自己與上級的思想同步,並適時予以鼓勵與理解
      • 關鍵時刻露一手:勇敢承擔重大的任務
      • 常用肯定的語氣
      • 讓老闆知道你的成績
      • 讓自己忙碌
      • 蛋糕若像一坨大便,再怎麼好吃也不會被看中
    • 比老闆更積極主動:
      • 老闆之所以是老闆,正因為他或他的祖先積極主動
      • 行動在老闆前面,並以此時刻勉勵自己
  • 把信送給加西亞:
    • 老闆看重的是具行動力的員工
    • 克服懶人的毛病
      • 懶是人類的大敵
      • 人無法完美,卻能從克服缺點做起
      • 煮青蛙的故事
    • 杜絕拖延:
      • 把握好時間,不要拖延,並追根究柢。
      • 勿以完美做藉口
    • 愈急的事要愈放慢腳步,冷靜仔細做好
    • 立刻行動起來:
      • 埋怨與等待對工作完全沒幫助
    • 最悲哀的一句話:
      • 我當初真該那麼做 ((卻沒有做))
    • 做一匹高效率的千里馬:
      • 耐跑而且會真的跑
    • 分清工作的輕重緩急
    • 不要延長你的工作時間:
      • 加班並不會讓人有效率
      • 延長工作時間會帶來藉口