OSDN Git Service

Don't attempt to check for updates if on a debug build
[android-x86/packages-apps-Taskbar.git] / app / src / main / java / com / farmerbb / taskbar / util / U.java
1 /* Copyright 2016 Braden Farmer
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 package com.farmerbb.taskbar.util;
17
18 import android.annotation.TargetApi;
19 import android.app.ActivityManager;
20 import android.app.ActivityOptions;
21 import android.app.AlertDialog;
22 import android.app.Service;
23 import android.app.admin.DevicePolicyManager;
24 import android.content.ActivityNotFoundException;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.SharedPreferences;
29 import android.content.pm.ActivityInfo;
30 import android.content.pm.LauncherActivityInfo;
31 import android.content.pm.LauncherApps;
32 import android.content.pm.PackageManager;
33 import android.content.pm.ResolveInfo;
34 import android.content.pm.ShortcutInfo;
35 import android.content.res.Configuration;
36 import android.graphics.Rect;
37 import android.graphics.drawable.BitmapDrawable;
38 import android.hardware.display.DisplayManager;
39 import android.net.Uri;
40 import android.os.Build;
41 import android.os.Bundle;
42 import android.os.Handler;
43 import android.os.Process;
44 import android.os.UserHandle;
45 import android.os.UserManager;
46 import android.provider.Settings;
47 import android.support.v4.content.LocalBroadcastManager;
48 import android.util.DisplayMetrics;
49 import android.view.Display;
50 import android.view.Surface;
51 import android.view.WindowManager;
52 import android.widget.Toast;
53
54 import com.farmerbb.taskbar.BuildConfig;
55 import com.farmerbb.taskbar.R;
56 import com.farmerbb.taskbar.activity.DummyActivity;
57 import com.farmerbb.taskbar.activity.InvisibleActivityFreeform;
58 import com.farmerbb.taskbar.activity.ShortcutActivity;
59 import com.farmerbb.taskbar.activity.StartTaskbarActivity;
60 import com.farmerbb.taskbar.receiver.LockDeviceReceiver;
61 import com.farmerbb.taskbar.service.PowerMenuService;
62
63 import java.util.ArrayList;
64 import java.util.List;
65
66 import moe.banana.support.ToastCompat;
67
68 public class U {
69
70     private U() {}
71
72     private static SharedPreferences pref;
73     private static Integer cachedRotation;
74
75     private static final int FULLSCREEN = 0;
76     private static final int LEFT = -1;
77     private static final int RIGHT = 1;
78
79     public static final int HIDDEN = 0;
80     public static final int TOP_APPS = 1;
81
82     public static SharedPreferences getSharedPreferences(Context context) {
83         if(pref == null) pref = context.getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
84         return pref;
85     }
86
87     @TargetApi(Build.VERSION_CODES.M)
88     public static void showPermissionDialog(final Context context) {
89         AlertDialog.Builder builder = new AlertDialog.Builder(context);
90         builder.setTitle(R.string.permission_dialog_title)
91                 .setMessage(R.string.permission_dialog_message)
92                 .setPositiveButton(R.string.action_grant_permission, (dialog, which) -> {
93                     try {
94                         context.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
95                                 Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
96                     } catch (ActivityNotFoundException e) {
97                         showErrorDialog(context, "SYSTEM_ALERT_WINDOW");
98                     }
99                 });
100
101         AlertDialog dialog = builder.create();
102         dialog.show();
103         dialog.setCancelable(false);
104     }
105
106     public static void showErrorDialog(final Context context, String appopCmd) {
107         AlertDialog.Builder builder = new AlertDialog.Builder(context);
108         builder.setTitle(R.string.error_dialog_title)
109                 .setMessage(context.getString(R.string.error_dialog_message, BuildConfig.APPLICATION_ID, appopCmd))
110                 .setPositiveButton(R.string.action_ok, null);
111
112         AlertDialog dialog = builder.create();
113         dialog.show();
114     }
115
116     public static void lockDevice(Context context) {
117         ComponentName component = new ComponentName(context, LockDeviceReceiver.class);
118         context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
119                 PackageManager.DONT_KILL_APP);
120
121         DevicePolicyManager mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
122         if(mDevicePolicyManager.isAdminActive(component))
123             mDevicePolicyManager.lockNow();
124         else {
125             Intent intent = new Intent(context, DummyActivity.class);
126             intent.putExtra("device_admin", true);
127             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
128             context.startActivity(intent);
129         }
130     }
131
132     public static void showPowerMenu(Context context) {
133         ComponentName component = new ComponentName(context, PowerMenuService.class);
134         context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
135                 PackageManager.DONT_KILL_APP);
136
137         if(isAccessibilityServiceEnabled(context))
138             LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.SHOW_POWER_MENU"));
139         else {
140             Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
141             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
142
143             try {
144                 context.startActivity(intent);
145                 showToastLong(context, R.string.enable_accessibility);
146             } catch (ActivityNotFoundException e) {
147                 showToast(context, R.string.lock_device_not_supported);
148             }
149         }
150     }
151
152     private static boolean isAccessibilityServiceEnabled(Context context) {
153         String accessibilityServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
154         ComponentName component = new ComponentName(context, PowerMenuService.class);
155
156         return accessibilityServices != null
157                 && (accessibilityServices.contains(component.flattenToString())
158                 || accessibilityServices.contains(component.flattenToShortString()));
159     }
160
161     public static void showToast(Context context, int message) {
162         showToast(context, context.getString(message), Toast.LENGTH_SHORT);
163     }
164
165     public static void showToastLong(Context context, int message) {
166         showToast(context, context.getString(message), Toast.LENGTH_LONG);
167     }
168
169     public static void showToast(Context context, String message, int length) {
170         ToastCompat.makeText(context, message, length).show();
171     }
172
173     public static void startShortcut(Context context, String packageName, String componentName, ShortcutInfo shortcut) {
174         launchApp(context,
175                 packageName,
176                 componentName,
177                 0,
178                 null,
179                 false,
180                 false,
181                 shortcut);
182     }
183
184     public static void launchApp(final Context context,
185                                  final String packageName,
186                                  final String componentName,
187                                  final long userId, final String windowSize,
188                                  final boolean launchedFromTaskbar,
189                                  final boolean openInNewWindow) {
190         launchApp(context,
191                 packageName,
192                 componentName,
193                 userId,
194                 windowSize,
195                 launchedFromTaskbar,
196                 openInNewWindow,
197                 null);
198     }
199
200     private static void launchApp(final Context context,
201                                  final String packageName,
202                                  final String componentName,
203                                  final long userId, final String windowSize,
204                                  final boolean launchedFromTaskbar,
205                                  final boolean openInNewWindow,
206                                  final ShortcutInfo shortcut) {
207         boolean shouldDelay = false;
208
209         SharedPreferences pref = getSharedPreferences(context);
210         boolean openInFullscreen = pref.getBoolean("open_in_fullscreen", true);
211         boolean freeformHackActive = openInNewWindow
212                 ? FreeformHackHelper.getInstance().isInFreeformWorkspace()
213                 : (openInFullscreen
214                     ? FreeformHackHelper.getInstance().isInFreeformWorkspace()
215                     : FreeformHackHelper.getInstance().isFreeformHackActive());
216
217         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
218                 && pref.getBoolean("freeform_hack", false)
219                 && !freeformHackActive) {
220             shouldDelay = true;
221
222             new Handler().postDelayed(() -> {
223                 startFreeformHack(context, true, launchedFromTaskbar);
224
225                 new Handler().postDelayed(() -> continueLaunchingApp(context, packageName, componentName, userId,
226                         windowSize, launchedFromTaskbar, openInNewWindow, shortcut), 100);
227             }, launchedFromTaskbar ? 0 : 100);
228         }
229
230         if(!FreeformHackHelper.getInstance().isFreeformHackActive()) {
231             if(!shouldDelay)
232                 continueLaunchingApp(context, packageName, componentName, userId,
233                         windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
234         } else if(FreeformHackHelper.getInstance().isInFreeformWorkspace() || !openInFullscreen)
235             continueLaunchingApp(context, packageName, componentName, userId,
236                     windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
237     }
238
239     @SuppressWarnings("deprecation")
240     @TargetApi(Build.VERSION_CODES.N)
241     public static void startFreeformHack(Context context, boolean checkMultiWindow, boolean launchedFromTaskbar) {
242         Intent freeformHackIntent = new Intent(context, InvisibleActivityFreeform.class);
243         freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
244
245         if(checkMultiWindow)
246             freeformHackIntent.putExtra("check_multiwindow", true);
247
248         if(launchedFromTaskbar) {
249             SharedPreferences pref = getSharedPreferences(context);
250             if(pref.getBoolean("disable_animations", false))
251                 freeformHackIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
252         }
253
254         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
255         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
256         try {
257             context.startActivity(freeformHackIntent, ActivityOptions.makeBasic().setLaunchBounds(new Rect(
258                     display.getWidth(),
259                     display.getHeight(),
260                     display.getWidth() + 1,
261                     display.getHeight() + 1
262             )).toBundle());
263         } catch (IllegalArgumentException e) { /* Gracefully fail */ }
264     }
265
266     @TargetApi(Build.VERSION_CODES.N)
267     private static void continueLaunchingApp(Context context,
268                                              String packageName,
269                                              String componentName,
270                                              long userId,
271                                              String windowSize,
272                                              boolean launchedFromTaskbar,
273                                              boolean openInNewWindow,
274                                              ShortcutInfo shortcut) {
275         SharedPreferences pref = getSharedPreferences(context);
276         Intent intent = new Intent();
277         intent.setComponent(ComponentName.unflattenFromString(componentName));
278         intent.setAction(Intent.ACTION_MAIN);
279         intent.addCategory(Intent.CATEGORY_LAUNCHER);
280         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
281         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
282
283         if(FreeformHackHelper.getInstance().isInFreeformWorkspace())
284             intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
285
286         if(launchedFromTaskbar) {
287             if(pref.getBoolean("disable_animations", false))
288                 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
289         }
290
291         if(openInNewWindow || pref.getBoolean("force_new_window", false)) {
292             intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
293
294             ActivityInfo activityInfo = intent.resolveActivityInfo(context.getPackageManager(), 0);
295             if(activityInfo != null) {
296                 switch(activityInfo.launchMode) {
297                     case ActivityInfo.LAUNCH_SINGLE_TASK:
298                     case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
299                         intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
300                         break;
301                 }
302             }
303         }
304
305         if(windowSize == null) {
306             if(pref.getBoolean("save_window_sizes", true))
307                 windowSize = SavedWindowSizes.getInstance(context).getWindowSize(context, packageName);
308             else
309                 windowSize = pref.getString("window_size", "standard");
310         }
311
312         if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !pref.getBoolean("freeform_hack", false)) {
313             if(shortcut == null) {
314                 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
315                 if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
316                     try {
317                         context.startActivity(intent, null);
318                     } catch (ActivityNotFoundException e) {
319                         launchAndroidForWork(context, intent.getComponent(), null, userId);
320                     } catch (IllegalArgumentException e) { /* Gracefully fail */ }
321                 } else
322                     launchAndroidForWork(context, intent.getComponent(), null, userId);
323             } else
324                 launchShortcut(context, shortcut, null);
325         } else switch(windowSize) {
326             case "standard":
327                 if(FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
328                     if(shortcut == null) {
329                         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
330                         if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
331                             try {
332                                 context.startActivity(intent);
333                             } catch (ActivityNotFoundException e) {
334                                 launchAndroidForWork(context, intent.getComponent(), null, userId);
335                             } catch (IllegalArgumentException e) { /* Gracefully fail */ }
336                         } else
337                             launchAndroidForWork(context, intent.getComponent(), null, userId);
338                     } else
339                         launchShortcut(context, shortcut, null);
340                 } else
341                     launchMode1(context, intent, 1, userId, shortcut);
342                 break;
343             case "large":
344                 launchMode1(context, intent, 2, userId, shortcut);
345                 break;
346             case "fullscreen":
347                 launchMode2(context, intent, FULLSCREEN, userId, shortcut);
348                 break;
349             case "half_left":
350                 launchMode2(context, intent, LEFT, userId, shortcut);
351                 break;
352             case "half_right":
353                 launchMode2(context, intent, RIGHT, userId, shortcut);
354                 break;
355             case "phone_size":
356                 launchMode3(context, intent, userId, shortcut);
357                 break;
358         }
359
360         if(pref.getBoolean("hide_taskbar", true) && !FreeformHackHelper.getInstance().isInFreeformWorkspace())
361             LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
362         else
363             LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
364     }
365     
366     @SuppressWarnings("deprecation")
367     @TargetApi(Build.VERSION_CODES.N)
368     private static void launchMode1(Context context, Intent intent, int factor, long userId, ShortcutInfo shortcut) {
369         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
370         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
371
372         int width1 = display.getWidth() / (4 * factor);
373         int width2 = display.getWidth() - width1;
374         int height1 = display.getHeight() / (4 * factor);
375         int height2 = display.getHeight() - height1;
376
377         Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
378                 width1,
379                 height1,
380                 width2,
381                 height2
382         )).toBundle();
383
384         if(shortcut == null) {
385             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
386             if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
387                 try {
388                     context.startActivity(intent, bundle);
389                 } catch (ActivityNotFoundException e) {
390                     launchAndroidForWork(context, intent.getComponent(), bundle, userId);
391                 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
392             } else
393                 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
394         } else
395             launchShortcut(context, shortcut, bundle);
396     }
397
398     @SuppressWarnings("deprecation")
399     @TargetApi(Build.VERSION_CODES.N)
400     private static void launchMode2(Context context, Intent intent, int launchType, long userId, ShortcutInfo shortcut) {
401         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
402         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
403
404         int statusBarHeight = getStatusBarHeight(context);
405         String position = getTaskbarPosition(context);
406
407         boolean isPortrait = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
408         boolean isLandscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
409
410         int left = launchType == RIGHT && isLandscape
411                 ? display.getWidth() / 2
412                 : 0;
413
414         int top = launchType == RIGHT && isPortrait
415                 ? display.getHeight() / 2
416                 : statusBarHeight;
417
418         int right = launchType == LEFT && isLandscape
419                 ? display.getWidth() / 2
420                 : display.getWidth();
421
422         int bottom = launchType == LEFT && isPortrait
423                 ? display.getHeight() / 2
424                 : display.getHeight();
425
426         int iconSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
427
428         if(position.contains("vertical_left")) {
429             if(launchType != RIGHT || isPortrait) left = left + iconSize;
430         } else if(position.contains("vertical_right")) {
431             if(launchType != LEFT || isPortrait) right = right - iconSize;
432         } else if(position.contains("bottom")) {
433             if(isLandscape || (launchType != LEFT && isPortrait))
434                 bottom = bottom - iconSize;
435         } else if(isLandscape || (launchType != RIGHT && isPortrait))
436             top = top + iconSize;
437
438         Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
439                 left,
440                 top,
441                 right,
442                 bottom
443         )).toBundle();
444
445         if(shortcut == null) {
446             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
447             if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
448                 try {
449                     context.startActivity(intent, bundle);
450                 } catch (ActivityNotFoundException e) {
451                     launchAndroidForWork(context, intent.getComponent(), bundle, userId);
452                 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
453             } else
454                 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
455         } else
456             launchShortcut(context, shortcut, bundle);
457     }
458
459     @SuppressWarnings("deprecation")
460     @TargetApi(Build.VERSION_CODES.N)
461     private static void launchMode3(Context context, Intent intent, long userId, ShortcutInfo shortcut) {
462         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
463         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
464
465         int width1 = display.getWidth() / 2;
466         int width2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_width) / 2;
467         int height1 = display.getHeight() / 2;
468         int height2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_height) / 2;
469
470         Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
471                 width1 - width2,
472                 height1 - height2,
473                 width1 + width2,
474                 height1 + height2
475         )).toBundle();
476
477         if(shortcut == null) {
478             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
479             if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
480                 try {
481                     context.startActivity(intent, bundle);
482                 } catch (ActivityNotFoundException e) {
483                     launchAndroidForWork(context, intent.getComponent(), bundle, userId);
484                 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
485             } else
486                 launchAndroidForWork(context, intent.getComponent(), bundle, userId);
487         } else
488             launchShortcut(context, shortcut, bundle);
489     }
490
491     private static void launchAndroidForWork(Context context, ComponentName componentName, Bundle bundle, long userId) {
492         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
493         LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
494
495         try {
496             launcherApps.startMainActivity(componentName, userManager.getUserForSerialNumber(userId), null, bundle);
497         } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
498     }
499
500     @TargetApi(Build.VERSION_CODES.N_MR1)
501     private static void launchShortcut(Context context, ShortcutInfo shortcut, Bundle bundle) {
502         LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
503
504         try {
505             launcherApps.startShortcut(shortcut, null, bundle);
506         } catch (ActivityNotFoundException | NullPointerException e) { /* Gracefully fail */ }
507     }
508
509     public static void launchAppFullscreen(Context context, Intent intent) {
510         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
511         long userId = userManager.getSerialNumberForUser(Process.myUserHandle());
512
513         launchMode2(context, intent, FULLSCREEN, userId, null);
514     }
515
516     public static void checkForUpdates(Context context) {
517         if(!BuildConfig.DEBUG) {
518             String url;
519             try {
520                 context.getPackageManager().getPackageInfo("com.android.vending", 0);
521                 url = "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID;
522             } catch (PackageManager.NameNotFoundException e) {
523                 url = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.BASE_APPLICATION_ID;
524             }
525
526             Intent intent = new Intent(Intent.ACTION_VIEW);
527             intent.setData(Uri.parse(url));
528             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
529
530             try {
531                 context.startActivity(intent);
532             } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
533         } else
534             showToast(context, R.string.debug_build);
535     }
536
537     public static boolean launcherIsDefault(Context context) {
538         Intent homeIntent = new Intent(Intent.ACTION_MAIN);
539         homeIntent.addCategory(Intent.CATEGORY_HOME);
540         ResolveInfo defaultLauncher = context.getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
541
542         return defaultLauncher.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID);
543     }
544
545     public static void setCachedRotation(int cachedRotation) {
546         U.cachedRotation = cachedRotation;
547     }
548
549     public static String getTaskbarPosition(Context context) {
550         SharedPreferences pref = getSharedPreferences(context);
551         String position = pref.getString("position", "bottom_left");
552
553         if(pref.getBoolean("anchor", false)) {
554             WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
555             int rotation = cachedRotation != null ? cachedRotation : windowManager.getDefaultDisplay().getRotation();
556
557             switch(position) {
558                 case "bottom_left":
559                     switch(rotation) {
560                         case Surface.ROTATION_0:
561                             return "bottom_left";
562                         case Surface.ROTATION_90:
563                             return "bottom_vertical_right";
564                         case Surface.ROTATION_180:
565                             return "top_right";
566                         case Surface.ROTATION_270:
567                             return "top_vertical_left";
568                     }
569                     break;
570                 case "bottom_vertical_left":
571                     switch(rotation) {
572                         case Surface.ROTATION_0:
573                             return "bottom_vertical_left";
574                         case Surface.ROTATION_90:
575                             return "bottom_right";
576                         case Surface.ROTATION_180:
577                             return "top_vertical_right";
578                         case Surface.ROTATION_270:
579                             return "top_left";
580                     }
581                     break;
582                 case "bottom_right":
583                     switch(rotation) {
584                         case Surface.ROTATION_0:
585                             return "bottom_right";
586                         case Surface.ROTATION_90:
587                             return "top_vertical_right";
588                         case Surface.ROTATION_180:
589                             return "top_left";
590                         case Surface.ROTATION_270:
591                             return "bottom_vertical_left";
592                     }
593                     break;
594                 case "bottom_vertical_right":
595                     switch(rotation) {
596                         case Surface.ROTATION_0:
597                             return "bottom_vertical_right";
598                         case Surface.ROTATION_90:
599                             return "top_right";
600                         case Surface.ROTATION_180:
601                             return "top_vertical_left";
602                         case Surface.ROTATION_270:
603                             return "bottom_left";
604                     }
605                     break;
606                 case "top_left":
607                     switch(rotation) {
608                         case Surface.ROTATION_0:
609                             return "top_left";
610                         case Surface.ROTATION_90:
611                             return "bottom_vertical_left";
612                         case Surface.ROTATION_180:
613                             return "bottom_right";
614                         case Surface.ROTATION_270:
615                             return "top_vertical_right";
616                     }
617                     break;
618                 case "top_vertical_left":
619                     switch(rotation) {
620                         case Surface.ROTATION_0:
621                             return "top_vertical_left";
622                         case Surface.ROTATION_90:
623                             return "bottom_left";
624                         case Surface.ROTATION_180:
625                             return "bottom_vertical_right";
626                         case Surface.ROTATION_270:
627                             return "top_right";
628                     }
629                     break;
630                 case "top_right":
631                     switch(rotation) {
632                         case Surface.ROTATION_0:
633                             return "top_right";
634                         case Surface.ROTATION_90:
635                             return "top_vertical_left";
636                         case Surface.ROTATION_180:
637                             return "bottom_left";
638                         case Surface.ROTATION_270:
639                             return "bottom_vertical_right";
640                     }
641                     break;
642                 case "top_vertical_right":
643                     switch(rotation) {
644                         case Surface.ROTATION_0:
645                             return "top_vertical_right";
646                         case Surface.ROTATION_90:
647                             return "top_left";
648                         case Surface.ROTATION_180:
649                             return "bottom_vertical_left";
650                         case Surface.ROTATION_270:
651                             return "bottom_right";
652                     }
653                     break;
654             }
655         }
656
657         return position;
658     }
659
660     private static int getMaxNumOfColumns(Context context) {
661         SharedPreferences pref = getSharedPreferences(context);
662         DisplayMetrics metrics = context.getResources().getDisplayMetrics();
663         float baseTaskbarSize = context.getResources().getDimension(pref.getBoolean("dashboard", false) ? R.dimen.base_taskbar_size_dashboard : R.dimen.base_taskbar_size) / metrics.density;
664         int numOfColumns = 0;
665
666         float maxScreenSize = getTaskbarPosition(context).contains("vertical")
667                 ? (metrics.heightPixels - getStatusBarHeight(context)) / metrics.density
668                 : metrics.widthPixels / metrics.density;
669
670         float iconSize = context.getResources().getDimension(R.dimen.icon_size) / metrics.density;
671
672         int userMaxNumOfColumns = Integer.valueOf(pref.getString("max_num_of_recents", "10"));
673
674         while(baseTaskbarSize + iconSize < maxScreenSize
675                 && numOfColumns < userMaxNumOfColumns) {
676             baseTaskbarSize = baseTaskbarSize + iconSize;
677             numOfColumns++;
678         }
679
680         return numOfColumns;
681     }
682
683     public static int getMaxNumOfEntries(Context context) {
684         SharedPreferences pref = getSharedPreferences(context);
685         return pref.getBoolean("disable_scrolling_list", false)
686                 ? getMaxNumOfColumns(context)
687                 : Integer.valueOf(pref.getString("max_num_of_recents", "10"));
688     }
689
690     public static int getStatusBarHeight(Context context) {
691         int statusBarHeight = 0;
692         int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
693         if(resourceId > 0)
694             statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
695
696         return statusBarHeight;
697     }
698
699     public static void refreshPinnedIcons(Context context) {
700         IconCache.getInstance(context).clearCache();
701
702         PinnedBlockedApps pba = PinnedBlockedApps.getInstance(context);
703         List<AppEntry> pinnedAppsList = new ArrayList<>(pba.getPinnedApps());
704         List<AppEntry> blockedAppsList = new ArrayList<>(pba.getBlockedApps());
705         PackageManager pm = context.getPackageManager();
706
707         pba.clear(context);
708
709         for(AppEntry entry : pinnedAppsList) {
710             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
711             LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
712
713             final List<UserHandle> userHandles = userManager.getUserProfiles();
714             LauncherActivityInfo appInfo = null;
715
716             for(UserHandle handle : userHandles) {
717                 List<LauncherActivityInfo> list = launcherApps.getActivityList(entry.getPackageName(), handle);
718                 if(!list.isEmpty()) {
719                     // Google App workaround
720                     if(!entry.getPackageName().equals("com.google.android.googlequicksearchbox"))
721                         appInfo = list.get(0);
722                     else {
723                         boolean added = false;
724                         for(LauncherActivityInfo info : list) {
725                             if(info.getName().equals("com.google.android.googlequicksearchbox.SearchActivity")) {
726                                 appInfo = info;
727                                 added = true;
728                             }
729                         }
730
731                         if(!added) appInfo = list.get(0);
732                     }
733
734                     break;
735                 }
736             }
737
738             if(appInfo != null) {
739                 AppEntry newEntry = new AppEntry(
740                         entry.getPackageName(),
741                         entry.getComponentName(),
742                         entry.getLabel(),
743                         IconCache.getInstance(context).getIcon(context, pm, appInfo),
744                         true);
745
746                 newEntry.setUserId(entry.getUserId(context));
747                 pba.addPinnedApp(context, newEntry);
748             }
749         }
750
751         for(AppEntry entry : blockedAppsList) {
752             pba.addBlockedApp(context, entry);
753         }
754     }
755
756     public static Intent getShortcutIntent(Context context) {
757         Intent shortcutIntent = new Intent(context, ShortcutActivity.class);
758         shortcutIntent.setAction(Intent.ACTION_MAIN);
759         shortcutIntent.putExtra("is_launching_shortcut", true);
760
761         BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_freeform_mode);
762
763         Intent intent = new Intent();
764         intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
765         if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
766         intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.pref_header_freeform));
767
768         return intent;
769     }
770
771     public static Intent getStartStopIntent(Context context) {
772         Intent shortcutIntent = new Intent(context, StartTaskbarActivity.class);
773         shortcutIntent.setAction(Intent.ACTION_MAIN);
774         shortcutIntent.putExtra("is_launching_shortcut", true);
775
776         BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_launcher);
777
778         Intent intent = new Intent();
779         intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
780         if(drawable != null) intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, drawable.getBitmap());
781         intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.start_taskbar));
782
783         return intent;
784     }
785
786     public static boolean hasFreeformSupport(Context context) {
787         return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
788                 && (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT)
789                 || Settings.Global.getInt(context.getContentResolver(), "enable_freeform_support", -1) == 1
790                 || Settings.Global.getInt(context.getContentResolver(), "force_resizable_activities", -1) == 1);
791     }
792
793     public static boolean isServiceRunning(Context context, Class<? extends Service> cls) {
794         ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
795         for(ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
796             if(cls.getName().equals(service.service.getClassName()))
797                 return true;
798         }
799
800         return false;
801     }
802
803     public static int getBackgroundTint(Context context) {
804         SharedPreferences pref = getSharedPreferences(context);
805
806         // Import old background tint preference
807         if(pref.contains("show_background")) {
808             SharedPreferences.Editor editor = pref.edit();
809
810             if(!pref.getBoolean("show_background", true))
811                 editor.putInt("background_tint", 0).apply();
812
813             editor.remove("show_background");
814             editor.apply();
815         }
816
817         return pref.getInt("background_tint", context.getResources().getInteger(R.integer.translucent_gray));
818     }
819
820     public static int getAccentColor(Context context) {
821         SharedPreferences pref = getSharedPreferences(context);
822         return pref.getInt("accent_color", context.getResources().getInteger(R.integer.translucent_white));
823     }
824
825     @TargetApi(Build.VERSION_CODES.M)
826     public static boolean canDrawOverlays(Context context) {
827         return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context);
828     }
829 }