Loading core/java/android/service/contentcapture/ContentCaptureService.java +20 −20 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.service.contentcapture; import static android.view.contentcapture.ContentCaptureHelper.sDebug; import static android.view.contentcapture.ContentCaptureHelper.sVerbose; import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; Loading @@ -36,9 +37,9 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.service.autofill.AutofillService; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.SparseIntArray; import android.view.contentcapture.ContentCaptureCondition; import android.view.contentcapture.ContentCaptureContext; import android.view.contentcapture.ContentCaptureEvent; Loading Loading @@ -117,7 +118,7 @@ public abstract class ContentCaptureService extends Service { } @Override public void onSessionStarted(ContentCaptureContext context, String sessionId, int uid, public void onSessionStarted(ContentCaptureContext context, int sessionId, int uid, IResultReceiver clientReceiver, int initialState) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnCreateSession, ContentCaptureService.this, context, sessionId, uid, clientReceiver, Loading @@ -125,14 +126,14 @@ public abstract class ContentCaptureService extends Service { } @Override public void onActivitySnapshot(String sessionId, SnapshotData snapshotData) { public void onActivitySnapshot(int sessionId, SnapshotData snapshotData) { mHandler.sendMessage( obtainMessage(ContentCaptureService::handleOnActivitySnapshot, ContentCaptureService.this, sessionId, snapshotData)); } @Override public void onSessionFinished(String sessionId) { public void onSessionFinished(int sessionId) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleFinishSession, ContentCaptureService.this, sessionId)); } Loading Loading @@ -171,7 +172,7 @@ public abstract class ContentCaptureService extends Service { * <p>This map is populated when an session is started, which is called by the system server * and can be trusted. Then subsequent calls made by the app are verified against this map. */ private final ArrayMap<String, Integer> mSessionUids = new ArrayMap<>(); private final SparseIntArray mSessionUids = new SparseIntArray(); @CallSuper @Override Loading Loading @@ -378,7 +379,7 @@ public abstract class ContentCaptureService extends Service { // so we don't need to create a temporary InteractionSessionId for each event. private void handleOnCreateSession(@NonNull ContentCaptureContext context, @NonNull String sessionId, int uid, IResultReceiver clientReceiver, int initialState) { int sessionId, int uid, IResultReceiver clientReceiver, int initialState) { mSessionUids.put(sessionId, uid); onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId)); Loading @@ -403,27 +404,27 @@ public abstract class ContentCaptureService extends Service { // Most events belong to the same session, so we can keep a reference to the last one // to avoid creating too many ContentCaptureSessionId objects String lastSessionId = null; int lastSessionId = NO_SESSION_ID; ContentCaptureSessionId sessionId = null; final List<ContentCaptureEvent> events = parceledEvents.getList(); for (int i = 0; i < events.size(); i++) { final ContentCaptureEvent event = events.get(i); if (!handleIsRightCallerFor(event, uid)) continue; String sessionIdString = event.getSessionId(); if (!sessionIdString.equals(lastSessionId)) { sessionId = new ContentCaptureSessionId(sessionIdString); lastSessionId = sessionIdString; int sessionIdInt = event.getSessionId(); if (sessionIdInt != lastSessionId) { sessionId = new ContentCaptureSessionId(sessionIdInt); lastSessionId = sessionIdInt; } switch (event.getType()) { case ContentCaptureEvent.TYPE_SESSION_STARTED: final ContentCaptureContext clientContext = event.getContentCaptureContext(); clientContext.setParentSessionId(event.getParentSessionId()); mSessionUids.put(sessionIdString, uid); mSessionUids.put(sessionIdInt, uid); onCreateContentCaptureSession(clientContext, sessionId); break; case ContentCaptureEvent.TYPE_SESSION_FINISHED: mSessionUids.remove(sessionIdString); mSessionUids.delete(sessionIdInt); onDestroyContentCaptureSession(sessionId); break; default: Loading @@ -432,13 +433,12 @@ public abstract class ContentCaptureService extends Service { } } private void handleOnActivitySnapshot(@NonNull String sessionId, @NonNull SnapshotData snapshotData) { private void handleOnActivitySnapshot(int sessionId, @NonNull SnapshotData snapshotData) { onActivitySnapshot(new ContentCaptureSessionId(sessionId), snapshotData); } private void handleFinishSession(@NonNull String sessionId) { mSessionUids.remove(sessionId); private void handleFinishSession(int sessionId) { mSessionUids.delete(sessionId); onDestroyContentCaptureSession(new ContentCaptureSessionId(sessionId)); } Loading @@ -454,7 +454,7 @@ public abstract class ContentCaptureService extends Service { * Checks if the given {@code uid} owns the session associated with the event. */ private boolean handleIsRightCallerFor(@NonNull ContentCaptureEvent event, int uid) { final String sessionId; final int sessionId; switch (event.getType()) { case ContentCaptureEvent.TYPE_SESSION_STARTED: case ContentCaptureEvent.TYPE_SESSION_FINISHED: Loading @@ -463,8 +463,7 @@ public abstract class ContentCaptureService extends Service { default: sessionId = event.getSessionId(); } final Integer rightUid = mSessionUids.get(sessionId); if (rightUid == null) { if (mSessionUids.indexOfKey(sessionId) < 0) { if (sVerbose) { Log.v(TAG, "handleIsRightCallerFor(" + event + "): no session for " + sessionId + ": " + mSessionUids); Loading @@ -472,6 +471,7 @@ public abstract class ContentCaptureService extends Service { // Just ignore, as the session could have been finished already return false; } final int rightUid = mSessionUids.get(sessionId); if (rightUid != uid) { Log.e(TAG, "invalid call from UID " + uid + ": session " + sessionId + " belongs to " + rightUid); Loading core/java/android/service/contentcapture/IContentCaptureService.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -35,10 +35,10 @@ import java.util.List; oneway interface IContentCaptureService { void onConnected(IBinder callback, boolean verbose, boolean debug); void onDisconnected(); void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid, void onSessionStarted(in ContentCaptureContext context, int sessionId, int uid, in IResultReceiver clientReceiver, int initialState); void onSessionFinished(String sessionId); void onActivitySnapshot(String sessionId, in SnapshotData snapshotData); void onSessionFinished(int sessionId); void onActivitySnapshot(int sessionId, in SnapshotData snapshotData); void onUserDataRemovalRequest(in UserDataRemovalRequest request); void onActivityEvent(in ActivityEvent event); } core/java/android/view/View.java +3 −5 Original line number Diff line number Diff line Loading @@ -86,7 +86,6 @@ import android.os.Trace; import android.sysprop.DisplayProperties; import android.text.InputType; import android.text.TextUtils; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.LayoutDirection; Loading Loading @@ -28590,8 +28589,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * hierarchy is traversed: value is either the view itself for appearead events, or its * autofill id for disappeared. */ // TODO(b/121197119): use SparseArray once session id becomes integer ArrayMap<String, ArrayList<Object>> mContentCaptureEvents; SparseArray<ArrayList<Object>> mContentCaptureEvents; /** * Cached reference to the {@link ContentCaptureManager}. Loading Loading @@ -28621,9 +28619,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @NonNull View view, boolean appeared) { if (mContentCaptureEvents == null) { // Most of the time there will be just one session, so intial capacity is 1 mContentCaptureEvents = new ArrayMap<>(1); mContentCaptureEvents = new SparseArray<>(1); } String sessionId = session.getId(); int sessionId = session.getId(); // TODO: life would be much easier if we provided a MultiMap implementation somwhere... ArrayList<Object> events = mContentCaptureEvents.get(sessionId); if (events == null) { core/java/android/view/ViewRootImpl.java +3 −4 Original line number Diff line number Diff line Loading @@ -2811,8 +2811,7 @@ public final class ViewRootImpl implements ViewParent, MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager .getMainContentCaptureSession(); for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) { String sessionId = mAttachInfo.mContentCaptureEvents .keyAt(i); int sessionId = mAttachInfo.mContentCaptureEvents.keyAt(i); mainSession.notifyViewTreeEvent(sessionId, /* started= */ true); ArrayList<Object> events = mAttachInfo.mContentCaptureEvents .valueAt(i); Loading @@ -2827,8 +2826,8 @@ public final class ViewRootImpl implements ViewParent, Log.w(mTag, "no content capture session on view: " + view); continue for_each_event; } String actualId = session.getId().toString(); if (!actualId.equals(sessionId)) { int actualId = session.getId(); if (actualId != sessionId) { Log.w(mTag, "content capture session mismatch for view (" + view + "): was " + sessionId + " before, it's " + actualId + " now"); continue for_each_event; Loading core/java/android/view/contentcapture/ContentCaptureContext.java +8 −6 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package android.view.contentcapture; import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -35,7 +37,6 @@ import com.android.internal.util.Preconditions; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Context associated with a {@link ContentCaptureSession} - see {@link ContentCaptureManager} for * more info. Loading Loading @@ -107,7 +108,7 @@ public final class ContentCaptureContext implements Parcelable { private final int mDisplayId; // Fields below are set by the service upon "delivery" and are not marshalled in the parcel private @Nullable String mParentSessionId; private int mParentSessionId = NO_SESSION_ID; /** @hide */ public ContentCaptureContext(@Nullable ContentCaptureContext clientContext, Loading Loading @@ -198,11 +199,12 @@ public final class ContentCaptureContext implements Parcelable { @SystemApi @TestApi public @Nullable ContentCaptureSessionId getParentSessionId() { return mParentSessionId == null ? null : new ContentCaptureSessionId(mParentSessionId); return mParentSessionId == NO_SESSION_ID ? null : new ContentCaptureSessionId(mParentSessionId); } /** @hide */ public void setParentSessionId(@NonNull String parentSessionId) { public void setParentSessionId(int parentSessionId) { mParentSessionId = parentSessionId; } Loading Loading @@ -317,7 +319,7 @@ public final class ContentCaptureContext implements Parcelable { } pw.print(", taskId="); pw.print(mTaskId); pw.print(", displayId="); pw.print(mDisplayId); if (mParentSessionId != null) { if (mParentSessionId != NO_SESSION_ID) { pw.print(", parentId="); pw.print(mParentSessionId); } if (mFlags > 0) { Loading Loading @@ -349,7 +351,7 @@ public final class ContentCaptureContext implements Parcelable { builder.append(", hasExtras"); } } if (mParentSessionId != null) { if (mParentSessionId != NO_SESSION_ID) { builder.append(", parentId=").append(mParentSessionId); } return builder.append(']').toString(); Loading Loading
core/java/android/service/contentcapture/ContentCaptureService.java +20 −20 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.service.contentcapture; import static android.view.contentcapture.ContentCaptureHelper.sDebug; import static android.view.contentcapture.ContentCaptureHelper.sVerbose; import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; Loading @@ -36,9 +37,9 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.service.autofill.AutofillService; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.SparseIntArray; import android.view.contentcapture.ContentCaptureCondition; import android.view.contentcapture.ContentCaptureContext; import android.view.contentcapture.ContentCaptureEvent; Loading Loading @@ -117,7 +118,7 @@ public abstract class ContentCaptureService extends Service { } @Override public void onSessionStarted(ContentCaptureContext context, String sessionId, int uid, public void onSessionStarted(ContentCaptureContext context, int sessionId, int uid, IResultReceiver clientReceiver, int initialState) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnCreateSession, ContentCaptureService.this, context, sessionId, uid, clientReceiver, Loading @@ -125,14 +126,14 @@ public abstract class ContentCaptureService extends Service { } @Override public void onActivitySnapshot(String sessionId, SnapshotData snapshotData) { public void onActivitySnapshot(int sessionId, SnapshotData snapshotData) { mHandler.sendMessage( obtainMessage(ContentCaptureService::handleOnActivitySnapshot, ContentCaptureService.this, sessionId, snapshotData)); } @Override public void onSessionFinished(String sessionId) { public void onSessionFinished(int sessionId) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleFinishSession, ContentCaptureService.this, sessionId)); } Loading Loading @@ -171,7 +172,7 @@ public abstract class ContentCaptureService extends Service { * <p>This map is populated when an session is started, which is called by the system server * and can be trusted. Then subsequent calls made by the app are verified against this map. */ private final ArrayMap<String, Integer> mSessionUids = new ArrayMap<>(); private final SparseIntArray mSessionUids = new SparseIntArray(); @CallSuper @Override Loading Loading @@ -378,7 +379,7 @@ public abstract class ContentCaptureService extends Service { // so we don't need to create a temporary InteractionSessionId for each event. private void handleOnCreateSession(@NonNull ContentCaptureContext context, @NonNull String sessionId, int uid, IResultReceiver clientReceiver, int initialState) { int sessionId, int uid, IResultReceiver clientReceiver, int initialState) { mSessionUids.put(sessionId, uid); onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId)); Loading @@ -403,27 +404,27 @@ public abstract class ContentCaptureService extends Service { // Most events belong to the same session, so we can keep a reference to the last one // to avoid creating too many ContentCaptureSessionId objects String lastSessionId = null; int lastSessionId = NO_SESSION_ID; ContentCaptureSessionId sessionId = null; final List<ContentCaptureEvent> events = parceledEvents.getList(); for (int i = 0; i < events.size(); i++) { final ContentCaptureEvent event = events.get(i); if (!handleIsRightCallerFor(event, uid)) continue; String sessionIdString = event.getSessionId(); if (!sessionIdString.equals(lastSessionId)) { sessionId = new ContentCaptureSessionId(sessionIdString); lastSessionId = sessionIdString; int sessionIdInt = event.getSessionId(); if (sessionIdInt != lastSessionId) { sessionId = new ContentCaptureSessionId(sessionIdInt); lastSessionId = sessionIdInt; } switch (event.getType()) { case ContentCaptureEvent.TYPE_SESSION_STARTED: final ContentCaptureContext clientContext = event.getContentCaptureContext(); clientContext.setParentSessionId(event.getParentSessionId()); mSessionUids.put(sessionIdString, uid); mSessionUids.put(sessionIdInt, uid); onCreateContentCaptureSession(clientContext, sessionId); break; case ContentCaptureEvent.TYPE_SESSION_FINISHED: mSessionUids.remove(sessionIdString); mSessionUids.delete(sessionIdInt); onDestroyContentCaptureSession(sessionId); break; default: Loading @@ -432,13 +433,12 @@ public abstract class ContentCaptureService extends Service { } } private void handleOnActivitySnapshot(@NonNull String sessionId, @NonNull SnapshotData snapshotData) { private void handleOnActivitySnapshot(int sessionId, @NonNull SnapshotData snapshotData) { onActivitySnapshot(new ContentCaptureSessionId(sessionId), snapshotData); } private void handleFinishSession(@NonNull String sessionId) { mSessionUids.remove(sessionId); private void handleFinishSession(int sessionId) { mSessionUids.delete(sessionId); onDestroyContentCaptureSession(new ContentCaptureSessionId(sessionId)); } Loading @@ -454,7 +454,7 @@ public abstract class ContentCaptureService extends Service { * Checks if the given {@code uid} owns the session associated with the event. */ private boolean handleIsRightCallerFor(@NonNull ContentCaptureEvent event, int uid) { final String sessionId; final int sessionId; switch (event.getType()) { case ContentCaptureEvent.TYPE_SESSION_STARTED: case ContentCaptureEvent.TYPE_SESSION_FINISHED: Loading @@ -463,8 +463,7 @@ public abstract class ContentCaptureService extends Service { default: sessionId = event.getSessionId(); } final Integer rightUid = mSessionUids.get(sessionId); if (rightUid == null) { if (mSessionUids.indexOfKey(sessionId) < 0) { if (sVerbose) { Log.v(TAG, "handleIsRightCallerFor(" + event + "): no session for " + sessionId + ": " + mSessionUids); Loading @@ -472,6 +471,7 @@ public abstract class ContentCaptureService extends Service { // Just ignore, as the session could have been finished already return false; } final int rightUid = mSessionUids.get(sessionId); if (rightUid != uid) { Log.e(TAG, "invalid call from UID " + uid + ": session " + sessionId + " belongs to " + rightUid); Loading
core/java/android/service/contentcapture/IContentCaptureService.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -35,10 +35,10 @@ import java.util.List; oneway interface IContentCaptureService { void onConnected(IBinder callback, boolean verbose, boolean debug); void onDisconnected(); void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid, void onSessionStarted(in ContentCaptureContext context, int sessionId, int uid, in IResultReceiver clientReceiver, int initialState); void onSessionFinished(String sessionId); void onActivitySnapshot(String sessionId, in SnapshotData snapshotData); void onSessionFinished(int sessionId); void onActivitySnapshot(int sessionId, in SnapshotData snapshotData); void onUserDataRemovalRequest(in UserDataRemovalRequest request); void onActivityEvent(in ActivityEvent event); }
core/java/android/view/View.java +3 −5 Original line number Diff line number Diff line Loading @@ -86,7 +86,6 @@ import android.os.Trace; import android.sysprop.DisplayProperties; import android.text.InputType; import android.text.TextUtils; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.LayoutDirection; Loading Loading @@ -28590,8 +28589,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * hierarchy is traversed: value is either the view itself for appearead events, or its * autofill id for disappeared. */ // TODO(b/121197119): use SparseArray once session id becomes integer ArrayMap<String, ArrayList<Object>> mContentCaptureEvents; SparseArray<ArrayList<Object>> mContentCaptureEvents; /** * Cached reference to the {@link ContentCaptureManager}. Loading Loading @@ -28621,9 +28619,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @NonNull View view, boolean appeared) { if (mContentCaptureEvents == null) { // Most of the time there will be just one session, so intial capacity is 1 mContentCaptureEvents = new ArrayMap<>(1); mContentCaptureEvents = new SparseArray<>(1); } String sessionId = session.getId(); int sessionId = session.getId(); // TODO: life would be much easier if we provided a MultiMap implementation somwhere... ArrayList<Object> events = mContentCaptureEvents.get(sessionId); if (events == null) {
core/java/android/view/ViewRootImpl.java +3 −4 Original line number Diff line number Diff line Loading @@ -2811,8 +2811,7 @@ public final class ViewRootImpl implements ViewParent, MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager .getMainContentCaptureSession(); for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) { String sessionId = mAttachInfo.mContentCaptureEvents .keyAt(i); int sessionId = mAttachInfo.mContentCaptureEvents.keyAt(i); mainSession.notifyViewTreeEvent(sessionId, /* started= */ true); ArrayList<Object> events = mAttachInfo.mContentCaptureEvents .valueAt(i); Loading @@ -2827,8 +2826,8 @@ public final class ViewRootImpl implements ViewParent, Log.w(mTag, "no content capture session on view: " + view); continue for_each_event; } String actualId = session.getId().toString(); if (!actualId.equals(sessionId)) { int actualId = session.getId(); if (actualId != sessionId) { Log.w(mTag, "content capture session mismatch for view (" + view + "): was " + sessionId + " before, it's " + actualId + " now"); continue for_each_event; Loading
core/java/android/view/contentcapture/ContentCaptureContext.java +8 −6 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package android.view.contentcapture; import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -35,7 +37,6 @@ import com.android.internal.util.Preconditions; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Context associated with a {@link ContentCaptureSession} - see {@link ContentCaptureManager} for * more info. Loading Loading @@ -107,7 +108,7 @@ public final class ContentCaptureContext implements Parcelable { private final int mDisplayId; // Fields below are set by the service upon "delivery" and are not marshalled in the parcel private @Nullable String mParentSessionId; private int mParentSessionId = NO_SESSION_ID; /** @hide */ public ContentCaptureContext(@Nullable ContentCaptureContext clientContext, Loading Loading @@ -198,11 +199,12 @@ public final class ContentCaptureContext implements Parcelable { @SystemApi @TestApi public @Nullable ContentCaptureSessionId getParentSessionId() { return mParentSessionId == null ? null : new ContentCaptureSessionId(mParentSessionId); return mParentSessionId == NO_SESSION_ID ? null : new ContentCaptureSessionId(mParentSessionId); } /** @hide */ public void setParentSessionId(@NonNull String parentSessionId) { public void setParentSessionId(int parentSessionId) { mParentSessionId = parentSessionId; } Loading Loading @@ -317,7 +319,7 @@ public final class ContentCaptureContext implements Parcelable { } pw.print(", taskId="); pw.print(mTaskId); pw.print(", displayId="); pw.print(mDisplayId); if (mParentSessionId != null) { if (mParentSessionId != NO_SESSION_ID) { pw.print(", parentId="); pw.print(mParentSessionId); } if (mFlags > 0) { Loading Loading @@ -349,7 +351,7 @@ public final class ContentCaptureContext implements Parcelable { builder.append(", hasExtras"); } } if (mParentSessionId != null) { if (mParentSessionId != NO_SESSION_ID) { builder.append(", parentId=").append(mParentSessionId); } return builder.append(']').toString(); Loading