Skip to content

Commit

Permalink
[service] add getVisibleWindows api
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornaco committed Jun 3, 2022
1 parent d3d26b3 commit 93a1cd7
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package github.tornaco.android.thanos.core.wm;

import github.tornaco.android.thanos.core.wm.WindowState;

interface IWindowManager {
int[] getScreenSize();

void setDialogForceCancelable(String packageName, boolean forceCancelable);
boolean isDialogForceCancelable(String packageName);
void reportDialogHasBeenForceSetCancelable(String packageName);

List<WindowState> getVisibleWindows();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public static class Default implements github.tornaco.android.thanos.core.wm.IWi
@Override public void reportDialogHasBeenForceSetCancelable(java.lang.String packageName) throws android.os.RemoteException
{
}
@Override public java.util.List<github.tornaco.android.thanos.core.wm.WindowState> getVisibleWindows() throws android.os.RemoteException
{
return null;
}
@Override
public android.os.IBinder asBinder() {
return null;
Expand Down Expand Up @@ -102,6 +106,14 @@ public static github.tornaco.android.thanos.core.wm.IWindowManager asInterface(a
reply.writeNoException();
return true;
}
case TRANSACTION_getVisibleWindows:
{
data.enforceInterface(descriptor);
java.util.List<github.tornaco.android.thanos.core.wm.WindowState> _result = this.getVisibleWindows();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
Expand Down Expand Up @@ -203,12 +215,33 @@ public java.lang.String getInterfaceDescriptor()
_data.recycle();
}
}
@Override public java.util.List<github.tornaco.android.thanos.core.wm.WindowState> getVisibleWindows() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<github.tornaco.android.thanos.core.wm.WindowState> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_getVisibleWindows, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getVisibleWindows();
}
_reply.readException();
_result = _reply.createTypedArrayList(github.tornaco.android.thanos.core.wm.WindowState.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static github.tornaco.android.thanos.core.wm.IWindowManager sDefaultImpl;
}
static final int TRANSACTION_getScreenSize = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_setDialogForceCancelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_isDialogForceCancelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_reportDialogHasBeenForceSetCancelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_getVisibleWindows = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
public static boolean setDefaultImpl(github.tornaco.android.thanos.core.wm.IWindowManager impl) {
// Only one user of this interface can use this function
// at a time. This is a heuristic to detect if two different
Expand All @@ -230,4 +263,5 @@ public static github.tornaco.android.thanos.core.wm.IWindowManager getDefaultImp
public void setDialogForceCancelable(java.lang.String packageName, boolean forceCancelable) throws android.os.RemoteException;
public boolean isDialogForceCancelable(java.lang.String packageName) throws android.os.RemoteException;
public void reportDialogHasBeenForceSetCancelable(java.lang.String packageName) throws android.os.RemoteException;
public java.util.List<github.tornaco.android.thanos.core.wm.WindowState> getVisibleWindows() throws android.os.RemoteException;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package github.tornaco.android.thanos.core.wm;

import android.os.UserHandle;

import java.util.List;

import github.tornaco.android.thanos.core.pm.Pkg;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;

Expand All @@ -17,4 +22,20 @@ public void setDialogForceCancelable(String packageName, boolean forceCancelable
public boolean isDialogForceCancelable(String packageName) {
return server.isDialogForceCancelable(packageName);
}

@SneakyThrows
public List<WindowState> getVisibleWindows() {
return server.getVisibleWindows();
}

@SneakyThrows
public boolean hasVisibleWindows(String pkgName) {
return getVisibleWindows().stream().anyMatch(windowState -> windowState.packageName.equals(pkgName));
}

@SneakyThrows
public boolean hasVisibleWindows(Pkg pkg) {
return getVisibleWindows().stream().anyMatch(windowState -> windowState.packageName.equals(pkg.getPkgName())
&& UserHandle.getUserId(windowState.uid) == pkg.getUserId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* (C) Copyright 2022 Thanox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package github.tornaco.android.thanos.core.wm;

import android.os.Parcel;
import android.os.Parcelable;

public class WindowState implements Parcelable {
public String packageName;
public int uid;
public boolean visible;
public int type;

public WindowState(String packageName, int uid, boolean visible, int type) {
this.packageName = packageName;
this.uid = uid;
this.visible = visible;
this.type = type;
}

protected WindowState(Parcel in) {
packageName = in.readString();
uid = in.readInt();
visible = in.readByte() != 0;
type = in.readInt();
}

public static final Creator<WindowState> CREATOR = new Creator<WindowState>() {
@Override
public WindowState createFromParcel(Parcel in) {
return new WindowState(in);
}

@Override
public WindowState[] newArray(int size) {
return new WindowState[size];
}
};

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(packageName);
parcel.writeInt(uid);
parcel.writeByte((byte) (visible ? 1 : 0));
parcel.writeInt(type);
}

@Override
public String toString() {
return "WindowState{" +
"packageName='" + packageName + '\'' +
", uid=" + uid +
", visible=" + visible +
", type=" + type + " " + WindowTypeMapping.INSTANCE.getMap().get(String.valueOf(type)) +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* (C) Copyright 2022 Thanox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package github.tornaco.android.thanos.core.wm

object WindowTypeMapping {

fun <K, V> MutableMap<K, V>.add(data: Pair<K, V>) {
this[data.first] = data.second
}

val map = mutableMapOf<String, String>().apply {
add("2" to "TYPE_APPLICATION")
add("3" to "TYPE_APPLICATION_STARTING")
add("4" to "TYPE_DRAWN_APPLICATION")
add("1000" to "TYPE_APPLICATION_PANEL")
add("1001" to "TYPE_APPLICATION_MEDIA")
add("1002" to "TYPE_APPLICATION_SUB_PANEL")
add("1003" to "TYPE_APPLICATION_ATTACHED_DIALOG")
add("1004" to "TYPE_APPLICATION_MEDIA_OVERLAY")
add("1005" to "TYPE_APPLICATION_ABOVE_SUB_PANEL")
add("2000" to "TYPE_STATUS_BAR")
add("2001" to "TYPE_SEARCH_BAR")
add("2002" to "TYPE_PHONE")
add("2003" to "TYPE_SYSTEM_ALERT")
add("2004" to "TYPE_KEYGUARD")
add("2005" to "TYPE_TOAST")
add("2006" to "TYPE_SYSTEM_OVERLAY")
add("2007" to "TYPE_PRIORITY_PHONE")
add("2008" to "TYPE_SYSTEM_DIALOG")
add("2009" to "TYPE_KEYGUARD_DIALOG")
add("2010" to "TYPE_SYSTEM_ERROR")
add("2011" to "TYPE_INPUT_METHOD")
add("2012" to "TYPE_INPUT_METHOD_DIALOG")
add("2013" to "TYPE_WALLPAPER")
add("2014" to "TYPE_STATUS_BAR_PANEL")
add("2015" to "TYPE_SECURE_SYSTEM_OVERLAY")
add("2016" to "TYPE_DRAG")
add("2017" to "TYPE_STATUS_BAR_SUB_PANEL")
add("2018" to "TYPE_POINTER")
add("2019" to "TYPE_NAVIGATION_BAR")
add("2020" to "TYPE_VOLUME_OVERLAY")
add("2021" to "TYPE_BOOT_PROGRESS")
add("2022" to "TYPE_INPUT_CONSUMER")
add("2024" to "TYPE_NAVIGATION_BAR_PANEL")
add("2026" to "TYPE_DISPLAY_OVERLAY")
add("2027" to "TYPE_MAGNIFICATION_OVERLAY")
add("2030" to "TYPE_PRIVATE_PRESENTATION")
add("2031" to "TYPE_VOICE_INTERACTION")
add("2032" to "TYPE_ACCESSIBILITY_OVERLAY")
add("2033" to "TYPE_VOICE_INTERACTION_STARTING")
add("2034" to "TYPE_DOCK_DIVIDER")
add("2035" to "TYPE_QS_DIALOG")
add("2036" to "TYPE_SCREENSHOT")
add("2037" to "TYPE_PRESENTATION")
add("2038" to "TYPE_APPLICATION_OVERLAY")
add("2039" to "TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY")
add("2040" to "TYPE_NOTIFICATION_SHADE")
add("2041" to "TYPE_STATUS_BAR_ADDITIONAL")
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package github.tornaco.android.thanos.services.patch.common.wm

import com.elvishew.xlog.XLog
import util.XposedHelpers
import java.util.function.Consumer

object XWindowManagerService {
@JvmStatic
fun wmsClass(classLoader: ClassLoader): Class<*> {
return XposedHelpers.findClass(
"com.android.server.wm.WindowManagerService",
classLoader
)
}

@JvmStatic
fun getInstance(classLoader: ClassLoader): Any? {
return kotlin.runCatching {
XposedHelpers.callStaticMethod(
wmsClass(classLoader),
"getInstance"
)
}.getOrElse {
XLog.e("XWindowManagerService#getInstance error")
null
}
}

@JvmStatic
fun getRoot(wms: Any): Any? {
return kotlin.runCatching {
XposedHelpers.getObjectField(
wms,
"mRoot"
)
}.getOrElse {
XLog.e("XWindowManagerService#getRoot error")
null
}
}

// void forAllWindows(Consumer<WindowState> var1, boolean var2)
@JvmStatic
fun forAllWindows(root: Any, consumer: Consumer<*>) {
kotlin.runCatching {
XposedHelpers.callMethod(
root,
"forAllWindows",
consumer,
false /* traverseTopToBottom */
)
}.onFailure {
XLog.e("XWindowManagerService#forAllWindows error")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package github.tornaco.android.thanos.services.patch.common.wm

import android.annotation.SuppressLint
import com.elvishew.xlog.XLog
import github.tornaco.android.thanos.core.wm.WindowState
import util.XposedHelpers


object XWindowState {

@SuppressLint("PrivateApi")
@JvmStatic
fun getState(state: Any?): WindowState? {
return if (state == null) null else try {
val visible = XposedHelpers.callMethod(state, "isVisible") as Boolean
val type = XposedHelpers.callMethod(state, "getWindowType") as Int
val uid = XposedHelpers.callMethod(state, "getOwningUid") as Int
val ownPackageName =
XposedHelpers.callMethod(state, "getOwningPackage") as String
WindowState(
ownPackageName,
uid,
visible,
type
)
} catch (e: Throwable) {
XLog.e("XWindowState#getState error", e)
null
}
}
}
1 change: 1 addition & 0 deletions android/android_sdk/thanos.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ parcelable github.tornaco.android.thanos.core.power.SeenWakeLock;
parcelable github.tornaco.android.thanos.core.su.SuRes;
parcelable github.tornaco.android.thanos.core.plus.RR;
parcelable github.tornaco.android.thanos.core.os.SwapInfo;
parcelable github.tornaco.android.thanos.core.wm.WindowState;

parcelable android.content.pm.UserInfo;
2 changes: 1 addition & 1 deletion android/internal/Thanox-Internal

0 comments on commit 93a1cd7

Please sign in to comment.