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

Commit 446e824e authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Add basic lifecycle transaction containers

This adds basic containers for holding some messages to a client,
that are related to activity lifecycle. Each transaction can hold
a list of callbacks and a final lifecycle state.

Some requests from ActivityManager to client that target activities
are now switched to use transactions. Scheduling, preparing and
executing a request is moved outside of ActivityThread class to
corresponding transaction items.

Bug: 64797980
Test: Existing AM CTS tests pass
Change-Id: I96df20787b3d792f655c9500e8a71032264d02cd
parent a420ae65
Loading
Loading
Loading
Loading
+114 −323

File changed.

Preview size limit exceeded, changes collapsed.

+114 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2017 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.app.servertransaction.ClientTransaction;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PersistableBundle;

import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;

import java.util.List;

/**
 * Defines operations that a {@link android.app.servertransaction.ClientTransaction} or its items
 * can perform on client.
 * @hide
 */
public abstract class ClientTransactionHandler {

    // Schedule phase related logic and handlers.

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.prepare(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

    abstract void sendMessage(int what, Object obj);


    // Prepare phase related logic and handlers. Methods that inform about about pending changes or
    // do other internal bookkeeping.

    /** Get current lifecycle request number to maintain correct ordering. */
    public abstract int getLifecycleSeq();

    /** Set pending config in case it will be updated by other transaction item. */
    public abstract void updatePendingConfiguration(Configuration config);

    /** Set current process state. */
    public abstract void updateProcessState(int processState, boolean fromIpc);


    // Execute phase related logic and handlers. Methods here execute actual lifecycle transactions
    // and deliver callbacks.

    /** Destroy the activity. */
    public abstract void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
            boolean getNonConfigInstance);

    /** Pause the activity. */
    public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, boolean dontReport, int seq);

    /** Resume the activity. */
    public abstract void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
            boolean reallyResume, int seq, String reason);

    /** Stop the activity. */
    public abstract void handleStopActivity(IBinder token, boolean show, int configChanges,
            int seq);

    /** Deliver activity (override) configuration change. */
    public abstract void handleActivityConfigurationChanged(IBinder activityToken,
            Configuration overrideConfig, int displayId);

    /** Deliver result from another activity. */
    public abstract void handleSendResult(IBinder token, List<ResultInfo> results);

    /** Deliver multi-window mode change notification. */
    public abstract void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
            Configuration overrideConfig);

    /** Deliver new intent. */
    public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents,
            boolean andPause);

    /** Deliver picture-in-picture mode change notification. */
    public abstract void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
            Configuration overrideConfig);

    /** Update window visibility. */
    public abstract void handleWindowVisibility(IBinder token, boolean show);

    /** Perform activity launch. */
    public abstract void handleLaunchActivity(IBinder token, Intent intent, int ident,
            ActivityInfo info, Configuration overrideConfig, CompatibilityInfo compatInfo,
            String referrer, IVoiceInteractor voiceInteractor, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
            ProfilerInfo profilerInfo);

    /** Deliver app configuration change notification. */
    public abstract void handleConfigurationChanged(Configuration config);
}
+2 −26
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.IInstrumentationWatcher;
import android.app.IUiAutomationConnection;
import android.app.IUiAutomationConnection;
import android.app.ProfilerInfo;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.app.ResultInfo;
import android.app.servertransaction.ClientTransaction;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.Intent;
@@ -52,24 +53,6 @@ import java.util.Map;
 * {@hide}
 * {@hide}
 */
 */
oneway interface IApplicationThread {
oneway interface IApplicationThread {
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, boolean dontReport);
    void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges);
    void scheduleWindowVisibility(IBinder token, boolean showWindow);
    void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
            in Bundle resumeArgs);
    void scheduleSendResult(IBinder token, in List<ResultInfo> results);
    void scheduleLaunchActivity(in Intent intent, IBinder token, int ident,
            in ActivityInfo info, in Configuration curConfig, in Configuration overrideConfig,
            in CompatibilityInfo compatInfo, in String referrer, IVoiceInteractor voiceInteractor,
            int procState, in Bundle state, in PersistableBundle persistentState,
            in List<ResultInfo> pendingResults, in List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, in ProfilerInfo profilerInfo);
    void scheduleNewIntent(
            in List<ReferrerIntent> intent, IBinder token, boolean andPause);
    void scheduleDestroyActivity(IBinder token, boolean finished,
            int configChanges);
    void scheduleReceiver(in Intent intent, in ActivityInfo info,
    void scheduleReceiver(in Intent intent, in ActivityInfo info,
            in CompatibilityInfo compatInfo,
            in CompatibilityInfo compatInfo,
            int resultCode, in String data, in Bundle extras, boolean sync,
            int resultCode, in String data, in Bundle extras, boolean sync,
@@ -87,7 +70,6 @@ oneway interface IApplicationThread {
            in Bundle coreSettings, in String buildSerial);
            in Bundle coreSettings, in String buildSerial);
    void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs);
    void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs);
    void scheduleExit();
    void scheduleExit();
    void scheduleConfigurationChanged(in Configuration config);
    void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
    void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
    void updateTimeZone();
    void updateTimeZone();
    void processInBackground();
    void processInBackground();
