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 package com.android.settingslib.drawer; 17 18 import android.annotation.LayoutRes; 19 import android.annotation.Nullable; 20 import android.app.Activity; 21 import android.content.BroadcastReceiver; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.content.pm.PackageManager; 27 import android.content.res.TypedArray; 28 import android.os.AsyncTask; 29 import android.os.Bundle; 30 import android.util.ArraySet; 31 import android.util.Log; 32 import android.view.LayoutInflater; 33 import android.view.View; 34 import android.view.ViewGroup; 35 import android.view.Window; 36 import android.view.WindowManager.LayoutParams; 37 import android.widget.FrameLayout; 38 import android.widget.Toolbar; 39 40 import com.android.settingslib.R; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 45 public class SettingsDrawerActivity extends Activity { 46 47 protected static final boolean DEBUG_TIMING = false; 48 private static final String TAG = "SettingsDrawerActivity"; 49 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 50 51 public static final String EXTRA_SHOW_MENU = "show_drawer_menu"; 52 53 // Serves as a temporary list of tiles to ignore until we heard back from the PM that they 54 // are disabled. 55 private static ArraySet<ComponentName> sTileBlacklist = new ArraySet<>(); 56 57 private final PackageReceiver mPackageReceiver = new PackageReceiver(); 58 private final List<CategoryListener> mCategoryListeners = new ArrayList<>(); 59 60 private FrameLayout mContentHeaderContainer; 61 62 @Override onCreate(@ullable Bundle savedInstanceState)63 protected void onCreate(@Nullable Bundle savedInstanceState) { 64 super.onCreate(savedInstanceState); 65 66 long startTime = System.currentTimeMillis(); 67 68 TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme); 69 if (!theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) { 70 getWindow().addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 71 requestWindowFeature(Window.FEATURE_NO_TITLE); 72 } 73 super.setContentView(R.layout.settings_with_drawer); 74 mContentHeaderContainer = findViewById(R.id.content_header_container); 75 76 Toolbar toolbar = findViewById(R.id.action_bar); 77 if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) { 78 toolbar.setVisibility(View.GONE); 79 return; 80 } 81 setActionBar(toolbar); 82 83 if (DEBUG_TIMING) { 84 Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) 85 + " ms"); 86 } 87 } 88 89 @Override onNavigateUp()90 public boolean onNavigateUp() { 91 if (!super.onNavigateUp()) { 92 finish(); 93 } 94 return true; 95 } 96 97 @Override onResume()98 protected void onResume() { 99 super.onResume(); 100 final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 101 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 102 filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 103 filter.addAction(Intent.ACTION_PACKAGE_REPLACED); 104 filter.addDataScheme("package"); 105 registerReceiver(mPackageReceiver, filter); 106 107 new CategoriesUpdateTask().execute(); 108 } 109 110 @Override onPause()111 protected void onPause() { 112 unregisterReceiver(mPackageReceiver); 113 super.onPause(); 114 } 115 addCategoryListener(CategoryListener listener)116 public void addCategoryListener(CategoryListener listener) { 117 mCategoryListeners.add(listener); 118 } 119 remCategoryListener(CategoryListener listener)120 public void remCategoryListener(CategoryListener listener) { 121 mCategoryListeners.remove(listener); 122 } 123 124 @Override setContentView(@ayoutRes int layoutResID)125 public void setContentView(@LayoutRes int layoutResID) { 126 final ViewGroup parent = findViewById(R.id.content_frame); 127 if (parent != null) { 128 parent.removeAllViews(); 129 } 130 LayoutInflater.from(this).inflate(layoutResID, parent); 131 } 132 133 @Override setContentView(View view)134 public void setContentView(View view) { 135 ((ViewGroup) findViewById(R.id.content_frame)).addView(view); 136 } 137 138 @Override setContentView(View view, ViewGroup.LayoutParams params)139 public void setContentView(View view, ViewGroup.LayoutParams params) { 140 ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params); 141 } 142 onCategoriesChanged()143 private void onCategoriesChanged() { 144 final int N = mCategoryListeners.size(); 145 for (int i = 0; i < N; i++) { 146 mCategoryListeners.get(i).onCategoriesChanged(); 147 } 148 } 149 150 /** 151 * @return whether or not the enabled state actually changed. 152 */ setTileEnabled(ComponentName component, boolean enabled)153 public boolean setTileEnabled(ComponentName component, boolean enabled) { 154 PackageManager pm = getPackageManager(); 155 int state = pm.getComponentEnabledSetting(component); 156 boolean isEnabled = state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 157 if (isEnabled != enabled || state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { 158 if (enabled) { 159 sTileBlacklist.remove(component); 160 } else { 161 sTileBlacklist.add(component); 162 } 163 pm.setComponentEnabledSetting(component, enabled 164 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 165 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 166 PackageManager.DONT_KILL_APP); 167 return true; 168 } 169 return false; 170 } 171 172 /** 173 * Updates dashboard categories. Only necessary to call this after setTileEnabled 174 */ updateCategories()175 public void updateCategories() { 176 new CategoriesUpdateTask().execute(); 177 } 178 getSettingPkg()179 public String getSettingPkg() { 180 return TileUtils.SETTING_PKG; 181 } 182 183 public interface CategoryListener { onCategoriesChanged()184 void onCategoriesChanged(); 185 } 186 187 private class CategoriesUpdateTask extends AsyncTask<Void, Void, Void> { 188 189 private final CategoryManager mCategoryManager; 190 CategoriesUpdateTask()191 public CategoriesUpdateTask() { 192 mCategoryManager = CategoryManager.get(SettingsDrawerActivity.this); 193 } 194 195 @Override doInBackground(Void... params)196 protected Void doInBackground(Void... params) { 197 mCategoryManager.reloadAllCategories(SettingsDrawerActivity.this, getSettingPkg()); 198 return null; 199 } 200 201 @Override onPostExecute(Void result)202 protected void onPostExecute(Void result) { 203 mCategoryManager.updateCategoryFromBlacklist(sTileBlacklist); 204 onCategoriesChanged(); 205 } 206 } 207 208 private class PackageReceiver extends BroadcastReceiver { 209 @Override onReceive(Context context, Intent intent)210 public void onReceive(Context context, Intent intent) { 211 new CategoriesUpdateTask().execute(); 212 } 213 } 214 } 215