-
-
Save RikkaW/be3fe4178903702c54ec73b2fc1187fe to your computer and use it in GitHub Desktop.
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); | |
} |
Change opPackageName? I don't remember:(
Btw, this will never work starting from Android 14 QPR 3 or Android 15, as addView now checks if the calling process is a valid Android app process.
Maybe there is some workaround for this? The most important thing I need is to draw something as an overlay from background process.
I am not writing viruses. Simply some oems put code to limit GPU performance of background apps.
Maybe SurfaceControl.Transactions?
From @huynhtanloc2612:
Hi @twaik You was correct. After I made subclass with a separated file MyContext.class, above error disappeared.
However, after code run, it has new below error. Do you have any advice?
java.lang.SecurityException: Given calling package android does not match caller's uid 2000 at ........
Late reply, I know, but the solution to this issue is to wrap your context to override getOpPackageName()
, like so:
Context context = new ContextWrapper(_context) {
/* @Override getSystemService() here if you want, not necessary for Toasts */
@Override
public String getOpPackageName() {
return "com.android.shell"; // aka ADB shell package name
}
};
I successfully managed to get a toast to show on Android 14 with the following:
Context _context = ActivityThread.systemMain().getSystemContext();
Context context = new ContextWrapper(_context) {
@Override
public String getOpPackageName() {
// I actually used "com.termux" here, because I was playing around with
// this in Termux, but, no matter.
return "com.android.shell"; // aka ADB shell package name
}
};
Toast.makeText(context, "test", Toast.LENGTH_LONG).show();
Thanks @JacobTDC for your comment
I've tried your suggestion
public class ShowToast {
public static void main(String[] args) {
Binder token = new Binder();
Looper.prepareMainLooper();
try{
Context _context = ActivityThread.systemMain().getSystemContext();
Context context = new ContextWrapper(_context) {
@Override
public String getOpPackageName() {
return "com.android.shell"; // aka ADB shell package name
}
};
Toast.makeText(context, "test", Toast.LENGTH_LONG).show();
} catch (Throwable tr) {
tr.printStackTrace(System.err);
}
}
}
but I still got the below error on Galaxy phone with Android 14
$ adb shell app_process -cp /data/local/tmp/toast.dex / com.htl.toast14.ShowToast
java.lang.SecurityException: Given calling package android does not match caller's uid 2000
at android.os.Parcel.createExceptionOrNull(Parcel.java:3069)
at android.os.Parcel.createException(Parcel.java:3053)
at android.os.Parcel.readException(Parcel.java:3036)
at android.os.Parcel.readException(Parcel.java:2978)
at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:6393)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:8160)
at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:3838)
at android.content.ContentResolver.acquireProvider(ContentResolver.java:2539)
at android.provider.Settings$ContentProviderHolder.getProvider(Settings.java:3328)
at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:3595)
at android.provider.Settings$System.getStringForUser(Settings.java:4362)
at android.provider.Settings$System.getIntForUser(Settings.java:4493)
at android.provider.Settings$System.getInt(Settings.java:4465)
at android.widget.Toast.checkGameHomeAllowList(Toast.java:1108)
at android.widget.Toast.show(Toast.java:313)
at com.htl.toast14.ShowToast.main(ShowToast.java:28)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:395)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.am.ContentProviderHelper.getContentProvider(ContentProviderHelper.java:148)
at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:8700)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:3091)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3202)
at android.os.Binder.execTransactInternal(Binder.java:1375)
Do you have any idea?
And can you show your full code?
Thanks.
@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.
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"
And unfortunately I am getting this on Android 12.
Any suggestions?