ClientTransaction.java revision 6b9d3a1400fea76f7c6be535b332a27cb21522b3
1446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian/*
2446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Copyright 2017 The Android Open Source Project
3446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
4446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Licensed under the Apache License, Version 2.0 (the "License");
5446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * you may not use this file except in compliance with the License.
6446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * You may obtain a copy of the License at
7446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
8446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *      http://www.apache.org/licenses/LICENSE-2.0
9446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
10446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Unless required by applicable law or agreed to in writing, software
11446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * distributed under the License is distributed on an "AS IS" BASIS,
12446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * See the License for the specific language governing permissions and
14446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * limitations under the License.
15446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */
16446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
17446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianpackage android.app.servertransaction;
18446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
196b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulianimport android.app.ClientTransactionHandler;
20446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.app.IApplicationThread;
21446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.IBinder;
22446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.Parcel;
23446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.Parcelable;
24446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.RemoteException;
25446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
26446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport java.util.ArrayList;
27446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport java.util.List;
286b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulianimport java.util.Objects;
29446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
30446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian/**
31446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * A container that holds a sequence of messages, which may be sent to a client.
32446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * This includes a list of callbacks and a final lifecycle state.
33446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
34446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see com.android.server.am.ClientLifecycleManager
35446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see ClientTransactionItem
36446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see ActivityLifecycleItem
37446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @hide
38446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */
39446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianpublic class ClientTransaction implements Parcelable {
40446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
41446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** A list of individual callbacks to a client. */
42446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private List<ClientTransactionItem> mActivityCallbacks;
43446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
44446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
45446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Final lifecycle state in which the client activity should be after the transaction is
46446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * executed.
47446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
48446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private ActivityLifecycleItem mLifecycleStateRequest;
49446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
50446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Target client. */
51446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private IApplicationThread mClient;
52446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
53446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Target client activity. Might be null if the entire transaction is targeting an app. */
54446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private IBinder mActivityToken;
55446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
56446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public ClientTransaction(IApplicationThread client, IBinder activityToken) {
57446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mClient = client;
58446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mActivityToken = activityToken;
59446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
60446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
61446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
62446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Add a message to the end of the sequence of callbacks.
63446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param activityCallback A single message that can contain a lifecycle request/callback.
64446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
65446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void addCallback(ClientTransactionItem activityCallback) {
66446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mActivityCallbacks == null) {
67446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mActivityCallbacks = new ArrayList<>();
68446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
69446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mActivityCallbacks.add(activityCallback);
70446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
71446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
72446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
73446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Set the lifecycle state in which the client should be after executing the transaction.
74446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param stateRequest A lifecycle request initialized with right parameters.
75446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
76446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
77446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mLifecycleStateRequest = stateRequest;
78446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
79446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
80446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
81446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Do what needs to be done while the transaction is being scheduled on the client side.
82446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param clientTransactionHandler Handler on the client side that will executed all operations
83446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *                                 requested by transaction items.
84446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
85446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void prepare(android.app.ClientTransactionHandler clientTransactionHandler) {
86446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mActivityCallbacks != null) {
87446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            final int size = mActivityCallbacks.size();
88446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            for (int i = 0; i < size; ++i) {
89446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian                mActivityCallbacks.get(i).prepare(clientTransactionHandler, mActivityToken);
90446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            }
91446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
92446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mLifecycleStateRequest != null) {
93446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mLifecycleStateRequest.prepare(clientTransactionHandler, mActivityToken);
94446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
95446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
96446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
97446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
98446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Execute the transaction.
99446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param clientTransactionHandler Handler on the client side that will execute all operations
100446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *                                 requested by transaction items.
101446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
102446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void execute(android.app.ClientTransactionHandler clientTransactionHandler) {
103446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mActivityCallbacks != null) {
104446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            final int size = mActivityCallbacks.size();
105446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            for (int i = 0; i < size; ++i) {
106446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian                mActivityCallbacks.get(i).execute(clientTransactionHandler, mActivityToken);
107446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            }
108446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
109446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mLifecycleStateRequest != null) {
110446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mLifecycleStateRequest.execute(clientTransactionHandler, mActivityToken);
111446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
112446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
113446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
114446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
115446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Schedule the transaction after it was initialized. It will be send to client and all its
116446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * individual parts will be applied in the following sequence:
1176b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian     * 1. The client calls {@link #prepare(ClientTransactionHandler)}, which triggers all work that
1186b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian     *    needs to be done before actually scheduling the transaction for callbacks and lifecycle
1196b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian     *    state request.
120446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * 2. The transaction message is scheduled.
1216b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian     * 3. The client calls {@link #execute(ClientTransactionHandler)}, which executes all callbacks
1226b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian     *    and necessary lifecycle transitions.
123446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
124446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void schedule() throws RemoteException {
125446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mClient.scheduleTransaction(this);
126446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
127446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
128446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
129446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    // Parcelable implementation
130446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
131446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Write to Parcel. */
132446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    @Override
133446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void writeToParcel(Parcel dest, int flags) {
134446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeStrongBinder(mClient.asBinder());
135446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean writeActivityToken = mActivityToken != null;
136446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeBoolean(writeActivityToken);
137446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (writeActivityToken) {
138446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            dest.writeStrongBinder(mActivityToken);
139446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
140446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeParcelable(mLifecycleStateRequest, flags);
141446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean writeActivityCallbacks = mActivityCallbacks != null;
142446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeBoolean(writeActivityCallbacks);
143446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (writeActivityCallbacks) {
144446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            dest.writeParcelableList(mActivityCallbacks, flags);
145446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
146446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
147446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
148446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Read from Parcel. */
149446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private ClientTransaction(Parcel in) {
150446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mClient = (IApplicationThread) in.readStrongBinder();
151446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean readActivityToken = in.readBoolean();
152446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (readActivityToken) {
153446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mActivityToken = in.readStrongBinder();
154446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
155446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader());
156446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean readActivityCallbacks = in.readBoolean();
157446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (readActivityCallbacks) {
158446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mActivityCallbacks = new ArrayList<>();
159446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            in.readParcelableList(mActivityCallbacks, getClass().getClassLoader());
160446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
161446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
162446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
163446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public static final Creator<ClientTransaction> CREATOR =
164446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            new Creator<ClientTransaction>() {
165446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        public ClientTransaction createFromParcel(Parcel in) {
166446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            return new ClientTransaction(in);
167446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
168446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
169446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        public ClientTransaction[] newArray(int size) {
170446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            return new ClientTransaction[size];
171446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
172446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    };
173446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
174446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    @Override
175446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public int describeContents() {
176446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        return 0;
177446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
1786b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian
1796b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    @Override
1806b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    public boolean equals(Object o) {
1816b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        if (this == o) {
1826b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian            return true;
1836b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        }
1846b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        if (o == null || getClass() != o.getClass()) {
1856b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian            return false;
1866b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        }
1876b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        final ClientTransaction other = (ClientTransaction) o;
1886b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        return Objects.equals(mActivityCallbacks, other.mActivityCallbacks)
1896b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian                && Objects.equals(mLifecycleStateRequest, other.mLifecycleStateRequest)
1906b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian                && mClient == other.mClient
1916b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian                && mActivityToken == other.mActivityToken;
1926b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    }
1936b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian
1946b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    @Override
1956b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    public int hashCode() {
1966b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        int result = 17;
1976b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        result = 31 * result + Objects.hashCode(mActivityCallbacks);
1986b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        result = 31 * result + Objects.hashCode(mLifecycleStateRequest);
1996b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        return result;
2006b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    }
201446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian}
202