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