OSDN Git Service

Use reflection to set stack id when launching apps + Replace "Open windows in fullscr...
authorBraden Farmer <farmerbb@gmail.com>
Wed, 8 Mar 2017 05:20:36 +0000 (22:20 -0700)
committerBraden Farmer <farmerbb@gmail.com>
Wed, 8 Mar 2017 05:20:36 +0000 (22:20 -0700)
app/src/main/java/com/farmerbb/taskbar/activity/ContextMenuActivity.java
app/src/main/java/com/farmerbb/taskbar/fragment/FreeformModeFragment.java
app/src/main/java/com/farmerbb/taskbar/service/StartMenuService.java
app/src/main/java/com/farmerbb/taskbar/util/U.java
app/src/main/res/values-de/strings.xml
app/src/main/res/values-ja/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/pref_freeform_hack.xml

index ee7d11c..ea70299 100644 (file)
@@ -253,7 +253,7 @@ public class ContextMenuActivity extends PreferenceActivity implements Preferenc
             SharedPreferences pref = U.getSharedPreferences(this);
             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
                     && pref.getBoolean("freeform_hack", false)
-                    && (FreeformHackHelper.getInstance().isFreeformHackActive() || isInMultiWindowMode())) {
+                    && !U.isGame(this, packageName)) {
                 addPreferencesFromResource(R.xml.pref_context_menu_show_window_sizes);
                 findPreference("show_window_sizes").setOnPreferenceClickListener(this);
             }
index c638c53..3fda5be 100644 (file)
@@ -54,7 +54,7 @@ public class FreeformModeFragment extends SettingsFragment implements Preference
 
             SharedPreferences pref = U.getSharedPreferences(getActivity());
             boolean freeformHackEnabled = pref.getBoolean("freeform_hack", false);
-            findPreference("open_in_fullscreen").setEnabled(freeformHackEnabled);
+            findPreference("launch_games_fullscreen").setEnabled(freeformHackEnabled);
             findPreference("save_window_sizes").setEnabled(freeformHackEnabled);
             findPreference("window_size").setEnabled(freeformHackEnabled);
             findPreference("add_shortcut").setEnabled(freeformHackEnabled);
@@ -79,7 +79,7 @@ public class FreeformModeFragment extends SettingsFragment implements Preference
 
             ((CheckBoxPreference) findPreference("freeform_hack")).setChecked(U.hasFreeformSupport(getActivity()));
 
-            findPreference("open_in_fullscreen").setEnabled(U.hasFreeformSupport(getActivity()));
+            findPreference("launch_games_fullscreen").setEnabled(U.hasFreeformSupport(getActivity()));
             findPreference("save_window_sizes").setEnabled(U.hasFreeformSupport(getActivity()));
             findPreference("window_size").setEnabled(U.hasFreeformSupport(getActivity()));
             findPreference("add_shortcut").setEnabled(U.hasFreeformSupport(getActivity()));
@@ -139,7 +139,7 @@ public class FreeformModeFragment extends SettingsFragment implements Preference
                     LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(new Intent("com.farmerbb.taskbar.FORCE_TASKBAR_RESTART"));
                 }
 
-                findPreference("open_in_fullscreen").setEnabled(((CheckBoxPreference) p).isChecked());
+                findPreference("launch_games_fullscreen").setEnabled(((CheckBoxPreference) p).isChecked());
                 findPreference("save_window_sizes").setEnabled(((CheckBoxPreference) p).isChecked());
                 findPreference("window_size").setEnabled(((CheckBoxPreference) p).isChecked());
                 findPreference("add_shortcut").setEnabled(((CheckBoxPreference) p).isChecked());
