1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.tuner;
16 
17 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
18 
19 import android.content.Context;
20 import android.content.pm.LauncherActivityInfo;
21 import android.content.pm.LauncherApps;
22 import android.content.pm.PackageManager.NameNotFoundException;
23 import android.os.Bundle;
24 import android.os.Process;
25 
26 import androidx.preference.Preference;
27 import androidx.preference.PreferenceCategory;
28 import androidx.preference.PreferenceFragment;
29 import androidx.preference.PreferenceScreen;
30 import androidx.preference.PreferenceViewHolder;
31 
32 import com.android.systemui.Dependency;
33 import com.android.systemui.R;
34 import com.android.systemui.tuner.ShortcutParser.Shortcut;
35 import com.android.systemui.tuner.TunerService.Tunable;
36 
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 public class ShortcutPicker extends PreferenceFragment implements Tunable {
41 
42     private final ArrayList<SelectablePreference> mSelectablePreferences = new ArrayList<>();
43     private String mKey;
44     private SelectablePreference mNonePreference;
45     private TunerService mTunerService;
46 
47     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)48     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
49         Context context = getPreferenceManager().getContext();
50         PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(context);
51         screen.setOrderingAsAdded(true);
52         PreferenceCategory otherApps = new PreferenceCategory(context);
53         otherApps.setTitle(R.string.tuner_other_apps);
54 
55         mNonePreference = new SelectablePreference(context);
56         mSelectablePreferences.add(mNonePreference);
57         mNonePreference.setTitle(R.string.lockscreen_none);
58         mNonePreference.setIcon(R.drawable.ic_remove_circle);
59         screen.addPreference(mNonePreference);
60 
61         LauncherApps apps = getContext().getSystemService(LauncherApps.class);
62         List<LauncherActivityInfo> activities = apps.getActivityList(null,
63                 Process.myUserHandle());
64 
65         screen.addPreference(otherApps);
66         activities.forEach(info -> {
67             try {
68                 List<Shortcut> shortcuts = new ShortcutParser(getContext(),
69                         info.getComponentName()).getShortcuts();
70                 AppPreference appPreference = new AppPreference(context, info);
71                 mSelectablePreferences.add(appPreference);
72                 if (shortcuts.size() != 0) {
73                     //PreferenceCategory category = new PreferenceCategory(context);
74                     //screen.addPreference(category);
75                     //category.setTitle(info.getLabel());
76                     screen.addPreference(appPreference);
77                     shortcuts.forEach(shortcut -> {
78                         ShortcutPreference shortcutPref = new ShortcutPreference(context, shortcut,
79                                 info.getLabel());
80                         mSelectablePreferences.add(shortcutPref);
81                         screen.addPreference(shortcutPref);
82                     });
83                     return;
84                 }
85                 otherApps.addPreference(appPreference);
86             } catch (NameNotFoundException e) {
87             }
88         });
89         // Move other apps to the bottom.
90         screen.removePreference(otherApps);
91         for (int i = 0; i < otherApps.getPreferenceCount(); i++) {
92             Preference p = otherApps.getPreference(0);
93             otherApps.removePreference(p);
94             p.setOrder(Preference.DEFAULT_ORDER);
95             screen.addPreference(p);
96         }
97         //screen.addPreference(otherApps);
98 
99         setPreferenceScreen(screen);
100         mKey = getArguments().getString(ARG_PREFERENCE_ROOT);
101         mTunerService = Dependency.get(TunerService.class);
102         mTunerService.addTunable(this, mKey);
103     }
104 
105     @Override
onPreferenceTreeClick(Preference preference)106     public boolean onPreferenceTreeClick(Preference preference) {
107         mTunerService.setValue(mKey, preference.toString());
108         getActivity().onBackPressed();
109         return true;
110     }
111 
112     @Override
onActivityCreated(Bundle savedInstanceState)113     public void onActivityCreated(Bundle savedInstanceState) {
114         super.onActivityCreated(savedInstanceState);
115         if (LOCKSCREEN_LEFT_BUTTON.equals(mKey)) {
116             getActivity().setTitle(R.string.lockscreen_shortcut_left);
117         } else {
118             getActivity().setTitle(R.string.lockscreen_shortcut_right);
119         }
120     }
121 
122     @Override
onDestroy()123     public void onDestroy() {
124         super.onDestroy();
125         mTunerService.removeTunable(this);
126     }
127 
128     @Override
onTuningChanged(String key, String newValue)129     public void onTuningChanged(String key, String newValue) {
130         String v = newValue != null ? newValue : "";
131         mSelectablePreferences.forEach(p -> p.setChecked(v.equals(p.toString())));
132     }
133 
134     private static class AppPreference extends SelectablePreference {
135         private final LauncherActivityInfo mInfo;
136         private boolean mBinding;
137 
AppPreference(Context context, LauncherActivityInfo info)138         public AppPreference(Context context, LauncherActivityInfo info) {
139             super(context);
140             mInfo = info;
141             setTitle(context.getString(R.string.tuner_launch_app, info.getLabel()));
142             setSummary(context.getString(R.string.tuner_app, info.getLabel()));
143         }
144 
145         @Override
onBindViewHolder(PreferenceViewHolder holder)146         public void onBindViewHolder(PreferenceViewHolder holder) {
147             mBinding = true;
148             if (getIcon() == null) {
149                 setIcon(mInfo.getBadgedIcon(
150                         getContext().getResources().getConfiguration().densityDpi));
151             }
152             mBinding = false;
153             super.onBindViewHolder(holder);
154         }
155 
156         @Override
notifyChanged()157         protected void notifyChanged() {
158             if (mBinding) return;
159             super.notifyChanged();
160         }
161 
162         @Override
toString()163         public String toString() {
164             return mInfo.getComponentName().flattenToString();
165         }
166     }
167 
168     private static class ShortcutPreference extends SelectablePreference {
169         private final Shortcut mShortcut;
170         private boolean mBinding;
171 
ShortcutPreference(Context context, Shortcut shortcut, CharSequence appLabel)172         public ShortcutPreference(Context context, Shortcut shortcut, CharSequence appLabel) {
173             super(context);
174             mShortcut = shortcut;
175             setTitle(shortcut.label);
176             setSummary(context.getString(R.string.tuner_app, appLabel));
177         }
178 
179         @Override
onBindViewHolder(PreferenceViewHolder holder)180         public void onBindViewHolder(PreferenceViewHolder holder) {
181             mBinding = true;
182             if (getIcon() == null) {
183                 setIcon(mShortcut.icon.loadDrawable(getContext()));
184             }
185             mBinding = false;
186             super.onBindViewHolder(holder);
187         }
188 
189         @Override
notifyChanged()190         protected void notifyChanged() {
191             if (mBinding) return;
192             super.notifyChanged();
193         }
194 
195         @Override
toString()196         public String toString() {
197             return mShortcut.toString();
198         }
199     }
200 }
201