Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3398941
  • 博文数量: 864
  • 博客积分: 14125
  • 博客等级: 上将
  • 技术积分: 10634
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 16:53
个人简介

https://github.com/zytc2009/BigTeam_learning

文章分类

全部博文(864)

文章存档

2023年(1)

2021年(1)

2019年(3)

2018年(1)

2017年(10)

2015年(3)

2014年(8)

2013年(3)

2012年(69)

2011年(103)

2010年(357)

2009年(283)

2008年(22)

分类: Java

2010-10-19 14:14:24

在 [] 的 LedTest 範例裡,找到 [] 檔案。這個檔案為應用程式的「交貨清單」;在開發 LedTest 的過程中,我們加入了一個屬性如下:

    package="com.mokoid.LedTest"
android:sharedUserId="android.uid.system">

原來,ServiceManager 會去檢查應用程式的權限;Android 作業系統會根據 UID 做權限管制,這裡所講的 UID 就是 Linux 系統管理面所討論的 User ID,即使用者 ID。在 [] 裡,找到這段實作:

int svc_can_register(unsigned uid, uint16_t *name)
{
unsigned n;
 
if ((uid == 0) || (uid == AID_SYSTEM))
return 1;
 
for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
return 1;
 
return 0;
}
 
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
void *ptr, unsigned uid)
{
struct svcinfo *si;
// LOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);
 
if (!ptr || (len == 0) || (len > 127))
return -1;
 
if (!svc_can_register(uid, s)) {
LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
str8(s), ptr, uid);
return -1;
}
...
}

AID_SYSTEM 被定義為 1000,即 system server 的 UID。從上述的實作可以了解,ServiceManager 會去檢查應用程式的 UID,當 UID 不符規定時,便無法執行 do_add_service()。

也就是:當應用程式的 UID 不是 1000 時,是沒有權限新增 Android Service 的。所以,在 AndroidManifest.xml 裡加上 android:sharedUserId 屬性的目的在於此:將應用程式的 UID 定義為 android.uid.system 即 1000,程式即可具備新增 Android Service 的權限。

以 Mokoid 所提供的範例為例,「因為我們是在 Android 應用程式裡啟動 Android Service」,因此要特別留意這個部份。典型的新增 Android Service 做法是修改 frameworks/base/services/java/com/android/server/SystemServer.java 檔案,但是,「因為 3M 分支維護策略的理念是儘量避免更動原始的 Android 程式碼」,所以我們採取這種「Start LedService in a seperated process.」的做法。細節請參考 Mokoid 範例。

經由 [] 範例,我們可以學習到擴充(Extent)Android 框架的做法。搭配 Product Tree 的方式,我們將 LedManager 與 LedService 二個類別編譯成獨立的 jar 檔(mokoid.jar),mokoid.jar 會被 Android build system 自動佈署到 system.img 裡(system/framework/mokoid.jar)。

因為 mokoid.jar 裡的類別沒有做 preload,並不是「preload class」,所以需要額外的系統設定,才能讓 Android 作業系統找到 LedManager 與 LedService 二個類別。在 Mokoid 範例中,找到一個名為 com.mokoid.server.xml 的設定檔,內容如下:



file="/system/framework/mokoid.jar"/>

此設定檔的作用為:指定 com.mokoid.server 的相對應 jar 檔。「com.mokoid.server」是 Java package(library name)、mokoid.jar 是檔案。透過 com.mokoid.server.xml 來設定其對應關係,並將此檔案置於 /etc/permissions 目錄下,這是基本的 Android 系統管理。

延伸閱讀


今天在上海進行「Android Framework & HAL 軟硬整合」培訓課程,課程中提到 init.rc 的用途,因此在此做一個紀錄。init.rc 是 Android 作業系統的 initial script,在開機時由 init 讀取並執行 init.rc 裡的命令。Android 的 init.rc 使用的的語法稱為 Android init language,有別於傳統 Embedded Linux 採用 shell script 的方式。

在 init.rc 裡找到類似以下的命令片斷:

on boot
setprop ro.FOREGROUND_APP_ADJ 0
setprop ro.VISIBLE_APP_ADJ 1
setprop ro.SECONDARY_SERVER_ADJ 2
...

以上是一個動作(action)區段的設定,說明如下:

1. on boot 表示在開機時(boot)觸發此動作區段裡的所有命令。
2. setprop 是設定 Android property 的命令。

上述提及的「動作區段」設定格式如下:

on 


當 "trigger" 為 "boot" 時,表示「開機觸發」。一個動作區段裡,可以有任意個命令(command),每個命令獨立於一行。最常見,也最重要的命令就是 'setprop'。'setprop' 用來設定 'property' 的值,property 有點像是系統的「環境變數(environment variable)」。其命令格式如下:

setprop  

例如:

setprop ro.product.device dma6410xp

表示「ro.product.device = "dma6410xp"」的意思。Android 系統有非常多 property,這些 property 都是 Android 作業系統本身在使用的重要變數,例如:上例的「ro.product.board」就是給 HAL 使用的重要變數。


上一則日記提到 Android property 的設定。在 Android 作業系統裡,取得 property 是很重要的工作。不管是 Android 框架層(使用 Java 語言),或是 Native 層(使用 C/C++ 語言),都可以看到讀取 property 的程式碼。

以下是一段簡單的範例程式,用以說明如何用 C 來讀取 Android 系統的 property:

/*
* Copyright (C) 2010 The Mokoid Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#define LOG_TAG "LED Stub"

#include
#include
#include
#include

#include
#include
#include

#define HAL_DEFAULT_VARIANT "default"

static const char *variant_keys[] = {
"ro.hardware", /* This goes first so that it can pick up a different file on the emulator. */
"ro.product.board",
"ro.board.platform",
"ro.arch"
};
#define HAL_VARIANT_KEYS_COUNT (sizeof(variant_keys)/sizeof(variant_keys[0]))

int main()
{
int i;
int status;
char prop[PATH_MAX];

status = -EINVAL;

for (i = 0; (status != 0) && (i < HAL_VARIANT_KEYS_COUNT); i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
printf("Your property is: %s = %s\n", variant_keys[i], prop);
}

return 0;
}

上述範例,是由 libhardware 的程式碼修改而成。HAL (即 libhardware) 會讀取以下四個 property:

  • ro.hardware
  • ro.product.board
  • ro.board.platform
  • ro.arch

習慣上,我們會以 "ro.product.board" 做為 HAL 模組的 "product name",ro.product.board 決定 HAL 模組的命名方式。例如,當 ro.product.board 為 "mokoid" 時,我們就必須將 HAL 模組命名為 *.mokoid.so,並存放於 system/lib/hw 目錄下。

阅读(1361) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~