cwac-presentation icon indicating copy to clipboard operation
cwac-presentation copied to clipboard

crash on Android 7.1.1

Open teicher opened this issue 5 years ago • 9 comments

Hello, I just checked out "master", imported in Android Studio and ran (otherwise untouched) on an Android 7.1.1 device. it crashes on me with

2020-10-28 10:38:24.687 5315-5315/? W/System: ClassLoader referenced unknown path: /data/app/com.commonsware.cwac.preso.demo.service-1/lib/arm64
2020-10-28 10:38:24.726 5315-5315/? W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
2020-10-28 10:38:24.753 5315-5315/? V/BoostFramework: mAcquireFunc method = public int com.qualcomm.qti.Performance.perfLockAcquire(int,int[])
2020-10-28 10:38:24.753 5315-5315/? V/BoostFramework: mReleaseFunc method = public int com.qualcomm.qti.Performance.perfLockRelease()
2020-10-28 10:38:24.753 5315-5315/? V/BoostFramework: mAcquireTouchFunc method = public int com.qualcomm.qti.Performance.perfLockAcquireTouch(android.view.MotionEvent,android.util.DisplayMetrics,int,int[])
2020-10-28 10:38:24.753 5315-5315/? V/BoostFramework: mIOPStart method = public int com.qualcomm.qti.Performance.perfIOPrefetchStart(int,java.lang.String)
2020-10-28 10:38:24.753 5315-5315/? V/BoostFramework: mIOPStop method = public int com.qualcomm.qti.Performance.perfIOPrefetchStop()
2020-10-28 10:38:24.756 5315-5315/? V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@d805c71
2020-10-28 10:38:24.756 5315-5315/? V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@c37fa56
2020-10-28 10:38:24.764 5315-5315/? I/art: Rejecting re-init on previously-failed class java.lang.Class<androidx.core.view.ViewCompat$OnUnhandledKeyEventListenerWrapper>: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/view/View$OnUnhandledKeyEventListener;
2020-10-28 10:38:24.764 5315-5315/? I/art:     at void androidx.core.view.ViewCompat.setBackground(android.view.View, android.graphics.drawable.Drawable) (ViewCompat.java:2341)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at void androidx.appcompat.widget.ActionBarContainer.<init>(android.content.Context, android.util.AttributeSet) (ActionBarContainer.java:62)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at java.lang.Object java.lang.reflect.Constructor.newInstance0!(java.lang.Object[]) (Constructor.java:-2)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:430)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.createView(java.lang.String, java.lang.String, android.util.AttributeSet) (LayoutInflater.java:645)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:787)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet) (LayoutInflater.java:727)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at void android.view.LayoutInflater.rInflate(org.xmlpull.v1.XmlPullParser, android.view.View, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:858)
2020-10-28 10:38:24.764 5315-5315/? I/art:     at void android.view.LayoutInflater.rInflateChildren(org.xmlpull.v1.XmlPullParser, android.view.View, android.util.AttributeSet, boolean) (LayoutInflater.java:821)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.inflate(org.xmlpull.v1.XmlPullParser, android.view.ViewGroup, boolean) (LayoutInflater.java:518)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup, boolean) (LayoutInflater.java:426)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup) (LayoutInflater.java:377)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.ViewGroup androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor() (AppCompatDelegateImpl.java:607)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor() (AppCompatDelegateImpl.java:518)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.app.AppCompatDelegateImpl.setContentView(int) (AppCompatDelegateImpl.java:466)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.app.AppCompatActivity.setContentView(int) (AppCompatActivity.java:140)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void com.commonsware.cwac.preso.demo.service.MainActivity.onCreate(android.os.Bundle) (MainActivity.java:28)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.Activity.performCreate(android.os.Bundle) (Activity.java:6720)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle) (Instrumentation.java:1119)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2618)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:2726)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread.-wrap12(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1477)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.os.Looper.loop() (Looper.java:154)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6119)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:886)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:776)
2020-10-28 10:38:24.765 5315-5315/? I/art: Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.View$OnUnhandledKeyEventListener" on path: DexPathList[[zip file "/data/app/com.commonsware.cwac.preso.demo.service-1/base.apk"],nativeLibraryDirectories=[/data/app/com.commonsware.cwac.preso.demo.service-1/lib/arm64, /system/lib64, /vendor/lib64]]
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:56)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:380)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.core.view.ViewCompat.setBackground(android.view.View, android.graphics.drawable.Drawable) (ViewCompat.java:2341)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.widget.ActionBarContainer.<init>(android.content.Context, android.util.AttributeSet) (ActionBarContainer.java:62)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Object java.lang.reflect.Constructor.newInstance0!(java.lang.Object[]) (Constructor.java:-2)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:430)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.createView(java.lang.String, java.lang.String, android.util.AttributeSet) (LayoutInflater.java:645)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:787)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet) (LayoutInflater.java:727)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.view.LayoutInflater.rInflate(org.xmlpull.v1.XmlPullParser, android.view.View, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:858)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.view.LayoutInflater.rInflateChildren(org.xmlpull.v1.XmlPullParser, android.view.View, android.util.AttributeSet, boolean) (LayoutInflater.java:821)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.inflate(org.xmlpull.v1.XmlPullParser, android.view.ViewGroup, boolean) (LayoutInflater.java:518)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup, boolean) (LayoutInflater.java:426)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup) (LayoutInflater.java:377)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.view.ViewGroup androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor() (AppCompatDelegateImpl.java:607)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor() (AppCompatDelegateImpl.java:518)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.app.AppCompatDelegateImpl.setContentView(int) (AppCompatDelegateImpl.java:466)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void androidx.appcompat.app.AppCompatActivity.setContentView(int) (AppCompatActivity.java:140)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void com.commonsware.cwac.preso.demo.service.MainActivity.onCreate(android.os.Bundle) (MainActivity.java:28)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.Activity.performCreate(android.os.Bundle) (Activity.java:6720)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle) (Instrumentation.java:1119)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent) (ActivityThread.java:2618)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:2726)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread.-wrap12(android.app.ActivityThread, android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:-1)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1477)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.os.Looper.loop() (Looper.java:154)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6119)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:886)
2020-10-28 10:38:24.765 5315-5315/? I/art:     at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:776)
2020-10-28 10:38:24.896 5315-5315/? D/AndroidRuntime: Shutting down VM
2020-10-28 10:38:24.910 5315-5315/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.commonsware.cwac.preso.demo.service, PID: 5315
    java.lang.RuntimeException: Unable to create service com.commonsware.cwac.preso.demo.service.SlideshowService: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@7d96dcf -- permission denied for window type 2003
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3201)
        at android.app.ActivityThread.-wrap5(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
     Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@7d96dcf -- permission denied for window type 2003
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:706)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:348)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
        at com.commonsware.cwac.preso.PresentationService.showPreso(PresentationService.java:104)
        at com.commonsware.cwac.preso.PresentationHelper.handleRoute(PresentationHelper.java:133)
        at com.commonsware.cwac.preso.PresentationHelper.onResume(PresentationHelper.java:70)
        at com.commonsware.cwac.preso.PresentationService.onCreate(PresentationService.java:79)
        at com.commonsware.cwac.preso.demo.service.SlideshowService.onCreate(SlideshowService.java:51)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3191)
        at android.app.ActivityThread.-wrap5(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6119) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

