From 49bd2d6a08104ac9fbd471e3bafa26a028059d95 Mon Sep 17 00:00:00 2001 From: KindBrave <1773747161@qq.com> Date: Fri, 8 Sep 2023 15:36:48 +0800 Subject: [PATCH] Support IME in Freeform --- .../java/com/sunshine/freeform/MiFreeform.kt | 6 ++- .../freeform/MiFreeformServiceManager.kt | 33 +++++++++---- .../freeform/ui/main/MainViewModel.kt | 9 ++++ .../freeform/ui/main/RemoteSettings.kt | 3 +- .../sunshine/freeform/ui/main/SettingView.kt | 11 +++++ app/src/main/res/values-zh-rCN/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + build.gradle.kts | 2 +- freeform-server/build.gradle.kts | 1 + .../customize.d/50-copy-mfdex-to-framework.sh | 1 + .../display/MiFreeformDisplayAdapter.java | 2 +- .../io/sunshine0523/freeform/ZygoteMain.java | 2 +- .../freeform/service/MiFreeformUIService.java | 7 ++- .../freeform/service/SystemServiceHolder.java | 19 ++++++-- .../ui/freeform/FreeformTaskStackListener.kt | 29 ++++++++++- .../freeform/ui/freeform/FreeformWindow.kt | 32 ++++++++++--- .../ui/freeform/FreeformWindowManager.java | 3 ++ .../sunshine0523/freeform/util/DataHelper.kt | 4 +- .../io/sunshine0523/freeform/util/Settings.kt | 3 +- .../java/android/app/IActivityManager.java | 21 ++++++++ .../android/app/IActivityTaskManager.java | 2 + .../java/android/app/ITaskStackListener.java | 48 +++++++++++++++++-- .../java/android/view/IWindowManager.java | 3 ++ .../server/am/ActivityManagerService.java | 5 -- 24 files changed, 211 insertions(+), 39 deletions(-) create mode 100644 hidden-api/src/main/java/android/app/IActivityManager.java delete mode 100644 hidden-api/src/main/java/com/android/server/am/ActivityManagerService.java diff --git a/app/src/main/java/com/sunshine/freeform/MiFreeform.kt b/app/src/main/java/com/sunshine/freeform/MiFreeform.kt index 1d161f5..2b02944 100644 --- a/app/src/main/java/com/sunshine/freeform/MiFreeform.kt +++ b/app/src/main/java/com/sunshine/freeform/MiFreeform.kt @@ -1,6 +1,8 @@ package com.sunshine.freeform import android.app.Application +import android.os.Build +import androidx.annotation.RequiresApi import org.lsposed.hiddenapibypass.HiddenApiBypass class MiFreeform: Application() { @@ -15,7 +17,9 @@ class MiFreeform: Application() { const val CONFIG = "config" init { - HiddenApiBypass.addHiddenApiExemptions("") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + HiddenApiBypass.addHiddenApiExemptions("") + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/sunshine/freeform/MiFreeformServiceManager.kt b/app/src/main/java/com/sunshine/freeform/MiFreeformServiceManager.kt index fab67e9..ac810f0 100644 --- a/app/src/main/java/com/sunshine/freeform/MiFreeformServiceManager.kt +++ b/app/src/main/java/com/sunshine/freeform/MiFreeformServiceManager.kt @@ -1,8 +1,11 @@ package com.sunshine.freeform import android.content.ComponentName +import android.os.Build import android.os.IBinder +import android.os.ServiceManager import android.util.Log +import androidx.annotation.RequiresApi import com.google.gson.Gson import com.sunshine.freeform.ui.main.RemoteSettings import io.sunshine0523.freeform.IMiFreeformUIService @@ -14,15 +17,27 @@ object MiFreeformServiceManager { private val gson = Gson() fun init() { - try { - val serviceManager = Class.forName("android.os.ServiceManager") - val r = HiddenApiBypass.invoke(serviceManager, null, "getService", "mi_freeform") as IBinder - Log.i(TAG, "mfs $r") - iMiFreeformService = IMiFreeformUIService.Stub.asInterface(r) - iMiFreeformService?.ping() - } catch (e: Exception) { - Log.e(TAG, "$e") - e.printStackTrace() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + try { + val serviceManager = Class.forName("android.os.ServiceManager") + val r = HiddenApiBypass.invoke(serviceManager, null, "getService", "mi_freeform") as IBinder + Log.i(TAG, "mfs $r") + iMiFreeformService = IMiFreeformUIService.Stub.asInterface(r) + iMiFreeformService?.ping() + } catch (e: Exception) { + Log.e(TAG, "$e") + e.printStackTrace() + } + } else { + try { + val r = ServiceManager.getService("mi_freeform") + Log.i(TAG, "mfs $r") + iMiFreeformService = IMiFreeformUIService.Stub.asInterface(r) + iMiFreeformService?.ping() + } catch (e: Exception) { + Log.e(TAG, "$e") + e.printStackTrace() + } } } diff --git a/app/src/main/java/com/sunshine/freeform/ui/main/MainViewModel.kt b/app/src/main/java/com/sunshine/freeform/ui/main/MainViewModel.kt index 43a3253..aeb76bd 100644 --- a/app/src/main/java/com/sunshine/freeform/ui/main/MainViewModel.kt +++ b/app/src/main/java/com/sunshine/freeform/ui/main/MainViewModel.kt @@ -31,6 +31,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { private val remoteSetting = Gson().fromJson(MiFreeformServiceManager.getSetting(), RemoteSettings::class.java) ?: RemoteSettings() private val _enableSideBar = MutableLiveData() val enableSideBar: LiveData get() = _enableSideBar + private val _showImeInFreeform = MutableLiveData() + val showImeInFreeform: LiveData get() = _showImeInFreeform private val _freeformWidth = MutableLiveData() val freeformWidth: LiveData get() = _freeformWidth private val _freeformHeight = MutableLiveData() @@ -45,6 +47,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { init { _enableSideBar.postValue(remoteSetting.enableSideBar) + _showImeInFreeform.postValue(remoteSetting.showImeInFreeform) _freeformWidth.postValue(sp.getInt("freeform_width", (screenWidth * 0.8).roundToInt())) _freeformHeight.postValue(sp.getInt("freeform_height", (screenHeight * 0.5).roundToInt())) _freeformDensityDpi.postValue(sp.getInt("freeform_dpi", screenDensityDpi)) @@ -58,6 +61,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { MiFreeformServiceManager.setSetting(remoteSetting) } + fun saveShowImeInFreeform(showImeInFreeform: Boolean) { + _showImeInFreeform.postValue(showImeInFreeform) + remoteSetting.showImeInFreeform = showImeInFreeform + MiFreeformServiceManager.setSetting(remoteSetting) + } + fun setFreeformWidth(width: Int) { setIntSp(width, "freeform_width") _freeformWidth.postValue(width) diff --git a/app/src/main/java/com/sunshine/freeform/ui/main/RemoteSettings.kt b/app/src/main/java/com/sunshine/freeform/ui/main/RemoteSettings.kt index e24fb67..f6c6928 100644 --- a/app/src/main/java/com/sunshine/freeform/ui/main/RemoteSettings.kt +++ b/app/src/main/java/com/sunshine/freeform/ui/main/RemoteSettings.kt @@ -4,5 +4,6 @@ import androidx.annotation.Keep @Keep data class RemoteSettings( - var enableSideBar: Boolean = false + var enableSideBar: Boolean = false, + var showImeInFreeform: Boolean = false ) \ No newline at end of file diff --git a/app/src/main/java/com/sunshine/freeform/ui/main/SettingView.kt b/app/src/main/java/com/sunshine/freeform/ui/main/SettingView.kt index dd2231b..226b59c 100644 --- a/app/src/main/java/com/sunshine/freeform/ui/main/SettingView.kt +++ b/app/src/main/java/com/sunshine/freeform/ui/main/SettingView.kt @@ -1,5 +1,6 @@ package com.sunshine.freeform.ui.main +import android.os.Build import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -39,6 +40,7 @@ import kotlin.math.roundToInt @Composable fun SettingWidget(mainViewModel: MainViewModel) { val enableSideBar by mainViewModel.enableSideBar.observeAsState(false) + val showImeInFreeform by mainViewModel.showImeInFreeform.observeAsState(false) val freeformWidth by mainViewModel.freeformWidth.observeAsState((mainViewModel.screenWidth * 0.8).roundToInt()) val freeformHeight by mainViewModel.freeformHeight.observeAsState((mainViewModel.screenHeight * 0.5).roundToInt()) val freeformDpi by mainViewModel.freeformDensityDpi.observeAsState(mainViewModel.screenDensityDpi) @@ -107,6 +109,15 @@ fun SettingWidget(mainViewModel: MainViewModel) { ) { mainViewModel.setFreeformDpi(it.roundToInt()) } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + SettingSwitchOption( + stringResource(id = R.string.show_ime_in_freeform), + stringResource(id = R.string.show_ime_in_freeform_message), + showImeInFreeform + ) { + mainViewModel.saveShowImeInFreeform(it) + } + } } } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index dd134cc..0c98654 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -19,4 +19,6 @@ 选择小窗应用 设置 日志 + 在小窗中展示输入法 + 在小窗中展示输入法,仅支持Android 12+ \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8bbf436..327a64c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,4 +32,6 @@ Choose Freeform App + Show IME in Freeform + Show IME in Freeform. Only support Android 12+ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 285e00c..d77768e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { } val androidTargetSdkVersion by extra(34) -val androidMinSdkVersion by extra(29) +val androidMinSdkVersion by extra(27) val androidBuildToolsVersion by extra("34.0.0-rc3") val androidCompileSdkVersion by extra(34) val androidSourceCompatibility by extra(JavaVersion.VERSION_17) diff --git a/freeform-server/build.gradle.kts b/freeform-server/build.gradle.kts index 070cffb..09c274b 100644 --- a/freeform-server/build.gradle.kts +++ b/freeform-server/build.gradle.kts @@ -30,6 +30,7 @@ dependencies { implementation(libs.gson) implementation(projects.service) compileOnly(projects.hiddenApi) + compileOnly(libs.core.ktx) } zygote { diff --git a/freeform-server/src/main/assets/customize.d/50-copy-mfdex-to-framework.sh b/freeform-server/src/main/assets/customize.d/50-copy-mfdex-to-framework.sh index 2e7214e..76b1f7d 100644 --- a/freeform-server/src/main/assets/customize.d/50-copy-mfdex-to-framework.sh +++ b/freeform-server/src/main/assets/customize.d/50-copy-mfdex-to-framework.sh @@ -1,4 +1,5 @@ ui_print "- Copy Mi-Freeform service dex to /data/system/mi_freeform" mkdir "/data/system/mi_freeform" +chmod 777 "/data/system/mi_freeform" cp "$MODPATH/classes.dex" "/data/system/mi_freeform/freeform.dex" \ No newline at end of file diff --git a/freeform-server/src/main/java/com/android/server/display/MiFreeformDisplayAdapter.java b/freeform-server/src/main/java/com/android/server/display/MiFreeformDisplayAdapter.java index ce8b8ed..0a1bd91 100644 --- a/freeform-server/src/main/java/com/android/server/display/MiFreeformDisplayAdapter.java +++ b/freeform-server/src/main/java/com/android/server/display/MiFreeformDisplayAdapter.java @@ -221,7 +221,7 @@ public DisplayDeviceInfo getDisplayDeviceInfoLocked() { mInfo.yDpi = mDensityDpi; mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos + 1000000000L / (int) mRefreshRate; // display's deadline + 1 frame - mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION; + //mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION; if (mFlags.mSecure) { mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE; } diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/ZygoteMain.java b/freeform-server/src/main/java/io/sunshine0523/freeform/ZygoteMain.java index d93766f..148e7dc 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/ZygoteMain.java +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/ZygoteMain.java @@ -85,7 +85,7 @@ private static void instanceMFService(Binder service) throws NoSuchFieldExceptio miFreeformDisplayAdapterObj = mfdaClass.getConstructors()[0].newInstance(mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mLogicalDisplayMapper, mUiHandler); mfdaClass.getMethod("registerLocked").invoke(miFreeformDisplayAdapterObj); } - // for Android Q,R + // for Android O,P,Q,R else { Field mListenerField = dmsClass.getDeclaredField("mDisplayAdapterListener"); Field mLogicalDisplaysField = dmsClass.getDeclaredField("mLogicalDisplays"); diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/service/MiFreeformUIService.java b/freeform-server/src/main/java/io/sunshine0523/freeform/service/MiFreeformUIService.java index 78bf734..ba8a25d 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/service/MiFreeformUIService.java +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/service/MiFreeformUIService.java @@ -14,7 +14,9 @@ import io.sunshine0523.freeform.IMiFreeformDisplayCallback; import io.sunshine0523.freeform.IMiFreeformUIService; +import io.sunshine0523.freeform.ui.freeform.FreeformWindow; import io.sunshine0523.freeform.ui.freeform.FreeformWindowManager; +import io.sunshine0523.freeform.util.DataChangeListener; import io.sunshine0523.freeform.util.DataHelper; import io.sunshine0523.freeform.util.MLog; import io.sunshine0523.freeform.util.Settings; @@ -110,7 +112,10 @@ public String getSettings() { @Override public void setSettings(String settings) { - DataHelper.INSTANCE.saveSettings(settings, this.sideBarService); + DataHelper.INSTANCE.saveSettings(settings, () -> { + sideBarService.onChanged(); + FreeformWindowManager.settings = DataHelper.INSTANCE.getSettings(); + }); } @Override diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/service/SystemServiceHolder.java b/freeform-server/src/main/java/io/sunshine0523/freeform/service/SystemServiceHolder.java index bc7f589..01ee39d 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/service/SystemServiceHolder.java +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/service/SystemServiceHolder.java @@ -1,12 +1,12 @@ package io.sunshine0523.freeform.service; +import android.app.IActivityManager; import android.app.IActivityTaskManager; +import android.os.Build; import android.os.ServiceManager; -import android.util.Log; import android.view.IWindowManager; import com.android.internal.statusbar.IStatusBarService; -import com.android.server.am.ActivityManagerService; import com.android.server.input.InputManagerService; import io.sunshine0523.freeform.util.MLog; @@ -16,17 +16,25 @@ public class SystemServiceHolder { private static final String TAG = "Mi-Freeform/SystemServiceHolder"; static InputManagerService inputManagerService; + //For O,P + public static IActivityManager activityManager; + //For Q,R,S,T public static IActivityTaskManager activityTaskManager; public static IWindowManager windowManager; public static IStatusBarService statusBarService; static void init(ServiceCallback callback) { new Thread(() -> { - waitSystemService("activity_task"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + waitSystemService("activity_task"); + activityTaskManager = IActivityTaskManager.Stub.asInterface(ServiceManager.getService("activity_task")); + } else { + waitSystemService("activity"); + activityManager = IActivityManager.Stub.asInterface(ServiceManager.getService("activity")); + } waitSystemService("input"); waitSystemService("window"); waitSystemService("statusbar"); - activityTaskManager = IActivityTaskManager.Stub.asInterface(ServiceManager.getService("activity_task")); inputManagerService = (InputManagerService) ServiceManager.getService("input"); windowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); statusBarService = IStatusBarService.Stub.asInterface(ServiceManager.getService("statusbar")); @@ -35,8 +43,9 @@ static void init(ServiceCallback callback) { } public static void waitSystemService(String name) { + int count = 20; try { - while (null == ServiceManager.getService(name)) { + while (count-- > 0 && null == ServiceManager.getService(name)) { Thread.sleep(1000); MLog.i(TAG, name + " not start, wait 1s"); } diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformTaskStackListener.kt b/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformTaskStackListener.kt index 45468eb..5e16700 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformTaskStackListener.kt +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformTaskStackListener.kt @@ -8,6 +8,7 @@ import android.os.Build import android.util.Log import android.view.Display import android.window.TaskSnapshot +import androidx.annotation.RequiresApi import io.sunshine0523.freeform.util.MLog import kotlin.math.max import kotlin.math.min @@ -58,6 +59,10 @@ class FreeformTaskStackListener( } + override fun onActivityLaunchOnSecondaryDisplayFailed() { + + } + override fun onActivityLaunchOnSecondaryDisplayFailed( taskInfo: ActivityManager.RunningTaskInfo?, requestedDisplayId: Int @@ -80,6 +85,10 @@ class FreeformTaskStackListener( Log.i(TAG, "onTaskRemoved $taskId") } + override fun onTaskMovedToFront(taskId: Int) { + Log.i(TAG, "onTaskMovedToFront $taskId") + } + override fun onTaskMovedToFront(taskInfo: ActivityManager.RunningTaskInfo) { Log.i(TAG, "onTaskMovedToFront $taskInfo") // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { @@ -88,6 +97,10 @@ class FreeformTaskStackListener( // } } + override fun onTaskDescriptionChanged(taskId: Int, td: ActivityManager.TaskDescription?) { + Log.i(TAG, "onTaskDescriptionChanged $taskId $td") + } + override fun onTaskDescriptionChanged(taskInfo: ActivityManager.RunningTaskInfo?) { Log.i(TAG, "onTaskDescriptionChanged $taskInfo") // Use this not onTaskMovedToFront because task maybe changed @@ -121,6 +134,14 @@ class FreeformTaskStackListener( Log.i(TAG, "onActivityRequestedOrientationChanged $taskId $requestedOrientation") } + override fun onTaskRemovalStarted(taskId: Int) { + Log.i(TAG, "onTaskRemovalStarted") + if (this.taskId == taskId) { + window.destroy(false) + } + } + + @RequiresApi(Build.VERSION_CODES.Q) override fun onTaskRemovalStarted(taskInfo: ActivityManager.RunningTaskInfo?) { Log.i(TAG, "onTaskRemovalStarted") if (this.taskId == taskInfo?.taskId) { @@ -128,11 +149,11 @@ class FreeformTaskStackListener( } } - override fun onTaskProfileLocked(taskInfo: ActivityManager.RunningTaskInfo?) { + override fun onTaskProfileLocked(taskId: Int, userId: Int) { } - override fun onTaskSnapshotChanged(taskId: Int, snapshot: TaskSnapshot?) { + override fun onTaskProfileLocked(taskInfo: ActivityManager.RunningTaskInfo?) { } @@ -140,6 +161,10 @@ class FreeformTaskStackListener( } + override fun onTaskSnapshotChanged(taskId: Int, snapshot: TaskSnapshot?) { + + } + override fun onBackPressedOnTaskRoot(taskInfo: ActivityManager.RunningTaskInfo?) { } diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindow.kt b/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindow.kt index 2fc9e24..f49f0a8 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindow.kt +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindow.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.content.Context import android.graphics.PixelFormat import android.graphics.SurfaceTexture +import android.os.Build import android.os.Handler import android.util.Log import android.view.Display @@ -93,12 +94,19 @@ class FreeformWindow( override fun onDisplayAdd(displayId: Int) { MLog.i(TAG, "onDisplayAdd displayId $displayId") - uiHandler.post { - this.displayId = displayId - freeformTaskStackListener = FreeformTaskStackListener(displayId, this) + this.displayId = displayId + freeformTaskStackListener = FreeformTaskStackListener(displayId, this) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { SystemServiceHolder.activityTaskManager.registerTaskStackListener(freeformTaskStackListener) - MiFreeformServiceHolder.startApp(context, appConfig, displayId) + } else { + SystemServiceHolder.activityManager.registerTaskStackListener(freeformTaskStackListener) + } + if (FreeformWindowManager.settings.showImeInFreeform && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + SystemServiceHolder.windowManager.setDisplayImePolicy(displayId, 0) + } + uiHandler.post { + MiFreeformServiceHolder.startApp(context, appConfig, displayId) val rightView = resourceHolder.getLayoutChildViewByTag(freeformLayout, "rightView") if (null == rightView) { MLog.e(TAG, "left&leftScale&rightScale view is null") @@ -325,10 +333,22 @@ class FreeformWindow( uiHandler.post { runCatching { windowManager.removeViewImmediate(freeformLayout) }.onFailure { exception -> Log.e(TAG, "removeView failed $exception") } } - SystemServiceHolder.activityTaskManager.unregisterTaskStackListener(freeformTaskStackListener) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + SystemServiceHolder.activityTaskManager.unregisterTaskStackListener(freeformTaskStackListener) + } else { + SystemServiceHolder.activityManager.unregisterTaskStackListener(freeformTaskStackListener) + } SystemServiceHolder.windowManager.removeRotationWatcher(rotationWatcher) MiFreeformServiceHolder.releaseFreeform(this) - if (removeTask) runCatching { SystemServiceHolder.activityTaskManager.removeTask(freeformTaskStackListener!!.taskId) }.onFailure { exception -> MLog.e(TAG, "removeTask failed $exception") } + if (removeTask) runCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + SystemServiceHolder.activityTaskManager.removeTask(freeformTaskStackListener!!.taskId) + } else { + SystemServiceHolder.activityManager.removeTask(freeformTaskStackListener!!.taskId) + } + }.onFailure { exception -> + MLog.e(TAG, "removeTask failed $exception") + } FreeformWindowManager.removeWindow(getFreeformId()) } } \ No newline at end of file diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindowManager.java b/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindowManager.java index 9598692..c3a7cc7 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindowManager.java +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/ui/freeform/FreeformWindowManager.java @@ -12,9 +12,12 @@ import io.sunshine0523.freeform.ui.freeform.FreeformConfig; import io.sunshine0523.freeform.ui.freeform.FreeformWindow; import io.sunshine0523.freeform.ui.freeform.UIConfig; +import io.sunshine0523.freeform.util.DataHelper; +import io.sunshine0523.freeform.util.Settings; public class FreeformWindowManager { static String topWindow = ""; + public static Settings settings = DataHelper.INSTANCE.getSettings(); private static final HashMap freeformWindows = new HashMap<>(); public static void addWindow( Handler uiHandler, Context context, diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/util/DataHelper.kt b/freeform-server/src/main/java/io/sunshine0523/freeform/util/DataHelper.kt index b65b972..e7ccc8c 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/util/DataHelper.kt +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/util/DataHelper.kt @@ -7,7 +7,7 @@ import java.io.File import java.lang.StringBuilder object DataHelper { - private const val TAG = "MiFreeform/DataHelper" + private const val TAG = "Mi-Freeform/DataHelper" private val dataDir = File("${Environment.getDataDirectory()}/system/mi_freeform") private val dataFile = File(dataDir, "settings.json") private val logFile = File(dataDir, "log.log") @@ -27,7 +27,7 @@ object DataHelper { } }.start() }.onFailure { - MLog.e(TAG, "$it") + MLog.e(TAG, "$it $dataDir") } } diff --git a/freeform-server/src/main/java/io/sunshine0523/freeform/util/Settings.kt b/freeform-server/src/main/java/io/sunshine0523/freeform/util/Settings.kt index 8a8b568..7bc0be5 100644 --- a/freeform-server/src/main/java/io/sunshine0523/freeform/util/Settings.kt +++ b/freeform-server/src/main/java/io/sunshine0523/freeform/util/Settings.kt @@ -1,5 +1,6 @@ package io.sunshine0523.freeform.util data class Settings( - var enableSideBar: Boolean = false + var enableSideBar: Boolean = false, + var showImeInFreeform: Boolean = false ) \ No newline at end of file diff --git a/hidden-api/src/main/java/android/app/IActivityManager.java b/hidden-api/src/main/java/android/app/IActivityManager.java new file mode 100644 index 0000000..54e2522 --- /dev/null +++ b/hidden-api/src/main/java/android/app/IActivityManager.java @@ -0,0 +1,21 @@ +package android.app; + +import android.os.Binder; +import android.os.IBinder; +import android.os.IInterface; + +/** + * Only For Android 8.1-Android 9 + */ +public interface IActivityManager extends IInterface { + void registerTaskStackListener(ITaskStackListener listener) throws RuntimeException; + void unregisterTaskStackListener(ITaskStackListener listener) throws RuntimeException; + boolean removeTask(int taskId) throws RuntimeException; + void moveStackToDisplay(int stackId, int displayId) throws RuntimeException; + + abstract class Stub extends Binder implements IActivityManager { + public static IActivityManager asInterface(IBinder binder) { + throw new RuntimeException("Stub!"); + } + } +} diff --git a/hidden-api/src/main/java/android/app/IActivityTaskManager.java b/hidden-api/src/main/java/android/app/IActivityTaskManager.java index 51afafc..cb4b8cb 100644 --- a/hidden-api/src/main/java/android/app/IActivityTaskManager.java +++ b/hidden-api/src/main/java/android/app/IActivityTaskManager.java @@ -8,7 +8,9 @@ public interface IActivityTaskManager extends IInterface { void registerTaskStackListener(ITaskStackListener listener) throws RuntimeException; void unregisterTaskStackListener(ITaskStackListener listener) throws RuntimeException; boolean removeTask(int taskId); + //For A11-A13 void moveRootTaskToDisplay(int taskId, int displayId) throws RuntimeException; + //Only for A10 void moveStackToDisplay(int stackId, int displayId) throws RuntimeException; abstract class Stub extends Binder implements IActivityTaskManager { diff --git a/hidden-api/src/main/java/android/app/ITaskStackListener.java b/hidden-api/src/main/java/android/app/ITaskStackListener.java index 3f59c96..10d1e64 100644 --- a/hidden-api/src/main/java/android/app/ITaskStackListener.java +++ b/hidden-api/src/main/java/android/app/ITaskStackListener.java @@ -44,6 +44,13 @@ void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean home */ void onActivityDismissingDockedTask(); + /** + * Called when an activity was requested to be launched on a secondary display but was not + * allowed there. + * Only for A8.1, A9 + */ + void onActivityLaunchOnSecondaryDisplayFailed(); + /** * Called when an activity was requested to be launched on a secondary display but was not * allowed there. @@ -79,6 +86,14 @@ void onActivityLaunchOnSecondaryDisplayRerouted(ActivityManager.RunningTaskInfo */ void onTaskRemoved(int taskId); + /** + * Called when a task is moved to the front of its stack. + * + * @param taskId id of the task. + * Only for A8.1,A9 + */ + void onTaskMovedToFront(int taskId); + /** * Called when a task is moved to the front of its stack. * @@ -86,6 +101,17 @@ void onActivityLaunchOnSecondaryDisplayRerouted(ActivityManager.RunningTaskInfo */ void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo); + /** + * Called when a task’s description is changed due to an activity calling + * ActivityManagerService.setTaskDescription + * + * @param taskId id of the task. + * @param td the new TaskDescription. + * + * Only for A8.1,A9 + */ + void onTaskDescriptionChanged(int taskId, ActivityManager.TaskDescription td); + /** * Called when a task’s description is changed due to an activity calling * ActivityManagerService.setTaskDescription @@ -103,6 +129,14 @@ void onActivityLaunchOnSecondaryDisplayRerouted(ActivityManager.RunningTaskInfo */ void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation); + /** + * Called when the task is about to be finished but before its surfaces are + * removed from the window manager. This allows interested parties to + * perform relevant animations before the window disappears. + * Only For A8.1, A9 + */ + void onTaskRemovalStarted(int taskId); + /** * Called when the task is about to be finished but before its surfaces are * removed from the window manager. This allows interested parties to @@ -116,13 +150,16 @@ void onActivityLaunchOnSecondaryDisplayRerouted(ActivityManager.RunningTaskInfo * Called when the task has been put in a locked state because one or more of the * activities inside it belong to a managed profile user, and that user has just * been locked. + * Only for A8.1,A9 */ - void onTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo); + void onTaskProfileLocked(int taskId, int userId); /** - * Called when a task snapshot got updated. + * Called when the task has been put in a locked state because one or more of the + * activities inside it belong to a managed profile user, and that user has just + * been locked. */ - void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot); + void onTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo); /** * Called when a task snapshot got updated. @@ -130,6 +167,11 @@ void onActivityLaunchOnSecondaryDisplayRerouted(ActivityManager.RunningTaskInfo */ void onTaskSnapshotChanged(int taskId, ActivityManagerHidden.TaskSnapshot snapshot); + /** + * Called when a task snapshot got updated. + */ + void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot); + /** * Reports that an Activity received a back key press when there were no additional activities * on the back stack. diff --git a/hidden-api/src/main/java/android/view/IWindowManager.java b/hidden-api/src/main/java/android/view/IWindowManager.java index 9cc17d1..bd698f6 100644 --- a/hidden-api/src/main/java/android/view/IWindowManager.java +++ b/hidden-api/src/main/java/android/view/IWindowManager.java @@ -9,6 +9,9 @@ public interface IWindowManager extends IInterface { void removeRotationWatcher(IRotationWatcher watcher); + //Only support A12+ + void setDisplayImePolicy(int displayId, int imePolicy); + abstract class Stub extends Binder implements IWindowManager { public static IWindowManager asInterface(IBinder binder) { throw new RuntimeException("Stub!"); diff --git a/hidden-api/src/main/java/com/android/server/am/ActivityManagerService.java b/hidden-api/src/main/java/com/android/server/am/ActivityManagerService.java deleted file mode 100644 index 92a6c03..0000000 --- a/hidden-api/src/main/java/com/android/server/am/ActivityManagerService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.android.server.am; - -public class ActivityManagerService { - -}