设为首页收藏本站

数码鹭岛论坛

 找回密码
 注-册

QQ登录

只需一步,快速开始

搜索
楼主: 翔子
打印 上一主题 下一主题

Android 技术专题系列

[复制链接]
11#
 楼主| 发表于 2010-10-13 16:43:19 | 只看该作者

Android 技术专题系列之十一 -- DRM

简而言之,DRM系统提供一套机制对用户使用手机上的媒体内容(如ringtong, mp3等)进行限制,如限制拷贝给第三方,限制使用次数或时限等,从而保护内容提供商的权利。建议读者可以阅读OMA DRM 的规范,以便更好的了解代码。

相关代码主要位于下列目录:
frameworks/base/media/java/android/drm/mobile1
frameworks/base/media/libdrm/moblile1
frameworks/base/media/libdrm/mobile2
packages/apps/Mms/src/com/android/mms/drm: drm
packages/providers/DrmProvider/src/com/android/providers/drm

下面先作简要分析:
frameworks/base/media/libdrm/moblile1应该是提供OMA DMA1.0的本地/c++ 实现
frameworks/base/media/libdrm/moblile2应该是提供OMA DAM2.0的本地/c++ 实现。

frameworks/base/media/java/android/drm/mobile1 对应用提供OMA DRM 1.0 (即frameworks/base/media/libdrm/moblile1)的java接口。目前尚没有OMA DRM 2.0的java接口,也就意味着OMA DRM 2.0在Android中尚未应用。

packages/apps/Mms/src/com/android/mms/drm 实现在MMS中如何使用DRM。
packages/providers/DrmProvider/src/com/android/providers/drm ?

下面再作具体介绍:
一 目录 frameworks/base/media/java/android/drm/mobile1
这个目录是OMA DRM 1.0的java 接口。
OMA DRM 1.0 定义了几个重要概念:
DRM消息(DRM message):用户下载的一条DRM内容。根据下面介绍的DRM内容传输方式的不同,DRM消息中包含的内容亦有所不同,可能只包含一个未经加密的媒体对象;也可能即包含未加密的媒体对象,也包含一个权利对象;也可能只包含一个经过加密的媒体对象(.dcf)。
媒体对象 (media object):包含媒体资源,如一个mp3, ringtone等。
权利对象(Right object): 限制用户如何使用媒体对象。


OMA DRM 1.0 定义了DRM内容的四种传输方式:
1. Combined delivery: 这种传输方式中,媒体对象以未经加密的方式(plain) 与Right object打成一个包,一块传输。这个包下载到手机设备上后,不允许转发给其他设备。
2. Forward lock: 这种传输方式是combined delivery的一个特例。媒体对象没有对应的Rigth object。媒体对象不允许转发给其他设备
3. Separate delivery: 媒体对象和权利对象分别传输。媒体对象采用对称密钥加密,文件以.dcf为后缀。权利对象中则包含对应的密钥。
4. Superdistribution:类似separate delivery, 但媒体内容允许转发给其他设备。

相应地,本目录的代码中:

DrmConstraintInfo对象描述了(对媒体内容的)一组限制属性,如开始/结束使用日期,使用次数等;

DrmRights对象代表了一个OMA 权利对象。

DrmRightsManager管理设备上的Rigth Objects。所有下载的权利对象,不论是由separate delivery 还是 combined delivery,权利对象都要首先安装到设备上。

DrmRawContent代表一条DRM内容,分为两类:DRM_MIMETYPE_MESSAGE_STRING --DRM内容是经combined delivery 或 forward lock传输的(也即媒体对象没有加密,没有或者有一个权利对象); DRM_MIMETYPE_CONTENT_STRING -- DRM内容是经 separate delivery传输的(也即媒体对象是经过加密的dcf格式,不包含权利对象)。

DrmInputStream:这个对象从一个DrmRawContent对象中读出经过权利对象验证并解密后的(需要的话)媒体对象内容。这个内容之后就可以传给相关应用输出给用户。


二 目录frameworks/base/media/libdrm/moblile1
本目录真正实现DRM DRM 1.0。
drm1_jni.c提供对DrmRawContent中方法的本地实现;
objmng目录下是具体实现。frameworks/base/media/libdrm/mobile1/include/objmng/svc_drm.h中有关于每个方法的详细解释,基本思路是每打开一个Drm 内容,就创建一个session,然后提供一系列方法,以此session为参数,对Drm进行各种操作,如获取属性,读取解密后内容等。这里不再赘述。
12#
 楼主| 发表于 2010-10-13 16:44:08 | 只看该作者

Android 技术专题系列之十二 -- Alarm manager

Alarm manager 主要管理硬件时钟。一些与时间相关的应用,如日历,闹钟等需要使用Alarm Manager的服务。Alarm manager功能相对比较简单,相关代码位于
frameworks/base/core/jni/server/com_android_server_AlarmManagerService.cpp
frameworks/base/services/java/com/android/server/AlarmManagerService.java

一. frameworks/base/core/jni/server/com_android_server_AlarmManagerService.cpp
这部分代码直接管理硬件时钟,设备名为/dev/alarm。包括打开设备,关闭设备,设置时区,设置触发时间(timeout),以及等待时钟触发。
二. frameworks/base/services/java/com/android/server/AlarmManagerService.java
这部分封装目录一中的代码,向上提供java接口,同时与客户端(如calendar)交互,接收来自客户端的时钟设置请求,并在时钟触发时通知客户端。
13#
 楼主| 发表于 2010-10-13 16:44:41 | 只看该作者

Android 技术专题系列之十三 -- 与PC同步

为了更好的了解Android 的Sync架构,建议读者可以参考OMA DS (Syncml)规范。 Android的Sync架构符合这一规范。相关代码主要位于frameworks/base/core/java/android/content。

网页http://mylifewithandroid.blogspot.com/2008/02/synchronization-in-android.html给出了目前来说比较深入的一篇关于Android同步的分析 (但是应该没有更新最近的Android cupcake的情况)。

值得注意的是,Android中的mail (GMail), Contact, Calendar等还可以与Google相应的服务器同步,而服务器又可以和PC同步。
14#
 楼主| 发表于 2010-10-13 16:45:22 | 只看该作者

Android 技术专题系列之十四 -- 组件模型及组件间通

PPT
15#
 楼主| 发表于 2010-10-13 16:46:00 | 只看该作者

Android 技术专题系列之十五 -- 更新开发手机到1.5

参照http://www.htc.com/www/support/android/adp.html,下面是在Android 开发手机上更新1.5 image的步骤 (主机是ubuntu Hardy):
1. 下载必要的image。
Radio image: ota-radio-2_22_19_26I.zip
Recovery image: signed-dream_devphone-ota-147201.zip

2. 在主机上创建文件/etc/udev/rules.d/50-android.rules,内容:
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
并修改文件属性:
chmod a+rx /etc/udev/rules.d/50-android.rules
然后重启机器

3. 将主机和Android开发手机通过usb 相连,运行命令 (./adb 命令来自sdk的tools)
./adb devices

应当看到一个device被列出。

4.参见http://www.htc.com/www/support/android/adp.html的 Update the Device Radio Firmware一节 ,更新firmware

5.参见http://www.htc.com/www/support/android/adp.html的 Copy the Recovery Image Package to the device一节 ,更新系统。

6. 切换到中文环境
./adb shell
$ su -
# setprop persist.sys.language zh;setprop persist.sys.country CN;stop;sleep 5;start

运行步骤6后,能看到有些应用的图标是中文,如"google 地图“。但大部分图标/环境仍然是英文。这应该是由于应用没有带中文语言包的缘故。读者可以试着安装一些带中文语言报的测试程序验证是否能够显示中文。
16#
 楼主| 发表于 2010-10-13 16:46:41 | 只看该作者

Android 技术专题系列之十六 -- 在模拟器上安装 sd

本文基于http://blog.jayway.com/2009/04/22/working-with-sd-cards-in-the-android-emulator/。特此申明。

今天想玩玩Android模拟上的music应用,可总是报告没有sd卡。网上搜了一下,有一哥们有一完整的解决方案(见上述连接)。这儿我将要点列在下面:
1.创建sd card image:
./mksdcard 1024M sdcard.img

2. 拷贝媒体文件, 如xxx.mp3, 到sd card image上。我考了一个我最喜欢的《滚滚长江东逝水》,呵呵。
sudo mount -o loop sdcard.img /mnt
cp xxx.mp3 /mnt
sudo umount /mnt

