Android USBデフォルト接続モードはMTP

18909 ワード

以下の内容はMTKプラットフォームに基づいている.
多くの場合、携帯電話プロジェクトの開発では、お客様がUSBのデフォルト接続方式を設定するように要求していますが、Android 6.0以降のバージョンではUSB接続モードを直接配置し、見たUSB接続モードは充電のみで、これはgoogleのデフォルト設計です.では、この問題についても、Android 5.0はデフォルト値を直接構成することができ、6.0は実行できません.また、USB接続時に設定を行い、接続後に一度USB接続モードを設定してMTPを現在の接続モードに設定するというやり方も7.0以上で可能です.
実際、充電のみの場合、現在のUSBモードの構成を確認すると、mtpでもSDカードや内部メモリが表示されず、主にフラグの問題です.
既存の解法
では、ここではまずUSB接続の場合、USB接続モードの設定を1回実行します.ここには牛の方法があります.そして、Android 6.0以前のやり方についてお話しします.Android 6.0 USB接続モードはデフォルトでMTPに選ばれています.皆さん、参考にして勉強してみてください.では、この牛の改法をお話しします.Android 6.0と7.0で表現が異なるところです.
Androidバージョン
スクリーンロックの場合
ロック解除の場合
6.0
充電のみ
MTP
7.0
MTP
MTP
私たちのテストでは、ロックを解除せずにSDカードや内部メモリのデータに直接アクセスできる不安全なバグを提案しました.これは安全ではありません.それも理にかなっているようだから、変えましょう.しかし、これはまたいくつかの会社のお客様のニーズがあるかもしれません.
会社6.0の解法
上記の解法が6.0に似ていない行為について、次に私が見てみましたが、うちの会社は以前Android 6.0がどのように修正したのか、直接値を修正したのか、この値を修正するとSDカード、内部メモリが表示されます.
ファイルframeworks/base/services/usb/java/com/android/server/usb/UsbDeviceManagement.の変更java.
public class UsbDeviceManager {
                  ···      ···
        private boolean mConfigured;
        //modified in 2017-05-22 start
        //    ,    ,           MTP
        private boolean mUsbDataUnlocked = true;
        //modified in 2017-05-22 end
        private String mCurrentFunctions;
        private String mDefaultFunctions;

                ······

         @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_STATE:
                    mConnected = (msg.arg1 == 1);
                    mConfigured = (msg.arg2 == 1);
                    mUsbConfigured = mConfigured;
                    if (!mConnected) {
                        //modified in 2017-05-22 start
                        //default usb connect mode as mtp
                        // When a disconnect occurs, relock access to sensitive user data
                        //       ,        ,         MTP
                        mUsbDataUnlocked = true;
                        //modified in 2017-05-22 end
                    }
                    updateUsbNotification();
                    updateAdbNotification();
                    if (UsbManager.containsFunction(mCurrentFunctions,
                            UsbManager.USB_FUNCTION_ACCESSORY)) {
                        updateCurrentAccessory();
                    } else if (!mConnected) {
                        //modified  in 2017-05-22 start
                        //change default usb connect mode as mtp,do not restore
                        //            ,           
                        setEnabledFunctions(null, true);
                        //modified  in 2017-05-22 end
                    }
                    if (mBootCompleted) {
                        updateUsbStateBroadcastIfNeeded();
                        updateUsbFunctions();
                    }

                      ······
    }

上記の修正方法はandroid 6で簡単です.0と7.0では可能ですが、まだ違いがあります.
Androidバージョン
スクリーンロックの場合
ロック解除の場合
6.0
充電のみ
MTP
7.0
MTP
MTP
この修正方式の最終結果はやはり上の大牛の修正方式と結果が一致した.Googleが7.0でこの部分のコードを修正したと言うべきで、会社の以前の6.0の改法を使って、やはりだめです.
現在Android 7.0の解法
しかし、まだ会社のテストに提出されていない問題については、引き続き修正する必要があります.では、このようなことをよく見て、インターネットでUSB接続モードを理解してください.これはまだ深いです.ハードウェアに関するものは、少し複雑ですが、下層と通信しなければなりません.少しぐらい理解してから、この問題を解決してください.USB接続モードを切り替える上層から実現するには、mUsbDataUnlockedの値を修正します.適当な時にmUsbDataUnlockedの値を修正すると言うべきですが、以下ではいくつかの状況を分析して変更する必要があります:1.携帯電話が画面ロックの場合はUSB接続、接続モードは充電のみ.1.携帯電話がロック解除の場合はUSB接続、接続モードはMTP.1.携帯電話が画面を消した場合はUSBを切り、接続方式を充電のみに更新する.1.携帯電話がロック解除された場合はUSBを切り、接続方式を充電のみに更新する.
この4つの状況であるべきで、次の主な解決すべき問題は:1.ユーザーはロックを解除し、主測定放送:Intent.ACTION_USER_PRESENTは、ロックを解除したかどうかを判断してフロントにユーザを移動させる.1.USB接続状態に対応するコールバックがあり、このときUSB接続モードを更新します.1.スクリーンを消して、登録放送を通じてIntent.ACTION_SCREEN_OFF判定は、放送Intentの登録も必要である.ACTION_SCREEN_ON、画面状態値としての切り替え.
UsbServices.JAvaクラスに上記の放送受信者を登録し、UsbDeviceManagement.JAvaクラスのIDを更新します.
1.frameworks/base/services/usb/java/com/android/server/usb/UsbServicesを変更します.java
public class UsbService extends IUsbManager.Stub {
                ······
        final IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        filter.addAction(Intent.ACTION_USER_STOPPED);
        //add by xx in 2017-06-12 for bug 169853 start
        //      
        filter.addAction(Intent.ACTION_USER_PRESENT);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_SCREEN_ON);
        //add by xx in 2017-06-12 for bug 169853 end
        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
        mContext.registerReceiver(mReceiver, filter, null, null);

                ······

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
            final String action = intent.getAction();
            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                setCurrentUser(userId);
            } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
                synchronized (mLock) {
                    mSettingsByUser.remove(userId);
                }
            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
                    .equals(action)) {
                if (mDeviceManager != null) {
                    mDeviceManager.updateUserRestrictions();
                }
            //add by xx in 2017-06-12 for bug 169853 start
            //      
            }else if (Intent.ACTION_USER_PRESENT.equals(action)) {

                if (mDeviceManager != null) {
                    mDeviceManager.usbDataUnlocked(true);//        
                    mDeviceManager.setUserPresent();//        
                }
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                if (mDeviceManager != null) {
                    mDeviceManager.updateScreentSate(true);//        ,        
                }
            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
              if (mDeviceManager != null) {
                    mDeviceManager.updateScreentSate(false);//        ,        
                }
            //add by xx in 2017-06-12 for bug 169853 end
            }
        }
    };
}

