usb状态相关处理

关于Usb的检测,相关联的和sd card一起研究。

在状态栏如何进行显示Sd卡插入状态的NotificationUsbDebugging时的Notification的?

先来看Sd卡的Notification显示:

StatusBarPolicy.javaStatusBarPolicy类的构造函数中,有这样关于Sd卡的状态监听机制:

 // storage

 mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

 mStorageManager.registerListener(

               new com.android.systemui.usb.StorageNotification(context));

 进入StorageManager.javaregisterListener去查看是怎样监听的:

  public void registerListener(StorageEventListener listener) {

        if (listener == null) {

            return;

        }

        synchronized (mListeners) {

            mListeners.add(new ListenerDelegate(listener));

        }

    }

可见所谓注册过程就是将监听类添加到监听的List表中,那么,在这个表中如何监听的?

查看ListenerDelegate

ListenerDelegate(StorageEventListener listener) {

            mStorageEventListener = listener;

            mHandler = new Handler(mTgtLooper) {

                @Override

                public void handleMessage(Message msg) {

                    StorageEvent e = (StorageEvent) msg.obj;

                    if (msg.what == StorageEvent.EVENT_UMS_CONNECTION_CHANGED) {

                        UmsConnectionChangedStorageEvent ev = (UmsConnectionChangedStorageEvent) e;

                        mStorageEventListener.onUsbMassStorageConnectionChanged(ev.available);

                    } else if (msg.what == StorageEvent.EVENT_STORAGE_STATE_CHANGED) {

                        StorageStateChangedStorageEvent ev = (StorageStateChangedStorageEvent) e;

                        mStorageEventListener.onStorageStateChanged(ev.path, ev.oldState, ev.newState);

                    } else {

                        Log.e(TAG, "Unsupported event " + msg.what);

                    }

                }

            };

        }

实际上就是开启一个无线循环的Handler等待消息的传送过来,到这一步自然就会想到是谁发送消息?

先插卡StorageManager类的构造函数:

  public StorageManager(Looper tgtLooper) throws RemoteException {

        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));

        if (mMountService == null) {

            Log.e(TAG, "Unable to connect to mount service! - is it running yet?");

            return;

        }

        mTgtLooper = tgtLooper;

        mBinderListener = new MountServiceBinderListener();

        mMountService.registerListener(mBinderListener);

    }

在开启StorageManager的时候实际上就开启一个MountService,将MountServiceBinderListener注册为监听类:

它的作用是这样的:

private class MountServiceBinderListener extends IMountServiceListener.Stub {

        public void onUsbMassStorageConnectionChanged(boolean available) {

            final int size = mListeners.size();

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

                mListeners.get(i).sendShareAvailabilityChanged(available);

            }

        }

        public void onStorageStateChanged(String path, String oldState, String newState) {

            final int size = mListeners.size();

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

                mListeners.get(i).sendStorageStateChanged(path, oldState, newState);

            }

        }

    }

也就是实际发送StorageEvent.EVENT_UMS_CONNECTION_CHANGED或者另外的消息:

EVENT_STORAGE_STATE_CHANGED

那么这个监听类如何知道状态变化的?

MountService.java中,

  public void registerListener(IMountServiceListener listener) {

        synchronized (mListeners) {

            MountServiceBinderListener bl = new MountServiceBinderListener(listener);

            try {

                listener.asBinder().linkToDeath(bl, 0);

                mListeners.add(bl);

            } catch (RemoteException rex) {

                Slog.e(TAG, "Failed to link to listener death");

            }

        }

    }

MountService中有一个可供守护进程调用的函数:

public boolean onEvent(int code, String raw, String[] cooked),它在有关状态发生变化时会调用相关函数,比如VolumeStateChange时,notifyShareAvailabilityChange(),而在 notifyShareAvailabilityChange()中会更新:

updatePublicVolumeState(),在这里我们看到实际就是通过Environment中相关函数判断Sd卡状态,

在这里:

synchronized (mListeners) {

            for (int i = mListeners.size() -1; i >= 0; i--) {

                MountServiceBinderListener bl = mListeners.get(i);

                try {

                    bl.mListener.onStorageStateChanged(path, oldState, state);

                } catch (RemoteException rex) {

                    Slog.e(TAG, "Listener dead");

                    mListeners.remove(i);

                } catch (Exception ex) {

                    Slog.e(TAG, "Listener failed", ex);

                }

            }

        }

也就是守护进程检测sd卡状态变化时调用StorageManager中的mBinderListener对象的onStorageStateChanged,此时在StorageManager中,就依次向需要知道Storage状态变化的目标发送消息,刚才我们说的StorageManager开启的无限循环的Handler收到消息就开始了相应处理。

Usb插入时有无Debugging时的Notification是怎样产生的?

UsbService.java中,private final UEventObserver mUEventObserver = new UEventObserver() 函数是用来监听底层Usb状态的机制。当"usb_connected""usb_configuration"、或者其它的Usb状态(Adb)发生变化时会发送一个Message,然后根据messageusbService做出相应的处理。

source code中,adb变化时,有Note如下:

Note: we do not broadcast a change when a function is enabled or disabled. We just record the state change for the next broadcast.

这就使得android系统不能及时更新Usb Notification状态。

handler处理函数处:

case MSG_FUNCTION_ENABLED:

case MSG_FUNCTION_DISABLED:

    functionEnabledLocked((String)msg.obj, msg.what == MSG_FUNCTION_ENABLED);

    break;

Note所说,仅仅是保存起来,并未进行更新。

要想即刻做出更新,应做出如下操作:

case MSG_FUNCTION_ENABLED:

case MSG_FUNCTION_DISABLED:

functionEnabledLocked((String)msg.obj, msg.what == MSG_FUNCTION_ENABLED);

// send a sticky broadcast containing current USB state

Intent intent = new Intent(UsbManager.ACTION_USB_STATE);

intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

intent.putExtra(UsbManager.USB_CONNECTED, mConnected != 0);

intent.putExtra(UsbManager.USB_CONFIGURATION, mConfiguration);

addEnabledFunctionsLocked(intent);

mContext.sendStickyBroadcast(intent);

break;

这就完成了及时更新策略。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值