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

Commit d5bf3ed9 authored by Clara Bayarri's avatar Clara Bayarri
Browse files

Show and trigger activities that implement Text Processing actions

This CL adds the Activities that support Intent.ACTION_PROCESS_TEXT
to the Text Selection Action Mode in Editor, and triggers an intent
with the currently selected text when they are selected.

It also adds the required mechanism to allow a View to request an
intent to be started, and return the activity result back to it.

Change-Id: I62ec618010edf01da41338c8c1a7dd4292a15227
parent 4c42bc04
Loading
Loading
Loading
Loading
+38 −8
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewManager;
import android.view.ViewRootImpl;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -4467,20 +4468,37 @@ public class Activity extends ContextThemeWrapper
     */
    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
            int requestCode, @Nullable Bundle options) {
        startActivityForResult(fragment.mWho, intent, requestCode, options);
    }

    /**
     * @hide
     */
    @Override
    public void startActivityForResult(
            String who, Intent intent, int requestCode, @Nullable Bundle options) {
        if (options != null) {
            mActivityTransitionState.startExitOutTransition(this, options);
        }
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, fragment,
                this, mMainThread.getApplicationThread(), mToken, who,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, fragment.mWho, requestCode,
                mToken, who, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
    }

    /**
     * @hide
     */
    @Override
    public boolean canStartActivityForResult() {
        return true;
    }

    /**
     * Same as calling {@link #startIntentSenderFromChild(Activity, IntentSender,
     * int, Intent, int, int, int, Bundle)} with no options.
@@ -6363,6 +6381,17 @@ public class Activity extends ContextThemeWrapper
            } else {
                onActivityResult(requestCode, resultCode, data);
            }
        } else {
            if (who.startsWith("@android:view:")) {
                ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
                        getActivityToken());
                for (ViewRootImpl viewRoot : views) {
                    if (viewRoot.getView() != null
                            && viewRoot.getView().dispatchActivityResult(
                                    who, requestCode, resultCode, data)) {
                        return;
                    }
                }
            } else {
                Fragment frag = mFragments.findFragmentByWho(who);
                if (frag != null) {
@@ -6374,6 +6403,7 @@ public class Activity extends ContextThemeWrapper
                }
            }
        }
    }

    /**
     * Request to put this Activity in a mode where the user is locked to the
+4 −5
Original line number Diff line number Diff line
@@ -1568,7 +1568,7 @@ public class Instrumentation {

    /**
     * Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
     * android.os.IBinder, Fragment, android.content.Intent, int, android.os.Bundle)},
     * android.os.IBinder, String, android.content.Intent, int, android.os.Bundle)},
     * but for calls from a {#link Fragment}.
     * 
     * @param who The Context from which the activity is being started.
@@ -1576,7 +1576,7 @@ public class Instrumentation {
     *                      is being started.
     * @param token Internal token identifying to the system who is starting 
     *              the activity; may be null.
     * @param target Which fragment is performing the start (and thus receiving 
     * @param target Which element is performing the start (and thus receiving 
     *               any result).
     * @param intent The actual Intent to start.
     * @param requestCode Identifier for this request's result; less than zero 
@@ -1595,7 +1595,7 @@ public class Instrumentation {
     * {@hide}
     */
    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Fragment target,
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
@@ -1619,8 +1619,7 @@ public class Instrumentation {
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mWho : null,
                        requestCode, 0, null, options);
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
+28 −0
Original line number Diff line number Diff line
@@ -1297,6 +1297,34 @@ public abstract class Context {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Version of {@link #startActivity(Intent, Bundle)} that returns a result to the caller. This
     * is only supported for Views and Fragments.
     * @param who The identifier for the calling element that will receive the result.
     * @param intent The intent to start.
     * @param requestCode The code that will be returned with onActivityResult() identifying this
     *          request.
     * @param options Additional options for how the Activity should be started.
     *          May be null if there are no options.  See {@link android.app.ActivityOptions}
     *          for how to build the Bundle supplied here; there are no supported definitions
     *          for building it manually.
     * @hide
     */
    public void startActivityForResult(
            @NonNull String who, Intent intent, int requestCode, @Nullable Bundle options) {
        throw new RuntimeException("This method is only implemented for Activity-based Contexts. "
                + "Check canStartActivityForResult() before calling.");
    }

    /**
     * Identifies whether this Context instance will be able to process calls to
     * {@link #startActivityForResult(String, Intent, int, Bundle)}.
     * @hide
     */
    public boolean canStartActivityForResult() {
        return false;
    }

    /**
     * Same as {@link #startActivities(Intent[], Bundle)} with no options
     * specified.
+11 −0
Original line number Diff line number Diff line
@@ -336,6 +336,17 @@ public class ContextWrapper extends Context {
        mBase.startActivityAsUser(intent, user);
    }

    /** @hide **/
    public void startActivityForResult(
            String who, Intent intent, int requestCode, Bundle options) {
        mBase.startActivityForResult(who, intent, requestCode, options);
    }

    /** @hide **/
    public boolean canStartActivityForResult() {
        return mBase.canStartActivityForResult();
    }

    @Override
    public void startActivity(Intent intent, Bundle options) {
        mBase.startActivity(intent, options);
+76 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.annotation.Nullable;
import android.annotation.Size;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -3549,6 +3550,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    private static SparseArray<String> mAttributeMap;
    /**
     * @hide
     */
    String mStartActivityRequestWho;
    /**
     * Simple constructor to use when creating a view from code.
     *
@@ -4914,6 +4920,58 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Call {@link Context#startActivityForResult(String, Intent, int, Bundle)} for the View's
     * Context, creating a unique View identifier to retrieve the result.
     *
     * @param intent The Intent to be started.
     * @param requestCode The request code to use.
     * @hide
     */
    public void startActivityForResult(Intent intent, int requestCode) {
        mStartActivityRequestWho = "@android:view:" + System.identityHashCode(this);
        getContext().startActivityForResult(mStartActivityRequestWho, intent, requestCode, null);
    }
    /**
     * If this View corresponds to the calling who, dispatches the activity result.
     * @param who The identifier for the targeted View to receive the result.
     * @param requestCode The integer request code originally supplied to
     *                    startActivityForResult(), allowing you to identify who this
     *                    result came from.
     * @param resultCode The integer result code returned by the child activity
     *                   through its setResult().
     * @param data An Intent, which can return result data to the caller
     *               (various data can be attached to Intent "extras").
     * @return {@code true} if the activity result was dispatched.
     * @hide
     */
    public boolean dispatchActivityResult(
            String who, int requestCode, int resultCode, Intent data) {
        if (mStartActivityRequestWho != null && mStartActivityRequestWho.equals(who)) {
            onActivityResult(requestCode, resultCode, data);
            mStartActivityRequestWho = null;
            return true;
        }
        return false;
    }
    /**
     * Receive the result from a previous call to {@link #startActivityForResult(Intent, int)}.
     *
     * @param requestCode The integer request code originally supplied to
     *                    startActivityForResult(), allowing you to identify who this
     *                    result came from.
     * @param resultCode The integer result code returned by the child activity
     *                   through its setResult().
     * @param data An Intent, which can return result data to the caller
     *               (various data can be attached to Intent "extras").
     * @hide
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Do nothing.
    }
    /**
     * Register a callback to be invoked when a hardware key is pressed in this view.
     * Key presses in software input methods will generally not trigger the methods of
@@ -13980,6 +14038,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    @CallSuper
    protected Parcelable onSaveInstanceState() {
        mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
        if (mStartActivityRequestWho != null) {
            BaseSavedState state = new BaseSavedState(AbsSavedState.EMPTY_STATE);
            state.mStartActivityRequestWhoSaved = mStartActivityRequestWho;
            return state;
        }
        return BaseSavedState.EMPTY_STATE;
    }
@@ -14039,13 +14102,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    @CallSuper
    protected void onRestoreInstanceState(Parcelable state) {
        mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
        if (state != BaseSavedState.EMPTY_STATE && state != null) {
        if (state != null && !(state instanceof AbsSavedState)) {
            throw new IllegalArgumentException("Wrong state class, expecting View State but "
                    + "received " + state.getClass().toString() + " instead. This usually happens "
                    + "when two views of different type have the same id in the same hierarchy. "
                    + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
                    + "other views do not use the same id.");
        }
        if (state != null && state instanceof BaseSavedState) {
            mStartActivityRequestWho = ((BaseSavedState) state).mStartActivityRequestWhoSaved;
        }
    }
    /**
@@ -20735,6 +20801,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * state in {@link android.view.View#onSaveInstanceState()}.
     */
    public static class BaseSavedState extends AbsSavedState {
        String mStartActivityRequestWhoSaved;
        /**
         * Constructor used when reading from a parcel. Reads the state of the superclass.
         *
@@ -20742,6 +20810,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         */
        public BaseSavedState(Parcel source) {
            super(source);
            mStartActivityRequestWhoSaved = source.readString();
        }
        /**
@@ -20753,6 +20822,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            super(superState);
        }
        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeString(mStartActivityRequestWhoSaved);
        }
        public static final Parcelable.Creator<BaseSavedState> CREATOR =
                new Parcelable.Creator<BaseSavedState>() {
            public BaseSavedState createFromParcel(Parcel in) {
Loading