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.util;
18 import android.annotation.TargetApi;
19 import android.app.ActivityManager;
20 import android.app.ActivityOptions;
21 import android.app.AlertDialog;
22 import android.app.Service;
23 import android.app.admin.DevicePolicyManager;
24 import android.content.ActivityNotFoundException;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.SharedPreferences;
29 import android.content.pm.ActivityInfo;
30 import android.content.pm.LauncherActivityInfo;
31 import android.content.pm.LauncherApps;
32 import android.content.pm.PackageManager;
33 import android.content.pm.ResolveInfo;
34 import android.content.pm.ShortcutInfo;
35 import android.content.res.Configuration;
36 import android.graphics.Rect;
37 import android.graphics.drawable.BitmapDrawable;
38 import android.hardware.display.DisplayManager;
39 import android.net.Uri;
40 import android.os.Build;
41 import android.os.Bundle;
42 import android.os.Handler;
43 import android.os.Process;
44 import android.os.UserHandle;
45 import android.os.UserManager;
46 import android.provider.Settings;
47 import android.support.v4.content.LocalBroadcastManager;
48 import android.util.DisplayMetrics;
49 import android.view.Display;
50 import android.view.Surface;
51 import android.view.WindowManager;
52 import android.widget.Toast;
54 import com.farmerbb.taskbar.BuildConfig;
55 import com.farmerbb.taskbar.R;
56 import com.farmerbb.taskbar.activity.DummyActivity;
57 import com.farmerbb.taskbar.activity.InvisibleActivityFreeform;
58 import com.farmerbb.taskbar.activity.ShortcutActivity;
59 import com.farmerbb.taskbar.activity.StartTaskbarActivity;
60 import com.farmerbb.taskbar.receiver.LockDeviceReceiver;
61 import com.farmerbb.taskbar.service.PowerMenuService;
63 import java.util.ArrayList;
64 import java.util.List;
66 import moe.banana.support.ToastCompat;
72 private static SharedPreferences pref;
73 private static Integer cachedRotation;
75 private static final int FULLSCREEN = 0;
76 private static final int LEFT = -1;
77 private static final int RIGHT = 1;
79 public static final int HIDDEN = 0;
80 public static final int TOP_APPS = 1;
82 public static SharedPreferences getSharedPreferences(Context context) {
83 if(pref == null) pref = context.getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
87 @TargetApi(Build.VERSION_CODES.M)
88 public static void showPermissionDialog(final Context context) {
89 AlertDialog.Builder builder = new AlertDialog.Builder(context);
90 builder.setTitle(R.string.permission_dialog_title)
91 .setMessage(R.string.permission_dialog_message)
92 .setPositiveButton(R.string.action_grant_permission, (dialog, which) -> {
94 context.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
95 Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
96 } catch (ActivityNotFoundException e) {
97 showErrorDialog(context, "SYSTEM_ALERT_WINDOW");
101 AlertDialog dialog = builder.create();
103 dialog.setCancelable(false);
106 public static void showErrorDialog(final Context context, String appopCmd) {
107 AlertDialog.Builder builder = new AlertDialog.Builder(context);
108 builder.setTitle(R.string.error_dialog_title)
109 .setMessage(context.getString(R.string.error_dialog_message, BuildConfig.APPLICATION_ID, appopCmd))
110 .setPositiveButton(R.string.action_ok, null);
112 AlertDialog dialog = builder.create();
116 public static void lockDevice(Context context) {
117 ComponentName component = new ComponentName(context, LockDeviceReceiver.class);
118 context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
119 PackageManager.DONT_KILL_APP);
121 DevicePolicyManager mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
122 if(mDevicePolicyManager.isAdminActive(component))
123 mDevicePolicyManager.lockNow();
125 Intent intent = new Intent(context, DummyActivity.class);
126 intent.putExtra("device_admin", true);
127 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
128 context.startActivity(intent);
132 public static void showPowerMenu(Context context) {
133 ComponentName component = new ComponentName(context, PowerMenuService.class);
134 context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
135 PackageManager.DONT_KILL_APP);
137 if(isAccessibilityServiceEnabled(context))
138 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.SHOW_POWER_MENU"));
140 Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
141 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
144 context.startActivity(intent);
145 showToastLong(context, R.string.enable_accessibility);
146 } catch (ActivityNotFoundException e) {
147 showToast(context, R.string.lock_device_not_supported);
152 private static boolean isAccessibilityServiceEnabled(Context context) {
153 String accessibilityServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
154 ComponentName component = new ComponentName(context, PowerMenuService.class);
156 return accessibilityServices != null
157 && (accessibilityServices.contains(component.flattenToString())
158 || accessibilityServices.contains(component.flattenToShortString()));
161 public static void showToast(Context context, int message) {
162 showToast(context, context.getString(message), Toast.LENGTH_SHORT);
165 public static void showToastLong(Context context, int message) {
166 showToast(context, context.getString(message), Toast.LENGTH_LONG);
169 public static void showToast(Context context, String message, int length) {
170 ToastCompat.makeText(context, message, length).show();
173 public static void startShortcut(Context context, String packageName, String componentName, ShortcutInfo shortcut) {
184 public static void launchApp(final Context context,
185 final String packageName,
186 final String componentName,
187 final long userId, final String windowSize,
188 final boolean launchedFromTaskbar,
189 final boolean openInNewWindow) {
200 private static void launchApp(final Context context,
201 final String packageName,
202 final String componentName,
203 final long userId, final String windowSize,
204 final boolean launchedFromTaskbar,
205 final boolean openInNewWindow,
206 final ShortcutInfo shortcut) {
207 boolean shouldDelay = false;
209 SharedPreferences pref = getSharedPreferences(context);
210 boolean openInFullscreen = pref.getBoolean("open_in_fullscreen", true);
211 boolean freeformHackActive = openInNewWindow
212 ? FreeformHackHelper.getInstance().isInFreeformWorkspace()
214 ? FreeformHackHelper.getInstance().isInFreeformWorkspace()
215 : FreeformHackHelper.getInstance().isFreeformHackActive());
217 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
218 && pref.getBoolean("freeform_hack", false)
219 && !freeformHackActive) {
222 new Handler().postDelayed(() -> {
223 startFreeformHack(context, true, launchedFromTaskbar);
225 new Handler().postDelayed(() -> continueLaunchingApp(context, packageName, componentName, userId,
226 windowSize, launchedFromTaskbar, openInNewWindow, shortcut), 100);
227 }, launchedFromTaskbar ? 0 : 100);
230 if(!FreeformHackHelper.getInstance().isFreeformHackActive()) {
232 continueLaunchingApp(context, packageName, componentName, userId,
233 windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
234 } else if(FreeformHackHelper.getInstance().isInFreeformWorkspace() || !openInFullscreen)
235 continueLaunchingApp(context, packageName, componentName, userId,
236 windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
239 @SuppressWarnings("deprecation")
240 @TargetApi(Build.VERSION_CODES.N)
241 public static void startFreeformHack(Context context, boolean checkMultiWindow, boolean launchedFromTaskbar) {
242 Intent freeformHackIntent = new Intent(context, InvisibleActivityFreeform.class);
243 freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
246 freeformHackIntent.putExtra("check_multiwindow", true);
248 if(launchedFromTaskbar) {
249 SharedPreferences pref = getSharedPreferences(context);
250 if(pref.getBoolean("disable_animations", false))
251 freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
254 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
255 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
257 context.startActivity(freeformHackIntent, ActivityOptions.makeBasic().setLaunchBounds(new Rect(
260 display.getWidth() + 1,
261 display.getHeight() + 1
263 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
266 @TargetApi(Build.VERSION_CODES.N)
267 private static void continueLaunchingApp(Context context,
269 String componentName,
272 boolean launchedFromTaskbar,
273 boolean openInNewWindow,
274 ShortcutInfo shortcut) {
275 SharedPreferences pref = getSharedPreferences(context);
276 Intent intent = new Intent();
277 intent.setComponent(ComponentName.unflattenFromString(componentName));
278 intent.setAction(Intent.ACTION_MAIN);
279 intent.addCategory(Intent.CATEGORY_LAUNCHER);
280 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
281 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
283 if(FreeformHackHelper.getInstance().isInFreeformWorkspace())
284 intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
286 if(launchedFromTaskbar) {
287 if(pref.getBoolean("disable_animations", false))
288 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
291 if(openInNewWindow || pref.getBoolean("force_new_window", false)) {
292 intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
294 ActivityInfo activityInfo = intent.resolveActivityInfo(context.getPackageManager(), 0);
295 if(activityInfo != null) {
296 switch(activityInfo.launchMode) {
297 case ActivityInfo.LAUNCH_SINGLE_TASK:
298 case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
299 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
305 if(windowSize == null) {
306 if(pref.getBoolean("save_window_sizes", true))
307 windowSize = SavedWindowSizes.getInstance(context).getWindowSize(context, packageName);
309 windowSize = pref.getString("window_size", "standard");
312 if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !pref.getBoolean("freeform_hack", false)) {
313 if(shortcut == null) {
314 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
315 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
317 context.startActivity(intent, null);
318 } catch (ActivityNotFoundException e) {
319 launchAndroidForWork(context, intent.getComponent(), null, userId);
320 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
322 launchAndroidForWork(context, intent.getComponent(), null, userId);
324 launchShortcut(context, shortcut, null);
325 } else switch(windowSize) {
327 if(FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
328 if(shortcut == null) {
329 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
330 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
332 context.startActivity(intent);
333 } catch (ActivityNotFoundException e) {
334 launchAndroidForWork(context, intent.getComponent(), null, userId);
335 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
337 launchAndroidForWork(context, intent.getComponent(), null, userId);
339 launchShortcut(context, shortcut, null);
341 launchMode1(context, intent, 1, userId, shortcut);
344 launchMode1(context, intent, 2, userId, shortcut);
347 launchMode2(context, intent, FULLSCREEN, userId, shortcut);
350 launchMode2(context, intent, LEFT, userId, shortcut);
353 launchMode2(context, intent, RIGHT, userId, shortcut);
356 launchMode3(context, intent, userId, shortcut);
360 if(pref.getBoolean("hide_taskbar", true) && !FreeformHackHelper.getInstance().isInFreeformWorkspace())
361 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
363 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
366 @SuppressWarnings("deprecation")
367 @TargetApi(Build.VERSION_CODES.N)
368 private static void launchMode1(Context context, Intent intent, int factor, long userId, ShortcutInfo shortcut) {
369 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
370 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
372 int width1 = display.getWidth() / (4 * factor);
373 int width2 = display.getWidth() - width1;
374 int height1 = display.getHeight() / (4 * factor);
375 int height2 = display.getHeight() - height1;
377 Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
384 if(shortcut == null) {
385 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
386 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
388 context.startActivity(intent, bundle);
389 } catch (ActivityNotFoundException e) {
390 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
391 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
393 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
395 launchShortcut(context, shortcut, bundle);
398 @SuppressWarnings("deprecation")
399 @TargetApi(Build.VERSION_CODES.N)
400 private static void launchMode2(Context context, Intent intent, int launchType, long userId, ShortcutInfo shortcut) {
401 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
402 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
404 int statusBarHeight = getStatusBarHeight(context);
405 String position = getTaskbarPosition(context);
407 boolean isPortrait = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
408 boolean isLandscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
410 int left = launchType == RIGHT && isLandscape
411 ? display.getWidth() / 2
414 int top = launchType == RIGHT && isPortrait
415 ? display.getHeight() / 2
418 int right = launchType == LEFT && isLandscape
419 ? display.getWidth() / 2
420 : display.getWidth();
422 int bottom = launchType == LEFT && isPortrait
423 ? display.getHeight() / 2
424 : display.getHeight();
426 int iconSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
428 if(position.contains("vertical_left")) {
429 if(launchType != RIGHT || isPortrait) left = left + iconSize;
430 } else if(position.contains("vertical_right")) {
431 if(launchType != LEFT || isPortrait) right = right - iconSize;
432 } else if(position.contains("bottom")) {
433 if(isLandscape || (launchType != LEFT && isPortrait))
434 bottom = bottom - iconSize;
435 } else if(isLandscape || (launchType != RIGHT && isPortrait))
436 top = top + iconSize;
438 Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
445 if(shortcut == null) {
446 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
447 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
449 context.startActivity(intent, bundle);
450 } catch (ActivityNotFoundException e) {
451 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
452 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
454 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
456 launchShortcut(context, shortcut, bundle);
459 @SuppressWarnings("deprecation")
460 @TargetApi(Build.VERSION_CODES.N)
461 private static void launchMode3(Context context, Intent intent, long userId, ShortcutInfo shortcut) {
462 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
463 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
465 int width1 = display.getWidth() / 2;
466 int width2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_width) / 2;
467 int height1 = display.getHeight() / 2;
468 int height2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_height) / 2;
470 Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
477 if(shortcut == null) {
478 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
479 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
481 context.startActivity(intent, bundle);
482 } catch (ActivityNotFoundException e) {
483 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
484 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
486 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
488 launchShortcut(context, shortcut, bundle);
491 private static void launchAndroidForWork(Context context, ComponentName componentName, Bundle bundle, long userId) {
492 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
493 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
496 launcherApps.startMainActivity(componentName, userManager.getUserForSerialNumber(userId), null, bundle);
497 } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
500 @TargetApi(Build.VERSION_CODES.N_MR1)
501 private static void launchShortcut(Context context, ShortcutInfo shortcut, Bundle bundle) {
502 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
505 launcherApps.startShortcut(shortcut, null, bundle);
506 } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
509 public static void launchAppFullscreen(Context context, Intent intent) {
510 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
511 long userId = userManager.getSerialNumberForUser(Process.myUserHandle());
513 launchMode2(context, intent, FULLSCREEN, userId, null);
516 public static void checkForUpdates(Context context) {
519 context.getPackageManager().getPackageInfo("com.android.vending", 0);
520 url = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
521 } catch (PackageManager.NameNotFoundException e) {
522 url = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.BASE_APPLICATION_ID;
525 Intent intent = new Intent(Intent.ACTION_VIEW);
526 intent.setData(Uri.parse(url));
527 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
530 context.startActivity(intent);
531 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
534 public static boolean launcherIsDefault(Context context) {
535 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
536 homeIntent.addCategory(Intent.CATEGORY_HOME);
537 ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
539 return defaultLauncher.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID);
542 public static void setCachedRotation(int cachedRotation) {
543 U.cachedRotation = cachedRotation;
546 public static String getTaskbarPosition(Context context) {
547 SharedPreferences pref = getSharedPreferences(context);
548 String position = pref.getString("position", "bottom_left");
550 if(pref.getBoolean("anchor", false)) {
551 WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
552 int rotation = cachedRotation != null ? cachedRotation : windowManager.getDefaultDisplay().getRotation();
557 case Surface.ROTATION_0:
558 return "bottom_left";
559 case Surface.ROTATION_90:
560 return "bottom_vertical_right";
561 case Surface.ROTATION_180:
563 case Surface.ROTATION_270:
564 return "top_vertical_left";
567 case "bottom_vertical_left":
569 case Surface.ROTATION_0:
570 return "bottom_vertical_left";
571 case Surface.ROTATION_90:
572 return "bottom_right";
573 case Surface.ROTATION_180:
574 return "top_vertical_right";
575 case Surface.ROTATION_270:
581 case Surface.ROTATION_0:
582 return "bottom_right";
583 case Surface.ROTATION_90:
584 return "top_vertical_right";
585 case Surface.ROTATION_180:
587 case Surface.ROTATION_270:
588 return "bottom_vertical_left";
591 case "bottom_vertical_right":
593 case Surface.ROTATION_0:
594 return "bottom_vertical_right";
595 case Surface.ROTATION_90:
597 case Surface.ROTATION_180:
598 return "top_vertical_left";
599 case Surface.ROTATION_270:
600 return "bottom_left";
605 case Surface.ROTATION_0:
607 case Surface.ROTATION_90:
608 return "bottom_vertical_left";
609 case Surface.ROTATION_180:
610 return "bottom_right";
611 case Surface.ROTATION_270:
612 return "top_vertical_right";
615 case "top_vertical_left":
617 case Surface.ROTATION_0:
618 return "top_vertical_left";
619 case Surface.ROTATION_90:
620 return "bottom_left";
621 case Surface.ROTATION_180:
622 return "bottom_vertical_right";
623 case Surface.ROTATION_270:
629 case Surface.ROTATION_0:
631 case Surface.ROTATION_90:
632 return "top_vertical_left";
633 case Surface.ROTATION_180:
634 return "bottom_left";
635 case Surface.ROTATION_270:
636 return "bottom_vertical_right";
639 case "top_vertical_right":
641 case Surface.ROTATION_0:
642 return "top_vertical_right";
643 case Surface.ROTATION_90:
645 case Surface.ROTATION_180:
646 return "bottom_vertical_left";
647 case Surface.ROTATION_270:
648 return "bottom_right";
657 private static int getMaxNumOfColumns(Context context) {
658 SharedPreferences pref = getSharedPreferences(context);
659 DisplayMetrics metrics = context.getResources().getDisplayMetrics();
660 float baseTaskbarSize = context.getResources().getDimension(pref.getBoolean("dashboard", false) ? R.dimen.base_taskbar_size_dashboard : R.dimen.base_taskbar_size) / metrics.density;
661 int numOfColumns = 0;
663 float maxScreenSize = getTaskbarPosition(context).contains("vertical")
664 ? (metrics.heightPixels - getStatusBarHeight(context)) / metrics.density
665 : metrics.widthPixels / metrics.density;
667 float iconSize = context.getResources().getDimension(R.dimen.icon_size) / metrics.density;
669 int userMaxNumOfColumns = Integer.valueOf(pref.getString("max_num_of_recents", "10"));
671 while(baseTaskbarSize + iconSize < maxScreenSize
672 && numOfColumns < userMaxNumOfColumns) {
673 baseTaskbarSize = baseTaskbarSize + iconSize;
680 public static int getMaxNumOfEntries(Context context) {
681 SharedPreferences pref = getSharedPreferences(context);
682 return pref.getBoolean("disable_scrolling_list", false)
683 ? getMaxNumOfColumns(context)
684 : Integer.valueOf(pref.getString("max_num_of_recents", "10"));
687 public static int getStatusBarHeight(Context context) {
688 int statusBarHeight = 0;
689 int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
691 statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
693 return statusBarHeight;
696 public static void refreshPinnedIcons(Context context) {
697 IconCache.getInstance(context).clearCache();
699 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(context);
700 List<AppEntry> pinnedAppsList = new ArrayList<>(pba.getPinnedApps());
701 List<AppEntry> blockedAppsList = new ArrayList<>(pba.getBlockedApps());
702 PackageManager pm = context.getPackageManager();
706 for(AppEntry entry : pinnedAppsList) {
707 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
708 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
710 final List<UserHandle> userHandles = userManager.getUserProfiles();
711 LauncherActivityInfo appInfo = null;
713 for(UserHandle handle : userHandles) {
714 List<LauncherActivityInfo> list = launcherApps.getActivityList(entry.getPackageName(), handle);
715 if(!list.isEmpty()) {
716 // Google App workaround
717 if(!entry.getPackageName().equals("com.google.android.googlequicksearchbox"))
718 appInfo = list.get(0);
720 boolean added = false;
721 for(LauncherActivityInfo info : list) {
722 if(info.getName().equals("com.google.android.googlequicksearchbox.SearchActivity")) {
728 if(!added) appInfo = list.get(0);
735 if(appInfo != null) {
736 AppEntry newEntry = new AppEntry(
737 entry.getPackageName(),
738 entry.getComponentName(),
740 IconCache.getInstance(context).getIcon(context, pm, appInfo),
743 newEntry.setUserId(entry.getUserId(context));
744 pba.addPinnedApp(context, newEntry);
748 for(AppEntry entry : blockedAppsList) {
749 pba.addBlockedApp(context, entry);
753 public static Intent getShortcutIntent(Context context) {
754 Intent shortcutIntent = new Intent(context, ShortcutActivity.class);
755 shortcutIntent.setAction(Intent.ACTION_MAIN);
756 shortcutIntent.putExtra("is_launching_shortcut", true);
758 BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_freeform_mode);
760 Intent intent = new Intent();
761 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
762 if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
763 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.pref_header_freeform));
768 public static Intent getStartStopIntent(Context context) {
769 Intent shortcutIntent = new Intent(context, StartTaskbarActivity.class);
770 shortcutIntent.setAction(Intent.ACTION_MAIN);
771 shortcutIntent.putExtra("is_launching_shortcut", true);
773 BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_launcher);
775 Intent intent = new Intent();
776 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
777 if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
778 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.start_taskbar));
783 public static boolean hasFreeformSupport(Context context) {
784 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
785 && (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT)
786 || Settings.Global.getInt(context.getContentResolver(), "enable_freeform_support", -1) == 1
787 || Settings.Global.getInt(context.getContentResolver(), "force_resizable_activities", -1) == 1);
790 public static boolean isServiceRunning(Context context, Class<? extends Service> cls) {
791 ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
792 for(ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
793 if(cls.getName().equals(service.service.getClassName()))
800 public static int getBackgroundTint(Context context) {
801 SharedPreferences pref = getSharedPreferences(context);
803 // Import old background tint preference
804 if(pref.contains("show_background")) {
805 SharedPreferences.Editor editor = pref.edit();
807 if(!pref.getBoolean("show_background", true))
808 editor.putInt("background_tint", 0).apply();
810 editor.remove("show_background");
814 return pref.getInt("background_tint", context.getResources().getInteger(R.integer.translucent_gray));
817 public static int getAccentColor(Context context) {
818 SharedPreferences pref = getSharedPreferences(context);
819 return pref.getInt("accent_color", context.getResources().getInteger(R.integer.translucent_white));
822 @TargetApi(Build.VERSION_CODES.M)
823 public static boolean canDrawOverlays(Context context) {
824 return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context);