1 /* 2 * Copyright (C) 2019 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.car.settings.wifi; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.Context; 21 import android.net.TetheringManager; 22 import android.os.Handler; 23 import android.os.HandlerExecutor; 24 import android.os.Looper; 25 26 import com.android.car.settings.R; 27 import com.android.car.settings.common.FragmentController; 28 import com.android.car.settings.common.PreferenceController; 29 import com.android.car.ui.preference.CarUiTwoActionSwitchPreference; 30 31 /** 32 * Controls the availability of wifi tethering preference based on whether tethering is supported 33 */ 34 public class WifiTetherPreferenceController extends 35 PreferenceController<CarUiTwoActionSwitchPreference> 36 implements WifiTetheringHandler.WifiTetheringAvailabilityListener { 37 38 private final TetheringManager mTetheringManager = 39 getContext().getSystemService(TetheringManager.class); 40 private final Handler mHandler; 41 private WifiTetheringHandler mWifiTetheringHandler; 42 private volatile boolean mIsTetheringSupported; 43 private volatile boolean mReceivedTetheringEventCallback = false; 44 45 private TetheringManager.TetheringEventCallback mTetheringCallback = 46 new TetheringManager.TetheringEventCallback() { 47 @Override 48 public void onTetheringSupported(boolean supported) { 49 mReceivedTetheringEventCallback = true; 50 if (mIsTetheringSupported != supported) { 51 mIsTetheringSupported = supported; 52 } 53 refreshUi(); 54 } 55 }; 56 WifiTetherPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)57 public WifiTetherPreferenceController(Context context, String preferenceKey, 58 FragmentController fragmentController, CarUxRestrictions uxRestrictions) { 59 super(context, preferenceKey, fragmentController, uxRestrictions); 60 mHandler = new Handler(Looper.getMainLooper()); 61 mWifiTetheringHandler = new WifiTetheringHandler(context, 62 fragmentController.getSettingsLifecycle(), this); 63 } 64 65 @Override getPreferenceType()66 protected Class<CarUiTwoActionSwitchPreference> getPreferenceType() { 67 return CarUiTwoActionSwitchPreference.class; 68 } 69 70 @Override onCreateInternal()71 protected void onCreateInternal() { 72 getPreference().setOnSecondaryActionClickListener(isChecked -> { 73 mWifiTetheringHandler.updateWifiTetheringState(isChecked); 74 }); 75 setClickableWhileDisabled(getPreference(), /* clickable= */ true, p -> { 76 WifiUtil.runClickableWhileDisabled(getContext(), getFragmentController()); 77 }); 78 } 79 80 @Override onStartInternal()81 protected void onStartInternal() { 82 mTetheringManager.registerTetheringEventCallback( 83 new HandlerExecutor(mHandler), mTetheringCallback); 84 boolean tetheringEnabled = mWifiTetheringHandler.isWifiTetheringEnabled(); 85 updateSwitchPreference(tetheringEnabled); 86 mWifiTetheringHandler.onStartInternal(); 87 } 88 89 @Override onStopInternal()90 protected void onStopInternal() { 91 mTetheringManager.unregisterTetheringEventCallback(mTetheringCallback); 92 mWifiTetheringHandler.onStopInternal(); 93 } 94 95 @Override getAvailabilityStatus()96 protected int getAvailabilityStatus() { 97 if (!mReceivedTetheringEventCallback) { 98 return AVAILABLE_FOR_VIEWING; 99 } 100 if (!mIsTetheringSupported) { 101 return UNSUPPORTED_ON_DEVICE; 102 } 103 if (WifiUtil.isConfigWifiRestrictedByUm(getContext()) 104 || WifiUtil.isConfigWifiRestrictedByDpm(getContext())) { 105 return AVAILABLE_FOR_VIEWING; 106 } 107 return AVAILABLE; 108 } 109 110 @Override onWifiTetheringAvailable()111 public void onWifiTetheringAvailable() { 112 updateSwitchPreference(true); 113 } 114 115 @Override onWifiTetheringUnavailable()116 public void onWifiTetheringUnavailable() { 117 updateSwitchPreference(false); 118 } 119 120 @Override enablePreference()121 public void enablePreference() { 122 getPreference().setSecondaryActionEnabled(true); 123 } 124 125 @Override disablePreference()126 public void disablePreference() { 127 getPreference().setSecondaryActionEnabled(false); 128 } 129 updateSwitchPreference(boolean switchOn)130 private void updateSwitchPreference(boolean switchOn) { 131 getPreference().setSummary(switchOn ? R.string.car_ui_preference_switch_on 132 : R.string.car_ui_preference_switch_off); 133 getPreference().setSecondaryActionChecked(switchOn); 134 } 135 } 136