1+ package com.parallelc.micts
2+
3+ import android.annotation.SuppressLint
4+ import android.content.Context
5+ import android.content.Intent
6+ import android.content.res.Resources
7+ import android.os.Build
8+ import android.os.Bundle
9+ import android.os.IBinder
10+ import android.os.SystemClock
11+ import android.view.MotionEvent
12+ import android.view.View
13+ import android.view.ViewConfiguration
14+ import io.github.libxposed.api.XposedInterface
15+ import io.github.libxposed.api.XposedInterface.AfterHookCallback
16+ import io.github.libxposed.api.XposedInterface.BeforeHookCallback
17+ import io.github.libxposed.api.XposedInterface.Hooker
18+ import io.github.libxposed.api.XposedModule
19+ import io.github.libxposed.api.XposedModuleInterface.ModuleLoadedParam
20+ import io.github.libxposed.api.XposedModuleInterface.PackageLoadedParam
21+ import io.github.libxposed.api.XposedModuleInterface.SystemServerLoadedParam
22+ import io.github.libxposed.api.annotations.AfterInvocation
23+ import io.github.libxposed.api.annotations.BeforeInvocation
24+ import io.github.libxposed.api.annotations.XposedHooker
25+
26+ private lateinit var module: ModuleMain
27+
28+ class ModuleMain (base : XposedInterface , param : ModuleLoadedParam ) : XposedModule(base, param) {
29+
30+ init {
31+ module = this
32+ }
33+
34+ @XposedHooker
35+ class ContextualSearchIntentHooker : Hooker {
36+ companion object {
37+ @JvmStatic
38+ @AfterInvocation
39+ fun after (callback : AfterHookCallback ) {
40+ (callback.result as Intent ).putExtra(" com.android.contextualsearch.flag_secure_found" , false )
41+ }
42+ }
43+ }
44+
45+ class ResourcesHooker {
46+ companion object {
47+ private var R : Class <* >? = null
48+
49+ @SuppressLint(" PrivateApi" )
50+ fun hook (param : SystemServerLoadedParam ) {
51+ R = param.classLoader.loadClass(" com.android.internal.R\$ string" )
52+ module.hook(Resources ::class .java.getDeclaredMethod(" getString" , Int ::class .java), GetStringHooker ::class .java)
53+ }
54+
55+ @XposedHooker
56+ class GetStringHooker : Hooker {
57+ companion object {
58+ @JvmStatic
59+ @BeforeInvocation
60+ fun before (callback : BeforeHookCallback ) {
61+ when (callback.args[0 ]) {
62+ R !! .getField(" config_defaultContextualSearchKey" ).getInt(null ) -> {
63+ callback.returnAndSkip(" omni.entry_point" )
64+ }
65+
66+ R !! .getField(" config_defaultContextualSearchPackageName" ).getInt(null ) -> {
67+ callback.returnAndSkip(" com.google.android.googlequicksearchbox" )
68+ }
69+ }
70+ }
71+ }
72+ }
73+ }
74+ }
75+
76+ @SuppressLint(" PrivateApi" )
77+ override fun onSystemServerLoaded (param : SystemServerLoadedParam ) {
78+ super .onSystemServerLoaded(param)
79+
80+ runCatching {
81+ ResourcesHooker .hook(param)
82+ val vims = param.classLoader.loadClass(" com.android.server.voiceinteraction.VoiceInteractionManagerService\$ VoiceInteractionManagerServiceStub" )
83+ hook(vims.getDeclaredMethod(" getContextualSearchIntent" , Bundle ::class .java), ContextualSearchIntentHooker ::class .java)
84+ }.onFailure { e ->
85+ log(" hook system fail" , e)
86+ }
87+ }
88+
89+ @XposedHooker
90+ class ReturnTrueHooker : Hooker {
91+ companion object {
92+ @JvmStatic
93+ @BeforeInvocation
94+ fun before (callback : BeforeHookCallback ) {
95+ callback.returnAndSkip(true )
96+ }
97+ }
98+ }
99+
100+ @XposedHooker
101+ class ReturnFalseHooker : Hooker {
102+ companion object {
103+ @JvmStatic
104+ @BeforeInvocation
105+ fun before (callback : BeforeHookCallback ) {
106+ callback.returnAndSkip(false )
107+ }
108+ }
109+ }
110+
111+ @XposedHooker
112+ class NavStubViewHooker : Hooker {
113+ companion object {
114+ @SuppressLint(" PrivateApi" )
115+ private val mCheckLongPress = Runnable {
116+ runCatching {
117+ val bundle = Bundle ()
118+ bundle.putLong(" invocation_time_ms" , SystemClock .elapsedRealtime())
119+ bundle.putInt(" omni.entry_point" , 1 )
120+ val iVims = Class .forName(" com.android.internal.app.IVoiceInteractionManagerService\$ Stub" )
121+ val asInterfaceMethod = iVims.getMethod(" asInterface" , IBinder ::class .java)
122+ val getServiceMethod = Class .forName(" android.os.ServiceManager" ).getMethod(" getService" , String ::class .java)
123+ val vimsInstance = asInterfaceMethod.invoke(null , getServiceMethod.invoke(null , " voiceinteraction" )) ? : return @Runnable
124+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
125+ val showSessionFromSession = vimsInstance.javaClass.getDeclaredMethod(" showSessionFromSession" , IBinder ::class .java, Bundle ::class .java, Integer .TYPE , String ::class .java)
126+ showSessionFromSession.invoke(vimsInstance, null , bundle, 7 , " hyperOS_home" )
127+ } else {
128+ val showSessionFromSession = vimsInstance.javaClass.getDeclaredMethod(" showSessionFromSession" , IBinder ::class .java, Bundle ::class .java, Integer .TYPE )
129+ showSessionFromSession.invoke(vimsInstance, null , bundle, 7 )
130+ }
131+ }.onFailure { e ->
132+ module.log(" NavStubViewHooker mCheckLongPress fail" , e)
133+ }
134+ }
135+
136+ @JvmStatic
137+ @AfterInvocation
138+ fun after (callback : AfterHookCallback ) {
139+ val view = callback.thisObject as View
140+ view.removeCallbacks(this .mCheckLongPress)
141+ runCatching {
142+ val mCurrAction = callback.thisObject!! .javaClass.getDeclaredField(" mCurrAction" )
143+ mCurrAction.isAccessible = true
144+ if (mCurrAction.getInt(callback.thisObject) == 0 ) {
145+ view.postDelayed(this .mCheckLongPress, ViewConfiguration .getLongPressTimeout().toLong())
146+ }
147+ }.onFailure { e ->
148+ module.log(" NavStubViewHooker onTouchEvent fail" , e)
149+ }
150+ }
151+ }
152+ }
153+
154+ override fun onPackageLoaded (param : PackageLoadedParam ) {
155+ super .onPackageLoaded(param)
156+ if (param.packageName != " com.miui.home" || ! param.isFirstPackage) return
157+
158+ runCatching {
159+ val circleToSearchHelper = param.classLoader.loadClass(" com.miui.home.recents.cts.CircleToSearchHelper" )
160+ hook(circleToSearchHelper.getDeclaredMethod(" isSceneForbid" , Context ::class .java, Int ::class .java), ReturnFalseHooker ::class .java)
161+ hook(circleToSearchHelper.getDeclaredMethod(" hasCtsFeature" , Context ::class .java), ReturnTrueHooker ::class .java)
162+ hook(circleToSearchHelper.getDeclaredMethod(" isSettingsLongPressHomeAssistantEnabled" , Context ::class .java), ReturnTrueHooker ::class .java)
163+ hook(circleToSearchHelper.getDeclaredMethod(" isThirdHome" , Context ::class .java), ReturnFalseHooker ::class .java)
164+ return
165+ }.onFailure { e ->
166+ log(" hook CircleToSearchHelper fail" , e)
167+ }
168+
169+ runCatching {
170+ val navStubView = param.classLoader.loadClass(" com.miui.home.recents.NavStubView" )
171+ runCatching { navStubView.getDeclaredField(" mCheckLongPress" ) }
172+ .onSuccess { throw Exception (" mCheckLongPress exists" ) }
173+ .onFailure {
174+ hook(navStubView.getDeclaredMethod(" onTouchEvent" , MotionEvent ::class .java), NavStubViewHooker ::class .java)
175+ }
176+ }.onFailure { e ->
177+ log(" hook NavStubView fail" , e)
178+ }
179+ }
180+ }
0 commit comments