OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / packages / SettingsLib / src / com / android / settingslib / drawer / SettingsDrawerActivity.java
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.ActivityNotFoundException;
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.provider.Settings;
32 import android.support.v4.widget.DrawerLayout;
33 import android.util.ArraySet;
34 import android.util.Log;
35 import android.util.Pair;
36 import android.view.Gravity;
37 import android.view.LayoutInflater;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.view.ViewGroup;
41 import android.view.Window;
42 import android.view.WindowManager.LayoutParams;
43 import android.widget.AdapterView;
44 import android.widget.ListView;
45 import android.widget.Toolbar;
46 import com.android.settingslib.R;
47 import com.android.settingslib.applications.InterestingConfigChanges;
48
49 import java.util.ArrayList;
50 import java.util.HashMap;
51 import java.util.List;
52
53 public class SettingsDrawerActivity extends Activity {
54
55     protected static final boolean DEBUG_TIMING = false;
56     private static final String TAG = "SettingsDrawerActivity";
57
58     public static final String EXTRA_SHOW_MENU = "show_drawer_menu";
59
60     private static List<DashboardCategory> sDashboardCategories;
61     private static HashMap<Pair<String, String>, Tile> sTileCache;
62     // Serves as a temporary list of tiles to ignore until we heard back from the PM that they
63     // are disabled.
64     private static ArraySet<ComponentName> sTileBlacklist = new ArraySet<>();
65     private static InterestingConfigChanges sConfigTracker;
66
67     private final PackageReceiver mPackageReceiver = new PackageReceiver();
68     private final List<CategoryListener> mCategoryListeners = new ArrayList<>();
69
70     private SettingsDrawerAdapter mDrawerAdapter;
71     private DrawerLayout mDrawerLayout;
72     private boolean mShowingMenu;
73
74     @Override
75     protected void onCreate(@Nullable Bundle savedInstanceState) {
76         super.onCreate(savedInstanceState);
77
78         long startTime = System.currentTimeMillis();
79
80         TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme);
81         if (!theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
82             getWindow().addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
83             getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
84             requestWindowFeature(Window.FEATURE_NO_TITLE);
85         }
86         super.setContentView(R.layout.settings_with_drawer);
87         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
88         if (mDrawerLayout == null) {
89             return;
90         }
91         Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
92         if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
93             toolbar.setVisibility(View.GONE);
94             mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
95             mDrawerLayout = null;
96             return;
97         }
98         getDashboardCategories();
99         setActionBar(toolbar);
100         mDrawerAdapter = new SettingsDrawerAdapter(this);
101         ListView listView = (ListView) findViewById(R.id.left_drawer);
102         listView.setAdapter(mDrawerAdapter);
103         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
104             public void onItemClick(android.widget.AdapterView<?> parent, View view, int position,
105                     long id) {
106                 onTileClicked(mDrawerAdapter.getTile(position));
107             };
108         });
109         if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
110                 + " ms");
111     }
112
113     @Override
114     public boolean onOptionsItemSelected(MenuItem item) {
115         if (mShowingMenu && mDrawerLayout != null && item.getItemId() == android.R.id.home
116                 && mDrawerAdapter.getCount() != 0) {
117             openDrawer();
118             return true;
119         }
120         return super.onOptionsItemSelected(item);
121     }
122
123     @Override
124     protected void onResume() {
125         super.onResume();
126
127         if (mDrawerLayout != null) {
128             final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
129             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
130             filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
131             filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
132             filter.addDataScheme("package");
133             registerReceiver(mPackageReceiver, filter);
134
135             new CategoriesUpdater().execute();
136         }
137         if (getIntent() != null && getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false)) {
138             showMenuIcon();
139         }
140     }
141
142     @Override
143     protected void onPause() {
144         if (mDrawerLayout != null) {
145             unregisterReceiver(mPackageReceiver);
146         }
147
148         super.onPause();
149     }
150
151     public void addCategoryListener(CategoryListener listener) {
152         mCategoryListeners.add(listener);
153     }
154
155     public void remCategoryListener(CategoryListener listener) {
156         mCategoryListeners.remove(listener);
157     }
158
159     public void setIsDrawerPresent(boolean isPresent) {
160         if (isPresent) {
161             mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
162             updateDrawer();
163         } else {
164             if (mDrawerLayout != null) {
165                 mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
166                 mDrawerLayout = null;
167             }
168         }
169     }
170
171     public void openDrawer() {
172         if (mDrawerLayout != null) {
173             mDrawerLayout.openDrawer(Gravity.START);
174         }
175     }
176
177     public void closeDrawer() {
178         if (mDrawerLayout != null) {
179             mDrawerLayout.closeDrawers();
180         }
181     }
182
183     @Override
184     public void setContentView(@LayoutRes int layoutResID) {
185         final ViewGroup parent = (ViewGroup) findViewById(R.id.content_frame);
186         if (parent != null) {
187             parent.removeAllViews();
188         }
189         LayoutInflater.from(this).inflate(layoutResID, parent);
190     }
191
192     @Override
193     public void setContentView(View view) {
194         ((ViewGroup) findViewById(R.id.content_frame)).addView(view);
195     }
196
197     @Override
198     public void setContentView(View view, ViewGroup.LayoutParams params) {
199         ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params);
200     }
201
202     public void updateDrawer() {
203         if (mDrawerLayout == null) {
204             return;
205         }
206         // TODO: Do this in the background with some loading.
207         mDrawerAdapter.updateCategories();
208         if (mDrawerAdapter.getCount() != 0) {
209             mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
210         } else {
211             mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
212         }
213     }
214
215     public void showMenuIcon() {
216         mShowingMenu = true;
217         getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
218         getActionBar().setDisplayHomeAsUpEnabled(true);
219     }
220
221     public List<DashboardCategory> getDashboardCategories() {
222         if (sDashboardCategories == null) {
223             sTileCache = new HashMap<>();
224             sConfigTracker = new InterestingConfigChanges();
225             // Apply initial current config.
226             sConfigTracker.applyNewConfig(getResources());
227             sDashboardCategories = TileUtils.getCategories(this, sTileCache);
228         }
229         return sDashboardCategories;
230     }
231
232     protected void onCategoriesChanged() {
233         updateDrawer();
234         final int N = mCategoryListeners.size();
235         for (int i = 0; i < N; i++) {
236             mCategoryListeners.get(i).onCategoriesChanged();
237         }
238     }
239
240     public boolean openTile(Tile tile) {
241         closeDrawer();
242         if (tile == null) {
243             startActivity(new Intent(Settings.ACTION_SETTINGS).addFlags(
244                     Intent.FLAG_ACTIVITY_CLEAR_TASK));
245             return true;
246         }
247         try {
248             int numUserHandles = tile.userHandle.size();
249             if (numUserHandles > 1) {
250                 ProfileSelectDialog.show(getFragmentManager(), tile);
251                 return false;
252             } else if (numUserHandles == 1) {
253                 // Show menu on top level items.
254                 tile.intent.putExtra(EXTRA_SHOW_MENU, true);
255                 tile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
256                 startActivityAsUser(tile.intent, tile.userHandle.get(0));
257             } else {
258                 // Show menu on top level items.
259                 tile.intent.putExtra(EXTRA_SHOW_MENU, true);
260                 tile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
261                 startActivity(tile.intent);
262             }
263         } catch (ActivityNotFoundException e) {
264             Log.w(TAG, "Couldn't find tile " + tile.intent, e);
265         }
266         return true;
267     }
268
269     protected void onTileClicked(Tile tile) {
270         if (openTile(tile)) {
271             finish();
272         }
273     }
274
275     public void onProfileTileOpen() {
276         finish();
277     }
278
279     public void setTileEnabled(ComponentName component, boolean enabled) {
280         PackageManager pm = getPackageManager();
281         int state = pm.getComponentEnabledSetting(component);
282         boolean isEnabled = state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
283         if (isEnabled != enabled || state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
284             if (enabled) {
285                 sTileBlacklist.remove(component);
286             } else {
287                 sTileBlacklist.add(component);
288             }
289             pm.setComponentEnabledSetting(component, enabled
290                     ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
291                     : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
292                     PackageManager.DONT_KILL_APP);
293             new CategoriesUpdater().execute();
294         }
295     }
296
297     public interface CategoryListener {
298         void onCategoriesChanged();
299     }
300
301     private class CategoriesUpdater extends AsyncTask<Void, Void, List<DashboardCategory>> {
302         @Override
303         protected List<DashboardCategory> doInBackground(Void... params) {
304             if (sConfigTracker.applyNewConfig(getResources())) {
305                 sTileCache.clear();
306             }
307             return TileUtils.getCategories(SettingsDrawerActivity.this, sTileCache);
308         }
309
310         @Override
311         protected void onPreExecute() {
312             if (sConfigTracker == null || sTileCache == null) {
313                 getDashboardCategories();
314             }
315         }
316
317         @Override
318         protected void onPostExecute(List<DashboardCategory> dashboardCategories) {
319             for (int i = 0; i < dashboardCategories.size(); i++) {
320                 DashboardCategory category = dashboardCategories.get(i);
321                 for (int j = 0; j < category.tiles.size(); j++) {
322                     Tile tile = category.tiles.get(j);
323                     if (sTileBlacklist.contains(tile.intent.getComponent())) {
324                         category.tiles.remove(j--);
325                     }
326                 }
327             }
328             sDashboardCategories = dashboardCategories;
329             onCategoriesChanged();
330         }
331     }
332
333     private class PackageReceiver extends BroadcastReceiver {
334         @Override
335         public void onReceive(Context context, Intent intent) {
336             new CategoriesUpdater().execute();
337         }
338     }
339 }