Use a flag to grant a temporary URI permission.
It turns out that we can let the system to call
InputMethodService#exposeContent(InputContentInfo, EditorInfo), which
added in my previous CL [1], during the IME is calling
InputConnection#commitContent() as follows.
[IME]
InputContentInfo contentInfo = new InputContentInfo(
contentUri,
new ClipDescription(description, new String[]{mimeType}),
linkUrl);
getCurrentInputConnection().commitContent(
inputContentInfo,
InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION,
null);
[App]
try {
contentInfo.requestPermission();
// Load inputContentInfo.getContentUri() here.
} finally {
contentInfo.releasePermission();
}
This gives us flexibility to let InputConnection#commitContent() do all
the magic for IME developers like other APIs such as
Context#startActivity(), rather than asking them to call one more API to
grant a temporary URI permission like a scenario where
Context#grantUriPermission() is used.
[1]: I2772889ca01f2ecb2cdeed4e04a9319bdf7bc5a6
25e0813e6eb6315b1016db805fa9b791b4ae5cc2
Bug: 29450031
Change-Id: I99536cd58c9984af30b0bafb4a1dd25a26634a2d
diff --git a/api/current.txt b/api/current.txt
index 8477bb5..f95c541 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18857,7 +18857,6 @@
public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
ctor public InputMethodService();
method public deprecated boolean enableHardwareAcceleration();
- method public final boolean exposeContent(android.view.inputmethod.InputContentInfo, android.view.inputmethod.EditorInfo);
method public int getBackDisposition();
method public int getCandidatesHiddenVisibility();
method public android.view.inputmethod.InputBinding getCurrentInputBinding();
@@ -44698,7 +44697,7 @@
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
method public boolean deleteSurroundingText(int, int);
@@ -44868,7 +44867,7 @@
method public abstract boolean clearMetaKeyStates(int);
method public abstract void closeConnection();
method public abstract boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public abstract boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public abstract boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public abstract boolean commitText(java.lang.CharSequence, int);
method public abstract boolean deleteSurroundingText(int, int);
@@ -44894,6 +44893,7 @@
field public static final int CURSOR_UPDATE_MONITOR = 2; // 0x2
field public static final int GET_EXTRACTED_TEXT_MONITOR = 1; // 0x1
field public static final int GET_TEXT_WITH_STYLES = 1; // 0x1
+ field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
}
public class InputConnectionWrapper implements android.view.inputmethod.InputConnection {
@@ -44902,7 +44902,7 @@
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
method public boolean deleteSurroundingText(int, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 1095ac3..6a23b6e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20057,7 +20057,6 @@
public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
ctor public InputMethodService();
method public deprecated boolean enableHardwareAcceleration();
- method public final boolean exposeContent(android.view.inputmethod.InputContentInfo, android.view.inputmethod.EditorInfo);
method public int getBackDisposition();
method public int getCandidatesHiddenVisibility();
method public android.view.inputmethod.InputBinding getCurrentInputBinding();
@@ -47805,7 +47804,7 @@
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
method public boolean deleteSurroundingText(int, int);
@@ -47975,7 +47974,7 @@
method public abstract boolean clearMetaKeyStates(int);
method public abstract void closeConnection();
method public abstract boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public abstract boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public abstract boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public abstract boolean commitText(java.lang.CharSequence, int);
method public abstract boolean deleteSurroundingText(int, int);
@@ -48001,6 +48000,7 @@
field public static final int CURSOR_UPDATE_MONITOR = 2; // 0x2
field public static final int GET_EXTRACTED_TEXT_MONITOR = 1; // 0x1
field public static final int GET_TEXT_WITH_STYLES = 1; // 0x1
+ field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
}
public class InputConnectionWrapper implements android.view.inputmethod.InputConnection {
@@ -48009,7 +48009,7 @@
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
method public boolean deleteSurroundingText(int, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 9e775a5..e688dcd 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -18871,7 +18871,6 @@
public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
ctor public InputMethodService();
method public deprecated boolean enableHardwareAcceleration();
- method public final boolean exposeContent(android.view.inputmethod.InputContentInfo, android.view.inputmethod.EditorInfo);
method public int getBackDisposition();
method public int getCandidatesHiddenVisibility();
method public android.view.inputmethod.InputBinding getCurrentInputBinding();
@@ -44778,7 +44777,7 @@
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
method public boolean deleteSurroundingText(int, int);
@@ -44948,7 +44947,7 @@
method public abstract boolean clearMetaKeyStates(int);
method public abstract void closeConnection();
method public abstract boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public abstract boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public abstract boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public abstract boolean commitText(java.lang.CharSequence, int);
method public abstract boolean deleteSurroundingText(int, int);
@@ -44974,6 +44973,7 @@
field public static final int CURSOR_UPDATE_MONITOR = 2; // 0x2
field public static final int GET_EXTRACTED_TEXT_MONITOR = 1; // 0x1
field public static final int GET_TEXT_WITH_STYLES = 1; // 0x1
+ field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
}
public class InputConnectionWrapper implements android.view.inputmethod.InputConnection {
@@ -44982,7 +44982,7 @@
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
- method public boolean commitContent(android.view.inputmethod.InputContentInfo, android.os.Bundle);
+ method public boolean commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
method public boolean deleteSurroundingText(int, int);
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index 3531926..29177b6 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -16,11 +16,14 @@
package android.inputmethodservice;
+import android.annotation.NonNull;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodSession;
@@ -208,7 +211,7 @@
*
* @param event The motion event being received.
* @return True if the event was handled in this function, false otherwise.
- * @see View#onTrackballEvent
+ * @see android.view.View#onTrackballEvent(MotionEvent)
*/
public boolean onTrackballEvent(MotionEvent event) {
return false;
@@ -219,9 +222,30 @@
*
* @param event The motion event being received.
* @return True if the event was handled in this function, false otherwise.
- * @see View#onGenericMotionEvent
+ * @see android.view.View#onGenericMotionEvent(MotionEvent)
*/
public boolean onGenericMotionEvent(MotionEvent event) {
return false;
}
+
+ /**
+ * Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access
+ * permission to the content.
+ *
+ * <p>Default implementation does nothing.</p>
+ *
+ * @param inputContentInfo Content to be temporarily exposed from the input method to the
+ * application.
+ * This cannot be {@code null}.
+ * @param inputConnection {@link InputConnection} with which
+ * {@link InputConnection#commitContent(InputContentInfo, int, android.os.Bundle)} will be
+ * called.
+ * @return {@code false} if we cannot allow a temporary access permission.
+ * @hide
+ */
+ public void exposeContent(@NonNull InputContentInfo inputContentInfo,
+ @NonNull InputConnection inputConnection) {
+ return;
+ }
+
}
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index cc71a9c..167d5a0 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -168,7 +168,7 @@
int missingMethods = msg.arg1;
IInputContext inputContext = (IInputContext)args.arg1;
InputConnection ic = inputContext != null
- ? new InputConnectionWrapper(inputContext, missingMethods) : null;
+ ? new InputConnectionWrapper(mTarget, inputContext, missingMethods) : null;
EditorInfo info = (EditorInfo)args.arg2;
info.makeCompatible(mTargetSdkVersion);
inputMethod.startInput(ic, info);
@@ -180,7 +180,7 @@
int missingMethods = msg.arg1;
IInputContext inputContext = (IInputContext)args.arg1;
InputConnection ic = inputContext != null
- ? new InputConnectionWrapper(inputContext, missingMethods) : null;
+ ? new InputConnectionWrapper(mTarget, inputContext, missingMethods) : null;
EditorInfo info = (EditorInfo)args.arg2;
info.makeCompatible(mTargetSdkVersion);
inputMethod.restartInput(ic, info);
@@ -251,7 +251,7 @@
public void bindInput(InputBinding binding) {
// This IInputContext is guaranteed to implement all the methods.
final int missingMethodFlags = 0;
- InputConnection ic = new InputConnectionWrapper(
+ InputConnection ic = new InputConnectionWrapper(mTarget,
IInputContext.Stub.asInterface(binding.getConnectionToken()), missingMethodFlags);
InputBinding nu = new InputBinding(ic, binding);
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_INPUT_CONTEXT, nu));
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 8e0e0b0..fede77d 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2603,33 +2603,23 @@
* Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access
* permission to the content.
*
- * <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 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
- * to any other IME as long as the client keeps {@link InputContentInfo} object.</p>
- *
* @param inputContentInfo Content to be temporarily exposed from the input method to the
* application.
* This cannot be {@code null}.
- * @param editorInfo The editor that receives {@link InputContentInfo}.
- * @return {@code false} if we cannot allow a temporary access permission.
+ * @param inputConnection {@link InputConnection} with which
+ * {@link InputConnection#commitContent(InputContentInfo, Bundle)} will be called.
+ * @hide
*/
- public final boolean exposeContent(@NonNull InputContentInfo inputContentInfo,
- @NonNull EditorInfo editorInfo) {
- if (inputContentInfo == null) {
- throw new NullPointerException("inputContentInfo");
+ @Override
+ public final void exposeContent(@NonNull InputContentInfo inputContentInfo,
+ @NonNull InputConnection inputConnection) {
+ if (inputConnection == null) {
+ return;
}
- if (editorInfo == null) {
- throw new NullPointerException("editorInfo");
+ if (getCurrentInputConnection() != inputConnection) {
+ return;
}
-
- return mImm.exposeContent(mToken, inputContentInfo, editorInfo);
+ mImm.exposeContent(mToken, inputContentInfo, getCurrentInputEditorInfo());
}
/**
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 0ebbf7f..38962a3 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -855,5 +855,7 @@
/**
* The default implementation does nothing.
*/
- public boolean commitContent(InputContentInfo inputContentInfo, Bundle opts) { return false; }
+ public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
+ return false;
+ }
}
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 2dca892..8038089 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -368,10 +368,10 @@
/**
* List of acceptable MIME types for
- * {@link InputConnection#commitContent(InputContentInfo, Bundle)}.
+ * {@link InputConnection#commitContent(InputContentInfo, int, Bundle)}.
*
* <p>{@code null} or an empty array means that
- * {@link InputConnection#commitContent(InputContentInfo, Bundle)} is not supported in this
+ * {@link InputConnection#commitContent(InputContentInfo, int, Bundle)} is not supported in this
* editor.</p>
*/
@Nullable
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index f7f3694..07910b6 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -840,6 +840,24 @@
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.
+ *
+ * <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 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
+ * to any other IME as long as the client keeps {@link InputContentInfo} object.</p>
+ **/
+ public static int INPUT_CONTENT_GRANT_READ_URI_PERMISSION =
+ android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; // 0x00000001
+
+ /**
* Called by the input method to commit a content such as PNG image to the editor.
*
* <p>In order to avoid variety of compatibility issues, this focuses on a simple use case,
@@ -862,9 +880,11 @@
* </ul>
*
* @param inputContentInfo Content to be inserted.
+ * @param flags {@code 0} or {@link #INPUT_CONTENT_GRANT_READ_URI_PERMISSION}.
* @param opts optional bundle data. This can be {@code null}.
* @return {@code true} if this request is accepted by the application, no matter if the request
* is already handled or still being handled in background.
*/
- public boolean commitContent(@NonNull InputContentInfo inputContentInfo, @Nullable Bundle opts);
+ public boolean commitContent(@NonNull InputContentInfo inputContentInfo, int flags,
+ @Nullable Bundle opts);
}
diff --git a/core/java/android/view/inputmethod/InputConnectionInspector.java b/core/java/android/view/inputmethod/InputConnectionInspector.java
index 727e9ca..2b292bb 100644
--- a/core/java/android/view/inputmethod/InputConnectionInspector.java
+++ b/core/java/android/view/inputmethod/InputConnectionInspector.java
@@ -82,7 +82,7 @@
*/
int CLOSE_CONNECTION = 1 << 6;
/**
- * {@link InputConnection#commitContent(InputContentInfo, Bundle)} is available in
+ * {@link InputConnection#commitContent(InputContentInfo, int, Bundle)} is available in
* {@link android.os.Build.VERSION_CODES#N} MR-1 and later.
*/
int COMMIT_CONTENT = 1 << 7;
@@ -209,7 +209,7 @@
private static boolean hasCommitContent(@NonNull final Class clazz) {
try {
final Method method = clazz.getMethod("commitContent", InputContentInfo.class,
- Bundle.class);
+ int.class, Bundle.class);
return !Modifier.isAbstract(method.getModifiers());
} catch (NoSuchMethodException e) {
return false;
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index af9bcae..317730c 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -274,7 +274,7 @@
* {@inheritDoc}
* @throws NullPointerException if the target is {@code null}.
*/
- public boolean commitContent(InputContentInfo inputContentInfo, Bundle opts) {
- return mTarget.commitContent(inputContentInfo, opts);
+ public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
+ return mTarget.commitContent(inputContentInfo, flags, opts);
}
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index b35f5c3..c0c8e64 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2304,10 +2304,9 @@
* application.
* This cannot be {@code null}.
* @param editorInfo The editor that receives {@link InputContentInfo}.
- * @return {@code false} if we cannot allow a temporary access permission.
* @hide
*/
- public boolean exposeContent(@NonNull IBinder token, @NonNull InputContentInfo inputContentInfo,
+ public void exposeContent(@NonNull IBinder token, @NonNull InputContentInfo inputContentInfo,
@NonNull EditorInfo editorInfo) {
final IInputContentUriToken uriToken;
final Uri contentUri = inputContentInfo.getContentUri();
@@ -2315,15 +2314,15 @@
uriToken = mService.createInputContentUriToken(token, contentUri,
editorInfo.packageName);
if (uriToken == null) {
- return false;
+ return;
}
} catch (RemoteException e) {
Log.e(TAG, "createInputContentAccessToken failed. contentUri=" + contentUri.toString()
+ " packageName=" + editorInfo.packageName, e);
- return false;
+ return;
}
inputContentInfo.setUriToken(uriToken);
- return true;
+ return;
}
void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index f296421..7d7b880 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5985,8 +5985,8 @@
}
@Override
- public boolean commitContent(InputContentInfo inputContentInfo, Bundle opts) {
- return getTarget().commitContent(inputContentInfo, opts);
+ public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
+ return getTarget().commitContent(inputContentInfo, flags, opts);
}
}
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index dce9d2c..62e34a6 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -243,9 +243,10 @@
dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
}
- public void commitContent(InputContentInfo inputContentInfo, Bundle opts,
+ public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
int seq, IInputContextCallback callback) {
- dispatchMessage(obtainMessageOOSC(DO_COMMIT_CONTENT, inputContentInfo, opts, seq, callback));
+ dispatchMessage(obtainMessageIOOSC(DO_COMMIT_CONTENT, flags, inputContentInfo, opts, seq,
+ callback));
}
void dispatchMessage(Message msg) {
@@ -560,6 +561,7 @@
return;
}
case DO_COMMIT_CONTENT: {
+ final int flags = msg.arg1;
SomeArgs args = (SomeArgs) msg.obj;
try {
InputConnection ic = getInputConnection();
@@ -576,7 +578,8 @@
return;
}
args.callback.setCommitContentResult(
- ic.commitContent(inputContentInfo, (Bundle) args.arg2), args.seq);
+ ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2),
+ args.seq);
} catch (RemoteException e) {
Log.w(TAG, "Got RemoteException calling commitContent", e);
}
@@ -612,14 +615,14 @@
return mH.obtainMessage(what, arg1, arg2, args);
}
- Message obtainMessageOOSC(int what, Object arg1, Object arg2, int seq,
+ Message obtainMessageIOOSC(int what, int arg1, Object objArg1, Object objArg2, int seq,
IInputContextCallback callback) {
SomeArgs args = new SomeArgs();
- args.arg1 = arg1;
- args.arg2 = arg2;
+ args.arg1 = objArg1;
+ args.arg2 = objArg2;
args.callback = callback;
args.seq = seq;
- return mH.obtainMessage(what, 0, 0, args);
+ return mH.obtainMessage(what, arg1, 0, args);
}
Message obtainMessageIOSC(int what, int arg1, Object arg2, int seq,
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 0d5c8a1..728c557 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -78,6 +78,6 @@
void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
IInputContextCallback callback);
- void commitContent(in InputContentInfo inputContentInfo, in Bundle opts, int sec,
+ void commitContent(in InputContentInfo inputContentInfo, int flags, in Bundle opts, int sec,
IInputContextCallback callback);
}
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 5e78ec5..9a09dcc 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -16,6 +16,8 @@
package com.android.internal.view;
+import android.annotation.NonNull;
+import android.inputmethodservice.AbstractInputMethodService;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
@@ -31,9 +33,14 @@
import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
import android.view.inputmethod.InputContentInfo;
+import java.lang.ref.WeakReference;
+
public class InputConnectionWrapper implements InputConnection {
private static final int MAX_WAIT_TIME_MILLIS = 2000;
private final IInputContext mIInputContext;
+ @NonNull
+ private final WeakReference<AbstractInputMethodService> mInputMethodService;
+
@MissingMethodFlags
private final int mMissingMethods;
@@ -210,8 +217,10 @@
}
}
- public InputConnectionWrapper(IInputContext inputContext,
- @MissingMethodFlags final int missingMethods) {
+ public InputConnectionWrapper(
+ @NonNull WeakReference<AbstractInputMethodService> inputMethodService,
+ IInputContext inputContext, @MissingMethodFlags final int missingMethods) {
+ mInputMethodService = inputMethodService;
mIInputContext = inputContext;
mMissingMethods = missingMethods;
}
@@ -506,15 +515,24 @@
// Nothing should happen when called from input method.
}
- public boolean commitContent(InputContentInfo inputContentInfo, Bundle opts) {
+ public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
boolean result = false;
if (isMethodMissing(MissingMethodFlags.COMMIT_CONTENT)) {
// This method is not implemented.
return false;
}
try {
+ 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;
+ }
+ inputMethodService.exposeContent(inputContentInfo, this);
+ }
+
InputContextCallback callback = InputContextCallback.getInstance();
- mIInputContext.commitContent(inputContentInfo, opts, callback.mSeq, callback);
+ mIInputContext.commitContent(inputContentInfo, flags, opts, callback.mSeq, callback);
synchronized (callback) {
callback.waitForResultLocked();
if (callback.mHaveValue) {