diff options
4 files changed, 87 insertions, 10 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4da02f902e60..ccc5797176e7 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3975,8 +3975,17 @@ public final class ViewRootImpl implements ViewParent, } private void notifyContentCaptureEvents() { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents"); try { + if (!isContentCaptureEnabled()) { + if (DEBUG_CONTENT_CAPTURE) { + Log.d(mTag, "notifyContentCaptureEvents while disabled"); + } + mAttachInfo.mContentCaptureEvents = null; + return; + } + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents"); + } MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager .getMainContentCaptureSession(); for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) { @@ -4890,13 +4899,14 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_CONTENT_CAPTURE) { Log.v(mTag, "performContentCaptureInitialReport() on " + rootView); } - if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for " - + getClass().getSimpleName()); - } try { if (!isContentCaptureEnabled()) return; + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for " + + getClass().getSimpleName()); + } + // Initial dispatch of window bounds to content capture if (mAttachInfo.mContentCaptureManager != null) { MainContentCaptureSession session = @@ -4916,13 +4926,14 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_CONTENT_CAPTURE) { Log.v(mTag, "handleContentCaptureFlush()"); } - if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for " - + getClass().getSimpleName()); - } try { if (!isContentCaptureEnabled()) return; + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for " + + getClass().getSimpleName()); + } + final ContentCaptureManager ccm = mAttachInfo.mContentCaptureManager; if (ccm == null) { Log.w(TAG, "No ContentCapture on AttachInfo"); diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 5f612d6b0009..1467a08060fd 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -783,7 +783,9 @@ public final class ContentCaptureManager { (params.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0; MainContentCaptureSession mainSession; + boolean alreadyDisabledByApp; synchronized (mLock) { + alreadyDisabledByApp = (mFlags & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0; if (flagSecureEnabled) { mFlags |= ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE; } else { @@ -791,7 +793,9 @@ public final class ContentCaptureManager { } mainSession = mMainSession; } - if (mainSession != null) { + + // Prevent overriding the status of disabling by app + if (mainSession != null && !alreadyDisabledByApp) { mainSession.setDisabled(flagSecureEnabled); } } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index b44d6a496058..d9b0f8035a6d 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -44,6 +44,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.IBinder.DeathRecipient; import android.os.RemoteException; +import android.os.Trace; import android.text.Selection; import android.text.Spannable; import android.text.TextUtils; @@ -373,12 +374,26 @@ public final class MainContentCaptureSession extends ContentCaptureSession { return; } + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + if (eventType == TYPE_VIEW_TREE_APPEARING) { + Trace.asyncTraceBegin( + Trace.TRACE_TAG_VIEW, /* methodName= */ "sendEventAsync", /* cookie= */ 0); + } + } + if (isContentProtectionReceiverEnabled()) { sendContentProtectionEvent(event); } if (isContentCaptureReceiverEnabled()) { sendContentCaptureEvent(event, forceFlush); } + + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + if (eventType == TYPE_VIEW_TREE_APPEARED) { + Trace.asyncTraceEnd( + Trace.TRACE_TAG_VIEW, /* methodName= */ "sendEventAsync", /* cookie= */ 0); + } + } } @UiThread diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java index 5c411d5335a7..35ddfdb3723b 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java @@ -23,6 +23,7 @@ import static org.testng.Assert.assertThrows; import android.content.ContentCaptureOptions; import android.content.Context; +import android.view.WindowManager; import com.android.internal.util.RingBuffer; @@ -147,6 +148,52 @@ public class ContentCaptureManagerTest { assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse(); } + @Test + public void testUpdateWindowAttribute_setFlagSecure() { + final ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS); + // Ensure main session is created. + final MainContentCaptureSession unused = manager.getMainContentCaptureSession(); + final WindowManager.LayoutParams initialParam = new WindowManager.LayoutParams(); + initialParam.flags |= WindowManager.LayoutParams.FLAG_SECURE; + + manager.updateWindowAttributes(initialParam); + + assertThat(manager.isContentCaptureEnabled()).isFalse(); + } + + @Test + public void testUpdateWindowAttribute_clearFlagSecure() { + final ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS); + // Ensure main session is created. + final MainContentCaptureSession unused = manager.getMainContentCaptureSession(); + final WindowManager.LayoutParams initialParam = new WindowManager.LayoutParams(); + initialParam.flags |= WindowManager.LayoutParams.FLAG_SECURE; + // Default param does not have FLAG_SECURE set. + final WindowManager.LayoutParams resetParam = new WindowManager.LayoutParams(); + + manager.updateWindowAttributes(initialParam); + manager.updateWindowAttributes(resetParam); + + assertThat(manager.isContentCaptureEnabled()).isTrue(); + } + + @Test + public void testUpdateWindowAttribute_clearFlagSecureAfterDisabledByApp() { + final ContentCaptureManager manager = + new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS); + // Ensure main session is created. + final MainContentCaptureSession unused = manager.getMainContentCaptureSession(); + // Default param does not have FLAG_SECURE set. + final WindowManager.LayoutParams resetParam = new WindowManager.LayoutParams(); + + manager.setContentCaptureEnabled(false); + manager.updateWindowAttributes(resetParam); + + assertThat(manager.isContentCaptureEnabled()).isFalse(); + } + private ContentCaptureOptions createOptions( ContentCaptureOptions.ContentProtectionOptions contentProtectionOptions) { return new ContentCaptureOptions( |