1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.connecteddevice.usb; 18 19 import android.content.Context; 20 import android.hardware.usb.UsbPort; 21 import android.support.v14.preference.SwitchPreference; 22 import android.support.v7.preference.Preference; 23 import android.support.v7.preference.Preference.OnPreferenceClickListener; 24 import android.support.v7.preference.PreferenceCategory; 25 import android.support.v7.preference.PreferenceScreen; 26 27 import com.android.settings.R; 28 import com.android.settings.Utils; 29 30 /** 31 * This class controls the switch for changing USB power direction. 32 */ 33 public class UsbDetailsPowerRoleController extends UsbDetailsController 34 implements OnPreferenceClickListener { 35 36 private PreferenceCategory mPreferenceCategory; 37 private SwitchPreference mSwitchPreference; 38 39 private int mNextPowerRole; 40 41 private final Runnable mFailureCallback = () -> { 42 if (mNextPowerRole != UsbPort.POWER_ROLE_NONE) { 43 mSwitchPreference.setSummary(R.string.usb_switching_failed); 44 mNextPowerRole = UsbPort.POWER_ROLE_NONE; 45 } 46 }; 47 48 public UsbDetailsPowerRoleController(Context context, UsbDetailsFragment fragment, 49 UsbBackend backend) { 50 super(context, fragment, backend); 51 mNextPowerRole = UsbPort.POWER_ROLE_NONE; 52 } 53 54 @Override 55 public void displayPreference(PreferenceScreen screen) { 56 super.displayPreference(screen); 57 mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey()); 58 mSwitchPreference = new SwitchPreference(mPreferenceCategory.getContext()); 59 mSwitchPreference.setTitle(R.string.usb_use_power_only); 60 mSwitchPreference.setOnPreferenceClickListener(this); 61 mPreferenceCategory.addPreference(mSwitchPreference); 62 } 63 64 @Override 65 protected void refresh(boolean connected, long functions, int powerRole, int dataRole) { 66 // Hide this option if this is not a PD compatible connection 67 if (connected && !mUsbBackend.areAllRolesSupported()) { 68 mFragment.getPreferenceScreen().removePreference(mPreferenceCategory); 69 } else if (connected && mUsbBackend.areAllRolesSupported()){ 70 mFragment.getPreferenceScreen().addPreference(mPreferenceCategory); 71 } 72 if (powerRole == UsbPort.POWER_ROLE_SOURCE) { 73 mSwitchPreference.setChecked(true); 74 mPreferenceCategory.setEnabled(true); 75 } else if (powerRole == UsbPort.POWER_ROLE_SINK) { 76 mSwitchPreference.setChecked(false); 77 mPreferenceCategory.setEnabled(true); 78 } else if (!connected || powerRole == UsbPort.POWER_ROLE_NONE){ 79 mPreferenceCategory.setEnabled(false); 80 if (mNextPowerRole == UsbPort.POWER_ROLE_NONE) { 81 mSwitchPreference.setSummary(""); 82 } 83 } 84 85 if (mNextPowerRole != UsbPort.POWER_ROLE_NONE && powerRole != UsbPort.POWER_ROLE_NONE) { 86 if (mNextPowerRole == powerRole) { 87 // Clear switching text if switch succeeded 88 mSwitchPreference.setSummary(""); 89 } else { 90 // Set failure text if switch failed 91 mSwitchPreference.setSummary(R.string.usb_switching_failed); 92 } 93 mNextPowerRole = UsbPort.POWER_ROLE_NONE; 94 mHandler.removeCallbacks(mFailureCallback); 95 } 96 } 97 98 @Override 99 public boolean onPreferenceClick(Preference preference) { 100 int newRole = mSwitchPreference.isChecked() ? UsbPort.POWER_ROLE_SOURCE 101 : UsbPort.POWER_ROLE_SINK; 102 if (mUsbBackend.getPowerRole() != newRole && mNextPowerRole == UsbPort.POWER_ROLE_NONE 103 && !Utils.isMonkeyRunning()) { 104 mUsbBackend.setPowerRole(newRole); 105 106 mNextPowerRole = newRole; 107 mSwitchPreference.setSummary(R.string.usb_switching); 108 109 mHandler.postDelayed(mFailureCallback, 110 mUsbBackend.areAllRolesSupported() ? UsbBackend.PD_ROLE_SWAP_TIMEOUT_MS 111 : UsbBackend.NONPD_ROLE_SWAP_TIMEOUT_MS); 112 } 113 114 // We don't know that the action succeeded until called back in refresh() 115 mSwitchPreference.setChecked(!mSwitchPreference.isChecked()); 116 return true; 117 } 118 119 @Override 120 public boolean isAvailable() { 121 return !Utils.isMonkeyRunning(); 122 } 123 124 @Override 125 public String getPreferenceKey() { 126 return "usb_details_power_role"; 127 } 128 } 129