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

Commit c981783f authored by Sunny Goyal's avatar Sunny Goyal Committed by android-build-team Robot
Browse files

[DO NOT MERGE] Adding API for defining and invoking DirectActions

DirectActions are abstract actions defined by an Activtiy. The
actual definition of these actions will be available through
the support lib.

This API provides a secure channel for system or assistant to
interact with a running app using these Actions.

Test: atest CtsVoiceInteractionTestCases
Test: added android.voiceinteraction.cts.DirectActionsTest

Bug: 129705716

Change-Id: I0ce568e0d8f41e0fe46306052016a74c7b394efa
(cherry picked from commit d40c3455)
parent d3243f7c
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -3763,6 +3763,7 @@ package android.app {
    method public void onDetachedFromWindow();
    method public void onEnterAnimationComplete();
    method public boolean onGenericMotionEvent(android.view.MotionEvent);
    method @NonNull public java.util.List<android.app.DirectAction> onGetDirectActions();
    method public boolean onKeyDown(int, android.view.KeyEvent);
    method public boolean onKeyLongPress(int, android.view.KeyEvent);
    method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
@@ -3782,6 +3783,7 @@ package android.app {
    method public void onOptionsMenuClosed(android.view.Menu);
    method public void onPanelClosed(int, @NonNull android.view.Menu);
    method @CallSuper protected void onPause();
    method public void onPerformDirectAction(@NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.os.Bundle>);
    method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
    method @Deprecated public void onPictureInPictureModeChanged(boolean);
    method @CallSuper protected void onPostCreate(@Nullable android.os.Bundle);
@@ -4603,6 +4605,22 @@ package android.app {
    field @Deprecated public static final int STYLE_NO_TITLE = 1; // 0x1
  }
  public final class DirectAction implements android.os.Parcelable {
    method public int describeContents();
    method @Nullable public android.os.Bundle getExtras();
    method @NonNull public String getId();
    method @Nullable public android.content.LocusId getLocusId();
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.DirectAction> CREATOR;
  }
  public static final class DirectAction.Builder {
    ctor public DirectAction.Builder(@NonNull String);
    method @NonNull public android.app.DirectAction build();
    method @NonNull public android.app.DirectAction.Builder setExtras(@Nullable android.os.Bundle);
    method @NonNull public android.app.DirectAction.Builder setLocusId(@Nullable android.content.LocusId);
  }
  public class DownloadManager {
    method public long addCompletedDownload(String, String, boolean, String, String, long, boolean);
    method public long addCompletedDownload(String, String, boolean, String, String, long, boolean, android.net.Uri, android.net.Uri);
@@ -6338,9 +6356,13 @@ package android.app {
  public final class VoiceInteractor {
    method public android.app.VoiceInteractor.Request getActiveRequest(String);
    method public android.app.VoiceInteractor.Request[] getActiveRequests();
    method public boolean isDestroyed();
    method public void notifyDirectActionsChanged();
    method public boolean registerOnDestroyedCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable);
    method public boolean submitRequest(android.app.VoiceInteractor.Request);
    method public boolean submitRequest(android.app.VoiceInteractor.Request, String);
    method public boolean[] supportsCommands(String[]);
    method public boolean unregisterOnDestroyedCallback(@NonNull Runnable);
  }
  public static class VoiceInteractor.AbortVoiceRequest extends android.app.VoiceInteractor.Request {
@@ -41790,9 +41812,11 @@ package android.service.voice {
    method public void onCreate();
    method public android.view.View onCreateContentView();
    method public void onDestroy();
    method public void onDirectActionsInvalidated(@NonNull android.service.voice.VoiceInteractionSession.ActivityId);
    method public boolean[] onGetSupportedCommands(String[]);
    method public void onHandleAssist(@Nullable android.os.Bundle, @Nullable android.app.assist.AssistStructure, @Nullable android.app.assist.AssistContent);
    method public void onHandleAssistSecondary(@Nullable android.os.Bundle, @Nullable android.app.assist.AssistStructure, @Nullable android.app.assist.AssistContent, int, int);
    method @Deprecated public void onHandleAssist(@Nullable android.os.Bundle, @Nullable android.app.assist.AssistStructure, @Nullable android.app.assist.AssistContent);
    method public void onHandleAssist(@NonNull android.service.voice.VoiceInteractionSession.AssistState);
    method @Deprecated public void onHandleAssistSecondary(@Nullable android.os.Bundle, @Nullable android.app.assist.AssistStructure, @Nullable android.app.assist.AssistContent, int, int);
    method public void onHandleScreenshot(@Nullable android.graphics.Bitmap);
    method public void onHide();
    method public boolean onKeyDown(int, android.view.KeyEvent);
@@ -41811,6 +41835,8 @@ package android.service.voice {
    method public void onTaskFinished(android.content.Intent, int);
    method public void onTaskStarted(android.content.Intent, int);
    method public void onTrimMemory(int);
    method public final void performDirectAction(@NonNull android.app.DirectAction, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.Bundle>);
    method public final void requestDirectActions(@NonNull android.service.voice.VoiceInteractionSession.ActivityId, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.DirectAction>>);
    method public void setContentView(android.view.View);
    method public void setDisabledShowContext(int);
    method public void setKeepAwake(boolean);
@@ -41835,6 +41861,19 @@ package android.service.voice {
    method public void sendAbortResult(android.os.Bundle);
  }
  public static class VoiceInteractionSession.ActivityId {
  }
  public static final class VoiceInteractionSession.AssistState {
    method @NonNull public android.service.voice.VoiceInteractionSession.ActivityId getActivityId();
    method @Nullable public android.app.assist.AssistContent getAssistContent();
    method @Nullable public android.os.Bundle getAssistData();
    method @Nullable public android.app.assist.AssistStructure getAssistStructure();
    method @IntRange(from=0) public int getCount();
    method @IntRange(from=0xffffffff) public int getIndex();
    method public boolean isFocused();
  }
  public static final class VoiceInteractionSession.CommandRequest extends android.service.voice.VoiceInteractionSession.Request {
    method public String getCommand();
    method public void sendIntermediateResult(android.os.Bundle);
+60 −5
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.net.Uri;
import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.GraphicsEnvironment;
import android.os.Handler;
import android.os.IBinder;
@@ -148,8 +149,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;


/**
@@ -788,6 +792,7 @@ public class Activity extends ContextThemeWrapper
    private Instrumentation mInstrumentation;
    @UnsupportedAppUsage
    private IBinder mToken;
    private IBinder mAssistToken;
    @UnsupportedAppUsage
    private int mIdent;
    @UnsupportedAppUsage
@@ -866,7 +871,7 @@ public class Activity extends ContextThemeWrapper
    private boolean mEnableDefaultActionBarUp;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private VoiceInteractor mVoiceInteractor;
    VoiceInteractor mVoiceInteractor;

    @UnsupportedAppUsage
    private CharSequence mTitle;
@@ -1858,11 +1863,14 @@ public class Activity extends ContextThemeWrapper

    void setVoiceInteractor(IVoiceInteractor voiceInteractor) {
        if (mVoiceInteractor != null) {
            final Request[] requests = mVoiceInteractor.getActiveRequests();
            if (requests != null) {
                for (Request activeRequest : mVoiceInteractor.getActiveRequests()) {
                    activeRequest.cancel();
                    activeRequest.clear();
                }
            }
        }
        if (voiceInteractor == null) {
            mVoiceInteractor = null;
        } else {
@@ -2315,6 +2323,47 @@ public class Activity extends ContextThemeWrapper
    public void onProvideAssistContent(AssistContent outContent) {
    }

    /**
     * Returns the list of direct actions supported by the app.
     *
     * <p>You should return the list of actions that could be executed in the
     * current context, which is in the current state of the app. If the actions
     * that could be executed by the app changes you should report that via
     * calling {@link VoiceInteractor#notifyDirectActionsChanged()}.
     *
     * <p>To get the voice interactor you need to call {@link #getVoiceInteractor()}
     * which would return non <code>null<c/ode> only if there is an ongoing voice
     * interaction session. You an also detect when the voice interactor is no
     * longer valid because the voice interaction session that is backing is finished
     * by calling {@link VoiceInteractor#registerOnDestroyedCallback(Executor, Runnable)}.
     *
     * <p>This method will be called only after {@link #onStart()} is being called and
     * before {@link #onStop()} is being called.
     *
     * @return The currently supported direct actions which cannot be <code>null</code>
     * or contain <code>null</null> elements.
     */
    @NonNull
    public List<DirectAction> onGetDirectActions() {
        return Collections.emptyList();
    }

    /**
     * This is called to perform an action previously defined by the app.
     * Apps also have access to {@link #getVoiceInteractor()} to follow up on the action.
     *
     * @param actionId The ID for the action
     * @param arguments Any additional arguments provided by the caller
     * @param cancellationSignal A signal to cancel the operation in progress, or {@code null}
     *                          if none.
     * @param resultListener The callback to provide the result back to the caller
     *
     * @see #onGetDirectActions()
     */
    public void onPerformDirectAction(@NonNull String actionId,
            @Nullable Bundle arguments, @Nullable CancellationSignal cancellationSignal,
            @NonNull Consumer<Bundle> resultListener) { }

    /**
     * Request the Keyboard Shortcuts screen to show up. This will trigger
     * {@link #onProvideKeyboardShortcuts} to retrieve the shortcuts for the foreground activity.
@@ -7626,7 +7675,7 @@ public class Activity extends ContextThemeWrapper
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);
@@ -7647,6 +7696,7 @@ public class Activity extends ContextThemeWrapper
        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mAssistToken = assistToken;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
@@ -7697,6 +7747,11 @@ public class Activity extends ContextThemeWrapper
        return mParent != null ? mParent.getActivityToken() : mToken;
    }

    /** @hide */
    public final IBinder getAssistToken() {
        return mParent != null ? mParent.getAssistToken() : mAssistToken;
    }

    /** @hide */
    @VisibleForTesting
    public final ActivityThread getActivityThread() {
+102 −4
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
@@ -95,6 +96,7 @@ import android.os.GraphicsEnvironment;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.LocaleList;
import android.os.Looper;
import android.os.Message;
@@ -121,6 +123,7 @@ import android.provider.Settings;
import android.renderscript.RenderScriptCacheDir;
import android.security.NetworkSecurityPolicy;
import android.security.net.config.NetworkSecurityConfigProvider;
import android.service.voice.VoiceInteractionSession;
import android.system.ErrnoException;
import android.system.OsConstants;
import android.system.StructStat;
@@ -160,6 +163,7 @@ import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.org.conscrypt.OpenSSLSocketImpl;
import com.android.org.conscrypt.TrustedCertificateStore;
@@ -450,6 +454,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    public static final class ActivityClientRecord {
        @UnsupportedAppUsage
        public IBinder token;
        public IBinder assistToken;
        int ident;
        @UnsupportedAppUsage
        Intent intent;
@@ -526,8 +531,10 @@ public final class ActivityThread extends ClientTransactionHandler {
                String referrer, IVoiceInteractor voiceInteractor, Bundle state,
                PersistableBundle persistentState, List<ResultInfo> pendingResults,
                List<ReferrerIntent> pendingNewIntents, boolean isForward,
                ProfilerInfo profilerInfo, ClientTransactionHandler client) {
                ProfilerInfo profilerInfo, ClientTransactionHandler client,
                IBinder assistToken) {
            this.token = token;
            this.assistToken = assistToken;
            this.ident = ident;
            this.intent = intent;
            this.referrer = referrer;
@@ -1645,6 +1652,33 @@ public final class ActivityThread extends ClientTransactionHandler {
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

        @Override
        public void requestDirectActions(@NonNull IBinder activityToken,
                @NonNull IVoiceInteractor interactor, @NonNull RemoteCallback callback) {
            mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
                    ActivityThread.this, activityToken, interactor, callback));
        }

        @Override
        public void performDirectAction(IBinder activityToken, String actionId, Bundle arguments,
                RemoteCallback cancellationCallback, RemoteCallback resultCallback) {
            final CancellationSignal cancellationSignal;
            if (cancellationCallback != null) {
                final ICancellationSignal transport = CancellationSignal.createTransport();
                cancellationSignal = CancellationSignal.fromTransport(transport);
                final Bundle cancellationResult = new Bundle();
                cancellationResult.putBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL,
                        transport.asBinder());
                cancellationCallback.sendResult(cancellationResult);
            } else {
                cancellationSignal = new CancellationSignal();
            }

            mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handlePerformDirectAction,
                    ActivityThread.this, activityToken, actionId, arguments,
                    cancellationSignal, resultCallback));
        }
    }

    class H extends Handler {
@@ -2877,9 +2911,10 @@ public final class ActivityThread extends ClientTransactionHandler {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public final Activity startActivityNow(Activity parent, String id,
        Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
        Activity.NonConfigurationInstances lastNonConfigurationInstances) {
        Activity.NonConfigurationInstances lastNonConfigurationInstances, IBinder assistToken) {
        ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.assistToken = assistToken;
            r.ident = 0;
            r.intent = intent;
            r.state = state;
@@ -3120,7 +3155,8 @@ public final class ActivityThread extends ClientTransactionHandler {
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
@@ -3352,7 +3388,6 @@ public final class ActivityThread extends ClientTransactionHandler {
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }

    }

    private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
@@ -3432,6 +3467,7 @@ public final class ActivityThread extends ClientTransactionHandler {
                    r.activity.onProvideAssistContent(content);
                }
            }

        }
        if (structure == null) {
            structure = new AssistStructure();
@@ -3451,6 +3487,68 @@ public final class ActivityThread extends ClientTransactionHandler {
        }
    }

    /** Fetches the user actions for the corresponding activity */
    private void handleRequestDirectActions(@NonNull IBinder activityToken,
            @NonNull IVoiceInteractor interactor, @NonNull RemoteCallback callback) {
        final ActivityClientRecord r = mActivities.get(activityToken);
        if (r != null) {
            final int lifecycleState = r.getLifecycleState();
            if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
                callback.sendResult(null);
                return;
            }
            if (r.activity.mVoiceInteractor == null
                    || r.activity.mVoiceInteractor.mInteractor.asBinder()
                    != interactor.asBinder()) {
                if (r.activity.mVoiceInteractor != null) {
                    r.activity.mVoiceInteractor.destroy();
                }
                r.activity.mVoiceInteractor = new VoiceInteractor(interactor, r.activity,
                        r.activity, Looper.myLooper());
            }
            final List<DirectAction> actions = r.activity.onGetDirectActions();
            Preconditions.checkNotNull(actions);
            Preconditions.checkCollectionElementsNotNull(actions, "actions");
            if (actions != null && !actions.isEmpty()) {
                final int actionCount = actions.size();
                for (int i = 0; i < actionCount; i++) {
                    final DirectAction action = actions.get(i);
                    action.setSource(r.activity.getTaskId(), r.activity.getAssistToken());
                }
                final Bundle result = new Bundle();
                result.putParcelable(DirectAction.KEY_ACTIONS_LIST,
                        new ParceledListSlice<>(actions));
                callback.sendResult(result);
            }
        }
        callback.sendResult(null);
    }

    /** Performs an actions in the corresponding activity */
    private void handlePerformDirectAction(@NonNull IBinder activityToken,
            @NonNull String actionId, @Nullable Bundle arguments,
            @NonNull CancellationSignal cancellationSignal,
            @NonNull RemoteCallback resultCallback) {
        final ActivityClientRecord r = mActivities.get(activityToken);
        if (r != null) {
            final int lifecycleState = r.getLifecycleState();
            if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
                resultCallback.sendResult(null);
                return;
            }
            final Bundle nonNullArguments = (arguments != null) ? arguments : Bundle.EMPTY;
            final WeakReference<RemoteCallback> weakCallback = new WeakReference<>(resultCallback);
            r.activity.onPerformDirectAction(actionId, nonNullArguments, cancellationSignal,
                    (b) -> {
                final RemoteCallback strongCallback = weakCallback.get();
                if (strongCallback != null) {
                    strongCallback.sendResult(b);
                }
            });
        }
        resultCallback.sendResult(null);
    }

    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
+188 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.app;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.LocusId;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.Preconditions;

/**
 * Represents a abstract action that can be perform on this app. This are requested from
 * outside the app's UI (eg by SystemUI or assistant).
 */
public final class DirectAction implements Parcelable {

    /**
     * @hide
     */
    public static final String KEY_ACTIONS_LIST = "actions_list";

    private int mTaskId;
    private IBinder mActivityId;

    @NonNull
    private final String mID;
    @Nullable
    private final Bundle mExtras;
    @Nullable
    private final LocusId mLocusId;

    /** @hide */
    public DirectAction(@NonNull String id, @Nullable Bundle extras,
            @Nullable LocusId locusId) {
        mID = Preconditions.checkStringNotEmpty(id);
        mExtras = extras;
        mLocusId = locusId;
    }

    /** @hide */
    public void setSource(int taskId, IBinder activityId) {
        mTaskId = taskId;
        mActivityId = activityId;
    }

    /**
     * @hide
     */
    public DirectAction(@NonNull DirectAction original) {
        mTaskId = original.mTaskId;
        mActivityId = original.mActivityId;
        mID = original.mID;
        mExtras = original.mExtras;
        mLocusId = original.mLocusId;
    }

    private DirectAction(Parcel in) {
        mTaskId = in.readInt();
        mActivityId = in.readStrongBinder();
        mID = in.readString();
        mExtras = in.readBundle();
        final String idString = in.readString();
        mLocusId = (idString != null) ? new LocusId(idString) : null;
    }

    /** @hide */
    public int getTaskId() {
        return mTaskId;
    }

    /** @hide */
    public IBinder getActivityId() {
        return mActivityId;
    }

    /**
     * Returns the ID for this action.
     */
    @NonNull
    public String getId() {
        return mID;
    }

    /**
     * Returns any extras associated with this action.
     */
    @Nullable
    public Bundle getExtras() {
        return mExtras;
    }

    /**
     * Returns the LocusId for the current state for the app
     */
    @Nullable
    public LocusId getLocusId() {
        return mLocusId;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mTaskId);
        dest.writeStrongBinder(mActivityId);
        dest.writeString(mID);
        dest.writeBundle(mExtras);
        dest.writeString(mLocusId.getId());
    }

    /**
     * Builder for construction of DirectAction.
     */
    public static final class Builder {
        private @NonNull String mId;
        private @Nullable Bundle mExtras;
        private @Nullable LocusId mLocusId;

        /**
         * Creates a new instance.
         *
         * @param id The mandatory action id.
         */
        public Builder(@NonNull String id) {
            Preconditions.checkNotNull(id);
            mId = id;
        }

        /**
         * Sets the optional action extras.
         *
         * @param extras The extras.
         * @return This builder.
         */
        public @NonNull Builder setExtras(@Nullable Bundle extras) {
            mExtras = extras;
            return this;
        }

        /**
         * Sets the optional locus id.
         *
         * @param locusId The locus id.
         * @return This builder.
         */
        public @NonNull Builder setLocusId(@Nullable LocusId locusId) {
            mLocusId = locusId;
            return this;
        }

        /**
         * @return A newly constructed instance.
         */
        public @NonNull DirectAction build() {
            return new DirectAction(mId, mExtras, mLocusId);
        }
    }

    public static final @NonNull Parcelable.Creator<DirectAction> CREATOR =
            new Parcelable.Creator<DirectAction>() {
                public DirectAction createFromParcel(Parcel in) {
                    return new DirectAction(in);
                }
                public DirectAction[] newArray(int size) {
                    return new DirectAction[size];
                }
            };
}
+5 −0
Original line number Diff line number Diff line
@@ -140,4 +140,9 @@ oneway interface IApplicationThread {
    void scheduleApplicationInfoChanged(in ApplicationInfo ai);
    void setNetworkBlockSeq(long procStateSeq);
    void scheduleTransaction(in ClientTransaction transaction);
    void requestDirectActions(IBinder activityToken, IVoiceInteractor intractor,
        in RemoteCallback callback);
    void performDirectAction(IBinder activityToken, String actionId,
            in Bundle arguments, in RemoteCallback cancellationCallback,
            in RemoteCallback resultCallback);
}
Loading