index f574b25..4f37749 100644 (file)
@@ -584,8 +584,7 @@ public class StartMenuService extends Service {
             boolean inFreeformMode = FreeformHackHelper.getInstance().isInFreeformWorkspace();
 
             if(!onHomeScreen || inFreeformMode) {
-                SharedPreferences pref = U.getSharedPreferences(this);
-                boolean forceFreeformMode = FreeformHackHelper.getInstance().isFreeformHackActive() && !pref.getBoolean("open_in_fullscreen", true);
+                boolean forceFreeformMode = FreeformHackHelper.getInstance().isFreeformHackActive();
 
                 Class clazz = inFreeformMode && !shouldShowSearchBox ? InvisibleActivityAlt.class : InvisibleActivity.class;
                 Intent intent = new Intent(this, clazz);
index 43b62fc..20aeaef 100644 (file)
@@ -27,6 +27,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
@@ -60,6 +61,7 @@ import com.farmerbb.taskbar.activity.StartTaskbarActivity;
 import com.farmerbb.taskbar.receiver.LockDeviceReceiver;
 import com.farmerbb.taskbar.service.PowerMenuService;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -79,6 +81,10 @@ public class U {
     public static final int HIDDEN = 0;
     public static final int TOP_APPS = 1;
 
+    // From android.app.ActivityManager.StackId
+    private static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
+    private static final int FREEFORM_WORKSPACE_STACK_ID = 2;
+
     public static SharedPreferences getSharedPreferences(Context context) {
         if(pref == null) pref = context.getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
         return pref;
@@ -218,12 +224,9 @@ public class U {
 
         SharedPreferences pref = getSharedPreferences(context);
         FreeformHackHelper helper = FreeformHackHelper.getInstance();
-        boolean openInFullscreen = pref.getBoolean("open_in_fullscreen", true);
         boolean freeformHackActive = openInNewWindow
                 ? helper.isInFreeformWorkspace()
-                : (openInFullscreen
-                    ? helper.isInFreeformWorkspace()
-                    : helper.isFreeformHackActive());
+                : helper.isFreeformHackActive();
 
         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
                 && pref.getBoolean("freeform_hack", false)
@@ -242,7 +245,7 @@ public class U {
             if(!shouldDelay)
                 continueLaunchingApp(context, packageName, componentName, userId,
                         windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
-        } else if(helper.isInFreeformWorkspace() || !openInFullscreen)
+        } else
             continueLaunchingApp(context, packageName, componentName, userId,
                     windowSize, launchedFromTaskbar, openInNewWindow, shortcut);
     }
@@ -327,35 +330,36 @@ public class U {
         } else switch(windowSize) {
             case "standard":
                 if(FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
+                    Bundle bundle = getActivityOptions(isGame(context, packageName)).toBundle();
                     if(shortcut == null) {
                         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
                         if(userId == userManager.getSerialNumberForUser(Process.myUserHandle())) {
                             try {
-                                context.startActivity(intent);
+                                context.startActivity(intent, bundle);
                             } catch (ActivityNotFoundException e) {
-                                launchAndroidForWork(context, intent.getComponent(), null, userId);
+                                launchAndroidForWork(context, intent.getComponent(), bundle, userId);
                             } catch (IllegalArgumentException e) { /* Gracefully fail */ }
                         } else
-                            launchAndroidForWork(context, intent.getComponent(), null, userId);
+                            launchAndroidForWork(context, intent.getComponent(), bundle, userId);
                     } else
-                        launchShortcut(context, shortcut, null);
+                        launchShortcut(context, shortcut, bundle);
                 } else
-                    launchMode1(context, intent, 1, userId, shortcut);
+                    launchMode1(context, intent, 1, userId, shortcut, isGame(context, packageName));
                 break;
             case "large":
-                launchMode1(context, intent, 2, userId, shortcut);
+                launchMode1(context, intent, 2, userId, shortcut, isGame(context, packageName));
                 break;
             case "fullscreen":
-                launchMode2(context, intent, FULLSCREEN, userId, shortcut);
+                launchMode2(context, intent, FULLSCREEN, userId, shortcut, isGame(context, packageName));
                 break;
             case "half_left":
-                launchMode2(context, intent, LEFT, userId, shortcut);
+                launchMode2(context, intent, LEFT, userId, shortcut, isGame(context, packageName));
                 break;
             case "half_right":
-                launchMode2(context, intent, RIGHT, userId, shortcut);
+                launchMode2(context, intent, RIGHT, userId, shortcut, isGame(context, packageName));
                 break;
             case "phone_size":
-                launchMode3(context, intent, userId, shortcut);
+                launchMode3(context, intent, userId, shortcut, isGame(context, packageName));
                 break;
         }
 
@@ -367,7 +371,7 @@ public class U {
     
     @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
-    private static void launchMode1(Context context, Intent intent, int factor, long userId, ShortcutInfo shortcut) {
+    private static void launchMode1(Context context, Intent intent, int factor, long userId, ShortcutInfo shortcut, Boolean isGame) {
         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
 
@@ -376,7 +380,7 @@ public class U {
         int height1 = display.getHeight() / (4 * factor);
         int height2 = display.getHeight() - height1;
 
-        Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
+        Bundle bundle = getActivityOptions(isGame).setLaunchBounds(new Rect(
                 width1,
                 height1,
                 width2,
@@ -399,7 +403,7 @@ public class U {
 
     @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
-    private static void launchMode2(Context context, Intent intent, int launchType, long userId, ShortcutInfo shortcut) {
+    private static void launchMode2(Context context, Intent intent, int launchType, long userId, ShortcutInfo shortcut, Boolean isGame) {
         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
 
@@ -437,7 +441,7 @@ public class U {
         } else if(isLandscape || (launchType != RIGHT && isPortrait))
             top = top + iconSize;
 
-        Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
+        Bundle bundle = getActivityOptions(isGame).setLaunchBounds(new Rect(
                 left,
                 top,
                 right,
@@ -460,7 +464,7 @@ public class U {
 
     @SuppressWarnings("deprecation")
     @TargetApi(Build.VERSION_CODES.N)
-    private static void launchMode3(Context context, Intent intent, long userId, ShortcutInfo shortcut) {
+    private static void launchMode3(Context context, Intent intent, long userId, ShortcutInfo shortcut, Boolean isGame) {
         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
 
@@ -469,7 +473,7 @@ public class U {
         int height1 = display.getHeight() / 2;
         int height2 = context.getResources().getDimensionPixelSize(R.dimen.phone_size_height) / 2;
 
-        Bundle bundle = ActivityOptions.makeBasic().setLaunchBounds(new Rect(
+        Bundle bundle = getActivityOptions(isGame).setLaunchBounds(new Rect(
                 width1 - width2,
                 height1 - height2,
                 width1 + width2,
@@ -512,7 +516,7 @@ public class U {
         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         long userId = userManager.getSerialNumberForUser(Process.myUserHandle());
 
-        launchMode2(context, intent, FULLSCREEN, userId, null);
+        launchMode2(context, intent, FULLSCREEN, userId, null, null);
     }
 
     @SuppressWarnings("deprecation")
@@ -521,7 +525,7 @@ public class U {
         DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
         Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
         try {
-            context.startActivity(intent, ActivityOptions.makeBasic().setLaunchBounds(new Rect(
+            context.startActivity(intent, getActivityOptions(false).setLaunchBounds(new Rect(
                     display.getWidth(),
                     display.getHeight(),
                     display.getWidth() + 1,
@@ -843,4 +847,33 @@ public class U {
     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) {
+        SharedPreferences pref = getSharedPreferences(context);
+        if(pref.getBoolean("launch_games_fullscreen", true)) {
+            PackageManager pm = context.getPackageManager();
+
+            try {
+                ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+                return (info.flags & ApplicationInfo.FLAG_IS_GAME) != 0;
+            } catch (PackageManager.NameNotFoundException e) {
+                return false;
+            }
+        } else
+            return false;
+    }
+
+    @TargetApi(Build.VERSION_CODES.M)
+    private static ActivityOptions getActivityOptions(Boolean isGame) {
+        ActivityOptions options = ActivityOptions.makeBasic();
+
+        if(isGame != null) {
+            try {
+                Method method = ActivityOptions.class.getMethod("setLaunchStackId", int.class);
+                method.invoke(options, isGame ? FULLSCREEN_WORKSPACE_STACK_ID : FREEFORM_WORKSPACE_STACK_ID);
+            } catch (Exception e) { /* Gracefully fail */ }
+        }
+
+        return options;
+    }
 }
index 839ffee..a92e831 100644 (file)
     <string name="already_top_app">%1$s kann nicht ausgewählt werden, da es auf der Liste der top Apps ist.</string>
 
     <string name="alt_button_config">Alternative Position für den Versteckknopf</string>
-    <string name="pref_title_open_in_fullscreen">Aus Fullscreenapps Fenster öffnen</string>
-    <string name="pref_description_open_in_fullscreen">Dazu muss der Freiform Modus mindestens ein mal initialisiert werden, nach dem Start von Taskbar. Wenn nicht aktiviert, werden freie Fenster nur im Freiform Desktop aufgerufen.</string>
     <string name="pref_title_save_window_sizes">Fenstergrößen der Apps speichern</string>
     <string name="pref_description_save_window_sizes">Wenn neue Fenster aus dem Kontextmenü geöffnet werden</string>
 
     <string name="hide_taskbar_disclaimer">Does not apply to apps in freeform mode</string>
     <string name="transparent_start_menu">Transparent start menu</string>
 
+    <string name="launch_games_fullscreen_title">Launch games fullscreen</string>
+    <string name="launch_games_fullscreen_message">If an application declares itself to be a game, disallow it from launching in freeform mode</string>
+
 </resources>
index 329478c..b938f8f 100644 (file)
     <string name="already_top_app">トップアプリリストにあるため %1$s は選択できません</string>
 
     <string name="alt_button_config">折りたたみボタンの代わりの位置</string>
-    <string name="pref_title_open_in_fullscreen">全画面アプリからウインドウを開く</string>
-    <string name="pref_description_open_in_fullscreen">Taskbar が起動した後、少なくとも 1 回フリーフォームモードを開始する必要があります。 このチェックボックスをオフにすると、フリーフォームワークスペースの間だけフリーフォームウィンドウが開きます。</string>
     <string name="pref_title_save_window_sizes">アプリのウインドウサイズを保存</string>
     <string name="pref_description_save_window_sizes">コンテキストメニューから新しいウインドウを開くとき</string>
 
     <string name="hide_taskbar_disclaimer">Does not apply to apps in freeform mode</string>
     <string name="transparent_start_menu">Transparent start menu</string>
 
+    <string name="launch_games_fullscreen_title">Launch games fullscreen</string>
+    <string name="launch_games_fullscreen_message">If an application declares itself to be a game, disallow it from launching in freeform mode</string>
+
 </resources>
index 356f725..613ab44 100644 (file)
     <string name="already_top_app">%1$s нельзя выбрать, он уже в списке</string>
 
     <string name="alt_button_config">Другая позиция кнопки скрытия</string>
-    <string name="pref_title_open_in_fullscreen">Открывать в полноэкранном режиме</string>
-    <string name="pref_description_open_in_fullscreen">Требует настройки Freeform. Когда не выбран, окна будут открыватся только в рабочем столе режима Freeform.</string>
     <string name="pref_title_save_window_sizes">Сохранять размеры окон</string>
     <string name="pref_description_save_window_sizes">при открытии окон с контекстного меню</string>
 
     <string name="hide_taskbar_disclaimer">Не применяется к приложениям в режмие Freeform</string>
     <string name="transparent_start_menu">Прозрачное меню запуска</string>
 
+    <string name="launch_games_fullscreen_title">Launch games fullscreen</string>
+    <string name="launch_games_fullscreen_message">If an application declares itself to be a game, disallow it from launching in freeform mode</string>
+
 </resources>
index 491fb1f..3fb98d8 100644 (file)
     <string name="pref_title_invisible_button">Hide button while Taskbar is collapsed</string>
     <string name="pref_title_freeform_mode_help">Help &amp; instructions for freeform mode</string>
     <string name="freeform_help_dialog_title">Help &amp; instructions</string>
-    <string name="freeform_help_dialog_message"><b>About freeform mode</b>\n\nTaskbar lets you launch apps in freeform floating windows on Android 7.0+ (Nougat). No root access is required. Simply follow these steps to configure your device for launching apps in freeform mode:\n\n<b>1.</b> Check the box for \"Freeform window support\" inside the Taskbar app\n\n<b>2.</b> Follow the directions that appear in the pop-up to enable the proper settings on your device\n\n<b>3.</b> With Taskbar turned on, go to your device\'s recent apps page\n\n<b>4.</b> Clear all recent apps, then go back to the (empty) recent apps page\n\n<b>5.</b> Press Taskbar\'s start button and select an app to launch it in a freeform window\n\n<b>Troubleshooting</b>\n\n<i>&#8226; Apps still launch full-screen</i>\n\nIf an app is launched that is already loaded into memory, Taskbar will bring it into the foreground. In order to launch the app into freeform mode, it has to be launched from a fresh state.\n\nSwipe the app away from recents, and then re-launch it from the recent apps page using Taskbar. If this doesn\'t work, then long-press the app icon, select \"App info\", and then force stop the app.\n\nNote that Taskbar can only initiate freeform mode from your device\'s recent apps page, from the home screen, or from the freeform workspace itself. Launching apps from within another full-screen app will also launch it into full-screen mode, unless freeform mode has already been initiated since Taskbar was last turned on and the \"Open windows from fullscreen apps\" option is enabled.\n\n<i>&#8226; Apps that are maximized cannot be restored into a window</i>\n\nIf you press the Maximize button on an app\'s title bar, Android will bring the app out of freeform mode and into full-screen mode. As mentioned above, Taskbar can only launch apps into freeform windows if they are launched from a fresh state.\n\nTo fix this, you can maximize windows by tapping or clicking just outside the app\'s window frame.  This will expand the window to fill all the available space while keeping it in the freeform window workspace.\n\n<b>Enabling full system-level freeform window support</b>\n\nIf you have access to a computer with the Android SDK installed, you can enable support for freeform mode at the system level by running the following adb shell command:\n\nsettings put global enable_freeform_support 1\n\nReboot your device after running the above command, and a new button will appear for app entries in your device\'s recent apps page to enter/exit freeform mode for a given app. (Note that the button currently does not work on Android 7.1.2)</string>
+    <string name="freeform_help_dialog_message"><b>About freeform mode</b>\n\nTaskbar lets you launch apps in freeform floating windows on Android 7.0+ (Nougat). No root access is required. Simply follow these steps to configure your device for launching apps in freeform mode:\n\n<b>1.</b> Check the box for \"Freeform window support\" inside the Taskbar app\n\n<b>2.</b> Follow the directions that appear in the pop-up to enable the proper settings on your device\n\n<b>3.</b> Go to your device\'s recent apps page and clear all recent apps\n\n<b>4.</b> Select an app using Taskbar to launch it in a freeform window\n\n<b>Troubleshooting</b>\n\n<i>&#8226; Apps still launch fullscreen</i>\n\nIf an app is launched that is already loaded into memory, Taskbar will bring it into the foreground. In order to launch the app into freeform mode, it has to be launched from a fresh state.\n\nSwipe the app away from recents, and then re-launch it from the recent apps page using Taskbar. If this doesn\'t work, then long-press the app icon, select \"App info\", and then force stop the app.\n\n<i>&#8226; Apps that are maximized cannot be restored into a window</i>\n\nIf you press the Maximize button on an app\'s title bar, Android will bring the app out of freeform mode and into fullscreen mode. As mentioned above, Taskbar can only launch apps into freeform windows if they are launched from a fresh state.\n\nTo fix this, you can maximize windows by tapping or clicking just outside the app\'s window frame.  This will expand the window to fill all the available space while keeping it in the freeform window workspace.\n\n<b>Enabling full system-level freeform window support</b>\n\nIf you have access to a computer with the Android SDK installed, you can enable support for freeform mode at the system level by running the following adb shell command:\n\nsettings put global enable_freeform_support 1\n\nReboot your device after running the above command, and a new button will appear for app entries in your device\'s recent apps page to enter/exit freeform mode for a given app. (Note that the button currently does not work on Android 7.1.2)</string>
 
     <string name="action_developer_options">Open Developer Options</string>
     <string name="action_close">Close</string>
     <string name="already_top_app">%1$s can\'t be selected because it is on the top apps list</string>
 
     <string name="alt_button_config">Alternative position for collapse button</string>
-    <string name="pref_title_open_in_fullscreen">Open windows from fullscreen apps</string>
-    <string name="pref_description_open_in_fullscreen">Requires freeform mode to be initiated at least once after Taskbar starts. When unchecked, freeform windows will only open while in the freeform workspace.</string>
     <string name="pref_title_save_window_sizes">Save window sizes for apps</string>
     <string name="pref_description_save_window_sizes">When opening new windows from the context menu</string>
 
     <string name="hide_taskbar_disclaimer">Does not apply to apps in freeform mode</string>
     <string name="transparent_start_menu">Transparent start menu</string>
 
+    <string name="launch_games_fullscreen_title">Launch games fullscreen</string>
+    <string name="launch_games_fullscreen_message">If an application declares itself to be a game, disallow it from launching in freeform mode</string>
+
 </resources>
index 4a38825..b5c3721 100644 (file)
 
     <CheckBoxPreference
         android:defaultValue="true"
-        android:key="open_in_fullscreen"
-        android:title="@string/pref_title_open_in_fullscreen"
-        android:summary="@string/pref_description_open_in_fullscreen" />
-
-    <CheckBoxPreference
-        android:defaultValue="true"
         android:key="save_window_sizes"
         android:title="@string/pref_title_save_window_sizes"
         android:summary="@string/pref_description_save_window_sizes" />
         android:title="@string/pref_title_force_new_window"
         android:summary="@string/pref_description_force_new_window" />
 
+    <CheckBoxPreference
+        android:defaultValue="true"
+        android:key="launch_games_fullscreen"
+        android:title="@string/launch_games_fullscreen_title"
+        android:summary="@string/launch_games_fullscreen_message" />
+
     <ListPreference
         android:defaultValue="standard"
         android:entries="@array/pref_window_size_list"