any idea hot to fix or better diagnose ?

Thanks Tom.

teicher avatar Oct 28 '20 09:10 teicher

You appeared to try the PresentationService demo. The documentation for PresentationService has:

Note that using this on Android 7.1+, where a TYPE_SYSTEM_ALERT window is used, requires the user to go into Settings and allow your app to draw over other apps.

Did you do this step?

commonsguy avatar Oct 28 '20 13:10 commonsguy

Ah, I missed that, many thanks, with the setting it starts.

But this can't be the (full) solution if anybody wants to use this in their app.... As a minimum, the problem should be diagnosed / caught and display a log message and a clear exception that the (programmer) user of the Service can recognize.

If this permission can be checked and requested at runtime, maybe we should do so?

So is this about PresentationService.getWindowType() ? Then maybe we can fallback to some other TYPE for Android >= O that does not require special permission ?

What do you think? Cheers, Tom.

teicher avatar Oct 28 '20 14:10 teicher

But this can't be the (full) solution if anybody wants to use this in their app....

PresentationService is a hack. On Android 8.0+, don't use it. Quoting the docs: "On Android 8.0+, please use multi-display instead of PresentationService."

If this permission can be checked and requested at runtime, maybe we should do so?

One of your activities needs to do this. You cannot request any runtime permissions from a service, and you cannot request SYSTEM_ALERT_WINDOW at runtime from anywhere, as it is not a standard runtime permission.

