@@ -539,9 +539,19 @@ public void createWindowParams_correctTypeAndFlags() {
539539 Assert .assertEquals ("Type should be TYPE_APPLICATION" ,
540540 WindowManager .LayoutParams .TYPE_APPLICATION , params .type );
541541
542+ // Expected base flags match the production set in createWindowParams:
543+ // FLAG_NOT_FOCUSABLE + FLAG_WATCH_OUTSIDE_TOUCH let the host
544+ // activity keep IME focus while still receiving outside-touch
545+ // events the overlay routes back via dispatchTouchEvent.
546+ // FLAG_NOT_TOUCHABLE is added only while content is still loading
547+ // (gates touches until the WebView is visible). The test
548+ // constructs the overlay with about:blank and never waits for
549+ // afterPageFinished, so isContentLoaded stays false here.
542550 int expectedFlags = WindowManager .LayoutParams .FLAG_LAYOUT_IN_SCREEN
543551 | WindowManager .LayoutParams .FLAG_LAYOUT_INSET_DECOR
544552 | WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL
553+ | WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE
554+ | WindowManager .LayoutParams .FLAG_WATCH_OUTSIDE_TOUCH
545555 | WindowManager .LayoutParams .FLAG_NOT_TOUCHABLE ;
546556 Assert .assertEquals ("Flags should match" , expectedFlags , params .flags );
547557
@@ -794,12 +804,21 @@ public void contentUrlAction_noQueryParams_returnsFalse() {
794804 // ===================== Memory leak prevention (issue #556) =====================
795805
796806 /**
797- * Structural invariant: the overlay's View.mContext must be the Application, not the
798- * constructing activity. This is what allows the overlay to outlive activity transitions
799- * without leaking the activity it was first opened in.
807+ * Structural invariant: the overlay's View.mContext must not pin the
808+ * constructing Activity. The overlay outlives activity transitions, and
809+ * View.mContext can never be swapped after construction — if it's the
810+ * Activity, that Activity stays GC-pinned for the overlay's full lifetime.
800811 *
801- * Regression guard: if anyone changes the constructor's super(...) call back to the
802- * activity, this test will fail and surface the leak before users do.
812+ * The exact context type is API-dependent (see ContentOverlayView#resolveOverlayContext):
813+ * - Pre-API 31: Application context.
814+ * - API 31+: createConfigurationContext from the Activity — a ContextImpl
815+ * wrapper that holds an IBinder token, not the Activity instance, so
816+ * GC isn't blocked. Required for StrictMode#detectIncorrectContextUse.
817+ *
818+ * In both cases, getApplicationContext() resolves to the same Application.
819+ * The test asserts both that the context is NOT the Activity and that it
820+ * routes back to the right Application — which is the actual leak-avoidance
821+ * contract independent of API level.
803822 */
804823 @ Test
805824 public void constructor_usesApplicationContext_notActivity () {
@@ -811,15 +830,19 @@ public void constructor_usesApplicationContext_notActivity() {
811830 + "that Activity for the lifetime of the overlay." ,
812831 activity , overlay .getContext ());
813832 Assert .assertSame (
814- "ContentOverlayView.mContext must be the Application context." ,
815- activity .getApplicationContext (), overlay .getContext ());
833+ "ContentOverlayView.mContext must resolve to the same Application as the "
834+ + "constructing Activity (Application directly on <API 31, "
835+ + "ConfigurationContext-of-Activity on API 31+)." ,
836+ activity .getApplicationContext (),
837+ overlay .getContext ().getApplicationContext ());
816838 });
817839 }
818840
819841 /**
820- * Same invariant for the embedded WebView. Even with the wrapper View using App context,
821- * a WebView constructed with Activity context would still pin the constructing activity
822- * via its own mContext.
842+ * Same invariant for the embedded WebView. Even with the wrapper View not
843+ * pinning the Activity, a WebView constructed with the Activity directly
844+ * would still pin it via its own mContext. See
845+ * constructor_usesApplicationContext_notActivity for the API-level rationale.
823846 */
824847 @ Test
825848 public void webView_usesApplicationContext_notActivity () {
@@ -830,8 +853,10 @@ public void webView_usesApplicationContext_notActivity() {
830853 "ContentOverlayView's WebView.mContext must not be the constructing Activity." ,
831854 activity , overlay .webView .getContext ());
832855 Assert .assertSame (
833- "ContentOverlayView's WebView.mContext must be the Application context." ,
834- activity .getApplicationContext (), overlay .webView .getContext ());
856+ "ContentOverlayView's WebView.mContext must resolve to the same Application "
857+ + "as the constructing Activity." ,
858+ activity .getApplicationContext (),
859+ overlay .webView .getContext ().getApplicationContext ());
835860 });
836861 }
837862}
0 commit comments