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 package com.android.car.developeroptions.network; 17 18 import android.app.settings.SettingsEnums; 19 import android.content.Context; 20 import android.net.NetworkScoreManager; 21 import android.net.NetworkScorerAppData; 22 import android.os.Bundle; 23 import android.text.TextUtils; 24 import android.view.LayoutInflater; 25 import android.view.View; 26 import android.view.ViewGroup; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.preference.Preference; 30 import androidx.preference.PreferenceScreen; 31 32 import com.android.car.developeroptions.R; 33 import com.android.car.developeroptions.core.InstrumentedPreferenceFragment; 34 import com.android.car.developeroptions.widget.RadioButtonPreference; 35 36 import java.util.List; 37 38 /** 39 * Fragment for choosing default network scorer. 40 */ 41 public class NetworkScorerPicker extends InstrumentedPreferenceFragment implements 42 RadioButtonPreference.OnClickListener { 43 44 private NetworkScoreManager mNetworkScoreManager; 45 46 @Override getMetricsCategory()47 public int getMetricsCategory() { 48 return SettingsEnums.SETTINGS_NETWORK_SCORER; 49 } 50 51 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)52 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 53 super.onCreatePreferences(savedInstanceState, rootKey); 54 updateCandidates(); 55 } 56 57 @Override onAttach(Context context)58 public void onAttach(Context context) { 59 super.onAttach(context); 60 mNetworkScoreManager = createNetworkScorerManager(context); 61 } 62 63 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)64 public View onCreateView(LayoutInflater inflater, ViewGroup container, 65 Bundle savedInstanceState) { 66 final View view = super.onCreateView(inflater, container, savedInstanceState); 67 // this is needed so the back button goes back to previous fragment 68 setHasOptionsMenu(true); 69 return view; 70 } 71 72 @Override getPreferenceScreenResId()73 protected int getPreferenceScreenResId() { 74 return R.xml.network_scorer_picker_prefs; 75 } 76 77 @VisibleForTesting updateCandidates()78 public void updateCandidates() { 79 final PreferenceScreen screen = getPreferenceScreen(); 80 screen.removeAll(); 81 82 final List<NetworkScorerAppData> scorers = mNetworkScoreManager.getAllValidScorers(); 83 final String defaultAppKey = getActiveScorerPackage(); 84 85 final RadioButtonPreference nonePref = new RadioButtonPreference(getPrefContext()); 86 nonePref.setTitle(R.string.network_scorer_picker_none_preference); 87 if (scorers.isEmpty()) { 88 nonePref.setChecked(true); 89 } else { 90 nonePref.setKey(null); 91 nonePref.setChecked(TextUtils.isEmpty(defaultAppKey)); 92 nonePref.setOnClickListener(this); 93 } 94 screen.addPreference(nonePref); 95 96 final int numScorers = scorers.size(); 97 for (int i = 0; i < numScorers; i++) { 98 final RadioButtonPreference pref = new RadioButtonPreference(getPrefContext()); 99 final NetworkScorerAppData appData = scorers.get(i); 100 final String appKey = appData.getRecommendationServicePackageName(); 101 pref.setTitle(appData.getRecommendationServiceLabel()); 102 pref.setKey(appKey); 103 pref.setChecked(TextUtils.equals(defaultAppKey, appKey)); 104 pref.setOnClickListener(this); 105 screen.addPreference(pref); 106 } 107 } 108 getActiveScorerPackage()109 private String getActiveScorerPackage() { 110 return mNetworkScoreManager.getActiveScorerPackage(); 111 } 112 setActiveScorer(String key)113 private boolean setActiveScorer(String key) { 114 if (!TextUtils.equals(key, getActiveScorerPackage())) { 115 return mNetworkScoreManager.setActiveScorer(key); 116 } 117 return false; 118 } 119 120 @Override onRadioButtonClicked(RadioButtonPreference selected)121 public void onRadioButtonClicked(RadioButtonPreference selected) { 122 final String selectedKey = selected.getKey(); 123 final boolean success = setActiveScorer(selectedKey); 124 if (success) { 125 updateCheckedState(selectedKey); 126 } 127 } 128 updateCheckedState(String selectedKey)129 private void updateCheckedState(String selectedKey) { 130 final PreferenceScreen screen = getPreferenceScreen(); 131 final int count = screen.getPreferenceCount(); 132 for (int i = 0; i < count; i++) { 133 final Preference pref = screen.getPreference(i); 134 if (pref instanceof RadioButtonPreference) { 135 final RadioButtonPreference radioPref = (RadioButtonPreference) pref; 136 radioPref.setChecked(TextUtils.equals(pref.getKey(), selectedKey)); 137 } 138 } 139 } 140 141 @VisibleForTesting createNetworkScorerManager(Context context)142 NetworkScoreManager createNetworkScorerManager(Context context) { 143 return (NetworkScoreManager) context.getSystemService(Context.NETWORK_SCORE_SERVICE); 144 } 145 } 146