1 /* 2 * Copyright (C) 2015 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.traceur; 18 19 import android.annotation.Nullable; 20 import android.app.AlertDialog; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.DialogInterface; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.content.pm.ApplicationInfo; 27 import android.content.pm.PackageManager; 28 import android.content.SharedPreferences; 29 import android.os.Build; 30 import android.os.Bundle; 31 import android.support.v14.preference.MultiSelectListPreference; 32 import android.support.v7.preference.ListPreference; 33 import android.support.v7.preference.Preference; 34 import android.support.v14.preference.PreferenceFragment; 35 import android.support.v7.preference.PreferenceManager; 36 import android.support.v7.preference.PreferenceScreen; 37 import android.support.v14.preference.SwitchPreference; 38 import android.view.LayoutInflater; 39 import android.view.View; 40 import android.view.ViewGroup; 41 import android.view.Menu; 42 import android.view.MenuInflater; 43 import android.widget.Toast; 44 45 import com.android.settingslib.HelpUtils; 46 47 import java.util.ArrayList; 48 import java.util.Collections; 49 import java.util.Comparator; 50 import java.util.Iterator; 51 import java.util.List; 52 import java.util.Map.Entry; 53 import java.util.Set; 54 import java.util.TreeMap; 55 56 public class MainFragment extends PreferenceFragment { 57 58 static final String TAG = AtraceUtils.TAG; 59 60 public static final String ACTION_REFRESH_TAGS = "com.android.traceur.REFRESH_TAGS"; 61 62 private SwitchPreference mTracingOn; 63 64 private AlertDialog mAlertDialog; 65 private SharedPreferences mPrefs; 66 67 private MultiSelectListPreference mTags; 68 69 private ListPreference mBufferSize; 70 71 private boolean mRefreshing; 72 73 private BroadcastReceiver mRefreshReceiver; 74 75 @Override 76 public void onCreate(@Nullable Bundle savedInstanceState) { 77 super.onCreate(savedInstanceState); 78 79 mPrefs = PreferenceManager.getDefaultSharedPreferences( 80 getActivity().getApplicationContext()); 81 82 mTracingOn = (SwitchPreference) findPreference(getActivity().getString(R.string.pref_key_tracing_on)); 83 mTracingOn.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 84 @Override 85 public boolean onPreferenceClick(Preference preference) { 86 Receiver.updateTracing(getContext()); 87 return true; 88 } 89 }); 90 91 mTags = (MultiSelectListPreference) findPreference(getContext().getString(R.string.pref_key_tags)); 92 mTags.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 93 @Override 94 public boolean onPreferenceChange(Preference preference, Object newValue) { 95 if (mRefreshing) { 96 return true; 97 } 98 Set<String> set = (Set<String>) newValue; 99 TreeMap<String, String> available = AtraceUtils.atraceListCategories(); 100 ArrayList<String> clean = new ArrayList<>(set.size()); 101 102 for (String s : set) { 103 if (available.containsKey(s)) { 104 clean.add(s); 105 } 106 } 107 set.clear(); 108 set.addAll(clean); 109 return true; 110 } 111 }); 112 113 mBufferSize = (ListPreference) findPreference(getContext().getString(R.string.pref_key_buffer_size)); 114 mBufferSize.setValue(mPrefs.getString(getContext().getString(R.string.pref_key_buffer_size), 115 getContext().getString(R.string.default_buffer_size))); 116 117 findPreference("restore_default_tags").setOnPreferenceClickListener( 118 new Preference.OnPreferenceClickListener() { 119 @Override 120 public boolean onPreferenceClick(Preference preference) { 121 refreshTags(/* restoreDefaultTags =*/ true); 122 Toast.makeText(getContext(), 123 getContext().getString(R.string.default_categories_restored), 124 Toast.LENGTH_SHORT).show(); 125 return true; 126 } 127 }); 128 129 findPreference(getString(R.string.pref_key_quick_setting)) 130 .setOnPreferenceClickListener( 131 new Preference.OnPreferenceClickListener() { 132 @Override 133 public boolean onPreferenceClick(Preference preference) { 134 Receiver.updateQuickSettings(getContext()); 135 return true; 136 } 137 }); 138 139 findPreference("clear_saved_traces").setOnPreferenceClickListener( 140 new Preference.OnPreferenceClickListener() { 141 @Override 142 public boolean onPreferenceClick(Preference preference) { 143 new AlertDialog.Builder(getContext()) 144 .setTitle(R.string.clear_saved_traces_question) 145 .setMessage(R.string.all_traces_will_be_deleted) 146 .setPositiveButton(R.string.clear, 147 new DialogInterface.OnClickListener() { 148 public void onClick(DialogInterface dialog, int which) { 149 AtraceUtils.clearSavedTraces(); 150 } 151 }) 152 .setNegativeButton(android.R.string.no, 153 new DialogInterface.OnClickListener() { 154 public void onClick(DialogInterface dialog, int which) { 155 dialog.dismiss(); 156 } 157 }) 158 .create() 159 .show(); 160 return true; 161 } 162 }); 163 164 refreshTags(); 165 166 mRefreshReceiver = new BroadcastReceiver() { 167 @Override 168 public void onReceive(Context context, Intent intent) { 169 refreshTags(); 170 } 171 }; 172 173 } 174 175 @Override 176 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 177 setHasOptionsMenu(true); 178 return super.onCreateView(inflater, container, savedInstanceState); 179 } 180 181 @Override 182 public void onResume() { 183 super.onResume(); 184 getActivity().registerReceiver(mRefreshReceiver, new IntentFilter(ACTION_REFRESH_TAGS)); 185 Receiver.updateTracing(getContext()); 186 } 187 188 @Override 189 public void onPause() { 190 getActivity().unregisterReceiver(mRefreshReceiver); 191 192 if (mAlertDialog != null) { 193 mAlertDialog.cancel(); 194 mAlertDialog = null; 195 } 196 197 super.onPause(); 198 } 199 200 @Override 201 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 202 addPreferencesFromResource(R.xml.main); 203 } 204 205 @Override 206 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 207 HelpUtils.prepareHelpMenuItem(getActivity(), menu, R.string.help_url, 208 this.getClass().getName()); 209 } 210 211 private void refreshTags() { 212 refreshTags(/* restoreDefaultTags =*/ false); 213 } 214 215 /* 216 * Refresh the preferences UI to make sure it reflects the current state of the preferences and 217 * system. 218 */ 219 private void refreshTags(boolean restoreDefaultTags) { 220 // Make sure the Record Trace toggle matches the preference value. 221 mTracingOn.setChecked(mTracingOn.getPreferenceManager().getSharedPreferences().getBoolean( 222 mTracingOn.getKey(), false)); 223 224 // Update category list to match the categories available on the system from atrace. 225 Set<Entry<String, String>> availableTags = AtraceUtils.atraceListCategories().entrySet(); 226 ArrayList<String> entries = new ArrayList<String>(availableTags.size()); 227 ArrayList<String> values = new ArrayList<String>(availableTags.size()); 228 for (Entry<String, String> entry : availableTags) { 229 entries.add(entry.getKey() + ": " + entry.getValue()); 230 values.add(entry.getKey()); 231 } 232 233 mRefreshing = true; 234 try { 235 mTags.setEntries(entries.toArray(new String[0])); 236 mTags.setEntryValues(values.toArray(new String[0])); 237 if (restoreDefaultTags || !mPrefs.contains(getContext().getString(R.string.pref_key_tags))) { 238 mTags.setValues(Receiver.getDefaultTagList()); 239 } 240 } finally { 241 mRefreshing = false; 242 } 243 } 244 } 245