Then maybe we can fallback to some other TYPE for Android >= O that does not require special permission ?

There is none, to the best of my knowledge. I don't want to use TYPE_SYSTEM_ALERT, but I had no choice due to restrictions placed on TYPE_TOAST with Android 7.1.

commonsguy avatar Oct 28 '20 14:10 commonsguy

There's a few suggestions including launching the app permissions dialog at https://stackoverflow.com/questions/36016369/system-alert-window-how-to-get-this-permission-automatically-on-android-6-0-an

Since I have no control on what Android device my users install/run my app, does this mean PresentationService can't be used for real (any more) ?

teicher avatar Oct 28 '20 14:10 teicher

There's a few suggestions including launching the app permissions dialog at

None of that should be done from a service. Your activity that starts the service should be checking this stuff before starting the service.

Since I have no control on what Android device my users install/run my app, does this mean PresentationService can't be used for real (any more) ?

Again, your activity that starts the service should be checking this stuff before starting the service. If you do not wish to do that, then I agree that you should not use PresentationService. Also, as I noted previously, PresentationService is a hack — prior to Android 8.0, this pattern (showing something on an external display from the background) was never properly supported.

commonsguy avatar Oct 28 '20 14:10 commonsguy

Yeah, that's right; I was just thinking a "demo" app should be running out-of-the box. And the code that requests the permissions (in the demo) would be a valuable guidance for implementors; the code to do this could even be put to PresentationHelper.

teicher avatar Oct 28 '20 14:10 teicher

ok so this is my "change request" ;-)

public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (PermissionChecker.checkSelfPermission(this, Manifest.permission.SYSTEM_ALERT_WINDOW)!= PermissionChecker.PERMISSION_GRANTED) {
      Toast.makeText(this, "This demo app need SYSTEM_ALERT_WINDOW manually granted in app settings", Toast.LENGTH_LONG ).show();
      finish();
    } else {
      setContentView(R.layout.activity_main);
      startService(new Intent(this, SlideshowService.class));
    }
  }

teicher avatar Oct 28 '20 14:10 teicher

unfortunately, I actually came here to learn how to make Presentations that survive activity changes (for minSdkVersion 17 and all up) and I'm not sure I want to do this like PresentationService now...

teicher avatar Oct 28 '20 15:10 teicher

ok so this is my "change request" ;-)

Ah, OK, you are looking for a change to the demo. I can look to do that at some point.

I actually came here to learn how to make Presentations that survive activity changes (for minSdkVersion 17 and all up)

The best answer for that is to use android:configChanges to opt out of the destroy-and-recreate cycle for all possible configuration changes, then handle all of those directly in your code. This should allow your Presentation survive configuration changes, as the activity (and its Presentation) is not destroyed.

I'm not sure I want to do this like PresentationService

I would not recommend PresentationService for that scenario.

commonsguy avatar Oct 28 '20 15:10 commonsguy