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.app.Activity; 20 import android.content.Context; 21 import android.os.AsyncTask; 22 import android.os.Bundle; 23 import android.support.v7.widget.LinearLayoutManager; 24 import android.util.Log; 25 import android.view.LayoutInflater; 26 import android.view.View; 27 import android.view.ViewGroup; 28 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 76 protected int getMetricsCategory() { 77 return MetricsEvent.DASHBOARD_SUMMARY; 78 } 79 80 @Override 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 Context context = getContext(); 89 mConditionManager = ConditionManager.get(context, false); 90 mSuggestionParser = new SuggestionParser(context, 91 context.getSharedPreferences(SUGGESTIONS, 0), R.xml.suggestion_ordering); 92 mSuggestionsChecks = new SuggestionsChecks(getContext()); 93 if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) 94 + " ms"); 95 } 96 97 @Override 98 public void onDestroy() { 99 mSummaryLoader.release(); 100 super.onDestroy(); 101 } 102 103 @Override 104 public void onStart() { 105 long startTime = System.currentTimeMillis(); 106 super.onStart(); 107 108 ((SettingsDrawerActivity) getActivity()).addCategoryListener(this); 109 mSummaryLoader.setListening(true); 110 for (Condition c : mConditionManager.getConditions()) { 111 if (c.shouldShow()) { 112 MetricsLogger.visible(getContext(), c.getMetricsConstant()); 113 } 114 } 115 if (mAdapter.getSuggestions() != null) { 116 for (Tile suggestion : mAdapter.getSuggestions()) { 117 MetricsLogger.action(getContext(), MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, 118 DashboardAdapter.getSuggestionIdentifier(getContext(), suggestion)); 119 } 120 } 121 if (DEBUG_TIMING) Log.d(TAG, "onStart took " + (System.currentTimeMillis() - startTime) 122 + " ms"); 123 } 124 125 @Override 126 public void onStop() { 127 super.onStop(); 128 129 ((SettingsDrawerActivity) getActivity()).remCategoryListener(this); 130 mSummaryLoader.setListening(false); 131 for (Condition c : mConditionManager.getConditions()) { 132 if (c.shouldShow()) { 133 MetricsLogger.hidden(getContext(), c.getMetricsConstant()); 134 } 135 } 136 if (mAdapter.getSuggestions() == null) { 137 return; 138 } 139 for (Tile suggestion : mAdapter.getSuggestions()) { 140 MetricsLogger.action(getContext(), MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, 141 DashboardAdapter.getSuggestionIdentifier(getContext(), suggestion)); 142 } 143 } 144 145 @Override 146 public void onWindowFocusChanged(boolean hasWindowFocus) { 147 long startTime = System.currentTimeMillis(); 148 if (hasWindowFocus) { 149 mConditionManager.addListener(this); 150 mConditionManager.refreshAll(); 151 } else { 152 mConditionManager.remListener(this); 153 } 154 if (DEBUG_TIMING) Log.d(TAG, "onWindowFocusChanged took " 155 + (System.currentTimeMillis() - startTime) + " ms"); 156 } 157 158 @Override 159 public View onCreateView(LayoutInflater inflater, ViewGroup container, 160 Bundle savedInstanceState) { 161 return inflater.inflate(R.layout.dashboard, container, false); 162 } 163 164 @Override 165 public void onSaveInstanceState(Bundle outState) { 166 super.onSaveInstanceState(outState); 167 if (mLayoutManager == null) return; 168 outState.putInt(EXTRA_SCROLL_POSITION, mLayoutManager.findFirstVisibleItemPosition()); 169 if (mAdapter != null) { 170 mAdapter.onSaveInstanceState(outState); 171 } 172 } 173 174 @Override 175 public void onViewCreated(View view, Bundle bundle) { 176 long startTime = System.currentTimeMillis(); 177 mDashboard = (FocusRecyclerView) view.findViewById(R.id.dashboard_container); 178 mLayoutManager = new LinearLayoutManager(getContext()); 179 mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 180 if (bundle != null) { 181 int scrollPosition = bundle.getInt(EXTRA_SCROLL_POSITION); 182 mLayoutManager.scrollToPosition(scrollPosition); 183 } 184 mDashboard.setLayoutManager(mLayoutManager); 185 mDashboard.setHasFixedSize(true); 186 mDashboard.setListener(this); 187 mDashboard.addItemDecoration(new DashboardDecorator(getContext())); 188 mAdapter = new DashboardAdapter(getContext(), mSuggestionParser, bundle, 189 mConditionManager.getConditions()); 190 mDashboard.setAdapter(mAdapter); 191 mSummaryLoader.setAdapter(mAdapter); 192 ConditionAdapterUtils.addDismiss(mDashboard); 193 if (DEBUG_TIMING) Log.d(TAG, "onViewCreated took " 194 + (System.currentTimeMillis() - startTime) + " ms"); 195 rebuildUI(); 196 } 197 198 private void rebuildUI() { 199 if (!isAdded()) { 200 Log.w(TAG, "Cannot build the DashboardSummary UI yet as the Fragment is not added"); 201 return; 202 } 203 204 // recheck to see if any suggestions have been changed. 205 new SuggestionLoader().execute(); 206 } 207 208 @Override 209 public void onCategoriesChanged() { 210 rebuildUI(); 211 } 212 213 @Override 214 public void onConditionsChanged() { 215 Log.d(TAG, "onConditionsChanged"); 216 mAdapter.setConditions(mConditionManager.getConditions()); 217 } 218 219 private class SuggestionLoader extends AsyncTask<Void, Void, List<Tile>> { 220 221 @Override 222 protected List<Tile> doInBackground(Void... params) { 223 List<Tile> suggestions = mSuggestionParser.getSuggestions(); 224 for (int i = 0; i < suggestions.size(); i++) { 225 if (mSuggestionsChecks.isSuggestionComplete(suggestions.get(i))) { 226 mAdapter.disableSuggestion(suggestions.get(i)); 227 suggestions.remove(i--); 228 } 229 } 230 return suggestions; 231 } 232 233 @Override 234 protected void onPostExecute(List<Tile> tiles) { 235 final Activity activity = getActivity(); 236 if (activity == null) { 237 return; 238 } 239 List<DashboardCategory> categories = 240 ((SettingsActivity) activity).getDashboardCategories(); 241 mAdapter.setCategoriesAndSuggestions(categories, tiles); 242 } 243 } 244 } 245