package com.farmerbb.taskbar.util;
+import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
import android.content.pm.Signature;
import android.content.res.Configuration;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
-import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.farmerbb.taskbar.BuildConfig;
import com.farmerbb.taskbar.R;
+import com.farmerbb.taskbar.activity.ContextMenuActivity;
import com.farmerbb.taskbar.activity.DummyActivity;
import com.farmerbb.taskbar.activity.InvisibleActivityFreeform;
import com.farmerbb.taskbar.activity.ShortcutActivity;
import com.farmerbb.taskbar.activity.StartTaskbarActivity;
+import com.farmerbb.taskbar.activity.TouchAbsorberActivity;
+import com.farmerbb.taskbar.activity.dark.ContextMenuActivityDark;
import com.farmerbb.taskbar.receiver.LockDeviceReceiver;
import com.farmerbb.taskbar.service.DashboardService;
import com.farmerbb.taskbar.service.NotificationService;
private static final int WINDOWING_MODE_FREEFORM = 5;
public static SharedPreferences getSharedPreferences(Context context) {
- return getSharedPreferences(context, Context.MODE_PRIVATE);
- }
-
- private static SharedPreferences getSharedPreferences(Context context, int mode) {
- return context.getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", mode);
+ return context.getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
}
public static void showPermissionDialog(Context context) {
showPermissionDialog(context, null, null);
}
-
+
@TargetApi(Build.VERSION_CODES.M)
public static AlertDialog showPermissionDialog(Context context, Runnable onError, Runnable onFinish) {
Runnable finalOnFinish = onFinish == null
AlertDialog dialog = builder.create();
dialog.show();
dialog.setCancelable(false);
-
+
return dialog;
}
launchApp(context, () -> {
Intent intent = new Intent(context, DummyActivity.class);
intent.putExtra("device_admin", true);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent, getActivityOptionsBundle(context, ApplicationType.APPLICATION));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
- if(context instanceof Activity)
- ((Activity) context).overridePendingTransition(0, 0);
+ try {
+ context.startActivity(intent, getActivityOptionsBundle(context, ApplicationType.APPLICATION));
+ } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
});
}
}
public static void sendAccessibilityAction(Context context, int action) {
+ sendAccessibilityAction(context, action, null);
+ }
+
+ public static void sendAccessibilityAction(Context context, int action, Runnable onComplete) {
ComponentName component = new ComponentName(context, PowerMenuService.class);
context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
- if(isAccessibilityServiceEnabled(context)) {
+ boolean isAccessibilityServiceEnabled = isAccessibilityServiceEnabled(context);
+
+ if(!isAccessibilityServiceEnabled
+ && hasWriteSecureSettingsPermission(context)) {
+ String notificationServices = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+
+ String powerMenuService = new ComponentName(context, PowerMenuService.class).flattenToString();
+
+ if(!notificationServices.contains(powerMenuService)) {
+ try {
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ notificationServices.isEmpty()
+ ? powerMenuService
+ : notificationServices + ":" + powerMenuService);
+ } catch (Exception e) { /* Gracefully fail */ }
+ }
+
+ new Handler().postDelayed(() -> {
+ Intent intent = new Intent("com.farmerbb.taskbar.ACCESSIBILITY_ACTION");
+ intent.putExtra("action", action);
+ LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+
+ try {
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ notificationServices);
+ } catch (Exception e) { /* Gracefully fail */ }
+
+ if(onComplete != null) onComplete.run();
+ }, 100);
+ } else if(isAccessibilityServiceEnabled) {
Intent intent = new Intent("com.farmerbb.taskbar.ACCESSIBILITY_ACTION");
intent.putExtra("action", action);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+
+ if(onComplete != null) onComplete.run();
} else {
launchApp(context, () -> {
Intent intent = new Intent(context, DummyActivity.class);
intent.putExtra("accessibility", true);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent, getActivityOptionsBundle(context, ApplicationType.APPLICATION));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
- if(context instanceof Activity)
- ((Activity) context).overridePendingTransition(0, 0);
+ try {
+ context.startActivity(intent, getActivityOptionsBundle(context, ApplicationType.APPLICATION));
+ } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
});
}
}
- private static boolean isAccessibilityServiceEnabled(Context context) {
+ public static boolean isAccessibilityServiceEnabled(Context context) {
String accessibilityServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
ComponentName component = new ComponentName(context, PowerMenuService.class);
|| accessibilityServices.contains(component.flattenToShortString()));
}
+ public static boolean hasWriteSecureSettingsPermission(Context context) {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+ && context.checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED;
+ }
+
public static void showToast(Context context, int message) {
showToast(context, context.getString(message), Toast.LENGTH_SHORT);
}
}
private static void launchApp(final Context context,
- final String packageName,
- final String componentName,
- final long userId, final String windowSize,
- final boolean launchedFromTaskbar,
- final boolean openInNewWindow,
- final ShortcutInfo shortcut) {
+ final String packageName,
+ final String componentName,
+ final long userId, final String windowSize,
+ final boolean launchedFromTaskbar,
+ final boolean openInNewWindow,
+ final ShortcutInfo shortcut) {
launchApp(context, launchedFromTaskbar, () -> continueLaunchingApp(context, packageName, componentName, userId,
- windowSize, launchedFromTaskbar, openInNewWindow, shortcut));
+ windowSize, openInNewWindow, shortcut));
}
public static void launchApp(Context context, Runnable runnable) {
FreeformHackHelper helper = FreeformHackHelper.getInstance();
boolean specialLaunch = hasBrokenSetLaunchBoundsApi()
- && FreeformHackHelper.getInstance().isInFreeformWorkspace()
+ && helper.isInFreeformWorkspace()
&& MenuHelper.getInstance().isContextMenuOpen();
+ boolean noAnimation = pref.getBoolean("disable_animations", false);
+
if(hasFreeformSupport(context)
&& pref.getBoolean("freeform_hack", false)
&& (!helper.isInFreeformWorkspace() || specialLaunch)) {
new Handler().postDelayed(() -> {
- startFreeformHack(context, true, launchedFromTaskbar);
+ startFreeformHack(context, true);
new Handler().postDelayed(runnable, helper.isFreeformHackActive() ? 0 : 100);
}, launchedFromTaskbar ? 0 : 100);
} else
- runnable.run();
+ new Handler().postDelayed(runnable, !launchedFromTaskbar && noAnimation ? 100 : 0);
+ }
+
+ public static void startFreeformHack(Context context) {
+ startFreeformHack(context, false);
}
- @SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
- public static void startFreeformHack(Context context, boolean checkMultiWindow, boolean launchedFromTaskbar) {
+ public static void startFreeformHack(Context context, boolean checkMultiWindow) {
Intent freeformHackIntent = new Intent(context, InvisibleActivityFreeform.class);
- freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
+ freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT
+ | Intent.FLAG_ACTIVITY_NO_ANIMATION);
if(checkMultiWindow)
freeformHackIntent.putExtra("check_multiwindow", true);
- if(launchedFromTaskbar) {
- SharedPreferences pref = getSharedPreferences(context);
- if(pref.getBoolean("disable_animations", false))
- freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- }
-
if(canDrawOverlays(context))
- launchAppLowerRight(context, freeformHackIntent);
+ startActivityLowerRight(context, freeformHackIntent);
}
public static void stopFreeformHack(Context context) {
String componentName,
long userId,
String windowSize,
- boolean launchedFromTaskbar,
boolean openInNewWindow,
ShortcutInfo shortcut) {
SharedPreferences pref = getSharedPreferences(context);
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1)
intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
- if(launchedFromTaskbar) {
- if(pref.getBoolean("disable_animations", false))
- intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- }
+ if(pref.getBoolean("disable_animations", false))
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
if(openInNewWindow || pref.getBoolean("force_new_window", false)) {
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
if(windowSize == null)
windowSize = SavedWindowSizes.getInstance(context).getWindowSize(context, packageName);
- if(!canEnableFreeform()
- || !pref.getBoolean("freeform_hack", false)
- || windowSize.equals("standard")) {
- launchStandard(context, intent, userId, shortcut, type);
- } else switch(windowSize) {
- case "large":
- launchMode1(context, intent, userId, shortcut, type);
- break;
- case "fullscreen":
- launchMode2(context, intent, MAXIMIZED, userId, shortcut, type);
- break;
- case "half_left":
- launchMode2(context, intent, LEFT, userId, shortcut, type);
- break;
- case "half_right":
- launchMode2(context, intent, RIGHT, userId, shortcut, type);
- break;
- case "phone_size":
- launchMode3(context, intent, userId, shortcut, type);
- break;
- }
+ Bundle bundle = getActivityOptionsBundle(context, type, windowSize);
+
+ prepareToStartActivity(context, () -> {
+ if(shortcut == null) {
+ UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
+ try {
+ context.startActivity(intent, bundle);
+ } catch (ActivityNotFoundException e) {
+ launchAndroidForWork(context, intent.getComponent(), bundle, userId);
+ } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
+ } else
+ launchAndroidForWork(context, intent.getComponent(), bundle, userId);
+ } else
+ launchShortcut(context, shortcut, bundle);
+ });
if(shouldCollapse(context, true))
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
else
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
}
-
- private static void launchStandard(Context context, Intent intent, long userId, ShortcutInfo shortcut, ApplicationType type) {
- Bundle bundle = canEnableFreeform() ? getActivityOptions(context, type).toBundle() : null;
- if(shortcut == null) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
- try {
- context.startActivity(intent, bundle);
- } catch (ActivityNotFoundException e) {
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
- } else
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } else
- launchShortcut(context, shortcut, bundle);
- }
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
- private static void launchMode1(Context context, Intent intent, long userId, ShortcutInfo shortcut, ApplicationType type) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ private static Bundle launchMode1(Context context, ApplicationType type) {
+ DisplayInfo display = getDisplayInfo(context);
- int width1 = metrics.widthPixels / 8;
- int width2 = metrics.widthPixels - width1;
- int height1 = metrics.heightPixels / 8;
- int height2 = metrics.heightPixels - height1;
+ int width1 = display.width / 8;
+ int width2 = display.width - width1;
+ int height1 = display.height / 8;
+ int height2 = display.height - height1;
- Bundle bundle = getActivityOptions(context, type).setLaunchBounds(new Rect(
+ return getActivityOptions(context, type).setLaunchBounds(new Rect(
width1,
height1,
width2,
height2
)).toBundle();
-
- if(shortcut == null) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
- try {
- context.startActivity(intent, bundle);
- } catch (ActivityNotFoundException e) {
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
- } else
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } else
- launchShortcut(context, shortcut, bundle);
}
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
- private static void launchMode2(Context context, Intent intent, int launchType, long userId, ShortcutInfo shortcut, ApplicationType type) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
-
+ private static Bundle launchMode2(Context context, int launchType, ApplicationType type) {
+ DisplayInfo display = getDisplayInfo(context);
+
int statusBarHeight = getStatusBarHeight(context);
String position = getTaskbarPosition(context);
boolean isPortrait = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
boolean isLandscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
- int left = launchType == RIGHT && isLandscape
- ? metrics.widthPixels / 2
- : 0;
-
- int top = launchType == RIGHT && isPortrait
- ? metrics.heightPixels / 2
- : statusBarHeight;
-
- int right = launchType == LEFT && isLandscape
- ? metrics.widthPixels / 2
- : metrics.widthPixels;
-
- int bottom = launchType == LEFT && isPortrait
- ? metrics.heightPixels / 2
- : metrics.heightPixels;
+ int left = 0;
+ int top = statusBarHeight;
+ int right = display.width;
+ int bottom = display.height;
int iconSize = isOverridingFreeformHack(context) && !LauncherHelper.getInstance().isOnHomeScreen()
? 0
: context.getResources().getDimensionPixelSize(R.dimen.icon_size);
- if(position.contains("vertical_left")) {
- if(launchType != RIGHT || isPortrait) left = left + iconSize;
- } else if(position.contains("vertical_right")) {
- if(launchType != LEFT || isPortrait) right = right - iconSize;
- } else if(position.contains("bottom")) {
- if(isLandscape || (launchType != LEFT && isPortrait))
- bottom = bottom - iconSize;
- } else if(isLandscape || (launchType != RIGHT && isPortrait))
+ if(position.contains("vertical_left"))
+ left = left + iconSize;
+ else if(position.contains("vertical_right"))
+ right = right - iconSize;
+ else if(position.contains("bottom"))
+ bottom = bottom - iconSize;
+ else
top = top + iconSize;
- Bundle bundle = getActivityOptions(context, type).setLaunchBounds(new Rect(
- left,
- top,
- right,
- bottom
- )).toBundle();
+ if(launchType == RIGHT && isLandscape)
+ left = (right / 2) + ((iconSize / 2) * (position.contains("vertical_left") ? 1 : 0));
+ else if(launchType == RIGHT && isPortrait)
+ top = (bottom / 2) + ((iconSize / 2)
+ * ((position.equals("top_left") || position.equals("top_right")) ? 1 : 0));
+ else if(launchType == LEFT && isLandscape)
+ right = (right / 2) + ((iconSize / 2) * (position.contains("vertical_left") ? 1 : 0));
+ else if(launchType == LEFT && isPortrait)
+ bottom = (bottom / 2) + ((iconSize / 2)
+ * ((position.equals("top_left") || position.equals("top_right")) ? 1 : 0));
- if(shortcut == null) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
- try {
- context.startActivity(intent, bundle);
- } catch (ActivityNotFoundException e) {
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
- } else
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } else
- launchShortcut(context, shortcut, bundle);
+ return getActivityOptions(context, type)
+ .setLaunchBounds(new Rect(left, top, right, bottom)).toBundle();
}
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
- private static void launchMode3(Context context, Intent intent, long userId, ShortcutInfo shortcut, ApplicationType type) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ private static Bundle launchMode3(Context context, ApplicationType type) {
+ DisplayInfo display = getDisplayInfo(context);
- int width1 = metrics.widthPixels / 2;
+ int width1 = display.width / 2;
int width2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_width) / 2;
- int height1 = metrics.heightPixels / 2;
+ int height1 = display.height / 2;
int height2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_height) / 2;
- Bundle bundle = getActivityOptions(context, type).setLaunchBounds(new Rect(
+ return getActivityOptions(context, type).setLaunchBounds(new Rect(
width1 - width2,
height1 - height2,
width1 + width2,
height1 + height2
)).toBundle();
-
- if(shortcut == null) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
- try {
- context.startActivity(intent, bundle);
- } catch (ActivityNotFoundException e) {
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
- } else
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } else
- launchShortcut(context, shortcut, bundle);
}
private static void launchAndroidForWork(Context context, ComponentName componentName, Bundle bundle, long userId) {
}
}
- public static void launchAppMaximized(Context context, Intent intent) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- long userId = userManager.getSerialNumberForUser(Process.myUserHandle());
+ private static void prepareToStartActivity(Context context, Runnable runnable) {
+ boolean shouldLaunchTouchAbsorber =
+ !FreeformHackHelper.getInstance().isTouchAbsorberActive()
+ && isOverridingFreeformHack(context)
+ && !isChromeOs(context);
- launchMode2(context, intent, MAXIMIZED, userId, null, ApplicationType.CONTEXT_MENU);
+ if(!shouldLaunchTouchAbsorber) {
+ runnable.run();
+ return;
+ }
+
+ startTouchAbsorberActivity(context);
+ new Handler().postDelayed(runnable, 100);
+ }
+
+ public static void startActivityMaximized(Context context, Intent intent) {
+ Bundle bundle = launchMode2(context, MAXIMIZED, ApplicationType.CONTEXT_MENU);
+ prepareToStartActivity(context, () -> context.startActivity(intent, bundle));
}
- @SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
- public static void launchAppLowerRight(Context context, Intent intent) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ public static void startActivityLowerRight(Context context, Intent intent) {
+ DisplayInfo display = getDisplayInfo(context);
try {
context.startActivity(intent,
getActivityOptions(context, ApplicationType.FREEFORM_HACK)
.setLaunchBounds(new Rect(
- metrics.widthPixels,
- metrics.heightPixels,
- metrics.widthPixels + 1,
- metrics.heightPixels + 1
- )).toBundle());
+ display.width,
+ display.height,
+ display.width + 1,
+ display.height + 1
+ )).toBundle());
} catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
}
+ @TargetApi(Build.VERSION_CODES.N)
+ public static void startTouchAbsorberActivity(Context context) {
+ String position = getTaskbarPosition(context);
+ DisplayInfo display = getDisplayInfo(context);
+
+ int left = 0;
+ int top = 0;
+ int right = display.width;
+ int bottom = display.height;
+
+ int iconSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
+
+ if(position.contains("vertical_left"))
+ right = iconSize;
+ else if(position.contains("vertical_right"))
+ left = right - iconSize;
+ else if(position.contains("bottom"))
+ top = bottom - iconSize;
+ else
+ bottom = iconSize;
+
+ Intent intent = new Intent(context, TouchAbsorberActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+
+ try {
+ context.startActivity(intent,
+ getActivityOptions(context, ApplicationType.FREEFORM_HACK)
+ .setLaunchBounds(new Rect(left, top, right, bottom)).toBundle());
+ } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
+ }
+
+ public static void startContextMenuActivity(Context context, Bundle args) {
+ SharedPreferences pref = getSharedPreferences(context);
+ Intent intent = null;
+
+ switch(pref.getString("theme", "light")) {
+ case "light":
+ intent = new Intent(context, ContextMenuActivity.class);
+ break;
+ case "dark":
+ intent = new Intent(context, ContextMenuActivityDark.class);
+ break;
+ }
+
+ if(intent != null) {
+ intent.putExtra("args", args);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ }
+
+ if(hasFreeformSupport(context) && FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
+ DisplayInfo display = getDisplayInfo(context);
+
+ if(intent != null && hasBrokenSetLaunchBoundsApi())
+ intent.putExtra("context_menu_fix", true);
+
+ context.startActivity(intent,
+ getActivityOptions(context, ApplicationType.CONTEXT_MENU)
+ .setLaunchBounds(
+ new Rect(0, 0, display.width, display.height)
+ ).toBundle());
+ } else
+ context.startActivity(intent);
+ }
+
public static void checkForUpdates(Context context) {
String url;
- if(isPlayStoreRelease(context))
- url = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
- else
+ if(isPlayStoreRelease(context)) {
+ if(BuildConfig.APPLICATION_ID.equals(BuildConfig.BASE_APPLICATION_ID)
+ && !isPlayStoreInstalled(context))
+ url = "https://github.com/farmerbb/Taskbar/releases";
+ else
+ url = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
+ } else
url = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.APPLICATION_ID;
Intent intent = new Intent(Intent.ACTION_VIEW);
private static int getMaxNumOfColumns(Context context) {
SharedPreferences pref = getSharedPreferences(context);
- DisplayMetrics metrics = getRealDisplayMetrics(context);
- float baseTaskbarSize = getBaseTaskbarSizeFloat(context) / metrics.density;
+ DisplayInfo display = getDisplayInfo(context);
+ float density = display.density / 160;
+ float baseTaskbarSize = getBaseTaskbarSizeFloat(context) / density;
int numOfColumns = 0;
float maxScreenSize = getTaskbarPosition(context).contains("vertical")
- ? (metrics.heightPixels - getStatusBarHeight(context)) / metrics.density
- : metrics.widthPixels / metrics.density;
+ ? (display.height - getStatusBarHeight(context)) / density
+ : display.width / density;
- float iconSize = context.getResources().getDimension(R.dimen.icon_size) / metrics.density;
+ float iconSize = context.getResources().getDimension(R.dimen.icon_size) / density;
int userMaxNumOfColumns = Integer.valueOf(pref.getString("max_num_of_recents", "10"));
}
public static int getStatusBarHeight(Context context) {
- int statusBarHeight = 0;
- int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
+ return getSystemDimen(context, "status_bar_height");
+ }
+
+ private static int getNavbarHeight(Context context) {
+ return getSystemDimen(context, "navigation_bar_height");
+ }
+
+ private static int getSystemDimen(Context context, String id) {
+ int value = 0;
+ int resourceId = context.getResources().getIdentifier(id, "dimen", "android");
if(resourceId > 0)
- statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
+ value = context.getResources().getDimensionPixelSize(resourceId);
- return statusBarHeight;
+ return value;
}
public static void refreshPinnedIcons(Context context) {
public static boolean canEnableFreeform() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
- }
+ }
@TargetApi(Build.VERSION_CODES.N)
public static boolean hasFreeformSupport(Context context) {
&& Settings.Global.getInt(context.getContentResolver(), "force_resizable_activities", 0) != 0));
}
- public static boolean hasPartialFreeformSupport() {
- return Build.MANUFACTURER.equalsIgnoreCase("Samsung");
+ public static boolean isSamsungDevice() {
+ return Build.MANUFACTURER.equalsIgnoreCase("Samsung");
+ }
+
+ public static boolean isNvidiaDevice() {
+ return Build.MANUFACTURER.equalsIgnoreCase("NVIDIA");
}
public static boolean isServiceRunning(Context context, Class<? extends Service> cls) {
return "setLaunchStackId";
}
- public static Bundle getActivityOptionsBundle(Context context, ApplicationType applicationType) {
- if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
+ public static Bundle getActivityOptionsBundle(Context context, ApplicationType type) {
+ SharedPreferences pref = getSharedPreferences(context);
+
+ return getActivityOptionsBundle(context, type, pref.getString("window_size", "standard"));
+ }
+
+ private static Bundle getActivityOptionsBundle(Context context, ApplicationType type, String windowSize) {
+ SharedPreferences pref = getSharedPreferences(context);
+ if(!canEnableFreeform() || !pref.getBoolean("freeform_hack", false))
return null;
- else
- return getActivityOptions(context, applicationType).toBundle();
+
+ switch(windowSize) {
+ case "large":
+ return launchMode1(context, type);
+ case "fullscreen":
+ return launchMode2(context, MAXIMIZED, type);
+ case "half_left":
+ return launchMode2(context, LEFT, type);
+ case "half_right":
+ return launchMode2(context, RIGHT, type);
+ case "phone_size":
+ return launchMode3(context, type);
+ }
+
+ return getActivityOptions(context, type).toBundle();
}
private static ApplicationType getApplicationType(Context context, String packageName) {
if(canEnableFreeform()) {
if(!pref.getBoolean("freeform_hack_override", false)) {
pref.edit()
- .putBoolean("freeform_hack", hasFreeformSupport(context) && !hasPartialFreeformSupport())
+ .putBoolean("freeform_hack", hasFreeformSupport(context) && !isSamsungDevice())
.putBoolean("save_window_sizes", false)
.putBoolean("freeform_hack_override", true)
.apply();
editor.putString("refresh_frequency", "0");
editor.putString("max_num_of_recents", "2147483647");
editor.putString("sort_order", "true");
+ editor.putString("window_size", "phone_size");
editor.putBoolean("full_length", true);
editor.putBoolean("dashboard", true);
editor.putBoolean("app_drawer_icon", true);
editor.putBoolean("button_recents", true);
editor.putBoolean("auto_hide_navbar", true);
editor.putBoolean("bliss_os_prefs", true);
-
- try {
- Settings.Secure.putString(context.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- new ComponentName(context, PowerMenuService.class).flattenToString());
- } catch (Exception e) { /* Gracefully fail */ }
-
editor.apply();
}
.putString("refresh_frequency", "0")
.putString("max_num_of_recents", "2147483647")
.putString("sort_order", "true")
+ .putString("window_size", "phone_size")
.putBoolean("full_length", true)
.putBoolean("dashboard", true)
.putBoolean("android_x86_prefs", true)
}
}
- public static DisplayMetrics getRealDisplayMetrics(Context context) {
- DisplayMetrics metrics = new DisplayMetrics();
+ public static DisplayInfo getDisplayInfo(Context context) {
+ context = context.getApplicationContext();
+
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();
- SharedPreferences pref = getSharedPreferences(context);
- if(isChromeOs(context) && !pref.getBoolean("chrome_os_context_menu_fix", true))
- disp.getRealMetrics(metrics);
- else
- disp.getMetrics(metrics);
+ DisplayMetrics metrics = new DisplayMetrics();
+ disp.getMetrics(metrics);
+
+ DisplayMetrics realMetrics = new DisplayMetrics();
+ disp.getRealMetrics(realMetrics);
+
+ DisplayInfo display = new DisplayInfo(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
+
+ if(isChromeOs(context)) {
+ SharedPreferences pref = getSharedPreferences(context);
+ if(!pref.getBoolean("chrome_os_context_menu_fix", true)) {
+ display.width = realMetrics.widthPixels;
+ display.height = realMetrics.heightPixels;
+ }
+
+ return display;
+ }
- return metrics;
+ boolean sameWidth = metrics.widthPixels == realMetrics.widthPixels;
+ boolean sameHeight = metrics.heightPixels == realMetrics.heightPixels;
+
+ if(sameWidth && !sameHeight) {
+ display.width = realMetrics.widthPixels;
+ display.height = realMetrics.heightPixels - getNavbarHeight(context);
+ }
+
+ if(!sameWidth && sameHeight) {
+ display.width = realMetrics.widthPixels - getNavbarHeight(context);
+ display.height = realMetrics.heightPixels;
+ }
+
+ return display;
}
- static void pinAppShortcut(Context context) {
- Intent intent = getShortcutIntent(context);
- intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
- intent.putExtra("duplicate", false);
+ public static void pinAppShortcut(Context context) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ ShortcutManager mShortcutManager = context.getSystemService(ShortcutManager.class);
- Intent homeIntent = new Intent(Intent.ACTION_MAIN);
- homeIntent.addCategory(Intent.CATEGORY_HOME);
- ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ if(mShortcutManager.isRequestPinShortcutSupported()) {
+ ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder(context, "freeform_mode").build();
+
+ mShortcutManager.requestPinShortcut(pinShortcutInfo, null);
+ } else
+ showToastLong(context, R.string.pin_shortcut_not_supported);
+ } else {
+ Intent intent = getShortcutIntent(context);
+ intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
+ intent.putExtra("duplicate", false);
+
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+ homeIntent.addCategory(Intent.CATEGORY_HOME);
+ ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
- intent.setPackage(defaultLauncher.activityInfo.packageName);
- context.sendBroadcast(intent);
+ intent.setPackage(defaultLauncher.activityInfo.packageName);
+ context.sendBroadcast(intent);
- showToast(context, R.string.shortcut_created);
+ showToast(context, R.string.shortcut_created);
+ }
}
public static boolean shouldCollapse(Context context, boolean pendingAppLaunch) {
public static boolean isOverridingFreeformHack(Context context) {
SharedPreferences pref = getSharedPreferences(context);
- return (isChromeOs(context) && pref.getBoolean("chrome_os_context_menu_fix", true))
- || (!isChromeOs(context) && getCurrentApiVersion() >= 28.0f);
- }
-
- @SuppressWarnings("unchecked")
- public static <T extends View> T findViewById(Activity target, int id) {
- return (T) target.findViewById(id);
- }
-
- @SuppressWarnings("unchecked")
- public static <T extends View> T findViewById(View target, int id) {
- return (T) target.findViewById(id);
+ return pref.getBoolean("freeform_hack", false)
+ && ((isChromeOs(context) && pref.getBoolean("chrome_os_context_menu_fix", true))
+ || (!isChromeOs(context) && getCurrentApiVersion() >= 28.0f));
}
public static boolean isPlayStoreInstalled(Context context) {
}
public static boolean hasBrokenSetLaunchBoundsApi() {
- return getCurrentApiVersion() >= 26.0f && getCurrentApiVersion() < 28.0f;
+ return getCurrentApiVersion() >= 26.0f
+ && getCurrentApiVersion() < 28.0f
+ && !isSamsungDevice()
+ && !isNvidiaDevice();
}
public static String getSecondScreenPackageName(Context context) {
public static boolean visualFeedbackEnabled(Context context) {
SharedPreferences pref = getSharedPreferences(context);
- return Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1 && pref.getBoolean("visual_feedback", true);
+ return (getCurrentApiVersion() < 26.0f || getCurrentApiVersion() >= 28.0f)
+ && pref.getBoolean("visual_feedback", true);
}
public static void showRecentAppsDialog(Context context) {
AlertDialog dialog = builder.create();
dialog.show();
dialog.setCancelable(false);
-
+
return dialog;
}
}
return false;
}
- public static boolean isTaskerDisabled(Context context) {
- SharedPreferences pref = getSharedPreferences(context, Context.MODE_MULTI_PROCESS);
+ public static boolean isExternalAccessDisabled(Context context) {
+ SharedPreferences pref = getSharedPreferences(context);
return !pref.getBoolean("tasker_enabled", true);
}
+
+ public static boolean enableFreeformModeShortcut(Context context) {
+ return canEnableFreeform()
+ && !U.isOverridingFreeformHack(context)
+ && !U.isChromeOs(context);
+ }
+
+ public static void startForegroundService(Context context, Intent intent) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ if(Settings.canDrawOverlays(context))
+ context.startForegroundService(intent);
+ } else
+ context.startService(intent);
+ }
+
+ public static int getOverlayType() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+ ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
+ : WindowManager.LayoutParams.TYPE_PHONE;
+ }
+
+ public static boolean isDelegatingHomeActivity(Context context) {
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+ homeIntent.addCategory(Intent.CATEGORY_HOME);
+
+ final List<ResolveInfo> listOfLaunchers = context.getPackageManager().queryIntentActivities(homeIntent, 0);
+ for(ResolveInfo launcher : listOfLaunchers) {
+ if(launcher.activityInfo.packageName.equals(BuildConfig.SUPPORT_APPLICATION_ID))
+ return true;
+ }
+
+ return false;
+ }
}