OSDN Git Service

be658be50638e8d605751d2f35fbf401f4e23a75
[android-x86/packages-apps-Taskbar.git] / app / src / main / java / com / farmerbb / taskbar / activity / ContextMenuActivity.java
1 /* Copyright 2016 Braden Farmer
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * 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
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 package com.farmerbb.taskbar.activity;
17
18 import android.accessibilityservice.AccessibilityService;
19 import android.annotation.SuppressLint;
20 import android.annotation.TargetApi;
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.SharedPreferences;
27 import android.content.pm.LauncherActivityInfo;
28 import android.content.pm.LauncherApps;
29 import android.content.pm.PackageManager;
30 import android.content.pm.ResolveInfo;
31 import android.content.pm.ShortcutInfo;
32 import android.media.AudioManager;
33 import android.net.Uri;
34 import android.os.Build;
35 import android.os.Bundle;
36 import android.os.UserManager;
37 import android.preference.Preference;
38 import android.preference.PreferenceActivity;
39 import android.provider.Settings;
40 import android.view.Gravity;
41 import android.view.View;
42 import android.view.WindowManager;
43
44 import com.farmerbb.taskbar.BuildConfig;
45 import com.farmerbb.taskbar.R;
46 import com.farmerbb.taskbar.util.TaskbarPosition;
47 import com.farmerbb.taskbar.util.AppEntry;
48 import com.farmerbb.taskbar.util.ApplicationType;
49 import com.farmerbb.taskbar.util.DesktopIconInfo;
50 import com.farmerbb.taskbar.util.DisplayInfo;
51 import com.farmerbb.taskbar.helper.FreeformHackHelper;
52 import com.farmerbb.taskbar.util.IconCache;
53 import com.farmerbb.taskbar.helper.LauncherHelper;
54 import com.farmerbb.taskbar.helper.MenuHelper;
55 import com.farmerbb.taskbar.util.PinnedBlockedApps;
56 import com.farmerbb.taskbar.util.SavedWindowSizes;
57 import com.farmerbb.taskbar.util.U;
58
59 import org.json.JSONArray;
60 import org.json.JSONException;
61
62 import java.io.File;
63 import java.util.List;
64
65 import static com.farmerbb.taskbar.util.Constants.*;
66
67 public class ContextMenuActivity extends PreferenceActivity implements Preference.OnPreferenceClickListener {
68
69     private AppEntry entry;
70     private DesktopIconInfo desktopIcon;
71
72     boolean showStartMenu = false;
73     boolean shouldHideTaskbar = false;
74     boolean isStartButton = false;
75     boolean isOverflowMenu = false;
76     boolean secondaryMenu = false;
77     boolean dashboardOrStartMenuAppearing = false;
78     boolean contextMenuFix = false;
79     boolean showQuitOption = false;
80
81     List<ShortcutInfo> shortcuts;
82
83     private BroadcastReceiver dashboardOrStartMenuAppearingReceiver = new BroadcastReceiver() {
84         @Override
85         public void onReceive(Context context, Intent intent) {
86             dashboardOrStartMenuAppearing = true;
87             finish();
88         }
89     };
90
91     private BroadcastReceiver finishReceiver = new BroadcastReceiver() {
92         @Override
93         public void onReceive(Context context, Intent intent) {
94             finish();
95         }
96     };
97
98
99     @SuppressLint("RtlHardcoded")
100     @Override
101     protected void onPostCreate(Bundle savedInstanceState) {
102         super.onPostCreate(savedInstanceState);
103
104         U.sendBroadcast(this, ACTION_CONTEXT_MENU_APPEARING);
105         MenuHelper.getInstance().setContextMenuOpen(true);
106
107         Bundle args = getIntent().getBundleExtra("args");
108         entry = (AppEntry) args.getSerializable("app_entry");
109         desktopIcon = (DesktopIconInfo) args.getSerializable("desktop_icon");
110
111         showStartMenu = args.getBoolean("launched_from_start_menu", false);
112         isStartButton = entry == null && args.getBoolean("is_start_button", false);
113         isOverflowMenu = entry == null && args.getBoolean("is_overflow_menu", false);
114         contextMenuFix = args.containsKey("context_menu_fix");
115         showQuitOption = !args.getBoolean("dont_show_quit", false);
116
117         // Determine where to position the dialog on screen
118         WindowManager.LayoutParams params = getWindow().getAttributes();
119         
120         if(args.containsKey("x") && args.containsKey("y"))
121             U.applyDisplayCutoutModeTo(params);
122
123         DisplayInfo display = U.getDisplayInfo(this);
124
125         int statusBarHeight = 0;
126         int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
127         if(resourceId > 0)
128             statusBarHeight = getResources().getDimensionPixelSize(resourceId);
129
130         int contextMenuWidth = getResources().getDimensionPixelSize(R.dimen.tb_context_menu_width);
131
132         if(showStartMenu || desktopIcon != null) {
133             int x = args.getInt("x", 0);
134             int y = args.getInt("y", 0);
135             int offsetResourceId = isOverflowMenu ? R.dimen.tb_context_menu_offset_overflow : R.dimen.tb_context_menu_offset;
136             int offset = getResources().getDimensionPixelSize(offsetResourceId);
137
138             switch(TaskbarPosition.getTaskbarPosition(this)) {
139                 case POSITION_BOTTOM_LEFT:
140                 case POSITION_BOTTOM_VERTICAL_LEFT:
141                     params.gravity = Gravity.BOTTOM | Gravity.LEFT;
142                     params.x = x;
143                     params.y = display.height - y - offset;
144                     break;
145                 case POSITION_BOTTOM_RIGHT:
146                 case POSITION_BOTTOM_VERTICAL_RIGHT:
147                     params.gravity = Gravity.BOTTOM | Gravity.LEFT;
148                     params.x = x - contextMenuWidth + offset + offset;
149                     params.y = display.height - y - offset;
150                     break;
151                 case POSITION_TOP_LEFT:
152                 case POSITION_TOP_VERTICAL_LEFT:
153                     params.gravity = Gravity.TOP | Gravity.LEFT;
154                     params.x = x;
155                     params.y = y - offset + statusBarHeight;
156                     break;
157                 case POSITION_TOP_RIGHT:
158                 case POSITION_TOP_VERTICAL_RIGHT:
159                     params.gravity = Gravity.TOP | Gravity.LEFT;
160                     params.x = x - contextMenuWidth + offset + offset;
161                     params.y = y - offset + statusBarHeight;
162                     break;
163             }
164         } else {
165             U.sendBroadcast(this, ACTION_HIDE_START_MENU);
166
167             int x = args.getInt("x", display.width);
168             int y = args.getInt("y", display.height);
169             int offset = getResources().getDimensionPixelSize(R.dimen.tb_icon_size);
170
171             switch(TaskbarPosition.getTaskbarPosition(this)) {
172                 case POSITION_BOTTOM_LEFT:
173                     params.gravity = Gravity.BOTTOM | Gravity.LEFT;
174                     params.x = isStartButton ? 0 : x;
175                     params.y = offset;
176                     break;
177                 case POSITION_BOTTOM_VERTICAL_LEFT:
178                     params.gravity = Gravity.BOTTOM | Gravity.LEFT;
179                     params.x = offset;
180                     params.y = display.height - y - (isStartButton ? 0 : offset);
181                     break;
182                 case POSITION_BOTTOM_RIGHT:
183                     params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
184                     params.x = display.width - x;
185                     params.y = offset;
186                     break;
187                 case POSITION_BOTTOM_VERTICAL_RIGHT:
188                     params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
189                     params.x = offset;
190                     params.y = display.height - y - (isStartButton ? 0 : offset);
191                     break;
192                 case POSITION_TOP_LEFT:
193                     params.gravity = Gravity.TOP | Gravity.LEFT;
194                     params.x = isStartButton ? 0 : x;
195                     params.y = offset;
196                     break;
197                 case POSITION_TOP_VERTICAL_LEFT:
198                     params.gravity = Gravity.TOP | Gravity.LEFT;
199                     params.x = offset;
200                     params.y = isStartButton ? 0 : y - statusBarHeight;
201                     break;
202                 case POSITION_TOP_RIGHT:
203                     params.gravity = Gravity.TOP | Gravity.RIGHT;
204                     params.x = display.width - x;
205                     params.y = offset;
206                     break;
207                 case POSITION_TOP_VERTICAL_RIGHT:
208                     params.gravity = Gravity.TOP | Gravity.RIGHT;
209                     params.x = offset;
210                     params.y = isStartButton ? 0 : y - statusBarHeight;
211                     break;
212             }
213
214             if(!TaskbarPosition.isVertical(this) && (params.x > display.width / 2))
215                 params.x = params.x - contextMenuWidth + offset;
216         }
217
218         params.width = getResources().getDimensionPixelSize(R.dimen.tb_context_menu_width);
219         params.dimAmount = 0;
220
221         if(U.isChromeOs(this)
222                 && TaskbarPosition.isBottom(this)) {
223             SharedPreferences pref = U.getSharedPreferences(this);
224
225             if(pref.getBoolean(PREF_CHROME_OS_CONTEXT_MENU_FIX, true)
226                     && !pref.getBoolean(PREF_HAS_CAPTION, false))
227                 params.y = params.y - getResources().getDimensionPixelSize(R.dimen.tb_caption_offset);
228         }
229
230         getWindow().setAttributes(params);
231
232         if(U.isChromeOs(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)
233             getWindow().setElevation(0);
234
235         View view = findViewById(android.R.id.list);
236         if(view != null) view.setPadding(0, 0, 0, 0);
237
238         generateMenu();
239
240         U.registerReceiver(this, dashboardOrStartMenuAppearingReceiver,
241                 ACTION_START_MENU_APPEARING,
242                 ACTION_DASHBOARD_APPEARING);
243
244         U.registerReceiver(this, finishReceiver, ACTION_HIDE_CONTEXT_MENU);
245     }
246
247     @SuppressWarnings("deprecation")
248     private void generateMenu() {
249         if(isStartButton) {
250             addPreferencesFromResource(R.xml.tb_pref_context_menu_open_settings);
251             findPreference(PREF_OPEN_TASKBAR_SETTINGS).setOnPreferenceClickListener(this);
252             findPreference(PREF_START_MENU_APPS).setOnPreferenceClickListener(this);
253
254             if(U.isFreeformModeEnabled(this)
255                     && !U.isDesktopIconsEnabled(this)
256                     && ((U.launcherIsDefault(this)
257                     && !U.isOverridingFreeformHack(this, false)
258                     && FreeformHackHelper.getInstance().isInFreeformWorkspace())
259                     || (U.isOverridingFreeformHack(this, false)
260                     && LauncherHelper.getInstance().isOnHomeScreen(this)))) {
261                 addPreferencesFromResource(R.xml.tb_pref_context_menu_change_wallpaper);
262                 findPreference(PREF_CHANGE_WALLPAPER).setOnPreferenceClickListener(this);
263             }
264
265             if(showQuitOption) {
266                 addPreferencesFromResource(R.xml.tb_pref_context_menu_quit);
267                 findPreference(PREF_QUIT_TASKBAR).setOnPreferenceClickListener(this);
268             }
269         } else if(isOverflowMenu) {
270             if(getResources().getConfiguration().screenWidthDp >= 600
271                     && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M)
272                 setTitle(R.string.tb_tools);
273             else {
274                 addPreferencesFromResource(R.xml.tb_pref_context_menu_header);
275                 findPreference(PREF_HEADER).setTitle(R.string.tb_tools);
276             }
277
278             addPreferencesFromResource(R.xml.tb_pref_context_menu_overflow);
279             findPreference(PREF_VOLUME).setOnPreferenceClickListener(this);
280             findPreference(PREF_SYSTEM_SETTINGS).setOnPreferenceClickListener(this);
281
282             if(!U.isLibrary(this))
283                 findPreference(PREF_POWER_MENU).setOnPreferenceClickListener(this);
284             else
285                 getPreferenceScreen().removePreference(findPreference(PREF_POWER_MENU));
286
287             if(!U.isLibrary(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
288                 findPreference(PREF_LOCK_DEVICE).setOnPreferenceClickListener(this);
289             else
290                 getPreferenceScreen().removePreference(findPreference(PREF_LOCK_DEVICE));
291
292             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
293                 findPreference(PREF_FILE_MANAGER).setOnPreferenceClickListener(this);
294             else
295                 getPreferenceScreen().removePreference(findPreference(PREF_FILE_MANAGER));
296         } else if(desktopIcon != null && entry == null) {
297             addPreferencesFromResource(R.xml.tb_pref_context_menu_desktop_icons);
298             findPreference(PREF_ADD_ICON_TO_DESKTOP).setOnPreferenceClickListener(this);
299             findPreference(PREF_ARRANGE_ICONS).setOnPreferenceClickListener(this);
300             findPreference(PREF_SORT_BY_NAME).setOnPreferenceClickListener(this);
301             findPreference(PREF_CHANGE_WALLPAPER).setOnPreferenceClickListener(this);
302         } else {
303             if(getResources().getConfiguration().screenWidthDp >= 600
304                     && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M)
305                 setTitle(entry.getLabel());
306             else {
307                 addPreferencesFromResource(R.xml.tb_pref_context_menu_header);
308                 findPreference(PREF_HEADER).setTitle(entry.getLabel());
309             }
310
311             if(U.hasFreeformSupport(this)
312                     && U.isFreeformModeEnabled(this)
313                     && !U.isGame(this, entry.getPackageName())) {
314                 addPreferencesFromResource(R.xml.tb_pref_context_menu_show_window_sizes);
315                 findPreference(PREF_SHOW_WINDOW_SIZES).setOnPreferenceClickListener(this);
316             }
317
318             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
319                 int shortcutCount = getLauncherShortcuts();
320
321                 if(shortcutCount > 1) {
322                     addPreferencesFromResource(R.xml.tb_pref_context_menu_shortcuts);
323                     findPreference(PREF_APP_SHORTCUTS).setOnPreferenceClickListener(this);
324                 } else if(shortcutCount == 1)
325                     generateShortcuts();
326             }
327
328             final PackageManager pm = getPackageManager();
329             Intent homeIntent = new Intent(Intent.ACTION_MAIN);
330             homeIntent.addCategory(Intent.CATEGORY_HOME);
331             ResolveInfo defaultLauncher = pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
332
333             if(desktopIcon != null) {
334                 addPreferencesFromResource(R.xml.tb_pref_context_menu_remove_desktop_icon);
335                 findPreference(PREF_ARRANGE_ICONS).setOnPreferenceClickListener(this);
336                 findPreference(PREF_REMOVE_DESKTOP_ICON).setOnPreferenceClickListener(this);
337             } else if(!entry.getPackageName().contains(BuildConfig.BASE_APPLICATION_ID)
338                     && !entry.getPackageName().equals(defaultLauncher.activityInfo.packageName)) {
339                 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(this);
340
341                 if(pba.isPinned(entry.getComponentName())) {
342                     addPreferencesFromResource(R.xml.tb_pref_context_menu_pin);
343                     findPreference(PREF_PIN_APP).setOnPreferenceClickListener(this);
344                     findPreference(PREF_PIN_APP).setTitle(R.string.tb_unpin_app);
345                 } else if(pba.isBlocked(entry.getComponentName())) {
346                     addPreferencesFromResource(R.xml.tb_pref_context_menu_block);
347                     findPreference(PREF_BLOCK_APP).setOnPreferenceClickListener(this);
348                     findPreference(PREF_BLOCK_APP).setTitle(R.string.tb_unblock_app);
349                 } else {
350                     final int MAX_NUM_OF_COLUMNS = U.getMaxNumOfEntries(this);
351
352                     if(pba.getPinnedApps().size() < MAX_NUM_OF_COLUMNS) {
353                         addPreferencesFromResource(R.xml.tb_pref_context_menu_pin);
354                         findPreference(PREF_PIN_APP).setOnPreferenceClickListener(this);
355                         findPreference(PREF_PIN_APP).setTitle(R.string.tb_pin_app);
356                     }
357
358                     addPreferencesFromResource(R.xml.tb_pref_context_menu_block);
359                     findPreference(PREF_BLOCK_APP).setOnPreferenceClickListener(this);
360                     findPreference(PREF_BLOCK_APP).setTitle(R.string.tb_block_app);
361                 }
362             }
363
364             addPreferencesFromResource(R.xml.tb_pref_context_menu);
365
366             findPreference(PREF_APP_INFO).setOnPreferenceClickListener(this);
367             findPreference(PREF_UNINSTALL).setOnPreferenceClickListener(this);
368         }
369     }
370
371     @SuppressWarnings("deprecation")
372     private void generateShortcuts() {
373         addPreferencesFromResource(R.xml.tb_pref_context_menu_shortcut_list);
374         switch(shortcuts.size()) {
375             case 5:
376                 findPreference(PREF_SHORTCUT_5).setTitle(getShortcutTitle(shortcuts.get(4)));
377                 findPreference(PREF_SHORTCUT_5).setOnPreferenceClickListener(this);
378             case 4:
379                 findPreference(PREF_SHORTCUT_4).setTitle(getShortcutTitle(shortcuts.get(3)));
380                 findPreference(PREF_SHORTCUT_4).setOnPreferenceClickListener(this);
381             case 3:
382                 findPreference(PREF_SHORTCUT_3).setTitle(getShortcutTitle(shortcuts.get(2)));
383                 findPreference(PREF_SHORTCUT_3).setOnPreferenceClickListener(this);
384             case 2:
385                 findPreference(PREF_SHORTCUT_2).setTitle(getShortcutTitle(shortcuts.get(1)));
386                 findPreference(PREF_SHORTCUT_2).setOnPreferenceClickListener(this);
387             case 1:
388                 findPreference(PREF_SHORTCUT_1).setTitle(getShortcutTitle(shortcuts.get(0)));
389                 findPreference(PREF_SHORTCUT_1).setOnPreferenceClickListener(this);
390                 break;
391         }
392
393         switch(shortcuts.size()) {
394             case 1:
395                 getPreferenceScreen().removePreference(findPreference(PREF_SHORTCUT_2));
396             case 2:
397                 getPreferenceScreen().removePreference(findPreference(PREF_SHORTCUT_3));
398             case 3:
399                 getPreferenceScreen().removePreference(findPreference(PREF_SHORTCUT_4));
400             case 4:
401                 getPreferenceScreen().removePreference(findPreference(PREF_SHORTCUT_5));
402                 break;
403         }
404     }
405
406     @SuppressWarnings("deprecation")
407     private void generateWindowSizes() {
408         getPreferenceScreen().removeAll();
409
410         addPreferencesFromResource(R.xml.tb_pref_context_menu_window_size_list);
411         findPreference(PREF_WINDOW_SIZE_STANDARD).setOnPreferenceClickListener(this);
412         findPreference(PREF_WINDOW_SIZE_LARGE).setOnPreferenceClickListener(this);
413         findPreference(PREF_WINDOW_SIZE_FULLSCREEN).setOnPreferenceClickListener(this);
414         findPreference(PREF_WINDOW_SIZE_HALF_LEFT).setOnPreferenceClickListener(this);
415         findPreference(PREF_WINDOW_SIZE_HALF_RIGHT).setOnPreferenceClickListener(this);
416         findPreference(PREF_WINDOW_SIZE_PHONE_SIZE).setOnPreferenceClickListener(this);
417
418         String windowSizePref = SavedWindowSizes.getInstance(this).getWindowSize(this, entry.getPackageName());
419         CharSequence title = findPreference("window_size_" + windowSizePref).getTitle();
420         findPreference("window_size_" + windowSizePref).setTitle('\u2713' + " " + title);
421     }
422
423     @SuppressWarnings("deprecation")
424     private void generateWallpaperOptions() {
425         getPreferenceScreen().removeAll();
426
427         addPreferencesFromResource(R.xml.tb_pref_context_menu_change_wallpaper_secondary);
428         findPreference(PREF_CHANGE_WALLPAPER_GLOBAL).setOnPreferenceClickListener(this);
429         findPreference(PREF_CHANGE_WALLPAPER_DESKTOP).setOnPreferenceClickListener(this);
430
431         File file = new File(getFilesDir() + "/tb_images", "desktop_wallpaper");
432         if(!file.exists()) return;
433
434         addPreferencesFromResource(R.xml.tb_pref_remove_desktop_wallpaper);
435         findPreference(PREF_REMOVE_DESKTOP_WALLPAPER).setOnPreferenceClickListener(this);
436     }
437
438     @SuppressWarnings("deprecation")
439     @TargetApi(Build.VERSION_CODES.N_MR1)
440     @Override
441     public boolean onPreferenceClick(Preference p) {
442         UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
443         LauncherApps launcherApps = (LauncherApps) getSystemService(LAUNCHER_APPS_SERVICE);
444         boolean appIsValid = isStartButton || isOverflowMenu || desktopIcon != null ||
445                 (entry != null && !launcherApps.getActivityList(entry.getPackageName(),
446                         userManager.getUserForSerialNumber(entry.getUserId(this))).isEmpty());
447         secondaryMenu = false;
448
449         if(appIsValid) switch(p.getKey()) {
450             case PREF_APP_INFO:
451                 U.launchApp(this, () ->
452                         launcherApps.startAppDetailsActivity(
453                                 ComponentName.unflattenFromString(entry.getComponentName()),
454                                 userManager.getUserForSerialNumber(entry.getUserId(this)),
455                                 null,
456                                 U.getActivityOptionsBundle(this, ApplicationType.APP_PORTRAIT, getListView().getChildAt(p.getOrder()))));
457
458                 prepareToClose();
459                 break;
460             case PREF_UNINSTALL:
461                 if(U.hasFreeformSupport(this) && isInMultiWindowMode()) {
462                     Intent intent2 = new Intent(this, DummyActivity.class);
463                     intent2.putExtra("uninstall", entry.getPackageName());
464                     intent2.putExtra("user_id", entry.getUserId(this));
465
466                     try {
467                         startActivity(intent2);
468                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
469                 } else {
470                     Intent intent2 = new Intent(Intent.ACTION_DELETE, Uri.parse("package:" + entry.getPackageName()));
471                     intent2.putExtra(Intent.EXTRA_USER, userManager.getUserForSerialNumber(entry.getUserId(this)));
472
473                     try {
474                         startActivity(intent2);
475                     } catch (ActivityNotFoundException | IllegalArgumentException e) { /* Gracefully fail */ }
476                 }
477
478                 prepareToClose();
479                 break;
480             case PREF_OPEN_TASKBAR_SETTINGS:
481                 U.launchApp(this, () -> {
482                     Intent intent2 = new Intent(this, MainActivity.class);
483                     intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
484                     
485                     LauncherHelper helper = LauncherHelper.getInstance();
486                     if(helper.isOnHomeScreen(this) || helper.isOnSecondaryHomeScreen(this))
487                         U.applyOpenInNewWindow(this, intent2);
488
489                     try {
490                         startActivity(intent2,
491                                 U.getActivityOptionsBundle(this, ApplicationType.APP_PORTRAIT, getListView().getChildAt(p.getOrder())));
492                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
493                 });
494
495                 prepareToClose();
496                 break;
497             case PREF_QUIT_TASKBAR:
498                 Intent quitIntent = new Intent(ACTION_QUIT);
499                 quitIntent.setPackage(getPackageName());
500                 sendBroadcast(quitIntent);
501                 prepareToClose();
502                 break;
503             case PREF_PIN_APP:
504                 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(this);
505                 if(pba.isPinned(entry.getComponentName()))
506                     pba.removePinnedApp(this, entry.getComponentName());
507                 else {
508                     Intent intent = new Intent();
509                     intent.setComponent(ComponentName.unflattenFromString(entry.getComponentName()));
510
511                     LauncherActivityInfo appInfo = launcherApps.resolveActivity(intent, userManager.getUserForSerialNumber(entry.getUserId(this)));
512                     if(appInfo != null) {
513                         AppEntry newEntry = new AppEntry(
514                                 entry.getPackageName(),
515                                 entry.getComponentName(),
516                                 entry.getLabel(),
517                                 IconCache.getInstance(this).getIcon(this, appInfo),
518                                 true);
519
520                         newEntry.setUserId(entry.getUserId(this));
521                         pba.addPinnedApp(this, newEntry);
522                     }
523                 }
524                 break;
525             case PREF_BLOCK_APP:
526                 PinnedBlockedApps pba2 = PinnedBlockedApps.getInstance(this);
527                 if(pba2.isBlocked(entry.getComponentName()))
528                     pba2.removeBlockedApp(this, entry.getComponentName());
529                 else
530                     pba2.addBlockedApp(this, entry);
531                 break;
532             case PREF_SHOW_WINDOW_SIZES:
533                 generateWindowSizes();
534
535                 if(U.hasBrokenSetLaunchBoundsApi())
536                     U.showToastLong(this, R.string.tb_window_sizes_not_available);
537
538                 getListView().setOnItemLongClickListener((parent, view, position, id) -> {
539                     String[] windowSizes = getResources().getStringArray(R.array.tb_pref_window_size_list_values);
540
541                     SavedWindowSizes.getInstance(this).setWindowSize(this, entry.getPackageName(), windowSizes[position]);
542
543                     generateWindowSizes();
544                     return true;
545                 });
546
547                 secondaryMenu = true;
548                 break;
549             case PREF_WINDOW_SIZE_STANDARD:
550             case PREF_WINDOW_SIZE_LARGE:
551             case PREF_WINDOW_SIZE_FULLSCREEN:
552             case PREF_WINDOW_SIZE_HALF_LEFT:
553             case PREF_WINDOW_SIZE_HALF_RIGHT:
554             case PREF_WINDOW_SIZE_PHONE_SIZE:
555                 String windowSize = p.getKey().replace("window_size_", "");
556
557                 SharedPreferences pref2 = U.getSharedPreferences(this);
558                 if(pref2.getBoolean(PREF_SAVE_WINDOW_SIZES, true)) {
559                     SavedWindowSizes.getInstance(this).setWindowSize(this, entry.getPackageName(), windowSize);
560                 }
561
562                 U.launchApp(
563                         U.getDisplayContext(this),
564                         entry,
565                         windowSize,
566                         false,
567                         true,
568                         getListView().getChildAt(p.getOrder()));
569
570                 if(U.hasBrokenSetLaunchBoundsApi())
571                     U.cancelToast();
572
573                 prepareToClose();
574                 break;
575             case PREF_APP_SHORTCUTS:
576                 getPreferenceScreen().removeAll();
577                 generateShortcuts();
578
579                 secondaryMenu = true;
580                 break;
581             case PREF_SHORTCUT_1:
582             case PREF_SHORTCUT_2:
583             case PREF_SHORTCUT_3:
584             case PREF_SHORTCUT_4:
585             case PREF_SHORTCUT_5:
586                 U.startShortcut(
587                         U.getDisplayContext(this),
588                         entry,
589                         shortcuts.get(Integer.parseInt(p.getKey().replace("shortcut_", "")) - 1),
590                         getListView().getChildAt(p.getOrder()));
591
592                 prepareToClose();
593                 break;
594             case PREF_START_MENU_APPS:
595                 Intent intent = U.getThemedIntent(this, SelectAppActivity.class);
596
597                 if(U.hasFreeformSupport(this)
598                         && U.isFreeformModeEnabled(this)
599                         && isInMultiWindowMode()) {
600                     intent.putExtra("no_shadow", true);
601                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
602
603                     U.startActivityMaximized(U.getDisplayContext(this), intent);
604                 } else {
605                     try {
606                         startActivity(intent);
607                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
608                 }
609
610                 prepareToClose();
611                 break;
612             case PREF_VOLUME:
613                 AudioManager audio = (AudioManager) getSystemService(AUDIO_SERVICE);
614                 audio.adjustSuggestedStreamVolume(AudioManager.ADJUST_SAME, AudioManager.USE_DEFAULT_STREAM_TYPE, AudioManager.FLAG_SHOW_UI);
615
616                 if(LauncherHelper.getInstance().isOnSecondaryHomeScreen(this)) {
617                     U.showToast(this, R.string.tb_opening_volume_control);
618                     U.sendBroadcast(this, ACTION_UNDIM_SCREEN);
619                 }
620
621                 prepareToClose();
622                 break;
623             case PREF_FILE_MANAGER:
624                 U.launchApp(this, () -> {
625                     Intent fileManagerIntent;
626
627                     if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)
628                         fileManagerIntent = new Intent(Intent.ACTION_VIEW);
629                     else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
630                         fileManagerIntent = new Intent("android.provider.action.BROWSE");
631                     else {
632                         fileManagerIntent = new Intent("android.provider.action.BROWSE_DOCUMENT_ROOT");
633                         fileManagerIntent.setComponent(ComponentName.unflattenFromString("com.android.documentsui/.DocumentsActivity"));
634                     }
635
636                     fileManagerIntent.addCategory(Intent.CATEGORY_DEFAULT);
637                     fileManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
638                     fileManagerIntent.setData(Uri.parse("content://com.android.externalstorage.documents/root/primary"));
639
640                     try {
641                         startActivity(fileManagerIntent,
642                                 U.getActivityOptionsBundle(this, ApplicationType.APP_PORTRAIT, getListView().getChildAt(p.getOrder())));
643                     } catch (ActivityNotFoundException e) {
644                         U.showToast(this, R.string.tb_lock_device_not_supported);
645                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
646                 });
647
648                 prepareToClose();
649                 break;
650             case PREF_SYSTEM_SETTINGS:
651                 U.launchApp(this, () -> {
652                     Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
653                     settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
654
655                     try {
656                         startActivity(settingsIntent,
657                                 U.getActivityOptionsBundle(this, ApplicationType.APP_PORTRAIT, getListView().getChildAt(p.getOrder())));
658                     } catch (ActivityNotFoundException e) {
659                         U.showToast(this, R.string.tb_lock_device_not_supported);
660                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
661                 });
662
663                 prepareToClose();
664                 break;
665             case PREF_LOCK_DEVICE:
666                 U.lockDevice(this);
667                 prepareToClose();
668                 break;
669             case PREF_POWER_MENU:
670                 U.sendAccessibilityAction(this, AccessibilityService.GLOBAL_ACTION_POWER_DIALOG, () -> {
671                     if(LauncherHelper.getInstance().isOnSecondaryHomeScreen(this)) {
672                         U.showToast(this, R.string.tb_opening_power_menu);
673                         U.sendBroadcast(this, ACTION_UNDIM_SCREEN);
674                     }
675                 });
676
677                 prepareToClose();
678                 break;
679             case PREF_ADD_ICON_TO_DESKTOP:
680                 Intent intent2 = U.getThemedIntent(this, DesktopIconSelectAppActivity.class);
681                 intent2.putExtra("desktop_icon", desktopIcon);
682
683                 if(U.hasFreeformSupport(this)
684                         && U.isFreeformModeEnabled(this)
685                         && isInMultiWindowMode()) {
686                     intent2.putExtra("no_shadow", true);
687                     intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
688
689                     U.startActivityMaximized(U.getDisplayContext(this), intent2);
690                 } else {
691                     try {
692                         startActivity(intent2);
693                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
694                 }
695
696                 prepareToClose();
697                 break;
698             case PREF_ARRANGE_ICONS:
699                 U.sendBroadcast(this, ACTION_ENTER_ICON_ARRANGE_MODE);
700                 break;
701             case PREF_SORT_BY_NAME:
702                 U.sendBroadcast(this, ACTION_SORT_DESKTOP_ICONS);
703                 break;
704             case PREF_CHANGE_WALLPAPER:
705                 if(LauncherHelper.getInstance().isOnSecondaryHomeScreen(this)) {
706                     generateWallpaperOptions();
707                     secondaryMenu = true;
708                 } else if(U.isChromeOs(this)) {
709                     U.sendBroadcast(this, ACTION_WALLPAPER_CHANGE_REQUESTED);
710                 } else {
711                     changeWallpaper();
712                     prepareToClose();
713                 }
714                 break;
715             case PREF_REMOVE_DESKTOP_ICON:
716                 try {
717                     SharedPreferences pref5 = U.getSharedPreferences(this);
718                     JSONArray jsonIcons = new JSONArray(pref5.getString(PREF_DESKTOP_ICONS, "[]"));
719                     int iconToRemove = -1;
720
721                     for(int i = 0; i < jsonIcons.length(); i++) {
722                         DesktopIconInfo info = DesktopIconInfo.fromJson(jsonIcons.getJSONObject(i));
723                         if(info != null && info.column == desktopIcon.column && info.row == desktopIcon.row) {
724                             iconToRemove = i;
725                             break;
726                         }
727                     }
728
729                     if(iconToRemove > -1) {
730                         jsonIcons.remove(iconToRemove);
731
732                         pref5.edit().putString(PREF_DESKTOP_ICONS, jsonIcons.toString()).apply();
733                         U.sendBroadcast(this, ACTION_REFRESH_DESKTOP_ICONS);
734                     }
735                 } catch (JSONException e) { /* Gracefully fail */ }
736                 break;
737             case PREF_CHANGE_WALLPAPER_GLOBAL:
738                 changeWallpaper();
739                 prepareToClose();
740                 break;
741             case PREF_CHANGE_WALLPAPER_DESKTOP:
742                 U.sendBroadcast(this, ACTION_WALLPAPER_CHANGE_REQUESTED);
743                 break;
744             case PREF_REMOVE_DESKTOP_WALLPAPER:
745                 U.sendBroadcast(this, ACTION_REMOVE_DESKTOP_WALLPAPER);
746                 break;
747         }
748
749         if(!secondaryMenu) finish();
750         return true;
751     }
752
753     @Override
754     protected void onPause() {
755         super.onPause();
756         if(!isFinishing()) finish();
757     }
758
759     @Override
760     public void finish() {
761         U.sendBroadcast(this, ACTION_CONTEXT_MENU_DISAPPEARING);
762         MenuHelper.getInstance().setContextMenuOpen(false);
763
764         if(!dashboardOrStartMenuAppearing) {
765             if(showStartMenu) {
766                 U.sendBroadcast(this, ACTION_TOGGLE_START_MENU);
767             } else {
768                 U.sendBroadcast(this, ACTION_RESET_START_MENU);
769
770                 if(shouldHideTaskbar && U.shouldCollapse(this, true)) {
771                     U.sendBroadcast(this, ACTION_HIDE_TASKBAR);
772                 }
773             }
774         }
775
776         SharedPreferences pref = U.getSharedPreferences(this);
777
778         super.finish();
779         if(showStartMenu || pref.getBoolean(PREF_DISABLE_ANIMATIONS, false))
780             overridePendingTransition(0, 0);
781     }
782
783     @TargetApi(Build.VERSION_CODES.N_MR1)
784     private int getLauncherShortcuts() {
785         LauncherApps launcherApps = (LauncherApps) getSystemService(LAUNCHER_APPS_SERVICE);
786         if(launcherApps.hasShortcutHostPermission()) {
787             UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
788
789             LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery();
790             query.setActivity(ComponentName.unflattenFromString(entry.getComponentName()));
791             query.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC
792                     | LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST
793                     | LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED);
794
795             shortcuts = launcherApps.getShortcuts(query, userManager.getUserForSerialNumber(entry.getUserId(this)));
796             if(shortcuts != null)
797                 return shortcuts.size();
798         }
799
800         return 0;
801     }
802
803     @TargetApi(Build.VERSION_CODES.N_MR1)
804     private CharSequence getShortcutTitle(ShortcutInfo shortcut) {
805         CharSequence longLabel = shortcut.getLongLabel();
806         if(longLabel != null && longLabel.length() > 0 && longLabel.length() <= 20)
807             return longLabel;
808         else
809             return shortcut.getShortLabel();
810     }
811
812     @SuppressWarnings("deprecation")
813     @Override
814     public void onBackPressed() {
815         if(secondaryMenu) {
816             secondaryMenu = false;
817
818             getPreferenceScreen().removeAll();
819             generateMenu();
820
821             getListView().setOnItemLongClickListener(null);
822
823             if(U.hasBrokenSetLaunchBoundsApi())
824                 U.cancelToast();
825         } else {
826             if(contextMenuFix && !showStartMenu)
827                 U.startFreeformHack(this);
828
829             super.onBackPressed();
830             if(FreeformHackHelper.getInstance().isInFreeformWorkspace())
831                 overridePendingTransition(0, 0);
832         }
833     }
834
835     @Override
836     protected void onDestroy() {
837         super.onDestroy();
838
839         U.unregisterReceiver(this, dashboardOrStartMenuAppearingReceiver);
840         U.unregisterReceiver(this, finishReceiver);
841     }
842
843     private void changeWallpaper() {
844         if(LauncherHelper.getInstance().isOnHomeScreen(this))
845             U.sendBroadcast(this, ACTION_TEMP_HIDE_TASKBAR);
846
847         Intent intent = Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), getString(R.string.tb_set_wallpaper));
848         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
849         U.startActivityMaximized(U.getDisplayContext(this), intent);
850     }
851     
852     private void prepareToClose() {
853         showStartMenu = false;
854         shouldHideTaskbar = true;
855         contextMenuFix = false;
856     }
857 }