Status Update
Comments
al...@google.com <al...@google.com> #2
Classfile /tmp/non-jetified/org/bouncycastle/jce/provider/ExtCRLException.class
Last modified Mar 1, 2015; size 362 bytes
MD5 checksum 3968a716f9e60e1ad36c34157bd0239f
class org.bouncycastle.jce.provider.ExtCRLException extends java.security.cert.CRLException
minor version: 0
major version: 49
flags: ACC_SUPER
Constant pool:
#1 = Utf8 <init>
#2 = Utf8 cause
#3 = Utf8 getCause
#4 = Utf8 java/security/cert/CRLException
#5 = Utf8 org/bouncycastle/jce/provider/ExtCRLException
#6 = Class #4 // java/security/cert/CRLException
#7 = Class #5 // org/bouncycastle/jce/provider/ExtCRLException
#8 = Utf8 Ljava/lang/Throwable;
#9 = Utf8 (Ljava/lang/String;)V
#10 = Utf8 ()Ljava/lang/Throwable;
#11 = Utf8 (Ljava/lang/String;Ljava/lang/Throwable;)V
#12 = NameAndType #2:#8 // cause:Ljava/lang/Throwable;
#13 = NameAndType #1:#9 // "<init>":(Ljava/lang/String;)V
#14 = Fieldref #7.#12 // org/bouncycastle/jce/provider/ExtCRLException.cause:Ljava/lang/Throwable;
#15 = Methodref #6.#13 // java/security/cert/CRLException."<init>":(Ljava/lang/String;)V
#16 = Utf8 Code
{
java.lang.Throwable cause;
descriptor: Ljava/lang/Throwable;
flags:
org.bouncycastle.jce.provider.ExtCRLException(java.lang.String, java.lang.Throwable);
descriptor: (Ljava/lang/String;Ljava/lang/Throwable;)V
flags:
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: aload_1
2: invokespecial #15 // Method java/security/cert/CRLException."<init>":(Ljava/lang/String;)V
5: aload_0
6: aload_2
7: putfield #14 // Field cause:Ljava/lang/Throwable;
10: return
public java.lang.Throwable getCause();
descriptor: ()Ljava/lang/Throwable;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #14 // Field cause:Ljava/lang/Throwable;
4: areturn
}
One processed with Jetifier:
Classfile /tmp/jetified/org/bouncycastle/jce/provider/ExtCRLException.class
Last modified Oct 14, 2019; size 362 bytes
MD5 checksum 76bc557706ee3480e53d88b21316913f
class org.bouncycastle.jce.provider.ExtCRLException extends java.security.cert.CRLException
minor version: 0
major version: 49
flags: ACC_SUPER
Constant pool:
#1 = Utf8 org/bouncycastle/jce/provider/ExtCRLException
#2 = Class #1 // org/bouncycastle/jce/provider/ExtCRLException
#3 = Utf8 java/security/cert/CRLException
#4 = Class #3 // java/security/cert/CRLException
#5 = Utf8 cause
#6 = Utf8 Ljava/lang/Throwable;
#7 = Utf8 <init>
#8 = Utf8 (Ljava/lang/String;Ljava/lang/Throwable;)V
#9 = Utf8 (Ljava/lang/String;)V
#10 = NameAndType #7:#9 // "<init>":(Ljava/lang/String;)V
#11 = Methodref #4.#10 // java/security/cert/CRLException."<init>":(Ljava/lang/String;)V
#12 = NameAndType #5:#6 // cause:Ljava/lang/Throwable;
#13 = Fieldref #2.#12 // org/bouncycastle/jce/provider/ExtCRLException.cause:Ljava/lang/Throwable;
#14 = Utf8 getCause
#15 = Utf8 ()Ljava/lang/Throwable;
#16 = Utf8 Code
{
java.lang.Throwable cause;
descriptor: Ljava/lang/Throwable;
flags:
org.bouncycastle.jce.provider.ExtCRLException(java.lang.String, java.lang.Throwable);
descriptor: (Ljava/lang/String;Ljava/lang/Throwable;)V
flags:
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: aload_1
2: invokespecial #11 // Method java/security/cert/CRLException."<init>":(Ljava/lang/String;)V
5: aload_0
6: aload_2
7: putfield #13 // Field cause:Ljava/lang/Throwable;
10: return
public java.lang.Throwable getCause();
descriptor: ()Ljava/lang/Throwable;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #13 // Field cause:Ljava/lang/Throwable;
4: areturn
}
Changes in the constants pool cause changes in the code (indices change), which causes different MD5 checksums. This means that signatures will not match any more.
This started happening in 3.6.0-beta01 because we are using Jetifier with copyUnmodifiedLibsAlso=true flag (previously it was false).
al...@google.com <al...@google.com> #3
android.jetifier.blacklist=.*bcprov.*
This will avoid Jetifying the bouncycastle library.
cf...@coyote-group.com <cf...@coyote-group.com> #4
al...@google.com <al...@google.com> #6
al...@google.com <al...@google.com> #7
To avoid waiting for new Android Studio you can workaround this in the meantime by forcing usage of a new version of jetifier in gradle:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:x.y.z'
classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta08' // <- Add this
}
}
al...@google.com <al...@google.com> #8
cf...@coyote-group.com <cf...@coyote-group.com> #9
cf...@coyote-group.com <cf...@coyote-group.com> #10
appcompat version 1.3.0:
MainActivity -> ActivityB -> ActivityC -> "change night mode"
=>logs:
05-21 14:41:04.307 D/NightMode(14750): ActivityC onConfigurationChanged
05-21 14:41:04.307 D/NightMode(14750): ActivityC onNightModeChanged mode 2, resource configuration in dark mode : true
------------> no configurationChanged nor onNightModeChanged in previous activities, even when back)
then back -> back -> ActivityB -> ActivityC -> "change night mode"
=>logs:
05-21 14:43:41.317 D/NightMode(14750): ActivityC onConfigurationChanged
05-21 14:43:41.317 D/NightMode(14750): ActivityC onNightModeChanged mode 1, resource configuration in dark mode : false
05-21 14:43:41.319 D/NightMode(14750): MainActivity onNightModeChanged mode 1, resource configuration in dark mode : false
------------> no onNightModeChanged for ActivityB
the third time is even odd:
logs:
05-21 14:46:30.951 D/NightMode(14750): ActivityC setDefaultNightMode, previous mode 1, new mode 2
05-21 14:46:30.955 D/NightMode(14750): ActivityB onNightModeChanged mode 2, resource configuration in dark mode : true
------------> ActivityC even not received onConfigurationChanged ! and only ActivityB received onNightModeChanged
And so on, inconsistent behavior for activities receiving onNightModeChanged / onConfigurationChanged, depending of the AppCompatDelegateImpl order in sActivityDelegates
appcompat version 1.4.0-alpha01:
MainActivity -> ActivityB -> ActivityC -> "change night mode"
=>logs:
05-21 14:54:27.480 D/NightMode(15350): MainActivity onNightModeChanged mode 2, resource configuration in dark mode : true
05-21 14:54:27.482 D/NightMode(15350): ActivityC onConfigurationChanged
05-21 14:54:27.482 D/NightMode(15350): ActivityC onNightModeChanged mode 2, resource configuration in dark mode : true
05-21 14:54:27.482 D/NightMode(15350): ActivityB onNightModeChanged mode 2, resource configuration in dark mode : true
------------> ok but weird order
then back -> back -> ActivityB -> ActivityC -> "change night mode"
=>logs:
05-21 14:54:37.811 D/NightMode(15350): ActivityC setDefaultNightMode, previous mode 2, new mode 1
05-21 14:54:37.817 D/NightMode(15350): ActivityC onConfigurationChanged
05-21 14:54:37.817 D/NightMode(15350): ActivityC onNightModeChanged mode 1, resource configuration in dark mode : false
05-21 14:54:37.819 D/NightMode(15350): ActivityB onNightModeChanged mode 1, resource configuration in dark mode : false
------------> no onNightModeChanged for MainActivity
I hope it will help
cf...@coyote-group.com <cf...@coyote-group.com> #11
al...@google.com <al...@google.com> #12
Thanks! Okay, interesting, that means we're not getting updateResourcesConfigurationForNightMode
at all and we may not be getting applyDayNight
.
We could see that if Activity A was destroyed, but I would expect it to come back up from onCreate
with the appropriate night mode.
Will do a bit of investigation using your sample app...
al...@google.com <al...@google.com> #13
MainActivity -> ActivityB -> ActivityC -> "change night mode"
2018-08-17 14:53:28.945 10425-10425/com.example.testnightmode D/NightMode: ActivityC setDefaultNightMode, previous mode -100, new mode 2
2018-08-17 14:53:28.949 10425-10425/com.example.testnightmode D/NightMode: ActivityC onConfigurationChanged
2018-08-17 14:53:28.949 10425-10425/com.example.testnightmode D/NightMode: ActivityC onNightModeChanged mode 2, resource configuration in dark mode : true
2018-08-17 14:53:28.949 10425-10425/com.example.testnightmode D/NightMode: ActivityC color: -4487428
2018-08-17 14:53:28.950 10425-10425/com.example.testnightmode D/NightMode: MainActivity onNightModeChanged mode 2, resource configuration in dark mode : true
2018-08-17 14:53:28.950 10425-10425/com.example.testnightmode D/NightMode: MainActivity color: -4487428
2018-08-17 14:53:28.951 10425-10425/com.example.testnightmode D/NightMode: ActivityB onNightModeChanged mode 2, resource configuration in dark mode : true
2018-08-17 14:53:28.951 10425-10425/com.example.testnightmode D/NightMode: ActivityB color: -4487428
back -> back
2018-08-17 14:54:27.806 10425-10425/com.example.testnightmode D/NightMode: ActivityB onNightModeChanged mode 2, resource configuration in dark mode : true
2018-08-17 14:54:27.806 10425-10425/com.example.testnightmode D/NightMode: ActivityB color: -4487428
2018-08-17 14:54:27.807 10425-10425/com.example.testnightmode D/NightMode: ActivityB onResume - in dark mode : true
2018-08-17 14:54:28.304 10425-10425/com.example.testnightmode D/NightMode: ActivityC onStop - in dark mode : true
2018-08-17 14:54:28.305 10425-10425/com.example.testnightmode D/NightMode: ActivityC onDestroy - in dark mode : true
2018-08-17 14:54:28.387 10425-10425/com.example.testnightmode D/NightMode: MainActivity onNightModeChanged mode 2, resource configuration in dark mode : true
2018-08-17 14:54:28.387 10425-10425/com.example.testnightmode D/NightMode: MainActivity color: -4487428
2018-08-17 14:54:28.388 10425-10425/com.example.testnightmode D/NightMode: MainActivity onResume - in dark mode : true
2018-08-17 14:54:28.869 10425-10425/com.example.testnightmode D/NightMode: ActivityB onStop - in dark mode : true
2018-08-17 14:54:28.871 10425-10425/com.example.testnightmode D/NightMode: ActivityB onDestroy - in dark mode : true
-> B -> C
2018-08-17 14:55:05.050 10425-10425/com.example.testnightmode D/NightMode: ActivityB onCreate - in dark mode : true
2018-08-17 14:55:05.094 10425-10425/com.example.testnightmode D/NightMode: ActivityB onResume - in dark mode : true
2018-08-17 14:55:05.156 1196-1252/system_process I/ActivityManager: Displayed com.example.testnightmode/.ActivityB: +123ms
2018-08-17 14:55:05.583 10425-10425/com.example.testnightmode D/NightMode: MainActivity onStop - in dark mode : true
2018-08-17 14:55:06.018 1196-1741/system_process I/ActivityManager: START u0 {cmp=com.example.testnightmode/.ActivityC} from uid 10145
2018-08-17 14:55:06.063 10425-10425/com.example.testnightmode D/NightMode: ActivityC onCreate - in dark mode : true
2018-08-17 14:55:06.096 10425-10425/com.example.testnightmode D/NightMode: ActivityC onResume - in dark mode : true
2018-08-17 14:55:06.150 1196-1252/system_process I/ActivityManager: Displayed com.example.testnightmode/.ActivityC: +105ms
2018-08-17 14:55:06.608 10425-10425/com.example.testnightmode D/NightMode: ActivityB onStop - in dark mode : true
change night mode
2018-08-17 14:56:27.601 10425-10425/com.example.testnightmode D/NightMode: ActivityC calling scheduleDirect
2018-08-17 14:56:27.603 10425-10425/com.example.testnightmode D/NightMode: ActivityC setDefaultNightMode, previous mode 2, new mode 1
2018-08-17 14:56:27.606 10425-10425/com.example.testnightmode D/NightMode: ActivityC onConfigurationChanged
2018-08-17 14:56:27.606 10425-10425/com.example.testnightmode D/NightMode: ActivityC onNightModeChanged mode 1, resource configuration in dark mode : false
2018-08-17 14:56:27.606 10425-10425/com.example.testnightmode D/NightMode: ActivityC color: -10354450
2018-08-17 14:56:27.607 10425-10425/com.example.testnightmode D/NightMode: ActivityB onNightModeChanged mode 1, resource configuration in dark mode : false
2018-08-17 14:56:27.607 10425-10425/com.example.testnightmode D/NightMode: ActivityB color: -10354450
al...@google.com <al...@google.com> #14
Yeah, this all comes down to STOPPED
activities not receiving onConfigurationChanged
. That's where mEffectiveConfiguration
gets updated, which is how activities track whether they need to respond to changes. The proposed fix addresses this.
al...@google.com <al...@google.com> #15
We'll do a 1.3.1
once the CL lands and gets through integration testing.
al...@google.com <al...@google.com> #16
And it ought to be in before we cut 1.4.0-alpha02
, as well.
al...@google.com <al...@google.com> #17
One little snag -- we have existing tests ensuring that activities that are not started do not receive configuration changes; however, it's not clear from the test whether it was intended to cover activities that are created, started, and then stopped.
@Test
fun testOnConfigurationChangeNotCalledWhenNotStarted() {
scenario.moveToState(Lifecycle.State.CREATED)
// And clear any previous config changes
scenario.onActivity { it.lastConfigurationChangeAndClear }
// Set local night mode to YES
scenario.onActivity { setNightMode(MODE_NIGHT_YES, it, setMode) }
// Assert that the onConfigurationChange was not called with a new correct config
scenario.onActivity {
assertNull(it.lastConfigurationChangeAndClear)
}
I think what we actually want here is State.INITIALIZED
and/or State.DESTROYED
, but I'm going to see if I can figure out how the platform handles onConfigurationChanged
for stopped activities.
al...@google.com <al...@google.com> #18
The platform will, in fact, send changes to stopped activities:
// Set local night mode to MODE_NIGHT_YES and wait for state RESUMED.
val scenario = ActivityScenario.launch(NightModeRotateDoesNotRecreateActivity::class.java)
scenario.moveToState(Lifecycle.State.RESUMED)
// Stop the activity.
scenario.moveToState(Lifecycle.State.CREATED)
// Now rotate the device. This should NOT result in a lifecycle event, just a call to
// onConfigurationChanged.
lateinit var activity: NightModeRotateDoesNotRecreateActivity
scenario.onActivity { activity = it }
activity.resetOnConfigurationChange()
device.withOrientation(Orientation.LEFT) {
activity.expectOnConfigurationChange(5000)
}
ap...@google.com <ap...@google.com> #19
Branch: androidx-main
commit 13a7752790ee585c733eb01a56ac94d3f196cf7a
Author: Alan Viverette <alanv@google.com>
Date: Thu May 20 09:59:34 2021
Ensure that all created activities receive onConfigurationChange
Also adds better test sync points around activity lifecycle.
Relnote: """Fix issue where stopped actvities did not receive configuration
changes from AppCompat-instrumented night mode changes."""
Fixes: 188681415
Test: NightModeStackedHandlingTestCase
Change-Id: I8fa8fbc2849499de9cd8af2b77726f7081a37139
M appcompat/appcompat/src/androidTest/AndroidManifest.xml
M appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeStackedHandlingTestCase.kt
A appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesActivityB.java
A appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesActivityC.java
M appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeUiModeConfigChangesTestCase.kt
M appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
Description
Devices/Android versions reproduced on: pretty much any device and api (seen on emulators/Huawei/Samsungs, api 27/29/30)
If you have a stack of activities with android:configChanges="uiMode" and you call AppCompatDelegate.setDefaultNightMode it can cause other activities resources (1 or more) not to be updated (and onNightModeChanged not triggered).
It happens when the setDefaultNightMode is called from another thread that the top activity (with a handler Handler(Looper.getMainLooper()).post {} or RX AndroidSchedulers.mainThread().scheduleDirect {})
Eg :
Activity A with uiMode
Activity B with uiMode
Activity C with uiMode
Here is your stack : A > B > C (C on top)
Call AppCompatDelegate.setDefaultNightMode with a new mode on activity C (but not directly from this activity, ex with RX AndroidSchedulers.mainThread or an handler)
Activity C receives the onConfigurationChanged/onNightModeChanged, Activity B receives the onNightModeChanged but one time out of two activity A not receives the onNightModeChanged (and the resources are indeed not updated when back to A).
Process:
A > B > C > setDefaultNightMode OK > go back to A (B & C destroyed) > B > C > setDefaultNightMode KO (wrong configuration for A)
& so on (OK/KO/OK/KO...)
I think the fix for the
Before the fix of the 169770885, i had a different issue (since 1.2.0) (onConfigurationChanged not called on Activity C after setDefaultNightMode)
Technically here is what I have seen :
- The AppCompatDelegate has 3 AppCompatDelegateImpl (for A,B and C) in sActivityDelegates (both when the setDefaultNightMode works well or not)
- When calculating the currentNightMode in AppCompatDelegateImpl.updateForNightMode, the Activity A has the wrong value so the changed is not applied
Regards,