1 /* Copyright 2016 Braden Farmer
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.farmerbb.taskbar.activity;
18 import android.annotation.SuppressLint;
19 import android.annotation.TargetApi;
20 import android.content.ActivityNotFoundException;
21 import android.content.ComponentName;
22 import android.content.Intent;
23 import android.content.SharedPreferences;
24 import android.content.pm.LauncherActivityInfo;
25 import android.content.pm.LauncherApps;
26 import android.content.pm.PackageManager;
27 import android.content.pm.ResolveInfo;
28 import android.content.pm.ShortcutInfo;
29 import android.hardware.display.DisplayManager;
30 import android.media.AudioManager;
31 import android.net.Uri;
32 import android.os.Build;
33 import android.os.Bundle;
34 import android.os.UserManager;
35 import android.preference.Preference;
36 import android.preference.PreferenceActivity;
37 import android.provider.Settings;
38 import android.support.v4.content.LocalBroadcastManager;
39 import android.view.Display;
40 import android.view.Gravity;
41 import android.view.View;
42 import android.view.WindowManager;
44 import com.farmerbb.taskbar.BuildConfig;
45 import com.farmerbb.taskbar.MainActivity;
46 import com.farmerbb.taskbar.R;
47 import com.farmerbb.taskbar.util.AppEntry;
48 import com.farmerbb.taskbar.util.FreeformHackHelper;
49 import com.farmerbb.taskbar.util.IconCache;
50 import com.farmerbb.taskbar.util.PinnedBlockedApps;
51 import com.farmerbb.taskbar.util.SavedWindowSizes;
52 import com.farmerbb.taskbar.util.U;
54 import java.util.List;
56 public class ContextMenuActivity extends PreferenceActivity implements Preference.OnPreferenceClickListener {
63 boolean showStartMenu = false;
64 boolean shouldHideTaskbar = false;
65 boolean isStartButton = false;
66 boolean isOverflowMenu = false;
67 boolean secondaryMenu = false;
69 List<ShortcutInfo> shortcuts;
71 @SuppressLint("RtlHardcoded")
72 @SuppressWarnings("deprecation")
74 protected void onPostCreate(Bundle savedInstanceState) {
75 super.onPostCreate(savedInstanceState);
77 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.CONTEXT_MENU_APPEARING"));
79 boolean isNonAppMenu = !getIntent().hasExtra("package_name") && !getIntent().hasExtra("app_name");
80 showStartMenu = getIntent().getBooleanExtra("launched_from_start_menu", false);
81 isStartButton = isNonAppMenu && getIntent().getBooleanExtra("is_start_button", false);
82 isOverflowMenu = isNonAppMenu && getIntent().getBooleanExtra("is_overflow_menu", false);
84 // Determine where to position the dialog on screen
85 WindowManager.LayoutParams params = getWindow().getAttributes();
86 DisplayManager dm = (DisplayManager) getSystemService(DISPLAY_SERVICE);
87 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
89 int statusBarHeight = 0;
90 int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
92 statusBarHeight = getResources().getDimensionPixelSize(resourceId);
95 int x = getIntent().getIntExtra("x", 0);
96 int y = getIntent().getIntExtra("y", 0);
97 int offset = getResources().getDimensionPixelSize(isOverflowMenu ? R.dimen.context_menu_offset_overflow : R.dimen.context_menu_offset);
99 switch(U.getTaskbarPosition(this)) {
101 case "bottom_vertical_left":
102 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
104 params.y = display.getHeight() - y - offset;
107 case "bottom_vertical_right":
108 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
109 params.x = x - getResources().getDimensionPixelSize(R.dimen.context_menu_width) + offset + offset;
110 params.y = display.getHeight() - y - offset;
113 case "top_vertical_left":
114 params.gravity = Gravity.TOP | Gravity.LEFT;
116 params.y = y - offset + statusBarHeight;
119 case "top_vertical_right":
120 params.gravity = Gravity.TOP | Gravity.LEFT;
121 params.x = x - getResources().getDimensionPixelSize(R.dimen.context_menu_width) + offset + offset;
122 params.y = y - offset + statusBarHeight;
126 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
128 int x = getIntent().getIntExtra("x", display.getWidth());
129 int y = getIntent().getIntExtra("y", display.getHeight());
130 int offset = getResources().getDimensionPixelSize(R.dimen.icon_size);
132 switch(U.getTaskbarPosition(this)) {
134 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
135 params.x = isStartButton ? 0 : x;
138 case "bottom_vertical_left":
139 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
141 params.y = display.getHeight() - y - (isStartButton ? 0 : offset);
144 params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
145 params.x = display.getWidth() - x;
148 case "bottom_vertical_right":
149 params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
151 params.y = display.getHeight() - y - (isStartButton ? 0 : offset);
154 params.gravity = Gravity.TOP | Gravity.LEFT;
155 params.x = isStartButton ? 0 : x;
158 case "top_vertical_left":
159 params.gravity = Gravity.TOP | Gravity.LEFT;
161 params.y = isStartButton ? 0 : y - statusBarHeight;
164 params.gravity = Gravity.TOP | Gravity.RIGHT;
165 params.x = display.getWidth() - x;
168 case "top_vertical_right":
169 params.gravity = Gravity.TOP | Gravity.RIGHT;
171 params.y = isStartButton ? 0 : y - statusBarHeight;
176 params.width = getResources().getDimensionPixelSize(R.dimen.context_menu_width);
177 params.dimAmount = 0;
179 getWindow().setAttributes(params);
181 View view = findViewById(android.R.id.list);
182 if(view != null) view.setPadding(0, 0, 0, 0);
187 @SuppressWarnings("deprecation")
188 private void generateMenu() {
190 addPreferencesFromResource(R.xml.pref_context_menu_open_settings);
191 findPreference("open_taskbar_settings").setOnPreferenceClickListener(this);
192 findPreference("start_menu_apps").setOnPreferenceClickListener(this);
194 if(U.launcherIsDefault(this) && FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
195 addPreferencesFromResource(R.xml.pref_context_menu_change_wallpaper);
196 findPreference("change_wallpaper").setOnPreferenceClickListener(this);
199 if(!getIntent().getBooleanExtra("dont_show_quit", false)) {
200 addPreferencesFromResource(R.xml.pref_context_menu_quit);
201 findPreference("quit_taskbar").setOnPreferenceClickListener(this);
203 } else if(isOverflowMenu) {
204 if(getResources().getConfiguration().screenWidthDp >= 600
205 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M)
206 setTitle(R.string.tools);
208 addPreferencesFromResource(R.xml.pref_context_menu_header);
209 findPreference("header").setTitle(R.string.tools);
212 addPreferencesFromResource(R.xml.pref_context_menu_overflow);
213 findPreference("volume").setOnPreferenceClickListener(this);
214 findPreference("system_settings").setOnPreferenceClickListener(this);
215 findPreference("lock_device").setOnPreferenceClickListener(this);
216 findPreference("power_menu").setOnPreferenceClickListener(this);
218 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
219 findPreference("file_manager").setOnPreferenceClickListener(this);
221 appName = getIntent().getStringExtra("app_name");
222 packageName = getIntent().getStringExtra("package_name");
223 componentName = getIntent().getStringExtra("component_name");
224 userId = getIntent().getLongExtra("user_id", 0);
226 if(getResources().getConfiguration().screenWidthDp >= 600
227 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M)
230 addPreferencesFromResource(R.xml.pref_context_menu_header);
231 findPreference("header").setTitle(appName);
234 SharedPreferences pref = U.getSharedPreferences(this);
235 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
236 && pref.getBoolean("freeform_hack", false)
237 && (FreeformHackHelper.getInstance().isFreeformHackActive() || isInMultiWindowMode())) {
238 addPreferencesFromResource(R.xml.pref_context_menu_show_window_sizes);
239 findPreference("show_window_sizes").setOnPreferenceClickListener(this);
242 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
243 int shortcutCount = getLauncherShortcuts();
245 if(shortcutCount > 1) {
246 addPreferencesFromResource(R.xml.pref_context_menu_shortcuts);
247 findPreference("app_shortcuts").setOnPreferenceClickListener(this);
248 } else if(shortcutCount == 1)
252 final PackageManager pm = getPackageManager();
253 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
254 homeIntent.addCategory(Intent.CATEGORY_HOME);
255 ResolveInfo defaultLauncher = pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
257 if(!packageName.contains(BuildConfig.BASE_APPLICATION_ID)
258 && !packageName.equals(defaultLauncher.activityInfo.packageName)) {
259 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(this);
261 if(pba.isPinned(componentName)) {
262 addPreferencesFromResource(R.xml.pref_context_menu_pin);
263 findPreference("pin_app").setOnPreferenceClickListener(this);
264 findPreference("pin_app").setTitle(R.string.unpin_app);
265 } else if(pba.isBlocked(componentName)) {
266 addPreferencesFromResource(R.xml.pref_context_menu_block);
267 findPreference("block_app").setOnPreferenceClickListener(this);
268 findPreference("block_app").setTitle(R.string.unblock_app);
270 final int MAX_NUM_OF_COLUMNS = U.getMaxNumOfEntries(this);
272 if(pba.getPinnedApps().size() < MAX_NUM_OF_COLUMNS) {
273 addPreferencesFromResource(R.xml.pref_context_menu_pin);
274 findPreference("pin_app").setOnPreferenceClickListener(this);
275 findPreference("pin_app").setTitle(R.string.pin_app);
278 addPreferencesFromResource(R.xml.pref_context_menu_block);
279 findPreference("block_app").setOnPreferenceClickListener(this);
280 findPreference("block_app").setTitle(R.string.block_app);
284 addPreferencesFromResource(R.xml.pref_context_menu);
286 findPreference("app_info").setOnPreferenceClickListener(this);
287 findPreference("uninstall").setOnPreferenceClickListener(this);
291 @SuppressWarnings("deprecation")
292 private void generateShortcuts() {
293 addPreferencesFromResource(R.xml.pref_context_menu_shortcut_list);
294 switch(shortcuts.size()) {
296 findPreference("shortcut_5").setTitle(getShortcutTitle(shortcuts.get(4)));
297 findPreference("shortcut_5").setOnPreferenceClickListener(this);
299 findPreference("shortcut_4").setTitle(getShortcutTitle(shortcuts.get(3)));
300 findPreference("shortcut_4").setOnPreferenceClickListener(this);
302 findPreference("shortcut_3").setTitle(getShortcutTitle(shortcuts.get(2)));
303 findPreference("shortcut_3").setOnPreferenceClickListener(this);
305 findPreference("shortcut_2").setTitle(getShortcutTitle(shortcuts.get(1)));
306 findPreference("shortcut_2").setOnPreferenceClickListener(this);
308 findPreference("shortcut_1").setTitle(getShortcutTitle(shortcuts.get(0)));
309 findPreference("shortcut_1").setOnPreferenceClickListener(this);
313 switch(shortcuts.size()) {
315 getPreferenceScreen().removePreference(findPreference("shortcut_2"));
317 getPreferenceScreen().removePreference(findPreference("shortcut_3"));
319 getPreferenceScreen().removePreference(findPreference("shortcut_4"));
321 getPreferenceScreen().removePreference(findPreference("shortcut_5"));
326 @SuppressWarnings("deprecation")
327 @TargetApi(Build.VERSION_CODES.N_MR1)
329 public boolean onPreferenceClick(Preference p) {
330 UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
331 LauncherApps launcherApps = (LauncherApps) getSystemService(LAUNCHER_APPS_SERVICE);
332 boolean appIsValid = isStartButton ||
333 !launcherApps.getActivityList(getIntent().getStringExtra("package_name"),
334 userManager.getUserForSerialNumber(userId)).isEmpty();
336 if(appIsValid) switch(p.getKey()) {
338 startFreeformActivity();
339 launcherApps.startAppDetailsActivity(ComponentName.unflattenFromString(componentName), userManager.getUserForSerialNumber(userId), null, null);
341 showStartMenu = false;
342 shouldHideTaskbar = true;
345 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode()) {
346 Intent intent2 = new Intent(ContextMenuActivity.this, DummyActivity.class);
347 intent2.putExtra("uninstall", packageName);
348 intent2.putExtra("user_id", userId);
350 startFreeformActivity();
351 startActivity(intent2);
353 startFreeformActivity();
355 Intent intent2 = new Intent(Intent.ACTION_DELETE, Uri.parse("package:" + packageName));
356 intent2.putExtra(Intent.EXTRA_USER, userManager.getUserForSerialNumber(userId));
359 startActivity(intent2);
360 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
363 showStartMenu = false;
364 shouldHideTaskbar = true;
366 case "open_taskbar_settings":
367 startFreeformActivity();
369 Intent intent2 = new Intent(this, MainActivity.class);
370 intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
371 startActivity(intent2);
373 showStartMenu = false;
374 shouldHideTaskbar = true;
377 sendBroadcast(new Intent("com.farmerbb.taskbar.QUIT"));
379 showStartMenu = false;
380 shouldHideTaskbar = true;
383 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(this);
384 if(pba.isPinned(componentName))
385 pba.removePinnedApp(this, componentName);
387 Intent intent = new Intent();
388 intent.setComponent(ComponentName.unflattenFromString(componentName));
390 LauncherActivityInfo appInfo = launcherApps.resolveActivity(intent, userManager.getUserForSerialNumber(userId));
391 if(appInfo != null) {
392 AppEntry newEntry = new AppEntry(
396 IconCache.getInstance(this).getIcon(this, getPackageManager(), appInfo),
399 newEntry.setUserId(userId);
400 pba.addPinnedApp(this, newEntry);
405 PinnedBlockedApps pba2 = PinnedBlockedApps.getInstance(this);
406 if(pba2.isBlocked(componentName))
407 pba2.removeBlockedApp(this, componentName);
409 pba2.addBlockedApp(this, new AppEntry(
417 case "show_window_sizes":
418 getPreferenceScreen().removeAll();
420 addPreferencesFromResource(R.xml.pref_context_menu_window_size_list);
421 findPreference("window_size_standard").setOnPreferenceClickListener(this);
422 findPreference("window_size_large").setOnPreferenceClickListener(this);
423 findPreference("window_size_fullscreen").setOnPreferenceClickListener(this);
424 findPreference("window_size_half_left").setOnPreferenceClickListener(this);
425 findPreference("window_size_half_right").setOnPreferenceClickListener(this);
426 findPreference("window_size_phone_size").setOnPreferenceClickListener(this);
428 SharedPreferences pref = U.getSharedPreferences(this);
429 if(pref.getBoolean("save_window_sizes", true)) {
430 String windowSizePref = SavedWindowSizes.getInstance(this).getWindowSize(this, packageName);
431 CharSequence title = findPreference("window_size_" + windowSizePref).getTitle();
432 findPreference("window_size_" + windowSizePref).setTitle('\u2713' + " " + title);
435 secondaryMenu = true;
437 case "window_size_standard":
438 case "window_size_large":
439 case "window_size_fullscreen":
440 case "window_size_half_left":
441 case "window_size_half_right":
442 case "window_size_phone_size":
443 String windowSize = p.getKey().replace("window_size_", "");
445 SharedPreferences pref2 = U.getSharedPreferences(this);
446 if(pref2.getBoolean("save_window_sizes", true)) {
447 SavedWindowSizes.getInstance(this).setWindowSize(this, packageName, windowSize);
450 startFreeformActivity();
451 U.launchApp(getApplicationContext(), packageName, componentName, userId, windowSize, false, true);
453 showStartMenu = false;
454 shouldHideTaskbar = true;
456 case "app_shortcuts":
457 getPreferenceScreen().removeAll();
460 secondaryMenu = true;
467 U.startShortcut(getApplicationContext(), packageName, componentName, shortcuts.get(Integer.parseInt(p.getKey().replace("shortcut_", "")) - 1));
469 showStartMenu = false;
470 shouldHideTaskbar = true;
472 case "start_menu_apps":
473 startFreeformActivity();
475 Intent intent = null;
477 SharedPreferences pref3 = U.getSharedPreferences(this);
478 switch(pref3.getString("theme", "light")) {
480 intent = new Intent(this, SelectAppActivity.class);
483 intent = new Intent(this, SelectAppActivityDark.class);
487 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
488 && pref3.getBoolean("freeform_hack", false)
489 && intent != null && isInMultiWindowMode()) {
490 intent.putExtra("no_shadow", true);
491 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
493 U.launchAppFullscreen(getApplicationContext(), intent);
495 startActivity(intent);
497 showStartMenu = false;
498 shouldHideTaskbar = true;
501 AudioManager audio = (AudioManager) getSystemService(AUDIO_SERVICE);
502 audio.adjustSuggestedStreamVolume(AudioManager.ADJUST_SAME, AudioManager.USE_DEFAULT_STREAM_TYPE, AudioManager.FLAG_SHOW_UI);
504 showStartMenu = false;
505 shouldHideTaskbar = true;
508 startFreeformActivity();
510 Intent fileManagerIntent = new Intent("android.provider.action.BROWSE");
511 fileManagerIntent.addCategory(Intent.CATEGORY_DEFAULT);
512 fileManagerIntent.setData(Uri.parse("content://com.android.externalstorage.documents/root/primary"));
515 startActivity(fileManagerIntent);
516 } catch (ActivityNotFoundException e) {
517 U.showToast(this, R.string.lock_device_not_supported);
520 showStartMenu = false;
521 shouldHideTaskbar = true;
523 case "system_settings":
524 startFreeformActivity();
526 Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
529 startActivity(settingsIntent);
530 } catch (ActivityNotFoundException e) {
531 U.showToast(this, R.string.lock_device_not_supported);
534 showStartMenu = false;
535 shouldHideTaskbar = true;
540 showStartMenu = false;
541 shouldHideTaskbar = true;
544 U.showPowerMenu(this);
546 showStartMenu = false;
547 shouldHideTaskbar = true;
549 case "change_wallpaper":
550 Intent intent3 = Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), getString(R.string.set_wallpaper));
551 intent3.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
552 U.launchAppFullscreen(getApplicationContext(), intent3);
554 showStartMenu = false;
555 shouldHideTaskbar = true;
559 if(!secondaryMenu) finish();
564 protected void onPause() {
566 if(!isFinishing()) finish();
570 public void finish() {
571 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.CONTEXT_MENU_DISAPPEARING"));
574 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TOGGLE_START_MENU_ALT"));
575 else if(shouldHideTaskbar) {
576 SharedPreferences pref = U.getSharedPreferences(this);
577 if(pref.getBoolean("hide_taskbar", true) && !FreeformHackHelper.getInstance().isInFreeformWorkspace())
578 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
584 @SuppressWarnings("deprecation")
585 private void startFreeformActivity() {
586 SharedPreferences pref = U.getSharedPreferences(this);
587 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
588 && pref.getBoolean("taskbar_active", false)
589 && pref.getBoolean("freeform_hack", false)
590 && isInMultiWindowMode()
591 && !FreeformHackHelper.getInstance().isFreeformHackActive()) {
592 U.startFreeformHack(this, false, false);
596 @TargetApi(Build.VERSION_CODES.N_MR1)
597 private int getLauncherShortcuts() {
598 LauncherApps launcherApps = (LauncherApps) getSystemService(LAUNCHER_APPS_SERVICE);
599 if(launcherApps.hasShortcutHostPermission()) {
600 UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
602 LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery();
603 query.setActivity(ComponentName.unflattenFromString(componentName));
604 query.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC
605 | LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST
606 | LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED);
608 shortcuts = launcherApps.getShortcuts(query, userManager.getUserForSerialNumber(userId));
609 return shortcuts.size();
615 @TargetApi(Build.VERSION_CODES.N_MR1)
616 private CharSequence getShortcutTitle(ShortcutInfo shortcut) {
617 CharSequence longLabel = shortcut.getLongLabel();
618 if(longLabel != null && longLabel.length() > 0 && longLabel.length() <= 20)
621 return shortcut.getShortLabel();
624 @SuppressWarnings("deprecation")
626 public void onBackPressed() {
628 secondaryMenu = false;
630 getPreferenceScreen().removeAll();
633 super.onBackPressed();