3. 创建一个AVD (Android Virtual Device)
./android create avd --name myAVD --target 2 --sdcard sdcard.img

这个命令会有很多选项让你确认,我只管一路回车。

4. 启动emulator
./emulator -avd myAVD

现在就可以打开music应用,欣赏音乐了。
17#
 楼主| 发表于 2010-10-13 16:47:12 | 只看该作者

Android 技术专题系列之十七 -- volume 服务

Android 的volume服务主要是用来管理usb/sd卡等外部存储设备。平台可以对外部存储设备进行操作和轮询状态,当外部存储设备状态发生变化时,volume 服务也会即时报告平台。

相关代码主要位于:
system/core/vold
frameworks/base/services/java/com/android/server/MountListener.java
frameworks/base/services/java/com/android/server/MountService.java
frameworks/base/core/java/android/os/IMountService.aidl
hardware/libhardware_legacy/mount/IMountService.cpp
hardware/libhardware_legacy/include/hardware_legacy/IMountService.h

下图概述了这些组件之间的关系。但是没有搞清楚IMountService.h/cpp是干什么用的。

还有一点值得注意,MountService被一个Android内部类ServiceManager注册(SystemServer.java):
ServiceManager.addService("mount", new MountService(context))
以这种方式注册有名服务(named service),所注册的服务是一个实现了aidl产生的stub类的派生类,并不需要实现一个Service的派生类。ServiceManager仅供Android平台内部使用。
18#
 楼主| 发表于 2010-10-13 16:47:41 | 只看该作者

Android 技术专题系列之十八-- 媒体文件管理

本文引用了http://letsgoustc.spaces.live.com/Blog/cns!89AD27DFB5E249BA!473.entry部分内容,特此申明。

Android平台上的媒体文件管理和桌面系统不同。在桌面系统上,不同目录下的媒体文件呈树状结构显示给用户,用户需要进入不同目录寻找该目录下的文件。而在Android平台上,不同目录下的媒体文件则以一层列表方式显示给用户,用户不需进入子目录就可以列出(某种类型的)所有媒体文件。

