package com.mogo.launcher.lancet; import android.app.Activity; import android.app.Dialog; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import android.widget.PopupWindow; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.knightboost.lancet.api.Origin; import com.knightboost.lancet.api.Scope; import com.knightboost.lancet.api.This; import com.knightboost.lancet.api.annotations.Group; import com.knightboost.lancet.api.annotations.Insert; import com.knightboost.lancet.api.annotations.ReplaceInvoke; import com.knightboost.lancet.api.annotations.TargetClass; import com.knightboost.lancet.api.annotations.TargetMethod; import com.knightboost.lancet.api.annotations.Weaver; import com.mogo.eagle.core.function.api.devatools.mofang.IMoGoMoFangProvider; import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager; import com.mogo.launcher.R; @Keep @Weaver @Group("window_callback") public class WindowCallbackLancet { @Insert(mayCreateSuper = true) @TargetClass(value = "androidx.appcompat.app.AppCompatActivity", scope = Scope.SELF) @TargetMethod(methodName = "onCreate") protected void onCreate(@Nullable Bundle savedInstanceState) { Origin.callVoid(); Object o = This.get(); if (o instanceof Activity) { Activity activity = (Activity) o; IMoGoMoFangProvider mofang = CallerDevaToolsManager.INSTANCE.mofang(); if (mofang != null) { Window.Callback callback = mofang.provideWindowCallback(activity.getWindow().getCallback()); activity.getWindow().setCallback(callback); } } } @Insert(mayCreateSuper = true) @TargetClass(value = "androidx.fragment.app.DialogFragment", scope = Scope.SELF) @TargetMethod(methodName = "onCreateDialog") public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { Dialog dialog = (Dialog) Origin.call(); IMoGoMoFangProvider mofang = CallerDevaToolsManager.INSTANCE.mofang(); if (dialog.getWindow() != null && mofang != null) { dialog.getWindow().setCallback(mofang.provideWindowCallback(dialog.getWindow().getCallback())); } return dialog; } @TargetClass(value = "android.view.WindowManager",scope = Scope.SELF) @TargetMethod(methodName = "addView") @ReplaceInvoke public static void proxyWindowManagerAddView(WindowManager manager, View view, ViewGroup.LayoutParams params) { view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { private final GlobalFocusChangedListener listener = new GlobalFocusChangedListener(); private boolean isAdd = false; @Override public void onViewAttachedToWindow(@NonNull View v) { try { v.getRootView().getViewTreeObserver().addOnGlobalFocusChangeListener(listener); isAdd = true; } catch (Throwable t) { t.printStackTrace(); } } @Override public void onViewDetachedFromWindow(@NonNull View v) { try { if (isAdd) { v.getRootView().getViewTreeObserver().removeOnGlobalFocusChangeListener(listener); } } catch (Throwable t) { t.printStackTrace(); } } }); manager.addView(view, params); } @TargetClass(value = "android.widget.PopupWindow",scope = Scope.ALL) @TargetMethod(methodName = "setContentView") @ReplaceInvoke public static void proxyPopupWindowSetContentView(PopupWindow window, View view) { view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { private final GlobalFocusChangedListener listener = new GlobalFocusChangedListener(); private boolean isAdd = false; @Override public void onViewAttachedToWindow(@NonNull View v) { try { v.getRootView().getViewTreeObserver().addOnGlobalFocusChangeListener(listener); isAdd = true; } catch (Throwable t) { t.printStackTrace(); } } @Override public void onViewDetachedFromWindow(@NonNull View v) { try { if (isAdd) { v.getRootView().getViewTreeObserver().removeOnGlobalFocusChangeListener(listener); } } catch (Throwable t) { t.printStackTrace(); } } }); window.setContentView(view); } private static class GlobalFocusChangedListener implements ViewTreeObserver.OnGlobalFocusChangeListener { private Window.Callback mCallBack = null; @Override public void onGlobalFocusChanged(View oldFocus, View newFocus) { if (newFocus != null) { Object tag = newFocus.getTag(R.id.on_key_set); if (tag == null) { newFocus.setTag(R.id.on_key_set, 1); newFocus.setOnKeyListener((v, keyCode, event) -> { if (mCallBack == null) { IMoGoMoFangProvider mofang = CallerDevaToolsManager.INSTANCE.mofang(); if (mofang != null) { mCallBack = mofang.provideWindowCallback(null); } } if (mCallBack != null) { return mCallBack.dispatchKeyEvent(event); } return false; }); } } } } }