欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-26 14:19:19
...

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()));
        }
    }
}


相关标签: 代码记录