在Android上,为了实现这种模式的媒体文件管理,对所有管理的媒体文件抽取其元数据(mp3文件包含的元数据可参考http://en.wikipedia.org/wiki/ID3),存储在数据库中,并作为一个content provider提供给其他应用使用。用户的每一次显示媒体文件的操作,就是对这个数据库的一次查询操作。

实现这一功能的代码位于
frameworks/base/core/java/android/provider/MediaStore.java
packages/providers/MediaProvider/src/com/android/providers/media.
frameworks/base/media/java/android/media/MediaScanner*
frameworks/base/media/jni/android_media_*
external/opencore/android/mediascanner.cpp

下面略作分析:

external/opencore/android/mediascanner.cpp负责从媒体文件(mp3, mp4, wma等)中提取元数据。
19#
 楼主| 发表于 2010-10-13 16:48:51 | 只看该作者

Android 技术专题系列之十九-- Appwidget

要了解AppWidget,得先了解Homescreen。
HomeScreen是一个手机的脸面,是一个门户网站的首页,是手机上最为重要的应用。有一个好的homescreen,可以说这个手机已经成功了一半。

开发者当然可以在homescreen上开发很多功能和界面,比如一个时钟,一个天气预报,一个显示当前电池电量,未读短信等状态的状态栏等等。实际上,传统的homescreen也是这样做的。但这样做的弊端有两个:1. homescreen代码过于庞杂,和系统各个子系统都有交互,容易出错,不易维护;2. homescreen不能定制。最终用户可能有不同需求,而预设的功能则限制了用户选择的权力。

AppWidget 的出现主要就解决了这些问题。AppWidget是一个特殊的view,由一个应用(假设应用A)创建和维护,而绘制却在另一个应用上(通常即 homescreen)。即应用A负责决定画什么,如一个时钟;而homescreen却负责具体画,即怎么画。如果用一个比喻来形容的话,homescreen和应用A之间的关系就像是一个Browser/Server架构, homesreen 就是一个负责显示的browser,而应用A就是后台的Server。应用A传递RemoteView给homescreen,而homescreen解析并绘制这个RemoteView。这样,不用对homescreen应用做任何改动,却可以定制并丰富了homescreen的显示内容,如一个时钟,一个日历等。

如何创建一个AppWidget, 如何深入理解AppWidget, 等等,可见下列链接:
1. http://www.google.com/url?sa=t&source=web&ct=res&cd=1&ved=0CAgQFjAA&url=http%3A%2F%2Fdeveloper.android.com%2Fguide%2Ftopics%2Fappwidgets%2F&ei=Ct6iS93OMc-GkAWp0ODFCA&usg=AFQjCNGPwi7jyY4KL4MVAQzOZr_ALxZfwQ&sig2=iLmH_iOVfFHZz5p7gpGENA
2. http://www.google.com/url?sa=t&source=web&ct=res&cd=3&ved=0CBAQFjAC&url=http%3A%2F%2Fandroid-developers.blogspot.com%2F2009%2F04%2Fintroducing-home-screen-widgets-and.html&ei=Ct6iS93OMc-GkAWp0ODFCA&usg=AFQjCNF-SNy2OXJjVbirZVZi5zroa-wHbg&sig2=-2PREps5wYMGqtLOqoghsA
3. http://mylifewithandroid.blogspot.com/2010/01/remoteviews-as-hypertext-document.html
4. sample code located in development/samples/ApiDemos/src/com/example/android/apis/appwidget/

使用service, 也可实现两个应用之间的交互,大家可以探讨一下二者的区别。
20#
 楼主| 发表于 2010-10-13 16:50:53 | 只看该作者

Android系列之二十-- 在eclipse中浏览Android源码

Pls refer to http://stuffthathappens.com/blog/2008/11/01/browsing-android-source-in-eclipse/

如果能够在eclipse中浏览Android源代码,这对提高阅读源码的效率非常有帮助。根据上面连接,下面是一个简要步骤描述:
1. 安装eclipse 3.4或3.5 (本人使用的是从http://www.eclipse.org/downloads/上下载的3.4.1。3.5版本下面有些步骤没有成功)
2. 安装Android plugin (参见sdk 文档docs/sdk/eclipse-adt.html)
3. 从源码中创建一个项目, (create a project from existing sources),如为packages/apps/calendar
4. 安装Android源码到这个项目中。
4.1 在eclipse的Window->Preference->Android中,指定sdk location,例如xxx/android-linux-sdk_86
4.2 假设使用的sdk是1.6,则在目录xxx/android-linux-sdk_86/platforms/android-1.6/下创建sources目录
4.3 符号连接 你的源码 ln -s frameworks/base/core/java/android xxx/android-linux-sdk_86/platforms/android-1.6/sources/android
4.4 符号连接其他源码到sources目录下。注意:源码文件所放路径应该与源码文件所属Java包的名字匹配。例如,Bitmap.java属于android.graphics包,则应放于目录sources/android/graphics目录下。
4.5 如果你仍然不能浏览源码的话,可通过重新创建一个project进行刷新。这可能是我这个版本的eclipse的一个bug。
4.6,下面的script给出了如何抽取所有的java源码文件(http://blog.michael-forster.de/2008/12/view-android-source-code-in-eclipse.html):

from __future__ import with_statement  # for Python < 2.6



import os


import re


import zipfile


# open a zip file


DST_FILE = 'sources.zip'


  if os.path.exists(DST_FILE):


  print DST_FILE, "already exists"
  

exit(1)


zip = zipfile.ZipFile(DST_FILE, 'w', zipfile.ZIP_DEFLATED)




# some files are duplicated, copy them only once
written = {}


# iterate over all Java files




for dir, subdirs, files in os.walk('.'):


   for file in files:
   

    if file.endswith('.java'):
      

      # search package name


      path = os.path.join(dir, file)


      with open(path) as f:
        

        for line in f:
         

          match = re.match(r'\s*package\s+([a-zA-Z0-9\._]+);', line)
         

          if match:


            # copy source into the zip file using the package as path
            

            zippath = match.group(1).replace('.', '/') + '/' + file
            

            if zippath not in written:
              

               written[zippath] = 1
              

               zip.write(path, zippath)
            

            break;


         
zip.close()
您需要登录后才可以回帖 登录 | 注-册

本版积分规则

小黑屋|手机版|Archiver|数码鹭岛 ( 闽ICP备20006246号 )  

counter

GMT+8, 2025-12-3 20:16 , Processed in 0.065989 second(s), 17 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表