田海立
2012/10/9
本文簡析Android內建的Factory Test(有測試模式/原廠模式/工程模式等叫法)架構,並非講解FactoryTest中的每個測試該怎麼寫。
Android架構中已經對FactoryTest做了支援,通過一些配置和開發工作就可以把FactoryTest代碼融入到Android系統中。
一、FactoryTest層級的定義
Android系統中在com.android.server.SystemServer(loc:frameworks/base/services/java/)中對FactoryTest的層級做了定義:
public static final int FACTORY_TEST_OFF =0;public static final int FACTORY_TEST_LOW_LEVEL = 1;public static final int FACTORY_TEST_HIGH_LEVEL= 2;
- FACTORY_TEST_OFF是正常模式;
- FACTORY_TEST_LOW_LEVEL是工程模式做在較低的層級,也就是運行工程模式的時候,很多的service並不需要啟動;
- FACTORY_TEST_HIGH_LEVEL是工程模式做在較高的層級,也就是運行工程模式的時候,基本的Android運行環境是同正常模式是相同的。在原生的實現中,與正常模式相比除了ActivityManagerService外並沒有太多不同。
後面著重來看FACTORY_TEST_LOW_LEVEL,也用此模式來代替FactoryTest的表述。
二、FactoryTest不需要啟動的服務
系統從FACTORY_TEST_LOW_LEVEL模式啟動,下列服務或Observer根本就不會被啟動:
BluetoothService
BluetoothA2dpService
DevicePolicyService
StatusBarManagerService
ClipboardService
InputMethodManagerService
NetStatService
NetworkManagementService
ConnectivityService
ThrottleService
AccessibilityManagerService
MountService
NotificationManagerService
DeviceStorageMonitorService
LocationManagerService
SearchManagerService
DropBoxManagerService
WallpaperManagerService
AudioService
HeadsetObserver
HookSwitchObserver
HdmiObserver
DockObserver
UsbService
UiModeManagerService
BackupManagerService
AppWidgetService
RecognitionManagerService
DiskStatsService
而下列基本的服務會在FACTORY_TEST_LOW_LEVEL模式時執行的路徑有所不同:
ActivityManagerService
FACTORY_TEST_LOW_LEVEL模式時,不會發出BOOT_COMPLETED廣播;啟動第一個程式不是通過Acrtion為MAIN,Category為Home的Intent來啟動第一個程式,而是通過Acrtion為Intent.ACTION_FACTORY_TEST (“android.intent.action.FACTORY_TEST)的Intent來啟動。
PackageManagerService
FACTORY_TEST_LOW_LEVEL模式時,對包含FACTORY_TEST這個Permission的包,加上ApplicationInfo.FLAG_FACTORY_TEST的標誌。
ContentService
FACTORY_TEST_LOW_LEVEL模式時,SyncManager會因為FactoryTest模式下的差異,而表現不同。
WindowManagerService
FACTORY_TEST_LOW_LEVEL模式時,沒有IME。
三、FactoryTest的配置
由上面簡要分析知道,FACTORY_TEST_LOW_LEVEL模式下,要對FactoryTest程式進行配置。另外,如何進入FactoryTest模式也要進行配置。
3.1 FactoryTest應用的配置
由上面簡要分析知道,FACTORY_TEST_LOW_LEVEL模式下,第一個被啟動的程式就是工程模式的測試程式,而這個程式必須:
- 有響應Action為Intent.ACTION_FACTORY_TEST(“android.intent.action.FACTORY_TEST”)的Activity;
- 另外,這個程式還必須擷取“android.permission.FACTORY_TEST”;
- 這個程式必須為系統內建程式(安裝在/system/app/)
響應Action為Intent.ACTION_FACTORY_TEST (“android.intent.action.FACTORY_TEST”)的Activity在開機之後就被執行。
3.2 啟動模式設定
啟動模式是由“ro.factorytest”這個系統屬性來決定的,取值範圍是0/1/2,對應第一部分定義的三個層級模式。可在在.mk檔案中通過PRODUCT_PROPERTY_OVERRIDES或ADDITIONAL_DEFUALT_PROPERTIES追加一個這樣的屬性。比如:
#FactoryTest LowLevelPRODUCT_PROPERTY_OVERRIDE += ro.factorytest=1
3.3 核心啟動模式
有些實現通過上面的設定還不起作用,那是因為在核心啟動時,通過啟動模式對“ro.factorytest”這個系統屬性進行了設定。
理想狀態是由核心來決定啟動模式,而不需要上小節的設定。
核心通過參數“androidboot.mode”來決定原廠模式(”factory”對應FACTORY_TEST_LOW_LEVEL;”factory2”對應FACTORY_TEST_HIGH_LEVEL;其他值或未設定對應”factory”對應FACTORY_TEST_OFF)。
上面需要核心支援,不支援的話就固定為正常模式。
所以,如果核心不支援,可以直接把init.c中判斷“androidboot.mode”而設定“ro.factorytest”的代碼暫時屏蔽,直接用上節所說的“ro.factorytest”來決定Factory的模式。
總結
本文分析了:
1. Android原生實現中已有的FactoryTest的架構:屏蔽了一些服務和功能;
2. 並通過下列方式就可實現工廠測試模式:
1) 寫一個FactoryTest的應用;
2) 設定“ro.factorytest”系統屬性,並屏蔽由核心來設定的設定,
或者
3) 通過核心啟動參數“androidboot.mode”決定FactoryTest的模式。