@@ -101,9 +83,6 @@ oneway interface IApplicationThread {
            int resultCode, in String data, in Bundle extras, boolean ordered,
            int resultCode, in String data, in Bundle extras, boolean ordered,
            boolean sticky, int sendingUser, int processState);
            boolean sticky, int sendingUser, int processState);
    void scheduleLowMemory();
    void scheduleLowMemory();
    void scheduleActivityConfigurationChanged(IBinder token, in Configuration overrideConfig);
    void scheduleActivityMovedToDisplay(IBinder token, int displayId,
            in Configuration overrideConfig);
    void scheduleRelaunchActivity(IBinder token, in List<ResultInfo> pendingResults,
    void scheduleRelaunchActivity(IBinder token, in List<ResultInfo> pendingResults,
            in List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed,
            in List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed,
            in Configuration config, in Configuration overrideConfig, boolean preserveWindow);
            in Configuration config, in Configuration overrideConfig, boolean preserveWindow);
@@ -146,14 +125,11 @@ oneway interface IApplicationThread {
    void notifyCleartextNetwork(in byte[] firstPacket);
    void notifyCleartextNetwork(in byte[] firstPacket);
    void startBinderTracking();
    void startBinderTracking();
    void stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
    void stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
    void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
            in Configuration newConfig);
    void schedulePictureInPictureModeChanged(IBinder token, boolean isInPictureInPictureMode,
            in Configuration newConfig);
    void scheduleLocalVoiceInteractionStarted(IBinder token,
    void scheduleLocalVoiceInteractionStarted(IBinder token,
            IVoiceInteractor voiceInteractor);
            IVoiceInteractor voiceInteractor);
    void handleTrustStorageUpdate();
    void handleTrustStorageUpdate();
    void attachAgent(String path);
    void attachAgent(String path);
    void scheduleApplicationInfoChanged(in ApplicationInfo ai);
    void scheduleApplicationInfoChanged(in ApplicationInfo ai);
    void setNetworkBlockSeq(long procStateSeq);
    void setNetworkBlockSeq(long procStateSeq);
    void scheduleTransaction(in ClientTransaction transaction);
}
}
+71 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2017 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.servertransaction;

import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.INVALID_DISPLAY;

import android.content.res.Configuration;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Trace;

/**
 * Activity configuration changed callback.
 * @hide
 */
public class ActivityConfigurationChangeItem extends ClientTransactionItem {

    private final Configuration mConfiguration;

    public ActivityConfigurationChangeItem(Configuration configuration) {
        mConfiguration = configuration;
    }

    @Override
    public void execute(android.app.ClientTransactionHandler client, IBinder token) {
        // TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
        client.handleActivityConfigurationChanged(token, mConfiguration, INVALID_DISPLAY);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }


    // Parcelable implementation

    /** Write to Parcel. */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedObject(mConfiguration, flags);
    }

    /** Read from Parcel. */
    private ActivityConfigurationChangeItem(Parcel in) {
        mConfiguration = in.readTypedObject(Configuration.CREATOR);
    }

    public static final Creator<ActivityConfigurationChangeItem> CREATOR =
            new Creator<ActivityConfigurationChangeItem>() {
        public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
            return new ActivityConfigurationChangeItem(in);
        }

        public ActivityConfigurationChangeItem[] newArray(int size) {
            return new ActivityConfigurationChangeItem[size];
        }
    };
}
+44 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2017 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.servertransaction;

import android.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Request for lifecycle state that an activity should reach.
 * @hide
 */
public abstract class ActivityLifecycleItem extends ClientTransactionItem {

    static final boolean DEBUG_ORDER = false;

    @IntDef({UNDEFINED, RESUMED, PAUSED, STOPPED, DESTROYED})
    @Retention(RetentionPolicy.SOURCE)
    @interface LifecycleState{}
    public static final int UNDEFINED = -1;
    public static final int RESUMED = 0;
    public static final int PAUSED = 1;
    public static final int STOPPED = 2;
    public static final int DESTROYED = 3;

    /** A final lifecycle state that an activity should reach. */
    @LifecycleState
    public abstract int getTargetState();
}
Loading