Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25e0813e authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Add InputMethodService#exposeContent()

This is a follow up CL to my previous CLs [1][2] that introduced
InputConnection#commitContent(InputContentInfo, Bundle) API to enable
IMEs to send a content to the target application.

With this CL, IME developers are able to temporarily expose
InputContentInfo object to the target package without permanently
granting URI permission.  Although calling IMS#exposeContent() 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 InputContentInfo
object.

Here is a sample code snippet about how to use this mechanism.

  [IME]
  InputContentInfo contentInfo = new InputContentInfo(
          contentUri,
          new ClipDescription(description, new String[]{mimeType}),
          linkUrl);
  exposeContent(contentInfo, getCurrentInputEditorInfo());
  getCurrentInputConnection().commitContent(inputContentInfo, null);

  [App]
  try {
      contentInfo.requestPermission();
      // Load inputContentInfo.getContentUri() here.
  } finally {
      contentInfo.releasePermission();
  }

 [1]: Iaadf934a997ffcd6000a516cc3c1873db56e60ad
      152944f4
 [2]: Ica1ba3154795c1bf44e140dfe639b299f83cd8af
      adebb525

Bug: 29450031
Change-Id: I2772889ca01f2ecb2cdeed4e04a9319bdf7bc5a6
parent f0823858
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -318,6 +318,7 @@ LOCAL_SRC_FILES += \
	core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
	core/java/com/android/internal/backup/IBackupTransport.aidl \
	core/java/com/android/internal/backup/IObbBackupService.aidl \
	core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
	core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
	core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
	core/java/com/android/internal/policy/IKeyguardService.aidl \
+4 −1
Original line number Diff line number Diff line
@@ -18862,6 +18862,7 @@ package android.inputmethodservice {
  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();
@@ -44921,13 +44922,15 @@ package android.view.inputmethod {
    method public void setTarget(android.view.inputmethod.InputConnection);
  }
  public class InputContentInfo implements android.os.Parcelable {
  public final class InputContentInfo implements android.os.Parcelable {
    ctor public InputContentInfo(android.net.Uri, android.content.ClipDescription);
    ctor public InputContentInfo(android.net.Uri, android.content.ClipDescription, android.net.Uri);
    method public int describeContents();
    method public android.net.Uri getContentUri();
    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;
  }
+4 −1
Original line number Diff line number Diff line
@@ -20062,6 +20062,7 @@ package android.inputmethodservice {
  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();
@@ -48028,13 +48029,15 @@ package android.view.inputmethod {
    method public void setTarget(android.view.inputmethod.InputConnection);
  }
  public class InputContentInfo implements android.os.Parcelable {
  public final class InputContentInfo implements android.os.Parcelable {
    ctor public InputContentInfo(android.net.Uri, android.content.ClipDescription);
    ctor public InputContentInfo(android.net.Uri, android.content.ClipDescription, android.net.Uri);
    method public int describeContents();
    method public android.net.Uri getContentUri();
    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;
  }
+4 −1
Original line number Diff line number Diff line
@@ -18876,6 +18876,7 @@ package android.inputmethodservice {
  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();
@@ -45001,13 +45002,15 @@ package android.view.inputmethod {
    method public void setTarget(android.view.inputmethod.InputConnection);
  }
  public class InputContentInfo implements android.os.Parcelable {
  public final class InputContentInfo implements android.os.Parcelable {
    ctor public InputContentInfo(android.net.Uri, android.content.ClipDescription);
    ctor public InputContentInfo(android.net.Uri, android.content.ClipDescription, android.net.Uri);
    method public int describeContents();
    method public android.net.Uri getContentUri();
    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;
  }
+35 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.CallSuper;
import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.Context;
@@ -65,6 +66,7 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
@@ -2597,6 +2599,39 @@ public class InputMethodService extends AbstractInputMethodService {
        return mImm.getInputMethodWindowVisibleHeight();
    }

    /**
     * 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
     * &lt;grant-uri-permissions&gt;} 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.
     */
    public final boolean exposeContent(@NonNull InputContentInfo inputContentInfo,
            @NonNull EditorInfo editorInfo) {
        if (inputContentInfo == null) {
            throw new NullPointerException("inputContentInfo");
        }
        if (editorInfo == null) {
            throw new NullPointerException("editorInfo");
        }

        return mImm.exposeContent(mToken, inputContentInfo, editorInfo);
    }

    /**
     * Performs a dump of the InputMethodService's internal state.  Override
     * to add your own information to the dump.
Loading