2.次にframeworks/base/services/usb/java/com/android/server/usb/UsbDeviceManagement.を変更する.java
public class UsbDeviceManager {
        ·····
    //        ,    
    //modified by xx in 2017-06-12 for bug 169853 start
    private boolean mUserPresent = false;//         
    private boolean screenOff = false;//       
    private boolean changeByUser = false;//  USB     ,        ,         。
    //modified by xx in 2017-06-12 for bug 169853 end

            ·····
    //       , UsbService.java   ,       
    //modified by xx in 2017-06-12 for bug 169853 start
    public void setUserPresent(){
        mUserPresent = true;
    }

    public void updateScreentSate(boolean state){
        screenOff = state;
        if(!screenOff) {
             mUserPresent = false;
        }
        if(mHandler != null){
            mHandler.updateUsbMode();
        }
    }

    public void usbDataUnlocked(){
        changeByUser  = false;
        mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, true);
    }
    //modified by xx in 2017-06-12 for bug 169853 end

            ·····

      //  USB    
      public void updateState(String state) {
            int connected, configured;

            if ("HWDISCONNECTED".equals(state)) {
                connected = 0;
                configured = 0;
                mHwDisconnected = true;
                //add by xx in 2017-08-03 for swtich usb mode start
                changeByUser = false;
                //add by xx in 2017-08-03 for swtich usb mode end
            } else if ("DISCONNECTED".equals(state)) {
                connected = 0;
                configured = 0;
                mHwDisconnected = false;

                //modified by xx in 2017-06-12 for bug 169853 start
                //       ,           
                if(screenOff){
                    mUserPresent = false;
                 }
                 //modified by xxx in 2017-06-12 for bug 169853 end

            } else if ("CONNECTED".equals(state)) {
                connected = 1;
                configured = 0;

                    ·····


        private final class UsbHandler extends Handler { 

                        ·····

        //     USB       ,  USB  ,                
         @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_STATE:
                    mConnected = (msg.arg1 == 1);
                    mConfigured = (msg.arg2 == 1);
                    mUsbConfigured = mConfigured;
                    //modified by xx in 2017-06-12 for bug 169853 start
                    //update usb state first
                    updateUsbMode();
                    if (mUserPresent && !changeByUser) {   //      
                        mUsbDataUnlocked = true;//    ,               MTP 
                    }
                    //modified by xx in 2017-06-12 for bug 169853 end

                    if (!mConnected) {
                        // When a disconnect occurs, relock access to sensitive user data
                        mUsbDataUnlocked = false;
                    }
                    updateUsbNotification();
                    updateAdbNotification();
                    if (UsbManager.containsFunction(mCurrentFunctions,
                            UsbManager.USB_FUNCTION_ACCESSORY)) {
                        updateCurrentAccessory();
                    } else if (!mConnected) {
                    }
                            ·····//    
                case MSG_SET_USB_DATA_UNLOCKED:
                    //add by xx in 2017-08-03 for swtich usb mode start
                    if(!changeByUser && mUsbDataUnlocked) return;
                    //add by xx in 2017-08-03 for swtich usb mode end
                    setUsbDataUnlocked(msg.arg1 == 1);
                    break;
                }
                            ·····
            // UsbHandler     ,       USB   :mConnected
            //add by xx in 2017-06-12 for bug 169853 start
            private void updateUsbMode(){
                if(!mConnected && screenOff){
                    mUserPresent = false;
                }
            }
            //add by xx in 2017-06-12 for bug 169853 end
        }
                ·····
   }
   //      
   public void setCurrentFunctions(String functions) {
        if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")");
        //add by xx in 2017-08-03 for swtich usb mode start
        changeByUser = true;
        //add by xx in 2017-08-03 for swtich usb mode end
        mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
    }
    //      
}

主に上の2つのクラスを変更し、以下の状況を実現します.
Androidバージョン
スクリーンロックの場合
ロック解除の場合
7.0
充電のみ
MTP
またAndroid 7.1
「persist.sys.usb.configという属性の値をmtpに設定し、adbなどを付けないでください」ということです.
では、このような行為はAndroid 6.0の表現と同じで、問題は解決したと言える.これらのようにデフォルト値を変更する問題は簡単です.実は、USBに全く触れていないので、もっと見てください.そんなにたくさんの巨人がいるので、肩を借りて立ってください.本文で最初に言った大神のように、ここで感謝します.