Merge "Revert "Remove InputContentInfo#requestPermission()"" into nyc-mr1-dev
This commit is contained in:
@@ -44923,6 +44923,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -48091,6 +48091,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -45003,6 +45003,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -840,16 +840,15 @@ public interface InputConnection {
|
||||
public void closeConnection();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* When this flag is used, 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
|
||||
* <grant-uri-permissions>} tag. Otherwise
|
||||
* {@link #commitContent(InputContentInfo, int, Bundle)} can fail.</p>
|
||||
* <grant-uri-permissions>} tag. Otherwise {@link InputContentInfo#requestPermission()}
|
||||
* 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
|
||||
|
||||
@@ -162,6 +162,22 @@ 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.
|
||||
*
|
||||
|
||||
@@ -22,5 +22,6 @@ import android.os.IBinder;
|
||||
* {@hide}
|
||||
*/
|
||||
interface IInputContentUriToken {
|
||||
void take();
|
||||
void release();
|
||||
}
|
||||
|
||||
@@ -517,22 +517,20 @@ 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 (grantUriPermission) {
|
||||
if ((flags & InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
|
||||
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) {
|
||||
@@ -542,10 +540,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -45,40 +45,48 @@ final class InputContentUriTokenHandler extends IInputContentUriToken.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private IBinder mPermissionOwnerToken = null;
|
||||
|
||||
static InputContentUriTokenHandler create(@NonNull Uri contentUri, int sourceUid,
|
||||
InputContentUriTokenHandler(@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;
|
||||
mPermissionOwnerToken = permissionOwnerToken;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3953,7 +3953,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
final int imeUserId = UserHandle.getUserId(uid);
|
||||
final int appUserId = UserHandle.getUserId(mCurClient.uid);
|
||||
return InputContentUriTokenHandler.create(contentUri, uid, packageName, imeUserId,
|
||||
return new InputContentUriTokenHandler(contentUri, uid, packageName, imeUserId,
|
||||
appUserId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user