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.DialogInterface;
28 import android.content.Intent;
29 import android.content.SharedPreferences;
30 import android.content.pm.ActivityInfo;
31 import android.content.pm.LauncherActivityInfo;
32 import android.content.pm.LauncherApps;
33 import android.content.pm.PackageManager;
34 import android.content.pm.ResolveInfo;
35 import android.content.pm.ShortcutInfo;
36 import android.content.res.Configuration;
37 import android.graphics.Rect;
38 import android.graphics.drawable.BitmapDrawable;
39 import android.hardware.display.DisplayManager;
40 import android.net.Uri;
41 import android.os.Build;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.Process;
45 import android.os.UserHandle;
46 import android.os.UserManager;
47 import android.provider.Settings;
48 import android.support.v4.content.LocalBroadcastManager;
49 import android.util.DisplayMetrics;
50 import android.view.Display;
51 import android.view.Surface;
52 import android.view.WindowManager;
53 import android.widget.Toast;
55 import com.farmerbb.taskbar.BuildConfig;
56 import com.farmerbb.taskbar.R;
57 import com.farmerbb.taskbar.activity.DummyActivity;
58 import com.farmerbb.taskbar.activity.InvisibleActivityFreeform;
59 import com.farmerbb.taskbar.activity.ShortcutActivity;
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, new DialogInterface.OnClickListener() {
94 public void onClick(DialogInterface dialog, int which) {
96 context.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
97 Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
98 } catch (ActivityNotFoundException e) {
99 showErrorDialog(context, "SYSTEM_ALERT_WINDOW");
104 AlertDialog dialog = builder.create();
106 dialog.setCancelable(false);
109 public static void showErrorDialog(final Context context, String appopCmd) {
110 AlertDialog.Builder builder = new AlertDialog.Builder(context);
111 builder.setTitle(R.string.error_dialog_title)
112 .setMessage(context.getString(R.string.error_dialog_message, BuildConfig.APPLICATION_ID, appopCmd))
113 .setPositiveButton(R.string.action_ok, null);
115 AlertDialog dialog = builder.create();
119 public static void lockDevice(Context context) {
120 ComponentName component = new ComponentName(context, LockDeviceReceiver.class);
121 context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
122 PackageManager.DONT_KILL_APP);
124 DevicePolicyManager mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
125 if(mDevicePolicyManager.isAdminActive(component))
126 mDevicePolicyManager.lockNow();
128 Intent intent = new Intent(context, DummyActivity.class);
129 intent.putExtra("device_admin", true);
130 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
131 context.startActivity(intent);
135 public static void showPowerMenu(Context context) {
136 ComponentName component = new ComponentName(context, PowerMenuService.class);
137 context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
138 PackageManager.DONT_KILL_APP);
140 if(isAccessibilityServiceEnabled(context))
141 context.startService(new Intent(context, PowerMenuService.class));
143 Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
144 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
147 context.startActivity(intent);
148 showToastLong(context, R.string.enable_accessibility);
149 } catch (ActivityNotFoundException e) {
150 showToast(context, R.string.lock_device_not_supported);
155 private static boolean isAccessibilityServiceEnabled(Context context) {
156 String accessibilityServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
157 ComponentName component = new ComponentName(context, PowerMenuService.class);
159 return accessibilityServices != null
160 && (accessibilityServices.contains(component.flattenToString())
161 || accessibilityServices.contains(component.flattenToShortString()));
164 public static void showToast(Context context, int message) {
165 showToast(context, context.getString(message), Toast.LENGTH_SHORT);
168 public static void showToastLong(Context context, int message) {
169 showToast(context, context.getString(message), Toast.LENGTH_LONG);
172 public static void showToast(Context context, String message, int length) {
173 ToastCompat.makeText(context, message, length).show();
176 public static void startShortcut(Context context, String packageName, String componentName, ShortcutInfo shortcut) {
187 public static void launchApp(final Context context,
188 final String packageName,
189 final String componentName,
190 final long userId, final String windowSize,
191 final boolean launchedFromTaskbar,
192 final boolean openInNewWindow) {
203 private static void launchApp(final Context context,
204 final String packageName,
205 final String componentName,
206 final long userId, final String windowSize,
207 final boolean launchedFromTaskbar,
208 final boolean openInNewWindow,
209 final ShortcutInfo shortcut) {
210 boolean shouldDelay = false;
212 SharedPreferences pref = getSharedPreferences(context);
213 boolean openInFullscreen = pref.getBoolean("open_in_fullscreen", true);
214 boolean freeformHackActive = openInNewWindow
215 ? FreeformHackHelper.getInstance().isInFreeformWorkspace()
217 ? FreeformHackHelper.getInstance().isInFreeformWorkspace()
218 : FreeformHackHelper.getInstance().isFreeformHackActive());
220 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
221 && pref.getBoolean("freeform_hack", false)
222 && !freeformHackActive) {
225 new Handler().postDelayed(new Runnable() {
228 startFreeformHack(context, true, launchedFromTaskbar);
230 new Handler().postDelayed(new Runnable() {
233 continueLaunchingApp(context, packageName, componentName, userId,
234 windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
238 }, launchedFromTaskbar ? 0 : 100);
241 if(!FreeformHackHelper.getInstance().isFreeformHackActive()) {
243 continueLaunchingApp(context, packageName, componentName, userId,
244 windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
245 } else if(FreeformHackHelper.getInstance().isInFreeformWorkspace() || !openInFullscreen)
246 continueLaunchingApp(context, packageName, componentName, userId,
247 windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
250 @SuppressWarnings("deprecation")
251 @TargetApi(Build.VERSION_CODES.N)
252 public static void startFreeformHack(Context context, boolean checkMultiWindow, boolean launchedFromTaskbar) {
253 Intent freeformHackIntent = new Intent(context, InvisibleActivityFreeform.class);
254 freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
257 freeformHackIntent.putExtra("check_multiwindow", true);
259 if(launchedFromTaskbar) {
260 SharedPreferences pref = getSharedPreferences(context);
261 if(pref.getBoolean("disable_animations", false))
262 freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
265 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
266 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
268 context.startActivity(freeformHackIntent, ActivityOptions.makeBasic().setLaunchBounds(new Rect(
271 display.getWidth() + 1,
272 display.getHeight() + 1
274 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
277 @TargetApi(Build.VERSION_CODES.N)
278 private static void continueLaunchingApp(Context context,
280 String componentName,
283 boolean launchedFromTaskbar,
284 boolean openInNewWindow,
285 ShortcutInfo shortcut) {
286 SharedPreferences pref = getSharedPreferences(context);
287 Intent intent = new Intent();
288 intent.setComponent(ComponentName.unflattenFromString(componentName));
289 intent.setAction(Intent.ACTION_MAIN);
290 intent.addCategory(Intent.CATEGORY_LAUNCHER);
291 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
292 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
294 if(launchedFromTaskbar) {
295 if(pref.getBoolean("disable_animations", false))
296 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
299 if(openInNewWindow || pref.getBoolean("force_new_window", false)) {
300 intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
302 ActivityInfo activityInfo = intent.resolveActivityInfo(context.getPackageManager(), 0);
303 if(activityInfo != null) {
304 switch(activityInfo.launchMode) {
305 case ActivityInfo.LAUNCH_SINGLE_TASK:
306 case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
307 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
313 if(windowSize == null) {
314 if(pref.getBoolean("save_window_sizes", true))
315 windowSize = SavedWindowSizes.getInstance(context).getWindowSize(context, packageName);
317 windowSize = pref.getString("window_size", "standard");
320 if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !pref.getBoolean("freeform_hack", false)) {
321 if(shortcut == null) {
322 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
323 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
325 context.startActivity(intent, null);
326 } catch (ActivityNotFoundException e) {
327 launchAndroidForWork(context, intent.getComponent(), null, userId);
328 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
330 launchAndroidForWork(context, intent.getComponent(), null, userId);
332 launchShortcut(context, shortcut, null);
333 } else switch(windowSize) {
335 if(FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
336 if(shortcut == null) {
337 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
338 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
340 context.startActivity(intent);
341 } catch (ActivityNotFoundException e) {
342 launchAndroidForWork(context, intent.getComponent(), null, userId);
343 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
345 launchAndroidForWork(context, intent.getComponent(), null, userId);
347 launchShortcut(context, shortcut, null);
349 launchMode1(context, intent, 1, userId, shortcut);
352 launchMode1(context, intent, 2, userId, shortcut);
355 launchMode2(context, intent, FULLSCREEN, userId, shortcut);
358 launchMode2(context, intent, LEFT, userId, shortcut);
361 launchMode2(context, intent, RIGHT, userId, shortcut);
364 launchMode3(context, intent, userId, shortcut);
368 if(pref.getBoolean("hide_taskbar", true) && !FreeformHackHelper.getInstance().isInFreeformWorkspace())
369 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
371 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
374 @SuppressWarnings("deprecation")
375 @TargetApi(Build.VERSION_CODES.N)
376 private static void launchMode1(Context context, Intent intent, int factor, long userId, ShortcutInfo shortcut) {
377 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
378 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
380 int width1 = display.getWidth() / (4 * factor);
381 int width2 = display.getWidth() - width1;
382 int height1 = display.getHeight() / (4 * factor);
383 int height2 = display.getHeight() - height1;
385 Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
392 if(shortcut == null) {
393 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
394 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
396 context.startActivity(intent, bundle);
397 } catch (ActivityNotFoundException e) {
398 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
399 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
401 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
403 launchShortcut(context, shortcut, bundle);
406 @SuppressWarnings("deprecation")
407 @TargetApi(Build.VERSION_CODES.N)
408 private static void launchMode2(Context context, Intent intent, int launchType, long userId, ShortcutInfo shortcut) {
409 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
410 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
412 int statusBarHeight = getStatusBarHeight(context);
413 String position = getTaskbarPosition(context);
415 boolean isPortrait = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
416 boolean isLandscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
418 int left = launchType == RIGHT && isLandscape
419 ? display.getWidth() / 2
422 int top = launchType == RIGHT && isPortrait
423 ? display.getHeight() / 2
426 int right = launchType == LEFT && isLandscape
427 ? display.getWidth() / 2
428 : display.getWidth();
430 int bottom = launchType == LEFT && isPortrait
431 ? display.getHeight() / 2
432 : display.getHeight();
434 int iconSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
436 if(position.contains("vertical_left")) {
437 if(launchType != RIGHT || isPortrait) left = left + iconSize;
438 } else if(position.contains("vertical_right")) {
439 if(launchType != LEFT || isPortrait) right = right - iconSize;
440 } else if(position.contains("bottom")) {
441 if(isLandscape || (launchType != LEFT && isPortrait))
442 bottom = bottom - iconSize;
443 } else if(isLandscape || (launchType != RIGHT && isPortrait))
444 top = top + iconSize;
446 Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
453 if(shortcut == null) {
454 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
455 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
457 context.startActivity(intent, bundle);
458 } catch (ActivityNotFoundException e) {
459 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
460 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
462 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
464 launchShortcut(context, shortcut, bundle);
467 @SuppressWarnings("deprecation")
468 @TargetApi(Build.VERSION_CODES.N)
469 private static void launchMode3(Context context, Intent intent, long userId, ShortcutInfo shortcut) {
470 DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
471 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
473 int width1 = display.getWidth() / 2;
474 int width2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_width) / 2;
475 int height1 = display.getHeight() / 2;
476 int height2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_height) / 2;
478 Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
485 if(shortcut == null) {
486 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
487 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
489 context.startActivity(intent, bundle);
490 } catch (ActivityNotFoundException e) {
491 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
492 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
494 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
496 launchShortcut(context, shortcut, bundle);
499 private static void launchAndroidForWork(Context context, ComponentName componentName, Bundle bundle, long userId) {
500 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
501 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
504 launcherApps.startMainActivity(componentName, userManager.getUserForSerialNumber(userId), null, bundle);
505 } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
508 @TargetApi(Build.VERSION_CODES.N_MR1)
509 private static void launchShortcut(Context context, ShortcutInfo shortcut, Bundle bundle) {
510 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
513 launcherApps.startShortcut(shortcut, null, bundle);
514 } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
517 public static void launchAppFullscreen(Context context, Intent intent) {
518 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
519 long userId = userManager.getSerialNumberForUser(Process.myUserHandle());
521 launchMode2(context, intent, FULLSCREEN, userId, null);
524 public static void checkForUpdates(Context context) {
527 context.getPackageManager().getPackageInfo("com.android.vending", 0);
528 url = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
529 } catch (PackageManager.NameNotFoundException e) {
530 url = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.BASE_APPLICATION_ID;
533 Intent intent = new Intent(Intent.ACTION_VIEW);
534 intent.setData(Uri.parse(url));
535 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
538 context.startActivity(intent);
539 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
542 public static boolean launcherIsDefault(Context context) {
543 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
544 homeIntent.addCategory(Intent.CATEGORY_HOME);
545 ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
547 return defaultLauncher.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID);
550 public static void setCachedRotation(int cachedRotation) {
551 U.cachedRotation = cachedRotation;
554 public static String getTaskbarPosition(Context context) {
555 SharedPreferences pref = getSharedPreferences(context);
556 String position = pref.getString("position", "bottom_left");
558 if(pref.getBoolean("anchor", false)) {
559 WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
560 int rotation = cachedRotation != null ? cachedRotation : windowManager.getDefaultDisplay().getRotation();
565 case Surface.ROTATION_0:
566 return "bottom_left";
567 case Surface.ROTATION_90:
568 return "bottom_vertical_right";
569 case Surface.ROTATION_180:
571 case Surface.ROTATION_270:
572 return "top_vertical_left";
575 case "bottom_vertical_left":
577 case Surface.ROTATION_0:
578 return "bottom_vertical_left";
579 case Surface.ROTATION_90:
580 return "bottom_right";
581 case Surface.ROTATION_180:
582 return "top_vertical_right";
583 case Surface.ROTATION_270:
589 case Surface.ROTATION_0:
590 return "bottom_right";
591 case Surface.ROTATION_90:
592 return "top_vertical_right";
593 case Surface.ROTATION_180:
595 case Surface.ROTATION_270:
596 return "bottom_vertical_left";
599 case "bottom_vertical_right":
601 case Surface.ROTATION_0:
602 return "bottom_vertical_right";
603 case Surface.ROTATION_90:
605 case Surface.ROTATION_180:
606 return "top_vertical_left";
607 case Surface.ROTATION_270:
608 return "bottom_left";
613 case Surface.ROTATION_0:
615 case Surface.ROTATION_90:
616 return "bottom_vertical_left";
617 case Surface.ROTATION_180:
618 return "bottom_right";
619 case Surface.ROTATION_270:
620 return "top_vertical_right";
623 case "top_vertical_left":
625 case Surface.ROTATION_0:
626 return "top_vertical_left";
627 case Surface.ROTATION_90:
628 return "bottom_left";
629 case Surface.ROTATION_180:
630 return "bottom_vertical_right";
631 case Surface.ROTATION_270:
637 case Surface.ROTATION_0:
639 case Surface.ROTATION_90:
640 return "top_vertical_left";
641 case Surface.ROTATION_180:
642 return "bottom_left";
643 case Surface.ROTATION_270:
644 return "bottom_vertical_right";
647 case "top_vertical_right":
649 case Surface.ROTATION_0:
650 return "top_vertical_right";
651 case Surface.ROTATION_90:
653 case Surface.ROTATION_180:
654 return "bottom_vertical_left";
655 case Surface.ROTATION_270:
656 return "bottom_right";
665 private static int getMaxNumOfColumns(Context context) {
666 SharedPreferences pref = getSharedPreferences(context);
667 DisplayMetrics metrics = context.getResources().getDisplayMetrics();
668 float baseTaskbarSize = context.getResources().getDimension(pref.getBoolean("dashboard", false) ? R.dimen.base_taskbar_size_dashboard : R.dimen.base_taskbar_size) / metrics.density;
669 int numOfColumns = 0;
671 float maxScreenSize = getTaskbarPosition(context).contains("vertical")
672 ? (metrics.heightPixels - getStatusBarHeight(context)) / metrics.density
673 : metrics.widthPixels / metrics.density;
675 float iconSize = context.getResources().getDimension(R.dimen.icon_size) / metrics.density;
677 int userMaxNumOfColumns = Integer.valueOf(pref.getString("max_num_of_recents", "10"));
679 while(baseTaskbarSize + iconSize < maxScreenSize
680 && numOfColumns < userMaxNumOfColumns) {
681 baseTaskbarSize = baseTaskbarSize + iconSize;
688 public static int getMaxNumOfEntries(Context context) {
689 SharedPreferences pref = getSharedPreferences(context);
690 return pref.getBoolean("disable_scrolling_list", false)
691 ? getMaxNumOfColumns(context)
692 : Integer.valueOf(pref.getString("max_num_of_recents", "10"));
695 public static int getStatusBarHeight(Context context) {
696 int statusBarHeight = 0;
697 int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
699 statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
701 return statusBarHeight;
704 public static void refreshPinnedIcons(Context context) {
705 IconCache.getInstance(context).clearCache();
707 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(context);
708 List<AppEntry> pinnedAppsList = new ArrayList<>(pba.getPinnedApps());
709 List<AppEntry> blockedAppsList = new ArrayList<>(pba.getBlockedApps());
710 PackageManager pm = context.getPackageManager();
714 for(AppEntry entry : pinnedAppsList) {
715 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
716 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
718 final List<UserHandle> userHandles = userManager.getUserProfiles();
719 LauncherActivityInfo appInfo = null;
721 for(UserHandle handle : userHandles) {
722 List<LauncherActivityInfo> list = launcherApps.getActivityList(entry.getPackageName(), handle);
723 if(!list.isEmpty()) {
724 // Google App workaround
725 if(!entry.getPackageName().equals("com.google.android.googlequicksearchbox"))
726 appInfo = list.get(0);
728 boolean added = false;
729 for(LauncherActivityInfo info : list) {
730 if(info.getName().equals("com.google.android.googlequicksearchbox.SearchActivity")) {
736 if(!added) appInfo = list.get(0);
743 if(appInfo != null) {
744 AppEntry newEntry = new AppEntry(
745 entry.getPackageName(),
746 entry.getComponentName(),
748 IconCache.getInstance(context).getIcon(context, pm, appInfo),
751 newEntry.setUserId(entry.getUserId(context));
752 pba.addPinnedApp(context, newEntry);
756 for(AppEntry entry : blockedAppsList) {
757 pba.addBlockedApp(context, entry);
761 public static Intent getShortcutIntent(Context context) {
762 Intent shortcutIntent = new Intent(context, ShortcutActivity.class);
763 shortcutIntent.setAction(Intent.ACTION_MAIN);
764 shortcutIntent.putExtra("is_launching_shortcut", true);
766 BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_freeform_mode);
768 Intent intent = new Intent();
769 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
770 if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
771 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.pref_header_freeform));
776 public static boolean hasFreeformSupport(Context context) {
777 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
778 && (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT)
779 || Settings.Global.getInt(context.getContentResolver(), "enable_freeform_support", -1) == 1
780 || Settings.Global.getInt(context.getContentResolver(), "force_resizable_activities", -1) == 1);
783 public static boolean isServiceRunning(Context context, Class<? extends Service> cls) {
784 ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
785 for(ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
786 if(cls.getName().equals(service.service.getClassName()))