android下usb框架系列⽂章---(6)UsbDeviceManager及功
能设置流。。。
⼀光盘bicr的流程(UsbDeviceManager.java)
1.1光盘backfile的控制
k_bicr_support:这个值系统变量⽤来标识是否显⽰光盘内容,两个值yes,yes_hide.
这个值的初始化发⽣在UsbDeviceManager.java⽂件⾥
if(nativeInitUMSproperty())
SystemProperties.t("k_bicr_support","yes");
staticjboolean android_rver_UsbService_initUMSproperty(JNIEnv *env,jobject thiz)
{
#ifdefMTK_BICR_SUPPORT
return true;
#el
clientupdateprohibitedreturn fal;
#endif
}
是否⽀持光盘内容弹出通过MTK_BICR_SUPPORT宏来决定。光盘作为mass_storage的⼀个⼦类,只要在使能了mass_storage 功能后,并且在mass_storage驱动中定义了cdrom的lun个数⾮0后,就会在pc上出现光驱。但是是否有⽂件系统还需要⼀个步骤。上⾯的k_bicr_support就是⽤来控制这个功能的开关。
该值为yes的话就会触发⽂件系统的挂载。
总体流程:
lfintroduction在UsbDeviceManager.java中showBuiltinInstallerUI,启⽤了BuiltinInstallerActivity。这个activity会弹出对话框询问⽤户是否需要光盘,其实是是否挂在光盘内容。
Mountrvice.java中,shareCDRom---doshareunshareCDRom--mconnector.doCommand
进⼊nativedaemonconnector.java docommand--
经过jni进⼊到comandlistener.cpp该⽂件位于vold⽂件夹内,
执⾏CDROMCmd的runCommand函数,执⾏bicr.cpp的shareCdRom函数,
const char*Bicr::CD_ROM_PATH = "/dev/block/loop0";
const char*Bicr::CD_ROM_LUN_PATH ="/sys/class/android_usb/android0/f_mass_storage/lun-cdrom/file";
最后通过el if (write(fd, CD_ROM_PATH,strlen(CD_ROM_PATH)) < 0) {
完成了⽂件对应介质的操作。
1.2光盘backfile的触发启动
PR:那么showBuiltinInstallerUI是什么时候启动的呢?挂载的介质在拔除usb cabel时有没有被清掉呢?防⽌下次在界⾯中虽然设置了hide,依然会显⽰光盘内容?所以应该是在拔除这个动作发⽣时清
除才对。代验证。
第⼀种情况:系统启动完成时,但是要判断usb是否连接着,连接着才会考虑
if(action.equals(Intent.ACTION_BOOT_COMPLETED)) {免费英语口语培训
Slog.i(TAG, "BOOT_COMPLETED");
Handler showBuiltinInstallerHandler = new Handler();
showBuiltinInstallerHandler.postDelayed(mShowBuiltinInstallerRunnable,14000);
}
private Runnable mShowBuiltinInstallerRunnable = newRunnable()
{
@Override
public void run()
{
Slog.i(TAG,"Delay show");
showBuiltinInstallerUI(mConnected);
}
};
⼆系统上电的时候
elif(action.equals(IPO_POWER_ON)) {
SXlog.d(TAG, "onReceive - [IPO_POWER_ON] mDefaultFunctions: " +mDefaultFunctions + ", mSettingUsbCharging: " +mSettingUsbCharging);
if (mSettingUsbCharging) {
mSettingUsbCharging= fal;
tCurrentFunction(mDefaultFunctions, fal);
}
showBuiltinInstallerUI(mConnected);
三收到更新消息,并且是发⽣了硬件重新插拔动作才进⾏处理,所以如果仅仅是软的连接不会发⽣这个动作
public void handleMessage(Message msg) {
switch (msg.what) {
ca MSG_UPDATE_STATE:
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
updateUsbNotification();
updateAdbNotification();
if (containsFunction(mCurrentFunctions,
UsbManager.USB_FUNCTION_ACCESSORY)) {
updateCurrentAccessory();
}
//注意下⾯这个处理,当usb状态位connect(fal),function会切换到默认的功能上,变成fal有两种情况:1 软断,这种断开后会紧跟着⼀个设置会进来,这种情况是为了设置新的,才会先断⼀下,所以要设置的会⽣效2、真断,这种就是硬件上断开、拔除了,下⾯这部分代码会将其设置到默认的function上。(⽬前打算是在tting中设置功能,但是每次设置完后,等再次插⼊时,⼜会恢复到默认的状态,mHwDisconnected标识硬件上是否连接的状态)
if(!mConnected &&!mSettingUsbCharging) {
// restore defaults when USB is disconnected
SXlog.d(TAG, "handleMessage - MSG_UPDATE_STATE - mConnected: " +mConnected + ", mSettingUsbCharging: " +mSettingUsbCharging);
tEnabledFunctions(mDefaultFunctions, fal);
}
if (mBootCompleted) {
updateUsbState();//将传过来的最新usb信息更新到UsbManager及其他全局变量中
Log.w(TAG, "handleMessage mConnected:" + mConnected +",mConfigured:" + mConfigured +
", mHwDisconnected:" + mHwDisconnected + ", mHwReconnected:" +mHwReconnected);
if(mHwReconnected == true &&mConnected == true) {
showBuiltinInstallerUI(true);//只有当硬件重新连接过,才会重新挂载介质
mHwReconnected = fal;
}
}
break;
下⾯这个函数⽤来更新状态,发送消息,随后上⾯的 handleMessage进⾏处理
public void updateState(String state)美藤
这个updateState的触发是有kernel层上来的,kernel层会发出uevent消息,所以上⾯需要接收、处理uevent消息。
如下:
private final UEventObrver mUEventObrver = new UEventObrver(){
@Override
public void onUEvent(UEventObrver.UEvent event) {
if (DEBUG) Slog.v(TAG, "USB UEVENT: " +String());
String state = ("USB_STATE");
String accessory = ("ACCESSORY");
//Added for USB Develpment debug, more log formore debuging help
if(DEBUG) Log.w(TAG, "mUEventObrver: onUEvent: state = " +state);
寂寞的意思//Added for USB Develpment debug, more log formore debuging help
if (state != null) {
mHandler.updateState(state);
} el if ("START".equals(accessory)) {
if (DEBUG) Slog.d(TAG, "got accessory start");
tCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY,fal);
}
}
};
下⾯看⼀下 mHandler = Looper());
private final class UsbHandlerextends Handler {
这个UsbHandler是⼀个主要的usb处理类。
public void updateState(Stringstate) {
………………
Message msg = Message.obtain(this, MSG_UPDATE_STATE);
msg.arg1 = connected;
msg.arg2 = configured;
// debounce disconnects to avoid problems bringing up USBtethering
if (mHwDisconnected ||mSettingUsbCharging){
SXlog.d(TAG, "updateState - UPDATE_DELAY " +state + " mSettingFunction: " + mSettingFunction); ndMessageDelayed(msg,(connected == 0) ? UPDATE_DELAY : 0);
}
老爸老妈浪漫史
………………
在updateState函数中,通过传进来的state,重新调整了connected 和 configured两个参数,并传递了消息。
然后回到了上⾯的第三种情况中的消息处理函数handleMessage。
root@android:/sys/class/android_usb/android0 # catstate
CONFIGURED
在updateState函数中有4个state状态:est
HWDISCONNECTED 硬件上拔除了usb cabel
DISCONNECTED 这个应该是软拔除,现在理解是软件上的⼀种设置
CONNECTED 已经连接上了
CONFIGURED 已经配置完成
其中有⼀个重要变量mHwReconnected⽤来记录这次连接是否是硬件的再次连接,⽽不是软件设置上的重新连接。
1.3光盘backfile的unshare
上⾯有⼀个疑问是,什么时候将光盘的⽂件系统介质拿掉的。如下,通过下⾯的receiver接收到usb的action:ACTION_USB_STATE,如果发⽣了拔除动作,则shareCDRom(fal)卸载掉⽂件系统介质。
// This class is ud to cloBuiltInstallerActivity and ims rvice unMount if it ismounted
public class BuiltinInstallerReceiver extendsBroadcastReceiver {
private static final String TAG ="BuiltinInstallerReceiver";
@Override
public void onReceive(Context context, Intent intent) {casualty
String action = Action();
if (UsbManager.ACTION_USB_STATE.equals(action)) {
boolean connected = Extras().getBoolean(UsbManager.USB_CONNECTED);
if (!connected && SharedStatus()){
try {
IMountService ims = MountService();
if (ims == null) {
Log.e(TAG, "Cant get mount rvice");
}
ims.shareCDRom(fal);ik是什么意思的缩写
BuiltinInstallerActivity.tSharedStatus(fal);
Log.i(TAG, "STOP sharing builtin installer");
} catch (RemoteException e) {
Log.e(TAG, "Cant call mount rvice");
}语文高考试卷
}