Merge "Remove InputContentInfo#requestPermission()" into nyc-mr1-dev

This commit is contained in:
Yohei Yukawa
2016-06-30 18:21:46 +00:00
committed by Android (Google) Code Review
9 changed files with 41 additions and 62 deletions

View File

@@ -44923,7 +44923,6 @@ package android.view.inputmethod {
method public android.content.ClipDescription getDescription();
method public android.net.Uri getLinkUri();
method public void releasePermission();
method public void requestPermission();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.inputmethod.InputContentInfo> CREATOR;
}

View File

@@ -48091,7 +48091,6 @@ package android.view.inputmethod {
method public android.content.ClipDescription getDescription();
method public android.net.Uri getLinkUri();
method public void releasePermission();
method public void requestPermission();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.inputmethod.InputContentInfo> CREATOR;
}

View File

@@ -45003,7 +45003,6 @@ package android.view.inputmethod {
method public android.content.ClipDescription getDescription();
method public android.net.Uri getLinkUri();
method public void releasePermission();
method public void requestPermission();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.inputmethod.InputContentInfo> CREATOR;
}

View File

@@ -840,15 +840,16 @@ public interface InputConnection {
public void closeConnection();
/**
* When this flag is used, the editor will be able to request read access to the content URI
* contained in the {@link InputContentInfo} object.
* When this flag is used in {@link #commitContent(InputContentInfo, int, Bundle)}, the editor
* will be able to request read access to the content URI contained in the
* {@link InputContentInfo} object.
*
* <p>Make sure that the content provider owning the Uri sets the
* {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
* grantUriPermissions} attribute in its manifest or included the
* {@link android.R.styleable#AndroidManifestGrantUriPermission
* &lt;grant-uri-permissions&gt;} tag. Otherwise {@link InputContentInfo#requestPermission()}
* can fail.</p>
* &lt;grant-uri-permissions&gt;} tag. Otherwise
* {@link #commitContent(InputContentInfo, int, Bundle)} can fail.</p>
*
* <p>Although calling this API is allowed only for the IME that is currently selected, the
* client is able to request a temporary read-only access even after the current IME is switched

View File

@@ -162,22 +162,6 @@ public final class InputContentInfo implements Parcelable {
mUriToken = token;
}
/**
* Requests a temporary read-only access permission for content URI associated with this object.
*
* <p>Does nothing if the temporary permission is already granted.</p>
*/
public void requestPermission() {
if (mUriToken == null) {
return;
}
try {
mUriToken.take();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Releases a temporary read-only access permission for content URI associated with this object.
*

View File

@@ -22,6 +22,5 @@ import android.os.IBinder;
* {@hide}
*/
interface IInputContentUriToken {
void take();
void release();
}

View File

@@ -517,20 +517,22 @@ public class InputConnectionWrapper implements InputConnection {
public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
boolean result = false;
final boolean grantUriPermission =
(flags & InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0;
if (isMethodMissing(MissingMethodFlags.COMMIT_CONTENT)) {
// This method is not implemented.
return false;
}
try {
if ((flags & InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
if (grantUriPermission) {
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
if (inputMethodService == null) {
// This basically should not happen, because it's the the caller of this method.
return false;
}
// Temporarily grant URI permission.
inputMethodService.exposeContent(inputContentInfo, this);
}
InputContextCallback callback = InputContextCallback.getInstance();
mIInputContext.commitContent(inputContentInfo, flags, opts, callback.mSeq, callback);
synchronized (callback) {
@@ -540,6 +542,10 @@ public class InputConnectionWrapper implements InputConnection {
}
}
callback.dispose();
// If this request is not handled, then there is no reason to keep the URI permission.
if (grantUriPermission && !result) {
inputContentInfo.releasePermission();
}
} catch (RemoteException e) {
return false;
}

View File

@@ -45,48 +45,40 @@ final class InputContentUriTokenHandler extends IInputContentUriToken.Stub {
@GuardedBy("mLock")
private IBinder mPermissionOwnerToken = null;
InputContentUriTokenHandler(@NonNull Uri contentUri, int sourceUid,
static InputContentUriTokenHandler create(@NonNull Uri contentUri, int sourceUid,
@NonNull String targetPackage, @UserIdInt int sourceUserId,
@UserIdInt int targetUserId) {
final IBinder permissionOwner;
try {
permissionOwner = ActivityManagerNative.getDefault()
.newUriPermissionOwner("InputContentUriTokenHandler");
} catch (RemoteException e) {
return null;
}
long origId = Binder.clearCallingIdentity();
try {
ActivityManagerNative.getDefault().grantUriPermissionFromOwner(
permissionOwner, sourceUserId, targetPackage, contentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId, targetUserId);
} catch (RemoteException e) {
return null;
} finally {
Binder.restoreCallingIdentity(origId);
}
return new InputContentUriTokenHandler(contentUri, sourceUid, targetPackage, sourceUserId,
targetUserId, permissionOwner);
}
private InputContentUriTokenHandler(@NonNull Uri contentUri, int sourceUid,
@NonNull String targetPackage, @UserIdInt int sourceUserId,
@UserIdInt int targetUserId, @NonNull IBinder permissionOwnerToken) {
mUri = contentUri;
mSourceUid = sourceUid;
mTargetPackage = targetPackage;
mSourceUserId = sourceUserId;
mTargetUserId = targetUserId;
}
@Override
public void take() {
synchronized (mLock) {
if (mPermissionOwnerToken != null) {
// Permission is already granted.
return;
}
try {
mPermissionOwnerToken = ActivityManagerNative.getDefault()
.newUriPermissionOwner("InputContentUriTokenHandler");
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
doTakeLocked(mPermissionOwnerToken);
}
}
private void doTakeLocked(@NonNull IBinder permissionOwner) {
long origId = Binder.clearCallingIdentity();
try {
try {
ActivityManagerNative.getDefault().grantUriPermissionFromOwner(
permissionOwner, mSourceUid, mTargetPackage, mUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION, mSourceUserId, mTargetUserId);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
} finally {
Binder.restoreCallingIdentity(origId);
}
mPermissionOwnerToken = permissionOwnerToken;
}
@Override

View File

@@ -3953,7 +3953,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
final int imeUserId = UserHandle.getUserId(uid);
final int appUserId = UserHandle.getUserId(mCurClient.uid);
return new InputContentUriTokenHandler(contentUri, uid, packageName, imeUserId,
return InputContentUriTokenHandler.create(contentUri, uid, packageName, imeUserId,
appUserId);
}
}