From f3806f57a59ede663f3fa2ad1f5080bdbf20e372 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 30 Jun 2016 16:27:46 -0700 Subject: [PATCH] Automatically grant URI permission as needed. With this CL, the system automatically grants a temporary URI permission to the target application when the IME calls InputConnection#commitContent() with InputConnection#INPUT_CONTENT_GRANT_READ_URI_PERMISSION. The temporary permission will be revoked by any of the following events: - InputContentInfo#releasePermission() is explicitly called by the target application. - The target application returned false in InputConnection#commitContent(). - All the InputContentInfo instances copied from the original one are GC-ed. If we do not do this and there is an application that forgot to call that method then there is no way for IME developers to prevent permission denial from happening in the application except for relaxing the default permission of the ContentProvider just because of such an application. Although application developers are still expected to explicitly call InputContentInfo#{request,release}Permission(), forgetting to call InputContentInfo#requestPermission() does not hurt the user anymore. With this CL, calling InputContentInfo#requestPermission() after calling InputContentInfo#releasePermission() is also allowed. Bug: 29892936 Change-Id: Id955435dd2e72549ee7134f46b3c6951581694ad --- .../view/inputmethod/InputContentInfo.java | 2 -- .../internal/view/IInputConnectionWrapper.java | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/java/android/view/inputmethod/InputContentInfo.java b/core/java/android/view/inputmethod/InputContentInfo.java index 9579bbf328355..b39705e0b1fa6 100644 --- a/core/java/android/view/inputmethod/InputContentInfo.java +++ b/core/java/android/view/inputmethod/InputContentInfo.java @@ -191,8 +191,6 @@ public final class InputContentInfo implements Parcelable { mUriToken.release(); } catch (RemoteException e) { e.rethrowFromSystemServer(); - } finally { - mUriToken = null; } } diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java index 62e34a6780fc8..644c7e90f8b02 100644 --- a/core/java/com/android/internal/view/IInputConnectionWrapper.java +++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java @@ -562,6 +562,8 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { } case DO_COMMIT_CONTENT: { final int flags = msg.arg1; + final boolean grantUriPermission = + (flags & InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0; SomeArgs args = (SomeArgs) msg.obj; try { InputConnection ic = getInputConnection(); @@ -577,9 +579,17 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { args.callback.setCommitContentResult(false, args.seq); return; } - args.callback.setCommitContentResult( - ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2), - args.seq); + if (grantUriPermission) { + inputContentInfo.requestPermission(); + } + final boolean result = + ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2); + // If this request is not handled, then there is no reason to keep the URI + // permission. + if (grantUriPermission && !result) { + inputContentInfo.releasePermission(); + } + args.callback.setCommitContentResult(result, args.seq); } catch (RemoteException e) { Log.w(TAG, "Got RemoteException calling commitContent", e); }