Skip to content

Instantly share code, notes, and snippets.

@RikkaW
Last active October 2, 2024 14:10
Show Gist options
  • Save RikkaW/be3fe4178903702c54ec73b2fc1187fe to your computer and use it in GitHub Desktop.
Save RikkaW/be3fe4178903702c54ec73b2fc1187fe to your computer and use it in GitHub Desktop.
show window in app_process (impossible to work from Android 14 QPR 3 or Android 15, as addView requires the calling process an Android app process)
token = new Binder();
try {
Context _context = android.app.ActivityThread.systemMain().getSystemContext();
final Context context = new ContextWrapper(_context) {
@Override
public Object getSystemService(String name) {
if (Context.WINDOW_SERVICE.equals(name)) {
WindowManager wm = (WindowManager) super.getSystemService(name);
if (wm != null) {
((android.view.WindowManagerImpl) wm).setDefaultToken(token);
}
return wm;
}
return super.getSystemService(name);
}
};
context.setTheme(android.R.style.Theme_Material_Light);
CharSequence label = context.getPackageManager().getApplicationLabel(context.getPackageManager().getApplicationInfo("com.android.settings", 0));
LogUtils.i("label " + label);
android.widget.Toast.makeText(context, "test", Toast.LENGTH_LONG).show();
LogUtils.i("toast");
android.view.WindowManager wm = context.getSystemService(WindowManager.class);
LogUtils.i("class: " + wm.getClass().getName());
//((android.view.WindowManagerImpl) wm).setDefaultToken(token);
LinearLayout root = new LinearLayout(context);
root.setBackground(new ColorDrawable(0xffffffff));
TextView textView = new TextView(context);
textView.setText("test");
root.addView(textView);
Button button = new Button(context);
button.setSoundEffectsEnabled(false);
button.setText("test");
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "?!", Toast.LENGTH_LONG).show();
}
});
root.addView(button);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
params.x = 0;
params.y = 0;
wm.addView(root, params);
} catch (Throwable tr) {
LogUtils.e(tr.getMessage(), tr);
}
@JacobTDC
Copy link

JacobTDC commented Oct 1, 2024

@huynhtanloc2612, the following works for me, I tested it in ADB as well.

$ adb shell app_process -cp /data/local/tmp/toast.dex /system/bin/ { class/package path }.ShowToast
public class ShowToast {
  public static final void main(String[] args) {
    Looper.prepare();

    ActivityThread activityThread = ActivityThread.systemMain();

    Context _context = activityThread.getSystemContext();
    Context context = new ContextWrapper(_context) {
      @Override
      public String getOpPackageName() {
        return "com.android.shell";
      }
    };

    // Maybe create a `new Handler(Looper.myLooper())` and wrap this
    // in `handler.post(() -> { ... }); Looper.loop();` if it doesn't work?
    // If you do, don't forget to add `Looper.myLooper().quit[Safely]()`
    // inside the `handler.post(() -> { ... });`.
    Toast.makeText(context, "test", Toast.LENGTH_LONG).show();
  }
}

If that doesn't work, maybe try something like this for creating and wrapping the context:

  static Context createPackageContext(String packageName) {
    Context sysCtx = ActivityThread.systemMain().getSystemContext();

    Context _context;
    try {
      _context = (Context) Context.class
        .getMethod("createPackageContextAsUser", new Class[] {
          String.class,
          int.class,
          UserHandle.class })
        .invoke(sysCtx, packageName, 0, Process.myUserHandle());
    } catch (Exception exc) {
      throw new RuntimeException(exc);
    }

    return new ContextWrapper(_context) {
      @Override
      public String getOpPackageName() {
        return packageName;
      }
    };
  }

What device are you using? I see you're using a Galaxy. That could make a difference, but I'm not sure. I'm using a Google Pixel 8 Pro.

@huynhtanloc2612
Copy link

Thanks @JacobTDC ,
Try your above suggestions but the same error happens when it executes Toast.makeText(...).show()
java.lang.SecurityException: Given calling package android does not match caller's uid 2000

I think it requires Android app process as the note of @RikkaW "addView requires the calling process an Android app process"

@D-R-99
Copy link

D-R-99 commented Oct 2, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment