1 /* 2 * Copyright (C) 2023 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.stylus; 18 19 import android.content.Context; 20 import android.hardware.usb.UsbDevice; 21 import android.hardware.usb.UsbManager; 22 23 import androidx.annotation.Nullable; 24 import androidx.annotation.VisibleForTesting; 25 import androidx.preference.Preference; 26 import androidx.preference.PreferenceCategory; 27 import androidx.preference.PreferenceScreen; 28 29 import com.android.settings.core.BasePreferenceController; 30 import com.android.settings.overlay.FeatureFactory; 31 import com.android.settingslib.core.lifecycle.LifecycleObserver; 32 import com.android.settingslib.core.lifecycle.events.OnStart; 33 import com.android.settingslib.core.lifecycle.events.OnStop; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 /** Preference controller for stylus firmware updates via USB **/ 39 public class StylusUsbFirmwareController extends BasePreferenceController 40 implements LifecycleObserver, OnStart, OnStop { 41 private static final String TAG = StylusUsbFirmwareController.class.getSimpleName(); 42 @Nullable 43 private UsbDevice mStylusUsbDevice; 44 private final UsbStylusBroadcastReceiver mUsbStylusBroadcastReceiver; 45 46 private PreferenceScreen mPreferenceScreen; 47 private PreferenceCategory mPreference; 48 49 @VisibleForTesting 50 UsbStylusBroadcastReceiver.UsbStylusConnectionListener mUsbConnectionListener = 51 (stylusUsbDevice, attached) -> { 52 refresh(); 53 }; 54 StylusUsbFirmwareController(Context context, String key)55 public StylusUsbFirmwareController(Context context, String key) { 56 super(context, key); 57 mUsbStylusBroadcastReceiver = new UsbStylusBroadcastReceiver(context, 58 mUsbConnectionListener); 59 } 60 61 @Override displayPreference(PreferenceScreen screen)62 public void displayPreference(PreferenceScreen screen) { 63 mPreferenceScreen = screen; 64 refresh(); 65 super.displayPreference(screen); 66 } 67 68 @Override getAvailabilityStatus()69 public int getAvailabilityStatus() { 70 // always available, preferences will be added or 71 // removed according to the connected usb device 72 return AVAILABLE; 73 } 74 refresh()75 private void refresh() { 76 if (mPreferenceScreen == null) return; 77 78 UsbDevice device = getStylusUsbDevice(); 79 if (device == mStylusUsbDevice) { 80 return; 81 } 82 mStylusUsbDevice = device; 83 mPreference = mPreferenceScreen.findPreference(getPreferenceKey()); 84 if (mPreference != null) { 85 mPreferenceScreen.removePreference(mPreference); 86 } 87 if (hasUsbStylusFirmwareUpdateFeature(mStylusUsbDevice)) { 88 StylusFeatureProvider featureProvider = 89 FeatureFactory.getFeatureFactory().getStylusFeatureProvider(); 90 List<Preference> preferences = 91 featureProvider.getUsbFirmwareUpdatePreferences(mContext, mStylusUsbDevice); 92 93 if (preferences != null) { 94 mPreference = new PreferenceCategory(mContext); 95 mPreference.setKey(getPreferenceKey()); 96 mPreferenceScreen.addPreference(mPreference); 97 98 for (Preference preference : preferences) { 99 mPreference.addPreference(preference); 100 } 101 } 102 } 103 } 104 105 @Override onStart()106 public void onStart() { 107 mUsbStylusBroadcastReceiver.register(); 108 } 109 110 @Override onStop()111 public void onStop() { 112 mUsbStylusBroadcastReceiver.unregister(); 113 } 114 getStylusUsbDevice()115 private UsbDevice getStylusUsbDevice() { 116 UsbManager usbManager = mContext.getSystemService(UsbManager.class); 117 118 if (usbManager == null) { 119 return null; 120 } 121 122 List<UsbDevice> devices = new ArrayList<>(usbManager.getDeviceList().values()); 123 if (devices.isEmpty()) { 124 return null; 125 } 126 127 UsbDevice usbDevice = devices.get(0); 128 if (hasUsbStylusFirmwareUpdateFeature(usbDevice)) { 129 return usbDevice; 130 } 131 return null; 132 } 133 hasUsbStylusFirmwareUpdateFeature(UsbDevice usbDevice)134 static boolean hasUsbStylusFirmwareUpdateFeature(UsbDevice usbDevice) { 135 if (usbDevice == null) return false; 136 137 StylusFeatureProvider featureProvider = 138 FeatureFactory.getFeatureFactory().getStylusFeatureProvider(); 139 140 return featureProvider.isUsbFirmwareUpdateEnabled(usbDevice); 141 } 142 } 143