1 /* 2 * Copyright (C) 2014 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.dashboard; 18 19 import android.content.Context; 20 import android.os.AsyncTask; 21 import android.os.Bundle; 22 import android.support.v7.widget.LinearLayoutManager; 23 import android.util.Log; 24 import android.view.LayoutInflater; 25 import android.view.Menu; 26 import android.view.MenuInflater; 27 import android.view.View; 28 import android.view.ViewGroup; 29 import com.android.internal.logging.MetricsLogger; 30 import com.android.internal.logging.MetricsProto.MetricsEvent; 31 import com.android.settings.InstrumentedFragment; 32 import com.android.settings.R; 33 import com.android.settings.Settings; 34 import com.android.settings.SettingsActivity; 35 import com.android.settings.dashboard.conditional.Condition; 36 import com.android.settings.dashboard.conditional.ConditionAdapterUtils; 37 import com.android.settings.dashboard.conditional.ConditionManager; 38 import com.android.settings.dashboard.conditional.FocusRecyclerView; 39 import com.android.settingslib.HelpUtils; 40 import com.android.settingslib.SuggestionParser; 41 import com.android.settingslib.drawer.DashboardCategory; 42 import com.android.settingslib.drawer.SettingsDrawerActivity; 43 import com.android.settingslib.drawer.Tile; 44 45 import java.util.List; 46 47 public class DashboardSummary extends InstrumentedFragment 48 implements SettingsDrawerActivity.CategoryListener, ConditionManager.ConditionListener, 49 FocusRecyclerView.FocusListener { 50 public static final boolean DEBUG = false; 51 private static final boolean DEBUG_TIMING = false; 52 private static final String TAG = "DashboardSummary"; 53 54 public static final String[] INITIAL_ITEMS = new String[] { 55 Settings.WifiSettingsActivity.class.getName(), 56 Settings.BluetoothSettingsActivity.class.getName(), 57 Settings.DataUsageSummaryActivity.class.getName(), 58 Settings.PowerUsageSummaryActivity.class.getName(), 59 Settings.ManageApplicationsActivity.class.getName(), 60 Settings.StorageSettingsActivity.class.getName(), 61 }; 62 63 private static final String SUGGESTIONS = "suggestions"; 64 65 private static final String EXTRA_SCROLL_POSITION = "scroll_position"; 66 67 private FocusRecyclerView mDashboard; 68 private DashboardAdapter mAdapter; 69 private SummaryLoader mSummaryLoader; 70 private ConditionManager mConditionManager; 71 private SuggestionParser mSuggestionParser; 72 private LinearLayoutManager mLayoutManager; 73 private SuggestionsChecks mSuggestionsChecks; 74 75 @Override getMetricsCategory()76 protected int getMetricsCategory() { 77 return MetricsEvent.DASHBOARD_SUMMARY; 78 } 79 80 @Override onCreate(Bundle savedInstanceState)81 public void onCreate(Bundle savedInstanceState) { 82 long startTime = System.currentTimeMillis(); 83 super.onCreate(savedInstanceState); 84 85 List<DashboardCategory> categories = 86 ((SettingsActivity) getActivity()).getDashboardCategories(); 87 mSummaryLoader = new SummaryLoader(getActivity(), categories); 88 setHasOptionsMenu(true); 89 Context context = getContext(); 90 mConditionManager = ConditionManager.get(context, false); 91 mSuggestionParser = new SuggestionParser(context, 92 context.getSharedPreferences(SUGGESTIONS, 0), R.xml.suggestion_ordering); 93 mSuggestionsChecks = new SuggestionsChecks(getContext()); 94 if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) 95 + " ms"); 96 } 97 98 @Override onDestroy()99 public void onDestroy() { 100 mSummaryLoader.release(); 101 super.onDestroy(); 102 } 103 104 @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)105 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 106 super.onCreateOptionsMenu(menu, inflater); 107 if (getActivity() == null) return; 108 HelpUtils.prepareHelpMenuItem(getActivity(), menu, R.string.help_uri_dashboard, 109 getClass().getName()); 110 } 111 112 @Override onStart()113 public void onStart() { 114 long startTime = System.currentTimeMillis(); 115 super.onStart(); 116 117 ((SettingsDrawerActivity) getActivity()).addCategoryListener(this); 118 mSummaryLoader.setListening(true); 119 for (Condition c : mConditionManager.getConditions()) { 120 if (c.shouldShow()) { 121 MetricsLogger.visible(getContext(), c.getMetricsConstant()); 122 } 123 } 124 if (mAdapter.getSuggestions() != null) { 125 for (Tile suggestion : mAdapter.getSuggestions()) { 126 MetricsLogger.action(getContext(), MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, 127 DashboardAdapter.getSuggestionIdentifier(getContext(), suggestion)); 128 } 129 } 130 if (DEBUG_TIMING) Log.d(TAG, "onStart took " + (System.currentTimeMillis() - startTime) 131 + " ms"); 132 } 133 134 @Override onStop()135 public void onStop() { 136 super.onStop(); 137 138 ((SettingsDrawerActivity) getActivity()).remCategoryListener(this); 139 mSummaryLoader.setListening(false); 140 for (Condition c : mConditionManager.getConditions()) { 141 if (c.shouldShow()) { 142 MetricsLogger.hidden(getContext(), c.getMetricsConstant()); 143 } 144 } 145 if (mAdapter.getSuggestions() == null) { 146 return; 147 } 148 for (Tile suggestion : mAdapter.getSuggestions()) { 149 MetricsLogger.action(getContext(), MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, 150 DashboardAdapter.getSuggestionIdentifier(getContext(), suggestion)); 151 } 152 } 153 154 @Override onWindowFocusChanged(boolean hasWindowFocus)155 public void onWindowFocusChanged(boolean hasWindowFocus) { 156 long startTime = System.currentTimeMillis(); 157 if (hasWindowFocus) { 158 mConditionManager.addListener(this); 159 mConditionManager.refreshAll(); 160 } else { 161 mConditionManager.remListener(this); 162 } 163 if (DEBUG_TIMING) Log.d(TAG, "onWindowFocusChanged took " 164 + (System.currentTimeMillis() - startTime) + " ms"); 165 } 166 167 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)168 public View onCreateView(LayoutInflater inflater, ViewGroup container, 169 Bundle savedInstanceState) { 170 return inflater.inflate(R.layout.dashboard, container, false); 171 } 172 173 @Override onSaveInstanceState(Bundle outState)174 public void onSaveInstanceState(Bundle outState) { 175 super.onSaveInstanceState(outState); 176 if (mLayoutManager == null) return; 177 outState.putInt(EXTRA_SCROLL_POSITION, mLayoutManager.findFirstVisibleItemPosition()); 178 } 179 180 @Override onViewCreated(View view, Bundle bundle)181 public void onViewCreated(View view, Bundle bundle) { 182 long startTime = System.currentTimeMillis(); 183 mDashboard = (FocusRecyclerView) view.findViewById(R.id.dashboard_container); 184 mLayoutManager = new LinearLayoutManager(getContext()); 185 mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 186 if (bundle != null) { 187 int scrollPosition = bundle.getInt(EXTRA_SCROLL_POSITION); 188 mLayoutManager.scrollToPosition(scrollPosition); 189 } 190 mDashboard.setLayoutManager(mLayoutManager); 191 mDashboard.setHasFixedSize(true); 192 mDashboard.setListener(this); 193 mDashboard.addItemDecoration(new DashboardDecorator(getContext())); 194 mAdapter = new DashboardAdapter(getContext(), mSuggestionParser); 195 mAdapter.setConditions(mConditionManager.getConditions()); 196 mDashboard.setAdapter(mAdapter); 197 mSummaryLoader.setAdapter(mAdapter); 198 ConditionAdapterUtils.addDismiss(mDashboard); 199 if (DEBUG_TIMING) Log.d(TAG, "onViewCreated took " 200 + (System.currentTimeMillis() - startTime) + " ms"); 201 202 rebuildUI(); 203 } 204 rebuildUI()205 private void rebuildUI() { 206 if (!isAdded()) { 207 Log.w(TAG, "Cannot build the DashboardSummary UI yet as the Fragment is not added"); 208 return; 209 } 210 211 List<DashboardCategory> categories = 212 ((SettingsActivity) getActivity()).getDashboardCategories(); 213 mAdapter.setCategories(categories); 214 215 // recheck to see if any suggestions have been changed. 216 new SuggestionLoader().execute(); 217 } 218 219 @Override onCategoriesChanged()220 public void onCategoriesChanged() { 221 rebuildUI(); 222 } 223 224 @Override onConditionsChanged()225 public void onConditionsChanged() { 226 Log.d(TAG, "onConditionsChanged"); 227 mAdapter.setConditions(mConditionManager.getConditions()); 228 } 229 230 private class SuggestionLoader extends AsyncTask<Void, Void, List<Tile>> { 231 232 @Override doInBackground(Void... params)233 protected List<Tile> doInBackground(Void... params) { 234 List<Tile> suggestions = mSuggestionParser.getSuggestions(); 235 for (int i = 0; i < suggestions.size(); i++) { 236 if (mSuggestionsChecks.isSuggestionComplete(suggestions.get(i))) { 237 mAdapter.disableSuggestion(suggestions.get(i)); 238 suggestions.remove(i--); 239 } 240 } 241 return suggestions; 242 } 243 244 @Override onPostExecute(List<Tile> tiles)245 protected void onPostExecute(List<Tile> tiles) { 246 mAdapter.setSuggestions(tiles); 247 } 248 } 249 } 250