Skip to content

Commit

Permalink
feat: long press home button
Browse files Browse the repository at this point in the history
  • Loading branch information
parallelcc committed Oct 29, 2024
1 parent b0aa0d6 commit 2e17584
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 188 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

## 操作步骤

1. `桌面设置-系统导航方式`里,选择`全面屏手势`,关闭`隐藏手势提示线`
1. 安装最新版[Google](https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox)应用,开启`自启动`权限,`省电策略`选择`无限制`


2. 安装最新版[Google](https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox)应用,开启`自启动`权限,`省电策略`选择`无限制`
2. 安装并启用模块,重启手机


3. 安装并启用模块,重启手机
3. 执行相应的动作触发
- 如果是全面屏手势,需要在`桌面设置-系统导航方式`里,关闭`隐藏手势提示线`,之后长按底部小白条触发
- 如果是经典导航键(三按钮),需要在`桌面设置-系统导航方式-按键快捷方式-长按Home键`里,选择`语音助手`,之后长按Home键触发


4. 长按底部小白条,如果没有反应,尝试在`设置-应用设置-右上角其他设置-默认应用设置-助手和语音输入-数字助理应用`里选择Google
4. 如果没有反应,尝试在`设置-应用设置-右上角其他设置-默认应用设置-助手和语音输入-数字助理应用`里选择Google
10 changes: 6 additions & 4 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ Enable Circle to Search for Xiaomi System Launcher

## Usage

1. In `Home Screen Settings - System Navigation`, select `Gestures` and turn off `Hide full screen indicator`
1. Install the latest version of [Google](https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox). In Google's `App info`, turn on `Autostart` if it exists and select `No restrictions` in `Battery saver`


2. Install the latest version of [Google](https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox). In Google's `App info`, turn on `Autostart` if it exists and select `No restrictions` in `Battery saver`
2. Install and enable the module, restart your phone


3. Install and enable the module, restart your phone
3. Perform the action to trigger
- For `Gesture`, turn off `Hide full screen indicator` in `Home Screen Settings - System Navigation`, and then long press the navigation handle at the bottom to trigger
- For `Buttons`, select `Launch Google Assistant` in `Home Screen Settings - System Navigation - Button shortcuts - Long press the Home button`, and then long press the home button to trigger


4. Long press the navigation handle at the bottom to trigger. If it doesn't work, try to select Google in `Settings - Apps - Manage apps - Other Settings in the upper right corner - Default apps - Assist & voice input - Digital Assistant App`
4. If it doesn't work, try to select Google in `Settings - Apps - Manage apps - Other Settings in the upper right corner - Default apps - Assist & voice input - Digital Assistant App`
180 changes: 0 additions & 180 deletions app/src/main/java/com/parallelc/micts/Main.kt

This file was deleted.

89 changes: 89 additions & 0 deletions app/src/main/java/com/parallelc/micts/ModuleMain.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.parallelc.micts

import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.os.SystemClock
import android.view.MotionEvent
import com.parallelc.micts.hooker.ContextualSearchIntentHooker
import com.parallelc.micts.hooker.LongPressHomeHooker
import com.parallelc.micts.hooker.NavStubViewHooker
import com.parallelc.micts.hooker.ResourcesHooker
import com.parallelc.micts.hooker.ReturnFalseHooker
import com.parallelc.micts.hooker.ReturnTrueHooker
import io.github.libxposed.api.XposedInterface
import io.github.libxposed.api.XposedModule
import io.github.libxposed.api.XposedModuleInterface.ModuleLoadedParam
import io.github.libxposed.api.XposedModuleInterface.PackageLoadedParam
import io.github.libxposed.api.XposedModuleInterface.SystemServerLoadedParam

