Tuesday, March 29, 2016

applications - Determine which app is drawing on top of other apps?


Is there a way to determine which application is drawing on top of other applications?


For example, Facebook Messenger app can draw the chat bubbles on top of everything, but how do I know which app is doing this?


My problem:


I have an app which is drawing ads on top of everything and I wanna know which app is doing this. Not just to uninstall it, but to warn everyone that uses this app. (I didn't install any application recently and I already verified the recent updates.)



I tried to use the Dump View Hierarchy for UI Automator from the Android Studio, but it seems that the applications that draw on top can't be selected this way.


(Click image to enlarge)


Android Studio Screen



Answer



Note:



  • should already be setup in PC.

  • For Android earlier than version 4.4.x, root access may be required.

  • Some commands would not work on Android earlier than version 5.1.

  • Jump to heading "Apps for apps" if you're unfamiliar or uncomfortable with command-line and/or the command-line fails to solve your issue.






Setup and run this command:


adb shell "dumpsys window windows | toybox grep -i system_alert_window"

You would get the output of all the active overlays on the screen. Example of an output with DU Screen Recorder, Tasker and AZ Screen Recorder showing active overlays on screen:



bash-4.3# adb shell "dumpsys window windows| toybox grep -i system_alert_window"
mOwnerUid=10087 mShowToOwnerOnly=true package=net.dinglisch.android.tasker appop=SYSTEM_ALERT_WINDOW

mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW
mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW
mOwnerUid=10649 mShowToOwnerOnly=true package=com.duapps.recorder appop=SYSTEM_ALERT_WINDOW
mOwnerUid=10649 mShowToOwnerOnly=true package=com.duapps.recorder appop=SYSTEM_ALERT_WINDOW
mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW
mOwnerUid=10604 mShowToOwnerOnly=true package=com.hecorat.screenrecorder.free appop=SYSTEM_ALERT_WINDOW
mOwnerUid=10638 mShowToOwnerOnly=true package=ninja.sesame.app.edge appop=SYSTEM_ALERT_WINDOW

The highlighted text next to package= and before appop is the package name(s) of the app(s) currently drawing overlay on the screen. In your case, the output including the package name(s) would differ.


Note down the package name(s) (henceforth as PKG) and execute this command:



adb shell am force-stop PKG

Replace PKG with the package name you noted down. If you had multiple package names, repeat the command with one package name at a time.


The command would forcefully stop the app and thereby discard the overlay. This should work. You may alternatively strip the permission of "Draw over other apps" (screen overlay in short) from the apps using this command:


adb shell appops set PKG SYSTEM_ALERT_WINDOW ignore

Again, replace PKG with package name as necessary. Furthermore, you may have to repeat the force-stop command for the PKG. If you decide to revert the changes, replace ignore with allow in aforesaid command.


You may alternatively use App Ops to manage the permissions from GUI.


To know which package name corresponds to which app you could try an open source app like Applications Info. Search by package name and you would get the App's name.




You really need not to read anymore now. I'm leaving the earlier solution (i.e. following section) intact because 21 people who voted it did find that helpful and I don't want to mess up anymore.




A simple way would be to find out all the apps having the permission "draw over other apps" and then single out them from the ones currently active on the screen. Afterwards, engage in force-stopping those common apps until you pin-point the app responsible for the active overlay.



The permission required by an app to create an overlay is android.permission.SYSTEM_ALERT_WINDOW (draw over other apps).


We need to find out all the installed apps having the said permission. It is up to you to find out a method for this. My answer here may aid you.


Note that we need the apps' package names and not their labels.



Execute the command


adb shell dumpsys window windows 


This would give you details on whatsoever causing something to be displayed on the screen, including the component name of an app causing it.


How you would extract the name is up to you. You may try this command however


adb shell 'dumpsys window windows | grep "Window #"'

If you receive the error: 'grep' is not recognized as an internal or external command, on Windows try this alternative command:


adb shell "dumpsys window windows | grep 'Window #'"

Demo output




Window #4 Window{42065d50 u0 com.android.phone/com.mediatek.phone.UssdAlertActivity}:
Window #5 Window{42197468 u0 ginlemon.flowerpro/ginlemon.flower.HomeScreen}:
Window #6 Window{420fdb58 u0 com.android.systemui.ImageWallpaper}:
Window #7 Window{421e3b88 u0 com.android.contacts/com.android.contacts.activities.DialtactsActivity}:

In the above output, anything succeeding u0 and preceding / is the package name of an app. An app can have multiple components displaying something on the screen.


You've to create a list of those package names. If you have BusyBox installed, you can do


adb shell 'dumpsys window windows | grep "Window #" | sed -e "s/.*u0 //g" -e "s/\/.*//g" -e "s/}://g"'

Anyhow, now you would be having two lists:




  • First list contains all the apps having the permission android.permission.SYSTEM_ALERT_WINDOW.

  • Second list contains all the apps actively displaying something on the screen.


Compare these two lists and single out apps which are common in both the lists. This third list would constitute of apps having the permission to draw overlay and are currently drawing an active overlay on screen.



Kill each of the apps from the third list one by one and notice the state of overlay. You can use am force-stop PACKAGE_NAME --user 0 or any other method that suits you. PACKAGE_NAME is the package name of the app.


EDIT: It is not necessary to kill an app. You can consider denying the app the permission to draw over other apps. Use this command:


adb shell 'appops set PACKAGE SYSTEM_ALERT_WINDOW deny'   # replace PACKAGE with package name of the app


To revert the changes, replace deny with allow in the said command and execute it.


If you're running Android Marshmallow, this answer by Andrew T. can be used.


Note: The aforesaid command is successfully tested on Android 5.1.1 and 6.0.1 (CM builds). It is also possible that the command works on Android 5.0.x but I can't guarantee. Execution of that command on Android version released prior to Lollipop would cause failure.


Since often the overlay is perceivable, it would instantly disappear the moment the app causing it is killed, hence, you would know which app was causing that overlay.



Originally suggested by Izzy, you can use an app which has the functionality of listing permissions granted to installed apps, to single out the apps having the permission "draw over other apps". You can either search such an app on your own or use the the list Permission checker maintained by Izzy on his website.


You would also need a process/app manager to force-stop/kill some processes. I recommend OS Monitor but you're at liberty to use any competent app. See related apps under System Info.


For demonstration purposes only


I tried Advanced Permission Manager to list apps with permission to "draw over other apps". Afterwards, I switched to OS Monitor to see the apps running in foreground and background. I matched the output from both the apps and individually force-stopped the apps common in both. You can kill a process from inside the OS Monitor, so no need to switch to App settings.


(Click image to enlarge)



IMG: IMG: IMG:


No comments:

Post a Comment

samsung galaxy s 2 - Cannot restore Kies backup after firmware upgrade

I backed up my Samsung Galaxy S2 on Kies before updating to Ice Cream Sandwich. After the upgrade I tried to restore, but the restore fails ...