Android 8.1 的 UsbMode 更改为跟随用户上次选择的模式

Android O的谷歌默认USB连接模式为充电,现客户要求更改为随用户上次选择的模式。思路是,用一个变量保存上次用户选择的模式,检测USB插入后,在代码里面重新选择USB模式。

1,alps\vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\deviceinfo\UsbModeChooserActivity.java

inflateOption()中添加上次用户选择的USB模式

        v.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (disallowedByAdmin && mEnforcedAdmin != null) {
                    RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
                            UsbModeChooserActivity.this, mEnforcedAdmin);
                    return;
                }
                if (!ActivityManager.isUserAMonkey()) {
                    mBackend.setMode(mode);
					//add by start
					System.putInt(getContentResolver(), "kst_usb_mode", mode);
					//add by y end
                }
                mDialog.dismiss();
                finish();
            }
        });

2, alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\usb\StorageNotification.java

添加USB拔插监听,插入后重新选择USB模式。

import  android.provider.Settings.System;  
import android.hardware.usb.UsbManager; 
	//add by  start
    private static final int MSG_CHOOSE_MODE = 0x10;
    private Handler mUsbCheckHandler = new Handler(){
    	public void handleMessage(android.os.Message msg) {
    		switch (msg.what) {
				case MSG_CHOOSE_MODE:
				 try {  	
				 		int mode = System.getInt(mContext.getContentResolver(), "kst_usb_mode", 0);	
						if(mBackend != null){
							mBackend.setMode(mode);     						
						}		             
		           
		            } catch (Exception e) {
		                Log.e(TAG,"Exception="+e);  
		            }
					break;

				default:
					break;
			}
    		
    	};
    };
	//add by end	
	
	//add by start	
	private UsbBackend mBackend;
    private UsbManager mUsbManager;
    private  int usbNums=0;    
	
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 
			boolean hostConnected = intent.getBooleanExtra(UsbManager.USB_HOST_CONNECTED, false);
          
            if (!connected && !hostConnected) { 
                usbNums = 0; 
            }else{
				if(usbNums == 0){  //set only one time
					usbNums++;
					mUsbCheckHandler.sendEmptyMessageDelayed(MSG_CHOOSE_MODE, 600);    
				}     
            }   

        }
    };
	//add by end 

start()方法中添加 mUsbReceiver

		//add by start
		mContext.registerReceiver(mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE)); 
		mBackend = new UsbBackend(mContext);
		//add by end
复制Settings模块的UsbBackend.java 类

3,alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\usb\UsbBackend.java

package com.android.systemui.usb;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;

public class UsbBackend {

    public static final int MODE_POWER_MASK  = 0x01;
    public static final int MODE_POWER_SINK   = 0x00;
    public static final int MODE_POWER_SOURCE = 0x01;

    public static final int MODE_DATA_MASK  = 0x03 << 1;
    public static final int MODE_DATA_NONE   = 0x00 << 1;
    public static final int MODE_DATA_MTP    = 0x01 << 1;
    public static final int MODE_DATA_PTP    = 0x02 << 1;
    public static final int MODE_DATA_MIDI   = 0x03 << 1;

    private final boolean mRestricted;
    private final boolean mRestrictedBySystem;
    private final boolean mMidi;

    private UsbManager mUsbManager;
    private UsbPort mPort;
    private UsbPortStatus mPortStatus;

    private Context mContext;

    public UsbBackend(Context context) {
        this(context, new UserRestrictionUtil(context));
    }

    @VisibleForTesting
    public UsbBackend(Context context, UserRestrictionUtil userRestrictionUtil) {
        mContext = context;
        mUsbManager = context.getSystemService(UsbManager.class);

        mRestricted = userRestrictionUtil.isUsbFileTransferRestricted();
        mRestrictedBySystem = userRestrictionUtil.isUsbFileTransferRestrictedBySystem();
        mMidi = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);

