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.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;
}
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);
}
}
- 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);
}
Bundle bundle = getActivityOptionsBundle(context, type, windowSize);
- if(shortcut == null) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
- try {
- startActivity(context, intent, bundle);
- } catch (ActivityNotFoundException e) {
+ 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);
- } catch (IllegalArgumentException | SecurityException e) { /* Gracefully fail */ }
} else
- launchAndroidForWork(context, intent.getComponent(), bundle, userId);
- } else
- launchShortcut(context, shortcut, bundle);
+ launchShortcut(context, shortcut, bundle);
+ });
if(shouldCollapse(context, true))
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
}
- private static Bundle launchStandard(Context context, ApplicationType type) {
- return canEnableFreeform() ? getActivityOptions(context, type).toBundle() : null;
- }
-
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
private static Bundle launchMode1(Context context, ApplicationType type) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ 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;
return getActivityOptions(context, type).setLaunchBounds(new Rect(
width1,
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
private static Bundle launchMode2(Context context, int launchType, ApplicationType type) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ DisplayInfo display = getDisplayInfo(context);
int statusBarHeight = getStatusBarHeight(context);
String position = getTaskbarPosition(context);
int left = 0;
int top = statusBarHeight;
- int right = metrics.widthPixels;
- int bottom = metrics.heightPixels;
+ int right = display.width;
+ int bottom = display.height;
int iconSize = isOverridingFreeformHack(context) && !LauncherHelper.getInstance().isOnHomeScreen()
? 0
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.N)
private static Bundle launchMode3(Context context, ApplicationType type) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ 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;
return getActivityOptions(context, type).setLaunchBounds(new Rect(
}
}
- private static void startActivity(Context context, Intent intent, Bundle bundle) {
+ private static void prepareToStartActivity(Context context, Runnable runnable) {
boolean shouldLaunchTouchAbsorber =
!FreeformHackHelper.getInstance().isTouchAbsorberActive()
&& isOverridingFreeformHack(context)
&& !isChromeOs(context);
if(!shouldLaunchTouchAbsorber) {
- context.startActivity(intent, bundle);
+ runnable.run();
return;
}
startTouchAbsorberActivity(context);
- new Handler().postDelayed(() -> context.startActivity(intent, bundle), 100);
+ new Handler().postDelayed(runnable, 100);
}
public static void startActivityMaximized(Context context, Intent intent) {
Bundle bundle = launchMode2(context, MAXIMIZED, ApplicationType.CONTEXT_MENU);
- startActivity(context, intent, bundle);
+ prepareToStartActivity(context, () -> context.startActivity(intent, bundle));
}
@TargetApi(Build.VERSION_CODES.N)
public static void startActivityLowerRight(Context context, Intent intent) {
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ 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
+ 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);
- DisplayMetrics metrics = getRealDisplayMetrics(context);
+ DisplayInfo display = getDisplayInfo(context);
int left = 0;
int top = 0;
- int right = metrics.widthPixels;
- int bottom = metrics.heightPixels;
+ int right = display.width;
+ int bottom = display.height;
int iconSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
} 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) {
&& Settings.Global.getInt(context.getContentResolver(), "force_resizable_activities", 0) != 0));
}
- public static boolean hasPartialFreeformSupport() {
+ 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 isServiceRunning(context, cls.getName());
}
}
private static Bundle getActivityOptionsBundle(Context context, ApplicationType type, String windowSize) {
- if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
- return null;
-
SharedPreferences pref = getSharedPreferences(context);
- if(!canEnableFreeform()
- || !pref.getBoolean("freeform_hack", false)
- || windowSize.equals("standard"))
- return launchStandard(context, type);
+ if(!canEnableFreeform() || !pref.getBoolean("freeform_hack", false))
+ return null;
switch(windowSize) {
case "large":
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;
+ }
+
+ 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);
+ }
- return metrics;
+ if(!sameWidth && sameHeight) {
+ display.width = realMetrics.widthPixels - getNavbarHeight(context);
+ display.height = realMetrics.heightPixels;
+ }
+
+ return display;
}
public static void pinAppShortcut(Context context) {
|| (!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);
- }
-
public static boolean isPlayStoreInstalled(Context context) {
try {
context.getPackageManager().getPackageInfo("com.android.vending", 0);
}
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) {
? 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;
+ }
}