@SuppressLint("PrivateApi")
fun triggerCircleToSearch() {
val bundle = Bundle()
bundle.putLong("invocation_time_ms", SystemClock.elapsedRealtime())
bundle.putInt("omni.entry_point", 1)
val iVims = Class.forName("com.android.internal.app.IVoiceInteractionManagerService\$Stub")
val asInterfaceMethod = iVims.getMethod("asInterface", IBinder::class.java)
val getServiceMethod = Class.forName("android.os.ServiceManager").getMethod("getService", String::class.java)
val vimsInstance = asInterfaceMethod.invoke(null, getServiceMethod.invoke(null, "voiceinteraction")) ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
val showSessionFromSession = vimsInstance.javaClass.getDeclaredMethod("showSessionFromSession", IBinder::class.java, Bundle::class.java, Integer.TYPE, String::class.java)
showSessionFromSession.invoke(vimsInstance, null, bundle, 7, "hyperOS_home")
} else {
val showSessionFromSession = vimsInstance.javaClass.getDeclaredMethod("showSessionFromSession", IBinder::class.java, Bundle::class.java, Integer.TYPE)
showSessionFromSession.invoke(vimsInstance, null, bundle, 7)
}
}

lateinit var module: ModuleMain

class ModuleMain(base: XposedInterface, param: ModuleLoadedParam) : XposedModule(base, param) {

init {
module = this
}

@SuppressLint("PrivateApi")
override fun onSystemServerLoaded(param: SystemServerLoadedParam) {
super.onSystemServerLoaded(param)

runCatching {
LongPressHomeHooker.hook(param)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) return
ResourcesHooker.hook(param)
val vims = param.classLoader.loadClass("com.android.server.voiceinteraction.VoiceInteractionManagerService\$VoiceInteractionManagerServiceStub")
hook(vims.getDeclaredMethod("getContextualSearchIntent", Bundle::class.java), ContextualSearchIntentHooker::class.java)
}.onFailure { e ->
log("hook system fail", e)
}
}

override fun onPackageLoaded(param: PackageLoadedParam) {
super.onPackageLoaded(param)
if (param.packageName != "com.miui.home" || !param.isFirstPackage) return

runCatching {
val circleToSearchHelper = param.classLoader.loadClass("com.miui.home.recents.cts.CircleToSearchHelper")
hook(circleToSearchHelper.getDeclaredMethod("isSceneForbid", Context::class.java, Int::class.java), ReturnFalseHooker::class.java)
hook(circleToSearchHelper.getDeclaredMethod("hasCtsFeature", Context::class.java), ReturnTrueHooker::class.java)
hook(circleToSearchHelper.getDeclaredMethod("isSettingsLongPressHomeAssistantEnabled", Context::class.java), ReturnTrueHooker::class.java)
hook(circleToSearchHelper.getDeclaredMethod("isThirdHome", Context::class.java), ReturnFalseHooker::class.java)
return
}.onFailure { e ->
log("hook CircleToSearchHelper fail", e)
}

runCatching {
val navStubView = param.classLoader.loadClass("com.miui.home.recents.NavStubView")
runCatching { navStubView.getDeclaredField("mCheckLongPress") }
.onSuccess { throw Exception("mCheckLongPress exists") }
.onFailure {
hook(navStubView.getDeclaredMethod("onTouchEvent", MotionEvent::class.java), NavStubViewHooker::class.java)
}
}.onFailure { e ->
log("hook NavStubView fail", e)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.parallelc.micts.hooker

import android.content.Intent
import io.github.libxposed.api.XposedInterface.AfterHookCallback
import io.github.libxposed.api.XposedInterface.Hooker
import io.github.libxposed.api.annotations.AfterInvocation
import io.github.libxposed.api.annotations.XposedHooker

@XposedHooker
class ContextualSearchIntentHooker : Hooker {
companion object {
@JvmStatic
@AfterInvocation
fun after(callback: AfterHookCallback) {
(callback.result as Intent).putExtra("com.android.contextualsearch.flag_secure_found", false)
}
}
}
Loading

0 comments on commit 2e17584

Please sign in to comment.