        UsbPort[] ports = mUsbManager.getPorts();
        if (ports == null) {
            return;
        }
        // For now look for a connected port, in the future we should identify port in the
        // notification and pick based on that.
        final int N = ports.length;
        for (int i = 0; i < N; i++) {
            UsbPortStatus status = mUsbManager.getPortStatus(ports[i]);
            if (status.isConnected()) {
                mPort = ports[i];
                mPortStatus = status;
                break;
            }
        }
    }

    public int getCurrentMode() {
        if (mPort != null) {
            int power = mPortStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
                    ? MODE_POWER_SOURCE : MODE_POWER_SINK;
            return power | getUsbDataMode();
        }
        return MODE_POWER_SINK | getUsbDataMode();
    }

    public int getUsbDataMode() {
        if (!isUsbDataUnlocked()) {
            return MODE_DATA_NONE;
        } else if (mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_MTP)) {
            return MODE_DATA_MTP;
        } else if (mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_PTP)) {
            return MODE_DATA_PTP;
        } else if (mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_MIDI)) {
            return MODE_DATA_MIDI;
        }
        return MODE_DATA_NONE; // ...
    }

    private boolean isUsbDataUnlocked() {
        Intent intent = mContext.registerReceiver(null,
            new IntentFilter(UsbManager.ACTION_USB_STATE));
        return intent == null ?
            false : intent.getBooleanExtra(UsbManager.USB_DATA_UNLOCKED, false);
    }

    private void setUsbFunction(int mode) {
        switch (mode) {
            case MODE_DATA_MTP:
                mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MTP, true);
                break;
            case MODE_DATA_PTP:
                mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_PTP, true);
                break;
            case MODE_DATA_MIDI:
                mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MIDI, true);
                break;
            default:
                mUsbManager.setCurrentFunction(null, false);
                break;
        }
    }

    public void setMode(int mode) {
        if (mPort != null) {
            int powerRole = modeToPower(mode);
            // If we aren't using any data modes and we support host mode, then go to host mode
            // so maybe? the other device can provide data if it wants, otherwise go into device
            // mode because we have no choice.
            int dataRole = (mode & MODE_DATA_MASK) == MODE_DATA_NONE
                    && mPortStatus.isRoleCombinationSupported(powerRole, UsbPort.DATA_ROLE_HOST)
                    ? UsbPort.DATA_ROLE_HOST : UsbPort.DATA_ROLE_DEVICE;
            mUsbManager.setPortRoles(mPort, powerRole, dataRole);
        }
        setUsbFunction(mode & MODE_DATA_MASK);
    }

    private int modeToPower(int mode) {
        return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
                    ? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
    }

    public boolean isModeDisallowed(int mode) {
        if (mRestricted && (mode & MODE_DATA_MASK) != MODE_DATA_NONE
                && (mode & MODE_DATA_MASK) != MODE_DATA_MIDI) {
            // No USB data modes are supported.
            return true;
        }
        return false;
    }

    public boolean isModeDisallowedBySystem(int mode) {
        if (mRestrictedBySystem && (mode & MODE_DATA_MASK) != MODE_DATA_NONE
                && (mode & MODE_DATA_MASK) != MODE_DATA_MIDI) {
            // No USB data modes are supported.
            return true;
        }
        return false;
    }

    public boolean isModeSupported(int mode) {
        if (!mMidi && (mode & MODE_DATA_MASK) == MODE_DATA_MIDI) {
            return false;
        }

        if (mPort != null) {
            int power = modeToPower(mode);
            if ((mode & MODE_DATA_MASK) != 0) {
                // We have a port and data, need to be in device mode.
                return mPortStatus.isRoleCombinationSupported(power,
                        UsbPort.DATA_ROLE_DEVICE);
            } else {
                // No data needed, we can do this power mode in either device or host.
                return mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_DEVICE)
                        || mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_HOST);
            }
        }
        // No port, support sink modes only.
        return (mode & MODE_POWER_MASK) != MODE_POWER_SOURCE;
    }

    // Wrapper class to enable testing with UserManager APIs
    public static class UserRestrictionUtil {
        private UserManager mUserManager;

        public UserRestrictionUtil(Context context) {
            mUserManager = UserManager.get(context);
        }

        public boolean isUsbFileTransferRestricted() {
            return mUserManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
        }

        public boolean isUsbFileTransferRestrictedBySystem() {
            return mUserManager.hasBaseUserRestriction(
                UserManager.DISALLOW_USB_FILE_TRANSFER, UserHandle.of(UserHandle.myUserId()));
        }
    }
}


你可能感兴趣的:(8.1代码记录)