SettingsDrawerActivity.java revision cafda1f90ebf79ec3a56d43d8d3c0d63c9d84cb2
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 */
16package com.android.settingslib.drawer;
17
18import android.annotation.LayoutRes;
19import android.annotation.Nullable;
20import android.app.Activity;
21import android.content.BroadcastReceiver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.content.res.TypedArray;
26import android.os.AsyncTask;
27import android.os.Bundle;
28import android.provider.Settings;
29import android.support.v4.widget.DrawerLayout;
30import android.util.Log;
31import android.util.Pair;
32import android.view.Gravity;
33import android.view.LayoutInflater;
34import android.view.MenuItem;
35import android.view.View;
36import android.view.ViewGroup;
37import android.view.Window;
38import android.view.WindowManager.LayoutParams;
39import android.widget.AdapterView;
40import android.widget.ListView;
41import android.widget.Toolbar;
42import com.android.settingslib.R;
43
44import java.util.ArrayList;
45import java.util.HashMap;
46import java.util.List;
47
48public class SettingsDrawerActivity extends Activity {
49
50    protected static final boolean DEBUG_TIMING = false;
51    private static final String TAG = "SettingsDrawerActivity";
52
53    static final String EXTRA_SHOW_MENU = "show_drawer_menu";
54
55    private static List<DashboardCategory> sDashboardCategories;
56    private static HashMap<Pair<String, String>, Tile> sTileCache;
57
58    private final PackageReceiver mPackageReceiver = new PackageReceiver();
59    private final List<CategoryListener> mCategoryListeners = new ArrayList<>();
60
61    private SettingsDrawerAdapter mDrawerAdapter;
62    private DrawerLayout mDrawerLayout;
63    private boolean mShowingMenu;
64
65    @Override
66    protected void onCreate(@Nullable Bundle savedInstanceState) {
67        super.onCreate(savedInstanceState);
68
69        long startTime = System.currentTimeMillis();
70
71        getWindow().addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
72        getWindow().addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
73        requestWindowFeature(Window.FEATURE_NO_TITLE);
74        super.setContentView(R.layout.settings_with_drawer);
75        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
76        if (mDrawerLayout == null) {
77            return;
78        }
79        Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
80        TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme);
81        if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
82            toolbar.setVisibility(View.GONE);
83            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
84            mDrawerLayout = null;
85            return;
86        }
87        getDashboardCategories();
88        setActionBar(toolbar);
89        mDrawerAdapter = new SettingsDrawerAdapter(this);
90        ListView listView = (ListView) findViewById(R.id.left_drawer);
91        listView.setAdapter(mDrawerAdapter);
92        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
93            public void onItemClick(android.widget.AdapterView<?> parent, View view, int position,
94                    long id) {
95                onTileClicked(mDrawerAdapter.getTile(position));
96            };
97        });
98        if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
99                + " ms");
100    }
101
102    @Override
103    public void onBackPressed() {
104        if (mShowingMenu) {
105            // If we are showing the menu, then we are a top level activity and the back should
106            // kick back to settings home.
107            openTile(null);
108        }
109        super.onBackPressed();
110    }
111
112    @Override
113    public boolean onOptionsItemSelected(MenuItem item) {
114        if (mShowingMenu && mDrawerLayout != null && item.getItemId() == android.R.id.home
115                && mDrawerAdapter.getCount() != 0) {
116            openDrawer();
117            return true;
118        }
119        return super.onOptionsItemSelected(item);
120    }
121
122    @Override
123    protected void onResume() {
124        super.onResume();
125
126        if (mDrawerLayout != null) {
127            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
128            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
129            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
130            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
131            filter.addDataScheme("package");
132            registerReceiver(mPackageReceiver, filter);
133
134            new CategoriesUpdater().execute();
135        }
136        if (getIntent() != null && getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false)) {
137            showMenuIcon();
138        }
139    }
140
141    @Override
142    protected void onPause() {
143        if (mDrawerLayout != null) {
144            unregisterReceiver(mPackageReceiver);
145        }
146
147        super.onPause();
148    }
149
150    public void addCategoryListener(CategoryListener listener) {
151        mCategoryListeners.add(listener);
152    }
153
154    public void remCategoryListener(CategoryListener listener) {
155        mCategoryListeners.remove(listener);
156    }
157
158    public void setIsDrawerPresent(boolean isPresent) {
159        if (isPresent) {
160            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
161            updateDrawer();
162        } else {
163            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
164            mDrawerLayout = null;
165        }
166    }
167
168    public void openDrawer() {
169        if (mDrawerLayout != null) {
170            mDrawerLayout.openDrawer(Gravity.START);
171        }
172    }
173
174    public void closeDrawer() {
175        if (mDrawerLayout != null) {
176            mDrawerLayout.closeDrawers();
177        }
178    }
179
180    @Override
181    public void setContentView(@LayoutRes int layoutResID) {
182        LayoutInflater.from(this).inflate(layoutResID,
183                (ViewGroup) findViewById(R.id.content_frame));
184    }
185
186    @Override
187    public void setContentView(View view) {
188        ((ViewGroup) findViewById(R.id.content_frame)).addView(view);
189    }
190
191    @Override
192    public void setContentView(View view, ViewGroup.LayoutParams params) {
193        ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params);
194    }
195
196    public void updateDrawer() {
197        if (mDrawerLayout == null) {
198            return;
199        }
200        // TODO: Do this in the background with some loading.
201        mDrawerAdapter.updateCategories();
202        if (mDrawerAdapter.getCount() != 0) {
203            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
204        } else {
205            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
206        }
207    }
208
209    public void showMenuIcon() {
210        mShowingMenu = true;
211        getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
212        getActionBar().setDisplayHomeAsUpEnabled(true);
213    }
214
215    public List<DashboardCategory> getDashboardCategories() {
216        if (sDashboardCategories == null) {
217            sTileCache = new HashMap<>();
218            sDashboardCategories = TileUtils.getCategories(this, sTileCache);
219        }
220        return sDashboardCategories;
221    }
222
223    protected void onCategoriesChanged() {
224        updateDrawer();
225        final int N = mCategoryListeners.size();
226        for (int i = 0; i < N; i++) {
227            mCategoryListeners.get(i).onCategoriesChanged();
228        }
229    }
230
231    public boolean openTile(Tile tile) {
232        closeDrawer();
233        if (tile == null) {
234            startActivity(new Intent(Settings.ACTION_SETTINGS).addFlags(
235                    Intent.FLAG_ACTIVITY_CLEAR_TASK));
236            return true;
237        }
238        int numUserHandles = tile.userHandle.size();
239        if (numUserHandles > 1) {
240            ProfileSelectDialog.show(getFragmentManager(), tile);
241            return false;
242        } else if (numUserHandles == 1) {
243            // Show menu on top level items.
244            tile.intent.putExtra(EXTRA_SHOW_MENU, true);
245            tile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
246            startActivityAsUser(tile.intent, tile.userHandle.get(0));
247        } else {
248            // Show menu on top level items.
249            tile.intent.putExtra(EXTRA_SHOW_MENU, true);
250            tile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
251            startActivity(tile.intent);
252        }
253        return true;
254    }
255
256    protected void onTileClicked(Tile tile) {
257        if (openTile(tile)) {
258            finish();
259        }
260    }
261
262    public void onProfileTileOpen() {
263        finish();
264    }
265
266    public interface CategoryListener {
267        void onCategoriesChanged();
268    }
269
270    private class CategoriesUpdater extends AsyncTask<Void, Void, List<DashboardCategory>> {
271        @Override
272        protected List<DashboardCategory> doInBackground(Void... params) {
273            return TileUtils.getCategories(SettingsDrawerActivity.this, sTileCache);
274        }
275
276        @Override
277        protected void onPostExecute(List<DashboardCategory> dashboardCategories) {
278            sDashboardCategories = dashboardCategories;
279            onCategoriesChanged();
280        }
281    }
282
283    private class PackageReceiver extends BroadcastReceiver {
284        @Override
285        public void onReceive(Context context, Intent intent) {
286            new CategoriesUpdater().execute();
287        }
288    }
289}
290