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
This commit is contained in:
Yohei Yukawa
2016-06-30 16:27:46 -07:00
parent 8acb1a7570
commit f3806f57a5
2 changed files with 13 additions and 5 deletions

View File

@@ -191,8 +191,6 @@ public final class InputContentInfo implements Parcelable {
mUriToken.release();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
} finally {
mUriToken = null;
}
}

View File

@@ -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);
}