package com.farmerbb.taskbar.util;
import android.Manifest;
+import android.accessibilityservice.AccessibilityService;
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.app.AppOpsManager;
import android.app.Service;
import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v7.view.ContextThemeWrapper;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.appcompat.view.ContextThemeWrapper;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
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.MainActivity;
import com.farmerbb.taskbar.activity.TouchAbsorberActivity;
import com.farmerbb.taskbar.activity.dark.ContextMenuActivityDark;
+import com.farmerbb.taskbar.content.TaskbarIntent;
import com.farmerbb.taskbar.service.DashboardService;
import com.farmerbb.taskbar.service.NotificationService;
import com.farmerbb.taskbar.service.PowerMenuService;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
private static final int WINDOWING_MODE_FULLSCREEN = 1;
private static final int WINDOWING_MODE_FREEFORM = 5;
+ public static final int EXPORT = 123;
+ public static final int IMPORT = 456;
+
+ @SuppressWarnings("deprecation")
public static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
}
showPermissionDialog(context, null, null);
}
- @TargetApi(Build.VERSION_CODES.M)
public static AlertDialog showPermissionDialog(Context context, Runnable onError, Runnable onFinish) {
Runnable finalOnFinish = onFinish == null
? () -> {}
? () -> showErrorDialog(context, "SYSTEM_ALERT_WINDOW", finalOnFinish)
: onError;
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.permission_dialog_title)
- .setMessage(R.string.permission_dialog_message)
- .setPositiveButton(R.string.action_grant_permission, (dialog, which) -> {
+ AlertDialog.Builder builder;
+ if(hasAndroidTVSettings(context))
+ builder = buildPermissionDialogAndroidTV(context, finalOnError, finalOnFinish);
+ else
+ builder = buildPermissionDialogStandard(context, finalOnError, finalOnFinish);
+
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ dialog.setCancelable(false);
+
+ return dialog;
+ }
+
+ @TargetApi(Build.VERSION_CODES.M)
+ private static AlertDialog.Builder buildPermissionDialogStandard(Context context, Runnable onError, Runnable onFinish) {
+ return new AlertDialog.Builder(context)
+ .setTitle(R.string.tb_permission_dialog_title)
+ .setMessage(R.string.tb_permission_dialog_message)
+ .setPositiveButton(R.string.tb_action_grant_permission, (dialog, which) -> {
try {
context.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
- Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
+ Uri.parse("package:" + context.getPackageName())));
- finalOnFinish.run();
+ onFinish.run();
} catch (ActivityNotFoundException e) {
- finalOnError.run();
+ onError.run();
}
});
+ }
- AlertDialog dialog = builder.create();
- dialog.show();
- dialog.setCancelable(false);
-
- return dialog;
+ private static AlertDialog.Builder buildPermissionDialogAndroidTV(Context context, Runnable onError, Runnable onFinish) {
+ return new AlertDialog.Builder(context)
+ .setTitle(R.string.tb_permission_dialog_title)
+ .setMessage(R.string.tb_permission_dialog_message_alt)
+ .setPositiveButton(R.string.tb_action_open_settings, (dialog, which) -> {
+ try {
+ context.startActivity(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
+ onFinish.run();
+ } catch (ActivityNotFoundException e) {
+ onError.run();
+ }
+ });
}
public static AlertDialog showErrorDialog(Context context, String appopCmd) {
: onFinish;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.error_dialog_title)
- .setMessage(context.getString(R.string.error_dialog_message, BuildConfig.APPLICATION_ID, appopCmd))
- .setPositiveButton(R.string.action_ok, (dialog, which) -> finalOnFinish.run());
+ builder.setTitle(R.string.tb_error_dialog_title)
+ .setMessage(context.getString(R.string.tb_error_dialog_message, context.getPackageName(), appopCmd))
+ .setPositiveButton(R.string.tb_action_ok, (dialog, which) -> finalOnFinish.run());
AlertDialog dialog = builder.create();
dialog.show();
return dialog;
}
+ @TargetApi(Build.VERSION_CODES.P)
+ public static void lockDevice(Context context) {
+ sendAccessibilityAction(context, AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN);
+ }
+
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);
+ setComponentEnabled(context, PowerMenuService.class, true);
boolean isAccessibilityServiceEnabled = isAccessibilityServiceEnabled(context);
}
new Handler().postDelayed(() -> {
- Intent intent = new Intent("com.farmerbb.taskbar.ACCESSIBILITY_ACTION");
+ Intent intent = new Intent(TaskbarIntent.ACTION_ACCESSIBILITY_ACTION);
intent.putExtra("action", action);
- LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+ sendBroadcast(context, intent);
try {
Settings.Secure.putString(context.getContentResolver(),
if(onComplete != null) onComplete.run();
}, 100);
} else if(isAccessibilityServiceEnabled) {
- Intent intent = new Intent("com.farmerbb.taskbar.ACCESSIBILITY_ACTION");
+ Intent intent = new Intent(TaskbarIntent.ACTION_ACCESSIBILITY_ACTION);
intent.putExtra("action", action);
- LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+ sendBroadcast(context, intent);
if(onComplete != null) onComplete.run();
} else {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
try {
- context.startActivity(intent, getActivityOptionsBundle(context, ApplicationType.APPLICATION, null));
+ context.startActivity(intent, getActivityOptionsBundle(context, ApplicationType.APP_PORTRAIT, null));
} catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
});
}
public static void showToast(Context context, String message, int length) {
cancelToast();
- ToastInterface toast = DependencyUtils.createToast(context, message, length);
+ ToastInterface toast = DependencyUtils.createToast(context.getApplicationContext(), message, length);
toast.show();
ToastHelper.getInstance().setLastToast(toast);
if(toast != null) toast.cancel();
}
- public static void startShortcut(Context context, AppEntry entry, ShortcutInfo shortcut) {
+ public static void startShortcut(Context context, AppEntry entry, ShortcutInfo shortcut, View view) {
launchApp(context,
entry,
null,
false,
false,
+ false,
shortcut,
+ view,
null);
}
entry,
windowSize,
launchedFromTaskbar,
+ false,
openInNewWindow,
null,
- view);
+ view,
+ null);
+ }
+
+ public static void launchApp(final Context context,
+ final AppEntry entry,
+ final String windowSize,
+ final Runnable onError) {
+ launchApp(context,
+ entry,
+ windowSize,
+ false,
+ true,
+ false,
+ null,
+ null,
+ onError);
}
private static void launchApp(final Context context,
final AppEntry entry,
final String windowSize,
final boolean launchedFromTaskbar,
+ final boolean isPersistentShortcut,
final boolean openInNewWindow,
final ShortcutInfo shortcut,
- final View view) {
- launchApp(context, launchedFromTaskbar, () -> continueLaunchingApp(context, entry,
- windowSize, openInNewWindow, shortcut, view));
+ final View view,
+ final Runnable onError) {
+ launchApp(context, launchedFromTaskbar, isPersistentShortcut, () ->
+ continueLaunchingApp(context, entry, windowSize, openInNewWindow, shortcut, view, onError)
+ );
}
public static void launchApp(Context context, Runnable runnable) {
- launchApp(context, true, runnable);
+ launchApp(context, true, false, runnable);
}
- private static void launchApp(Context context, boolean launchedFromTaskbar, Runnable runnable) {
+ private static void launchApp(Context context, boolean launchedFromTaskbar, boolean isPersistentShortcut, Runnable runnable) {
SharedPreferences pref = getSharedPreferences(context);
FreeformHackHelper helper = FreeformHackHelper.getInstance();
boolean noAnimation = pref.getBoolean("disable_animations", false);
if(hasFreeformSupport(context)
- && pref.getBoolean("freeform_hack", false)
+ && (pref.getBoolean("freeform_hack", false) || isPersistentShortcut)
&& (!helper.isInFreeformWorkspace() || specialLaunch)) {
new Handler().postDelayed(() -> {
startFreeformHack(context, true);
if(checkMultiWindow)
freeformHackIntent.putExtra("check_multiwindow", true);
- if(canDrawOverlays(context, false))
+ if(canDrawOverlays(context))
startActivityLowerRight(context, freeformHackIntent);
}
public static void stopFreeformHack(Context context) {
- LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.FINISH_FREEFORM_ACTIVITY"));
+ sendBroadcast(context, TaskbarIntent.ACTION_FINISH_FREEFORM_ACTIVITY);
- if(isOverridingFreeformHack(context)) {
+ if(isOverridingFreeformHack(context, false)) {
FreeformHackHelper helper = FreeformHackHelper.getInstance();
helper.setFreeformHackActive(false);
helper.setInFreeformWorkspace(false);
String windowSize,
boolean openInNewWindow,
ShortcutInfo shortcut,
- View view) {
+ View view,
+ Runnable onError) {
SharedPreferences pref = getSharedPreferences(context);
Intent intent = new Intent();
intent.setComponent(ComponentName.unflattenFromString(entry.getComponentName()));
if(pref.getBoolean("disable_animations", false))
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- if(openInNewWindow || pref.getBoolean("force_new_window", false)) {
+ boolean realOpenInNewWindow = openInNewWindow || pref.getBoolean("force_new_window", false);
+ if(realOpenInNewWindow) {
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
ActivityInfo activityInfo = intent.resolveActivityInfo(context.getPackageManager(), 0);
}
}
- ApplicationType type = getApplicationType(context, entry.getPackageName());
+ ApplicationType type = getApplicationType(context, entry);
if(windowSize == null)
windowSize = SavedWindowSizes.getInstance(context).getWindowSize(context, entry.getPackageName());
Bundle bundle = getActivityOptionsBundle(context, type, windowSize, view);
- prepareToStartActivity(context, () -> {
+ prepareToStartActivity(context, realOpenInNewWindow, () -> {
if(shortcut == null) {
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
if(entry.getUserId(context) == userManager.getSerialNumberForUser(Process.myUserHandle())) {
try {
context.startActivity(intent, bundle);
} catch (ActivityNotFoundException e) {
- launchAndroidForWork(context, intent.getComponent(), bundle, entry.getUserId(context));
+ launchAndroidForWork(context, intent.getComponent(), bundle, entry.getUserId(context), onError);
} catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
} else
- launchAndroidForWork(context, intent.getComponent(), bundle, entry.getUserId(context));
+ launchAndroidForWork(context, intent.getComponent(), bundle, entry.getUserId(context), onError);
} else
- launchShortcut(context, shortcut, bundle);
+ launchShortcut(context, shortcut, bundle, onError);
});
- 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"));
+ if(shouldCollapse(context, true)) {
+ sendBroadcast(context, TaskbarIntent.ACTION_HIDE_TASKBAR);
+ } else {
+ sendBroadcast(context, TaskbarIntent.ACTION_HIDE_START_MENU);
+ }
}
- @TargetApi(Build.VERSION_CODES.N)
- private static Bundle launchMode1(Context context, ApplicationType type, View view) {
+ private static Bundle launchMode1(Context context, ApplicationType type, View view, int factor) {
DisplayInfo display = getDisplayInfo(context);
- int width1 = display.width / 8;
+ int width1 = display.width / factor;
int width2 = display.width - width1;
- int height1 = display.height / 8;
+ int height1 = display.height / factor;
int height2 = display.height - height1;
- return getActivityOptions(context, type, view).setLaunchBounds(new Rect(
+ return getActivityOptionsBundle(context, type, view,
width1,
height1,
width2,
height2
- )).toBundle();
+ );
}
- @TargetApi(Build.VERSION_CODES.N)
private static Bundle launchMode2(Context context, int launchType, ApplicationType type, View view) {
DisplayInfo display = getDisplayInfo(context);
int iconSize = isOverridingFreeformHack(context) && !LauncherHelper.getInstance().isOnHomeScreen()
? 0
- : context.getResources().getDimensionPixelSize(R.dimen.icon_size);
+ : context.getResources().getDimensionPixelSize(R.dimen.tb_icon_size);
if(position.contains("vertical_left"))
left = left + iconSize;
else if(launchType == LEFT && isPortrait)
bottom = halfPortrait;
- return getActivityOptions(context, type, view)
- .setLaunchBounds(new Rect(left, top, right, bottom)).toBundle();
+ return getActivityOptionsBundle(context, type, view, left, top, right, bottom);
}
- @TargetApi(Build.VERSION_CODES.N)
private static Bundle launchMode3(Context context, ApplicationType type, View view) {
DisplayInfo display = getDisplayInfo(context);
+ boolean isLandscape = type == ApplicationType.APP_LANDSCAPE;
+ int widthDimen = isLandscape ? R.dimen.tb_phone_size_height : R.dimen.tb_phone_size_width;
+ int heightDimen = isLandscape ? R.dimen.tb_phone_size_width : R.dimen.tb_phone_size_height;
+
int width1 = display.width / 2;
- int width2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_width) / 2;
+ int width2 = context.getResources().getDimensionPixelSize(widthDimen) / 2;
int height1 = display.height / 2;
- int height2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_height) / 2;
+ int height2 = context.getResources().getDimensionPixelSize(heightDimen) / 2;
- return getActivityOptions(context, type, view).setLaunchBounds(new Rect(
+ return getActivityOptionsBundle(context, type, view,
width1 - width2,
height1 - height2,
width1 + width2,
height1 + height2
- )).toBundle();
+ );
}
- private static void launchAndroidForWork(Context context, ComponentName componentName, Bundle bundle, long userId) {
+ private static void launchAndroidForWork(Context context, ComponentName componentName, Bundle bundle, long userId, Runnable onError) {
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
try {
launcherApps.startMainActivity(componentName, userManager.getUserForSerialNumber(userId), null, bundle);
- } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
+ } catch (ActivityNotFoundException | NullPointerException
+ | IllegalStateException | SecurityException e) {
+ if(onError != null) launchApp(context, onError);
+ }
}
@TargetApi(Build.VERSION_CODES.N_MR1)
- private static void launchShortcut(Context context, ShortcutInfo shortcut, Bundle bundle) {
+ private static void launchShortcut(Context context, ShortcutInfo shortcut, Bundle bundle, Runnable onError) {
LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
if(launcherApps.hasShortcutHostPermission()) {
try {
launcherApps.startShortcut(shortcut, null, bundle);
- } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
+ } catch (ActivityNotFoundException | NullPointerException
+ | IllegalStateException | SecurityException e) {
+ if(onError != null) launchApp(context, onError);
+ }
}
}
- private static void prepareToStartActivity(Context context, Runnable runnable) {
- LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_CONTEXT_MENU"));
+ private static void prepareToStartActivity(Context context, boolean openInNewWindow, Runnable runnable) {
+ sendBroadcast(context, TaskbarIntent.ACTION_HIDE_CONTEXT_MENU);
- if(!shouldLaunchTouchAbsorber(context)) {
- runnable.run();
- return;
- }
+ if(!FreeformHackHelper.getInstance().isTouchAbsorberActive()
+ && shouldLaunchTouchAbsorber(context)) {
+ startTouchAbsorberActivity(context);
+ new Handler().postDelayed(runnable, 100);
+ } else if(openInNewWindow) {
+ Intent intent = new Intent(context, DummyActivity.class);
+ intent.putExtra("finish_on_pause", true);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivityLowerRight(context, intent);
- startTouchAbsorberActivity(context);
- new Handler().postDelayed(runnable, 100);
+ new Handler().postDelayed(runnable, 100);
+ } else
+ runnable.run();
}
public static void startActivityMaximized(Context context, Intent intent) {
Bundle bundle = launchMode2(context, MAXIMIZED, ApplicationType.CONTEXT_MENU, null);
- prepareToStartActivity(context, () -> context.startActivity(intent, bundle));
+ prepareToStartActivity(context, false, () -> context.startActivity(intent, bundle));
}
- @TargetApi(Build.VERSION_CODES.N)
public static void startActivityLowerRight(Context context, Intent intent) {
DisplayInfo display = getDisplayInfo(context);
try {
context.startActivity(intent,
- getActivityOptions(context, ApplicationType.FREEFORM_HACK, null)
- .setLaunchBounds(new Rect(
- display.width,
- display.height,
- display.width + 1,
- display.height + 1
- )).toBundle());
+ getActivityOptionsBundle(context, ApplicationType.FREEFORM_HACK, null,
+ display.width,
+ display.height,
+ display.width + 1,
+ display.height + 1
+ ));
} 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 right = display.width;
int bottom = display.height;
- int iconSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
+ int iconSize = context.getResources().getDimensionPixelSize(R.dimen.tb_icon_size);
if(position.contains("vertical_left"))
right = iconSize;
try {
context.startActivity(intent,
- getActivityOptions(context, ApplicationType.FREEFORM_HACK, null)
- .setLaunchBounds(new Rect(left, top, right, bottom)).toBundle());
+ getActivityOptionsBundle(context, ApplicationType.FREEFORM_HACK, null,
+ left, top, right, bottom));
} catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
}
intent.putExtra("context_menu_fix", true);
context.startActivity(intent,
- getActivityOptions(context, ApplicationType.CONTEXT_MENU, null)
- .setLaunchBounds(
- new Rect(0, 0, display.width, display.height)
- ).toBundle());
+ getActivityOptionsBundle(context, ApplicationType.CONTEXT_MENU, null,
+ 0, 0, display.width, display.height));
} else
context.startActivity(intent);
}
public static void checkForUpdates(Context context) {
String url;
if(isPlayStoreRelease(context)) {
- if(BuildConfig.APPLICATION_ID.equals(BuildConfig.BASE_APPLICATION_ID)
+ if(context.getPackageName().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;
+ url = "https://play.google.com/store/apps/details?id=" + context.getPackageName();
} else
- url = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.APPLICATION_ID;
+ url = "https://f-droid.org/repository/browse/?fdid=" + context.getPackageName();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
homeIntent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
- return defaultLauncher.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID);
+ return defaultLauncher.activityInfo.packageName.equals(context.getPackageName());
}
public static void setCachedRotation(int cachedRotation) {
? (display.height - getStatusBarHeight(context)) / density
: display.width / density;
- float iconSize = context.getResources().getDimension(R.dimen.icon_size) / density;
+ float iconSize = context.getResources().getDimension(R.dimen.tb_icon_size) / density;
int userMaxNumOfColumns = Integer.valueOf(pref.getString("max_num_of_recents", "10"));
}
}
- public static Intent getShortcutIntent(Context context) {
- Intent shortcutIntent = new Intent(context, ShortcutActivity.class);
- shortcutIntent.setAction(Intent.ACTION_MAIN);
- shortcutIntent.putExtra("is_launching_shortcut", true);
-
- Intent intent = new Intent();
- intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
- intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.mipmap.ic_freeform_mode));
- intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.pref_header_freeform));
-
- return intent;
- }
-
- public static Intent getStartStopIntent(Context context) {
- Intent shortcutIntent = new Intent(context, StartTaskbarActivity.class);
- shortcutIntent.setAction(Intent.ACTION_MAIN);
- shortcutIntent.putExtra("is_launching_shortcut", true);
-
- Intent intent = new Intent();
- intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
- intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.mipmap.ic_launcher));
- intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.start_taskbar));
-
- return intent;
- }
-
public static boolean canEnableFreeform() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
}
}
public static boolean canBootToFreeform(Context context) {
- SharedPreferences pref = getSharedPreferences(context);
- return hasFreeformSupport(context)
- && pref.getBoolean("freeform_hack", false)
- && !isOverridingFreeformHack(context);
+ return canBootToFreeform(context, true);
+ }
+
+ private static boolean canBootToFreeform(Context context, boolean checkPref) {
+ return hasFreeformSupport(context) && !isOverridingFreeformHack(context, checkPref);
}
public static boolean isSamsungDevice() {
}
public static boolean isServiceRunning(Context context, Class<? extends Service> cls) {
- if(LauncherHelper.getInstance().isOnHomeScreen()
- && FeatureFlags.homeActivityUIHost()
+ if(LauncherHelper.getInstance().isOnSecondaryHomeScreen()
&& (cls.equals(TaskbarService.class)
|| cls.equals(StartMenuService.class)
|| cls.equals(DashboardService.class)))
editor.apply();
}
- return pref.getInt("background_tint", context.getResources().getInteger(R.integer.translucent_gray));
+ return pref.getInt("background_tint", context.getResources().getInteger(R.integer.tb_translucent_gray));
}
public static int getAccentColor(Context context) {
SharedPreferences pref = getSharedPreferences(context);
- return pref.getInt("accent_color", context.getResources().getInteger(R.integer.translucent_white));
+ return pref.getInt("accent_color", context.getResources().getInteger(R.integer.tb_translucent_white));
}
- @TargetApi(Build.VERSION_CODES.M)
- public static boolean canDrawOverlays(Context context, boolean forHomeScreen) {
- return (forHomeScreen && FeatureFlags.homeActivityUIHost() && !canBootToFreeform(context))
- || Build.VERSION.SDK_INT < Build.VERSION_CODES.M
- || Settings.canDrawOverlays(context);
+ public static boolean canDrawOverlays(Context context) {
+ return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context);
}
public static boolean isGame(Context context, String packageName) {
return getActivityOptions(null, null, view);
}
- @TargetApi(Build.VERSION_CODES.N)
- private static ActivityOptions getActivityOptions(Context context, ApplicationType applicationType, View view) {
+ public static ActivityOptions getActivityOptions(Context context, ApplicationType applicationType, View view) {
ActivityOptions options;
if(view != null)
options = ActivityOptions.makeScaleUpAnimation(view, 0, 0, view.getWidth(), view.getHeight());
- else
+ else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
options = ActivityOptions.makeBasic();
+ else {
+ try {
+ Constructor<ActivityOptions> constructor = ActivityOptions.class.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ options = constructor.newInstance();
+ } catch (Exception e) {
+ return null;
+ }
+ }
if(applicationType == null)
return options;
int stackId = -1;
switch(applicationType) {
- case APPLICATION:
+ case APP_PORTRAIT:
+ case APP_LANDSCAPE:
if(FreeformHackHelper.getInstance().isFreeformHackActive())
stackId = getFreeformWindowModeId();
else
stackId = getFullscreenWindowModeId();
break;
- case GAME:
+ case APP_FULLSCREEN:
stackId = getFullscreenWindowModeId();
break;
case FREEFORM_HACK:
method.invoke(options, stackId);
} catch (Exception e) { /* Gracefully fail */ }
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ int launchDisplayId = LauncherHelper.getInstance().getSecondaryDisplayId();
+ if(launchDisplayId != -1)
+ options.setLaunchDisplayId(launchDisplayId);
+ }
+
return options;
}
public static Bundle getActivityOptionsBundle(Context context, ApplicationType type, View view) {
SharedPreferences pref = getSharedPreferences(context);
- return getActivityOptionsBundle(context, type, pref.getString("window_size", "standard"), view);
+ return getActivityOptionsBundle(context, type, pref.getString("window_size", context.getString(R.string.tb_def_window_size)), view);
}
-
+
private static Bundle getActivityOptionsBundle(Context context, ApplicationType type, String windowSize, View view) {
SharedPreferences pref = getSharedPreferences(context);
if(!canEnableFreeform() || !pref.getBoolean("freeform_hack", false))
return getActivityOptions(view).toBundle();
-
+
switch(windowSize) {
+ case "standard":
+ if(getCurrentApiVersion() > 29.0f)
+ return launchMode1(context, type, view, 4);
+ break;
case "large":
- return launchMode1(context, type, view);
+ return launchMode1(context, type, view, 8);
case "fullscreen":
return launchMode2(context, MAXIMIZED, type, view);
case "half_left":
return getActivityOptions(context, type, view).toBundle();
}
- private static ApplicationType getApplicationType(Context context, String packageName) {
- return isGame(context, packageName) ? ApplicationType.GAME : ApplicationType.APPLICATION;
+ private static Bundle getActivityOptionsBundle(Context context, ApplicationType applicationType, View view,
+ int left, int top, int right, int bottom) {
+ ActivityOptions options = getActivityOptions(context, applicationType, view);
+ if(options == null)
+ return null;
+
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
+ return options.toBundle();
+
+ return options.setLaunchBounds(new Rect(left, top, right, bottom)).toBundle();
+ }
+
+ @SuppressLint("SwitchIntDef")
+ private static ApplicationType getApplicationType(Context context, AppEntry entry) {
+ if(isGame(context, entry.getPackageName()))
+ return ApplicationType.APP_FULLSCREEN;
+
+ try {
+ ActivityInfo info = context.getPackageManager().getActivityInfo(
+ ComponentName.unflattenFromString(entry.getComponentName()),
+ 0
+ );
+
+ switch(info.screenOrientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ return ApplicationType.APP_LANDSCAPE;
+
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ return ApplicationType.APP_PORTRAIT;
+ }
+ } catch (PackageManager.NameNotFoundException e) { /* Gracefully fail */ }
+
+ return context.getPackageName().equals(BuildConfig.ANDROIDX86_APPLICATION_ID)
+ ? ApplicationType.APP_LANDSCAPE
+ : ApplicationType.APP_PORTRAIT;
}
public static boolean isSystemApp(Context context) {
try {
- ApplicationInfo info = context.getPackageManager().getApplicationInfo(BuildConfig.APPLICATION_ID, 0);
+ ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
return (info.flags & mask) != 0;
} catch (PackageManager.NameNotFoundException e) {
validBlissOsBuildProp = true;
return validBlissOsBuildProp
- && BuildConfig.APPLICATION_ID.equals(BuildConfig.BASE_APPLICATION_ID)
+ && context.getPackageName().equals(BuildConfig.BASE_APPLICATION_ID)
&& isSystemApp(context);
}
public static boolean isLauncherPermanentlyEnabled(Context context) {
- if(BuildConfig.APPLICATION_ID.equals(BuildConfig.ANDROIDX86_APPLICATION_ID))
+ if(context.getPackageName().equals(BuildConfig.ANDROIDX86_APPLICATION_ID))
return true;
+ return hasSupportLibrary(context, 0);
+ }
+
+ public static boolean hasSupportLibrary(Context context, int minVersion) {
PackageManager pm = context.getPackageManager();
try {
- pm.getPackageInfo(BuildConfig.SUPPORT_APPLICATION_ID, 0);
- return pm.checkSignatures(BuildConfig.SUPPORT_APPLICATION_ID, BuildConfig.APPLICATION_ID) == PackageManager.SIGNATURE_MATCH
- && BuildConfig.APPLICATION_ID.equals(BuildConfig.BASE_APPLICATION_ID)
+ PackageInfo pInfo = pm.getPackageInfo(BuildConfig.SUPPORT_APPLICATION_ID, 0);
+ return pInfo.versionCode >= minVersion
+ && pm.checkSignatures(BuildConfig.SUPPORT_APPLICATION_ID, context.getPackageName()) == PackageManager.SIGNATURE_MATCH
+ && context.getPackageName().equals(BuildConfig.BASE_APPLICATION_ID)
&& isSystemApp(context);
} catch (PackageManager.NameNotFoundException e) {
return false;
private static float getBaseTaskbarSizeFloat(Context context) {
SharedPreferences pref = getSharedPreferences(context);
- float baseTaskbarSize = context.getResources().getDimension(R.dimen.base_taskbar_size);
+ float baseTaskbarSize = context.getResources().getDimension(R.dimen.tb_base_taskbar_size);
boolean navbarButtonsEnabled = false;
- if(pref.getBoolean("dashboard", false))
- baseTaskbarSize += context.getResources().getDimension(R.dimen.dashboard_button_size);
+ if(pref.getBoolean("dashboard", context.getResources().getBoolean(R.bool.tb_def_dashboard)))
+ baseTaskbarSize += context.getResources().getDimension(R.dimen.tb_dashboard_button_size);
if(pref.getBoolean("button_back", false)) {
navbarButtonsEnabled = true;
- baseTaskbarSize += context.getResources().getDimension(R.dimen.icon_size);
+ baseTaskbarSize += context.getResources().getDimension(R.dimen.tb_icon_size);
}
if(pref.getBoolean("button_home", false)) {
navbarButtonsEnabled = true;
- baseTaskbarSize += context.getResources().getDimension(R.dimen.icon_size);
+ baseTaskbarSize += context.getResources().getDimension(R.dimen.tb_icon_size);
}
if(pref.getBoolean("button_recents", false)) {
navbarButtonsEnabled = true;
- baseTaskbarSize += context.getResources().getDimension(R.dimen.icon_size);
+ baseTaskbarSize += context.getResources().getDimension(R.dimen.tb_icon_size);
}
if(navbarButtonsEnabled)
- baseTaskbarSize += context.getResources().getDimension(R.dimen.navbar_buttons_margin);
+ baseTaskbarSize += context.getResources().getDimension(R.dimen.tb_navbar_buttons_margin);
+
+ if(isSystemTrayEnabled(context))
+ baseTaskbarSize += context.getResources().getDimension(R.dimen.tb_systray_size);
return baseTaskbarSize;
}
startTaskbarService(context, false);
}
- LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.RESTART"));
+ sendBroadcast(context, TaskbarIntent.ACTION_RESTART);
}
public static void restartNotificationService(Context context) {
}
public static void showHideNavigationBar(Context context, boolean show) {
+ if(!isDesktopModeActive(context)
+ && !isBlissOs(context)
+ && !hasSupportLibrary(context, 7)) {
+ return;
+ }
+
+ int displayID = getDisplayID();
+ int value = show ? 0 : getNavbarHeight(context) * -1;
+
+ if(hasWriteSecureSettingsPermission(context)) {
+ try {
+ setOverscan(displayID, value);
+ return;
+ } catch (Exception e) {
+ // Fallback to next method
+ }
+ }
+
+ if(hasSupportLibrary(context, 7)) {
+ Intent intent = new Intent(BuildConfig.SUPPORT_APPLICATION_ID + ".CHANGE_OVERSCAN");
+ intent.setPackage(BuildConfig.SUPPORT_APPLICATION_ID);
+
+ intent.putExtra("display_id", displayID);
+ intent.putExtra("value", value);
+
+ context.sendBroadcast(intent);
+ return;
+ }
+
// Show or hide the system navigation bar on Bliss-x86
+ if(!isBlissOs(context)) return;
+
try {
if(getCurrentApiVersion() >= 28.0f)
Settings.Secure.putInt(context.getContentResolver(), "navigation_bar_visible", show ? 1 : 0);
}
public static void initPrefs(Context context) {
- // On smaller-screened devices, set "Grid" as the default start menu layout
- SharedPreferences pref = getSharedPreferences(context);
- if(context.getApplicationContext().getResources().getConfiguration().smallestScreenWidthDp < 720
- && pref.getString("start_menu_layout", "null").equals("null")) {
- pref.edit().putString("start_menu_layout", "grid").apply();
- }
-
// Enable freeform hack automatically on supported devices
+ SharedPreferences pref = getSharedPreferences(context);
if(canEnableFreeform()) {
if(!pref.getBoolean("freeform_hack_override", false)) {
pref.edit()
editor.putString("refresh_frequency", "0");
editor.putString("max_num_of_recents", "2147483647");
editor.putString("sort_order", "true");
- editor.putString("window_size", "phone_size");
editor.putString("start_button_image", "app_logo");
- editor.putBoolean("full_length", true);
- editor.putBoolean("dashboard", true);
editor.putBoolean("button_back", true);
editor.putBoolean("button_home", true);
editor.putBoolean("button_recents", true);
editor.putBoolean("auto_hide_navbar", true);
- // editor.putBoolean("shortcut_icon", false);
+ editor.putBoolean("shortcut_icon", false);
editor.putBoolean("bliss_os_prefs", true);
editor.apply();
}
// Customizations for Android-x86 devices (non-Bliss)
- if(BuildConfig.APPLICATION_ID.equals(BuildConfig.ANDROIDX86_APPLICATION_ID)
+ if(context.getPackageName().equals(BuildConfig.ANDROIDX86_APPLICATION_ID)
&& isSystemApp(context)
&& !pref.getBoolean("android_x86_prefs", false)) {
pref.edit()
.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("shortcut_icon", false)
+ .putBoolean("shortcut_icon", false)
.putBoolean("android_x86_prefs", true)
.apply();
}
}
public static DisplayInfo getDisplayInfo(Context context) {
+ return getDisplayInfo(context, false);
+ }
+
+ public static DisplayInfo getDisplayInfo(Context context, boolean fromTaskbar) {
context = context.getApplicationContext();
+ int displayID = getDisplayID();
+
+ DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+ Display currentDisplay = null;
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- Display disp = wm.getDefaultDisplay();
+ for(Display display : dm.getDisplays()) {
+ if(display.getDisplayId() == displayID) {
+ currentDisplay = display;
+ break;
+ }
+ }
+
+ if(currentDisplay == null)
+ return new DisplayInfo(0, 0, 0);
DisplayMetrics metrics = new DisplayMetrics();
- disp.getMetrics(metrics);
+ currentDisplay.getMetrics(metrics);
DisplayMetrics realMetrics = new DisplayMetrics();
- disp.getRealMetrics(realMetrics);
+ currentDisplay.getRealMetrics(realMetrics);
- DisplayInfo display = new DisplayInfo(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
+ DisplayInfo info = 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;
+ info.width = realMetrics.widthPixels;
+ info.height = realMetrics.heightPixels;
}
- return display;
+ return info;
}
+ // Workaround for incorrect display size on devices with notches in landscape mode
+ if(fromTaskbar && context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
+ return info;
+
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);
+ info.width = realMetrics.widthPixels;
+ info.height = realMetrics.heightPixels - getNavbarHeight(context);
}
if(!sameWidth && sameHeight) {
- display.width = realMetrics.widthPixels - getNavbarHeight(context);
- display.height = realMetrics.heightPixels;
+ info.width = realMetrics.widthPixels - getNavbarHeight(context);
+ info.height = realMetrics.heightPixels;
}
- return display;
+ return info;
+ }
+
+ private static int getDisplayID() {
+ LauncherHelper helper = LauncherHelper.getInstance();
+
+ if(helper.isOnSecondaryHomeScreen())
+ return helper.getSecondaryDisplayId();
+ else
+ return Display.DEFAULT_DISPLAY;
}
public static void pinAppShortcut(Context context) {
mShortcutManager.requestPinShortcut(pinShortcutInfo, null);
} else
- showToastLong(context, R.string.pin_shortcut_not_supported);
+ showToastLong(context, R.string.tb_pin_shortcut_not_supported);
} else {
- Intent intent = getShortcutIntent(context);
+ Intent intent = ShortcutUtils.getShortcutIntent(context);
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
intent.putExtra("duplicate", false);
intent.setPackage(defaultLauncher.activityInfo.packageName);
context.sendBroadcast(intent);
- showToast(context, R.string.shortcut_created);
+ showToast(context, R.string.tb_shortcut_created);
}
}
public static boolean shouldCollapse(Context context, boolean pendingAppLaunch) {
SharedPreferences pref = getSharedPreferences(context);
if(pref.getBoolean("hide_taskbar", true)) {
- if(isOverridingFreeformHack(context))
+ if(!pref.getBoolean("freeform_hack", false)
+ || isOverridingFreeformHack(context, false))
return !LauncherHelper.getInstance().isOnHomeScreen();
else {
FreeformHackHelper helper = FreeformHackHelper.getInstance();
}
public static boolean isOverridingFreeformHack(Context context) {
+ return isOverridingFreeformHack(context, true);
+ }
+
+ public static boolean isOverridingFreeformHack(Context context, boolean checkPref) {
SharedPreferences pref = getSharedPreferences(context);
- return pref.getBoolean("freeform_hack", false)
+ return (!checkPref || pref.getBoolean("freeform_hack", false))
&& ((isChromeOs(context) && pref.getBoolean("chrome_os_context_menu_fix", true))
|| (!isChromeOs(context) && getCurrentApiVersion() >= 28.0f));
}
}
}
- private static float getCurrentApiVersion() {
+ public static float getCurrentApiVersion() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return Float.valueOf(Build.VERSION.SDK_INT + "." + Build.VERSION.PREVIEW_SDK_INT);
else
}
public static String getSecondScreenPackageName(Context context) {
- return getInstalledPackage(context, Arrays.asList(
+ return getInstalledPackage(context,
"com.farmerbb.secondscreen.free",
- "com.farmerbb.secondscreen"));
+ "com.farmerbb.secondscreen");
}
// Returns the name of an installed package from a list of package names, in order of preference
+ private static String getInstalledPackage(Context context, String... packageNames) {
+ return getInstalledPackage(context, Arrays.asList(packageNames));
+ }
+
private static String getInstalledPackage(Context context, List<String> packageNames) {
if(packageNames == null || packageNames.isEmpty())
return null;
}
}
- public static boolean visualFeedbackEnabled(Context context) {
- SharedPreferences pref = getSharedPreferences(context);
- return (getCurrentApiVersion() < 26.0f || getCurrentApiVersion() >= 28.0f)
- && pref.getBoolean("visual_feedback", true);
- }
-
public static void showRecentAppsDialog(Context context) {
showRecentAppsDialog(context, null, null);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !isSystemApp(context)) {
ApplicationInfo applicationInfo = null;
try {
- applicationInfo = context.getPackageManager().getApplicationInfo(BuildConfig.APPLICATION_ID, 0);
+ applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) { /* Gracefully fail */ }
if(applicationInfo != null) {
int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
if(mode != AppOpsManager.MODE_ALLOWED) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.pref_header_recent_apps)
- .setMessage(R.string.enable_recent_apps)
- .setPositiveButton(R.string.action_ok, (dialog, which) -> {
- try {
- context.startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
- showToastLong(context, R.string.usage_stats_message);
-
- finalOnFinish.run();
- } catch (ActivityNotFoundException e) {
- finalOnError.run();
- }
- })
- .setNegativeButton(R.string.action_cancel, (dialog, which) -> finalOnFinish.run());
+ AlertDialog.Builder builder;
+ if(hasAndroidTVSettings(context))
+ builder = buildRecentAppsDialogAndroidTV(context, finalOnError, finalOnFinish);
+ else
+ builder = buildRecentAppsDialogStandard(context, finalOnError, finalOnFinish);
AlertDialog dialog = builder.create();
dialog.show();
return null;
}
+ private static AlertDialog.Builder buildRecentAppsDialogStandard(Context context, Runnable onError, Runnable onFinish) {
+ return new AlertDialog.Builder(context)
+ .setTitle(R.string.tb_pref_header_recent_apps)
+ .setMessage(R.string.tb_enable_recent_apps)
+ .setPositiveButton(R.string.tb_action_ok, (dialog, which) -> {
+ try {
+ context.startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
+ showToastLong(context, R.string.tb_usage_stats_message);
+
+ onFinish.run();
+ } catch (ActivityNotFoundException e) {
+ onError.run();
+ }
+ })
+ .setNegativeButton(R.string.tb_action_cancel, (dialog, which) -> onFinish.run());
+ }
+
+ private static AlertDialog.Builder buildRecentAppsDialogAndroidTV(Context context, Runnable onError, Runnable onFinish) {
+ return new AlertDialog.Builder(context)
+ .setTitle(R.string.tb_pref_header_recent_apps)
+ .setMessage(R.string.tb_enable_recent_apps_alt)
+ .setPositiveButton(R.string.tb_action_open_settings, (dialog, which) -> {
+ try {
+ context.startActivity(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
+ onFinish.run();
+ } catch (ActivityNotFoundException e) {
+ onError.run();
+ }
+ })
+ .setNegativeButton(R.string.tb_action_cancel, (dialog, which) -> onFinish.run());
+ }
+
public static Context wrapContext(Context context) {
SharedPreferences pref = getSharedPreferences(context);
int theme = -1;
switch(pref.getString("theme", "light")) {
case "light":
- theme = R.style.AppTheme;
+ theme = R.style.Taskbar;
break;
case "dark":
- theme = R.style.AppTheme_Dark;
+ theme = R.style.Taskbar_Dark;
break;
}
}
public static boolean isPlayStoreRelease(Context context) {
- return isPlayStoreRelease(context, BuildConfig.APPLICATION_ID);
+ return isPlayStoreRelease(context, context.getPackageName());
}
@SuppressLint("PackageManagerGetSignatures")
public static boolean isPlayStoreRelease(Context context, String packageName) {
- Signature playStoreSignature = new Signature(context.getString(R.string.signature));
+ Signature playStoreSignature = new Signature(context.getString(R.string.tb_signature));
try {
PackageManager pm = context.getPackageManager();
PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
}
public static boolean isExternalAccessDisabled(Context context) {
+ if(isLibrary(context)) return true;
+
SharedPreferences pref = getSharedPreferences(context);
return !pref.getBoolean("tasker_enabled", true);
}
public static boolean enableFreeformModeShortcut(Context context) {
return canEnableFreeform()
- && !U.isOverridingFreeformHack(context)
- && !U.isChromeOs(context);
+ && !isOverridingFreeformHack(context, false)
+ && !isChromeOs(context);
}
public static void startForegroundService(Context context, Intent intent) {
@SuppressWarnings("ResultOfMethodCallIgnored")
public static boolean importCustomStartButtonImage(Context context, Uri uri) {
try {
- File imagesDir = new File(context.getFilesDir(), "images");
+ File imagesDir = new File(context.getFilesDir(), "tb_images");
imagesDir.mkdirs();
File importedFile = new File(imagesDir, "custom_image_new");
}
private static boolean shouldLaunchTouchAbsorber(Context context) {
- return !FreeformHackHelper.getInstance().isTouchAbsorberActive()
- && isOverridingFreeformHack(context)
- && !isChromeOs(context)
- && getCurrentApiVersion() < 29.0f;
+ return isOverridingFreeformHack(context) && !isChromeOs(context) && getCurrentApiVersion() < 29.0f;
}
public static boolean isDesktopIconsEnabled(Context context) {
- return !U.canBootToFreeform(context) && !U.shouldLaunchTouchAbsorber(context);
+ return !canBootToFreeform(context, false) && !shouldLaunchTouchAbsorber(context);
+ }
+
+ public static boolean isSystemTrayEnabled(Context context) {
+ SharedPreferences pref = getSharedPreferences(context);
+
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+ && pref.getBoolean("sys_tray", context.getResources().getBoolean(R.bool.tb_def_sys_tray))
+ && pref.getBoolean("full_length", context.getResources().getBoolean(R.bool.tb_def_full_length))
+ && !getTaskbarPosition(context).contains("vertical");
+ }
+
+ @SuppressWarnings("deprecation")
+ public static boolean isLibrary(Context context) {
+ return !context.getPackageName().equals(BuildConfig.APPLICATION_ID);
+ }
+
+ public static boolean applyDisplayCutoutModeTo(WindowManager.LayoutParams params) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean hasAndroidTVSettings(Context context) {
+ return getInstalledPackage(context, "com.android.tv.settings") != null
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
+ }
+
+ public static void restartApp(Activity activity, boolean shouldFade) {
+ Intent restartIntent = new Intent(activity, MainActivity.class);
+ restartIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ activity.startActivity(restartIntent);
+
+ activity.overridePendingTransition(
+ shouldFade ? android.R.anim.fade_in : 0,
+ shouldFade ? android.R.anim.fade_out : 0
+ );
+
+ System.exit(0);
+ }
+
+ public static boolean isDesktopModeSupported(Context context) {
+ if(isLauncherPermanentlyEnabled(context)
+ || isLibrary(context)
+ || !BuildConfig.DEBUG // TODO remove this line
+ || isChromeOs(context))
+ return false;
+
+ return Build.VERSION.SDK_INT > Build.VERSION_CODES.P
+ && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
+ }
+
+ public static boolean isDesktopModeActive(Context context) {
+ if(!isDesktopModeSupported(context)) return false;
+
+ boolean desktopModePrefEnabled;
+
+ try {
+ desktopModePrefEnabled = Settings.Global.getInt(context.getContentResolver(), "force_desktop_mode_on_external_displays") == 1;
+ } catch (Settings.SettingNotFoundException e) {
+ desktopModePrefEnabled = false;
+ }
+
+ return desktopModePrefEnabled && getExternalDisplayID(context) != Display.DEFAULT_DISPLAY;
+ }
+
+ public static boolean shouldStartDesktopMode(Context context) {
+ SharedPreferences pref = getSharedPreferences(context);
+
+ return isDesktopModeSupported(context)
+ && pref.getBoolean("desktop_mode", false)
+ && !pref.getBoolean("launcher", false);
+ }
+
+ // TODO remove this in favor of the existing getDisplayID method?
+ public static int getExternalDisplayID(Context context) {
+ DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+ Display[] displays = dm.getDisplays();
+
+ return displays[displays.length - 1].getDisplayId();
+ }
+
+ @SuppressLint("PrivateApi")
+ private static Object getWindowManagerService() throws Exception {
+ return Class.forName("android.view.WindowManagerGlobal")
+ .getMethod("getWindowManagerService")
+ .invoke(null);
+ }
+
+ @SuppressLint("PrivateApi")
+ private static void setDensity(int displayID, String value) throws Exception {
+ // From android.os.UserHandle
+ final int USER_CURRENT_OR_SELF = -3;
+
+ if(value.equals("reset")) {
+ Class.forName("android.view.IWindowManager")
+ .getMethod("clearForcedDisplayDensityForUser", int.class, int.class)
+ .invoke(getWindowManagerService(), displayID, USER_CURRENT_OR_SELF);
+ } else {
+ int density = Integer.parseInt(value);
+
+ Class.forName("android.view.IWindowManager")
+ .getMethod("setForcedDisplayDensityForUser", int.class, int.class, int.class)
+ .invoke(getWindowManagerService(), displayID, density, USER_CURRENT_OR_SELF);
+ }
+ }
+
+ @SuppressLint("PrivateApi")
+ private static void setOverscan(int displayID, int value) throws Exception {
+ Class.forName("android.view.IWindowManager")
+ .getMethod("setOverscan", int.class, int.class, int.class, int.class, int.class)
+ .invoke(getWindowManagerService(), displayID, 0, 0, 0, value);
+ }
+
+ public static void registerReceiver(Context context, BroadcastReceiver receiver, String... actions) {
+ unregisterReceiver(context, receiver);
+
+ IntentFilter intentFilter = new IntentFilter();
+ for(String action : actions) {
+ intentFilter.addAction(action);
+ }
+
+ LocalBroadcastManager.getInstance(context).registerReceiver(receiver, intentFilter);
+ }
+
+ public static void unregisterReceiver(Context context, BroadcastReceiver receiver) {
+ LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
+ }
+
+ public static void sendBroadcast(Context context, String action) {
+ sendBroadcast(context, new Intent(action));
+ }
+
+ public static void sendBroadcast(Context context, Intent intent) {
+ LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static void setComponentEnabled(Context context, Class clazz, boolean enabled) {
+ ComponentName component = new ComponentName(context, clazz);
+ context.getPackageManager().setComponentEnabledSetting(component,
+ enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
}
}