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) {
517 if(!BuildConfig.DEBUG) {
520 context.getPackageManager().getPackageInfo("com.android.vending", 0);
521 url = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
522 } catch (PackageManager.NameNotFoundException e) {
523 url = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.BASE_APPLICATION_ID;
526 Intent intent = new Intent(Intent.ACTION_VIEW);
527 intent.setData(Uri.parse(url));
528 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
531 context.startActivity(intent);
532 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
534 showToast(context, R.string.debug_build);
537 public static boolean launcherIsDefault(Context context) {
538 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
539 homeIntent.addCategory(Intent.CATEGORY_HOME);
540 ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
542 return defaultLauncher.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID);
545 public static void setCachedRotation(int cachedRotation) {
546 U.cachedRotation = cachedRotation;
549 public static String getTaskbarPosition(Context context) {
550 SharedPreferences pref = getSharedPreferences(context);
551 String position = pref.getString("position", "bottom_left");
553 if(pref.getBoolean("anchor", false)) {
554 WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
555 int rotation = cachedRotation != null ? cachedRotation : windowManager.getDefaultDisplay().getRotation();
560 case Surface.ROTATION_0:
561 return "bottom_left";
562 case Surface.ROTATION_90:
563 return "bottom_vertical_right";
564 case Surface.ROTATION_180:
566 case Surface.ROTATION_270:
567 return "top_vertical_left";
570 case "bottom_vertical_left":
572 case Surface.ROTATION_0:
573 return "bottom_vertical_left";
574 case Surface.ROTATION_90:
575 return "bottom_right";
576 case Surface.ROTATION_180:
577 return "top_vertical_right";
578 case Surface.ROTATION_270:
584 case Surface.ROTATION_0:
585 return "bottom_right";
586 case Surface.ROTATION_90:
587 return "top_vertical_right";
588 case Surface.ROTATION_180:
590 case Surface.ROTATION_270:
591 return "bottom_vertical_left";
594 case "bottom_vertical_right":
596 case Surface.ROTATION_0:
597 return "bottom_vertical_right";
598 case Surface.ROTATION_90:
600 case Surface.ROTATION_180:
601 return "top_vertical_left";
602 case Surface.ROTATION_270:
603 return "bottom_left";
608 case Surface.ROTATION_0:
610 case Surface.ROTATION_90:
611 return "bottom_vertical_left";
612 case Surface.ROTATION_180:
613 return "bottom_right";
614 case Surface.ROTATION_270:
615 return "top_vertical_right";
618 case "top_vertical_left":
620 case Surface.ROTATION_0:
621 return "top_vertical_left";
622 case Surface.ROTATION_90:
623 return "bottom_left";
624 case Surface.ROTATION_180:
625 return "bottom_vertical_right";
626 case Surface.ROTATION_270:
632 case Surface.ROTATION_0:
634 case Surface.ROTATION_90:
635 return "top_vertical_left";
636 case Surface.ROTATION_180:
637 return "bottom_left";
638 case Surface.ROTATION_270:
639 return "bottom_vertical_right";
642 case "top_vertical_right":
644 case Surface.ROTATION_0:
645 return "top_vertical_right";
646 case Surface.ROTATION_90:
648 case Surface.ROTATION_180:
649 return "bottom_vertical_left";
650 case Surface.ROTATION_270:
651 return "bottom_right";
660 private static int getMaxNumOfColumns(Context context) {
661 SharedPreferences pref = getSharedPreferences(context);
662 DisplayMetrics metrics = context.getResources().getDisplayMetrics();
663 float baseTaskbarSize = context.getResources().getDimension(pref.getBoolean("dashboard", false) ? R.dimen.base_taskbar_size_dashboard : R.dimen.base_taskbar_size) / metrics.density;
664 int numOfColumns = 0;
666 float maxScreenSize = getTaskbarPosition(context).contains("vertical")
667 ? (metrics.heightPixels - getStatusBarHeight(context)) / metrics.density
668 : metrics.widthPixels / metrics.density;
670 float iconSize = context.getResources().getDimension(R.dimen.icon_size) / metrics.density;
672 int userMaxNumOfColumns = Integer.valueOf(pref.getString("max_num_of_recents", "10"));
674 while(baseTaskbarSize + iconSize < maxScreenSize
675 && numOfColumns < userMaxNumOfColumns) {
676 baseTaskbarSize = baseTaskbarSize + iconSize;
683 public static int getMaxNumOfEntries(Context context) {
684 SharedPreferences pref = getSharedPreferences(context);
685 return pref.getBoolean("disable_scrolling_list", false)
686 ? getMaxNumOfColumns(context)
687 : Integer.valueOf(pref.getString("max_num_of_recents", "10"));
690 public static int getStatusBarHeight(Context context) {
691 int statusBarHeight = 0;
692 int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
694 statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
696 return statusBarHeight;
699 public static void refreshPinnedIcons(Context context) {
700 IconCache.getInstance(context).clearCache();
702 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(context);
703 List<AppEntry> pinnedAppsList = new ArrayList<>(pba.getPinnedApps());
704 List<AppEntry> blockedAppsList = new ArrayList<>(pba.getBlockedApps());
705 PackageManager pm = context.getPackageManager();
709 for(AppEntry entry : pinnedAppsList) {
710 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
711 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
713 final List<UserHandle> userHandles = userManager.getUserProfiles();
714 LauncherActivityInfo appInfo = null;
716 for(UserHandle handle : userHandles) {
717 List<LauncherActivityInfo> list = launcherApps.getActivityList(entry.getPackageName(), handle);
718 if(!list.isEmpty()) {
719 // Google App workaround
720 if(!entry.getPackageName().equals("com.google.android.googlequicksearchbox"))
721 appInfo = list.get(0);
723 boolean added = false;
724 for(LauncherActivityInfo info : list) {
725 if(info.getName().equals("com.google.android.googlequicksearchbox.SearchActivity")) {
731 if(!added) appInfo = list.get(0);
738 if(appInfo != null) {
739 AppEntry newEntry = new AppEntry(
740 entry.getPackageName(),
741 entry.getComponentName(),
743 IconCache.getInstance(context).getIcon(context, pm, appInfo),
746 newEntry.setUserId(entry.getUserId(context));
747 pba.addPinnedApp(context, newEntry);
751 for(AppEntry entry : blockedAppsList) {
752 pba.addBlockedApp(context, entry);
756 public static Intent getShortcutIntent(Context context) {
757 Intent shortcutIntent = new Intent(context, ShortcutActivity.class);
758 shortcutIntent.setAction(Intent.ACTION_MAIN);
759 shortcutIntent.putExtra("is_launching_shortcut", true);
761 BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_freeform_mode);
763 Intent intent = new Intent();
764 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
765 if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
766 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.pref_header_freeform));
771 public static Intent getStartStopIntent(Context context) {
772 Intent shortcutIntent = new Intent(context, StartTaskbarActivity.class);
773 shortcutIntent.setAction(Intent.ACTION_MAIN);
774 shortcutIntent.putExtra("is_launching_shortcut", true);
776 BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_launcher);
778 Intent intent = new Intent();
779 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
780 if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
781 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.start_taskbar));
786 public static boolean hasFreeformSupport(Context context) {
787 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
788 && (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT)
789 || Settings.Global.getInt(context.getContentResolver(), "enable_freeform_support", -1) == 1
790 || Settings.Global.getInt(context.getContentResolver(), "force_resizable_activities", -1) == 1);
793 public static boolean isServiceRunning(Context context, Class<? extends Service> cls) {
794 ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
795 for(ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
796 if(cls.getName().equals(service.service.getClassName()))
803 public static int getBackgroundTint(Context context) {
804 SharedPreferences pref = getSharedPreferences(context);
806 // Import old background tint preference
807 if(pref.contains("show_background")) {
808 SharedPreferences.Editor editor = pref.edit();
810 if(!pref.getBoolean("show_background", true))
811 editor.putInt("background_tint", 0).apply();
813 editor.remove("show_background");
817 return pref.getInt("background_tint", context.getResources().getInteger(R.integer.translucent_gray));
820 public static int getAccentColor(Context context) {
821 SharedPreferences pref = getSharedPreferences(context);
822 return pref.getInt("accent_color", context.getResources().getInteger(R.integer.translucent_white));
825 @TargetApi(Build.VERSION_CODES.M)
826 public static boolean canDrawOverlays(Context context) {
827 return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context);