ClientTransaction.java revision 0bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbcc
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
1988e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulianimport android.annotation.Nullable;
206b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulianimport android.app.ClientTransactionHandler;
21446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.app.IApplicationThread;
22446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.IBinder;
23446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.Parcel;
24446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.Parcelable;
25446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.RemoteException;
26446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
270bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbccBryce Leeimport com.android.internal.annotations.VisibleForTesting;
280bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbccBryce Lee
29446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport java.util.ArrayList;
30446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport java.util.List;
316b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulianimport java.util.Objects;
32446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
33446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian/**
34446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * A container that holds a sequence of messages, which may be sent to a client.
35446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * This includes a list of callbacks and a final lifecycle state.
36446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
37446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see com.android.server.am.ClientLifecycleManager
38446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see ClientTransactionItem
39446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see ActivityLifecycleItem
40446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @hide
41446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */
429c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulianpublic class ClientTransaction implements Parcelable, ObjectPoolItem {
43446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
44446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** A list of individual callbacks to a client. */
45446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private List<ClientTransactionItem> mActivityCallbacks;
46446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
47446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
48446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Final lifecycle state in which the client activity should be after the transaction is
49446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * executed.
50446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
51446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private ActivityLifecycleItem mLifecycleStateRequest;
52446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
53446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Target client. */
54446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private IApplicationThread mClient;
55446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
56446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Target client activity. Might be null if the entire transaction is targeting an app. */
57446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private IBinder mActivityToken;
58446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
59446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
60446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Add a message to the end of the sequence of callbacks.
61446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param activityCallback A single message that can contain a lifecycle request/callback.
62446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
63446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void addCallback(ClientTransactionItem activityCallback) {
64446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mActivityCallbacks == null) {
65446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mActivityCallbacks = new ArrayList<>();
66446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
67446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mActivityCallbacks.add(activityCallback);
68446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
69446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
7088e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    /** Get the list of callbacks. */
7188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    @Nullable
7288e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    List<ClientTransactionItem> getCallbacks() {
7388e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian        return mActivityCallbacks;
7488e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    }
7588e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian
7688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    /** Get the target activity. */
7788e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    @Nullable
7888e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    public IBinder getActivityToken() {
7988e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian        return mActivityToken;
8088e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    }
8188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian
8288e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    /** Get the target state lifecycle request. */
830bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbccBryce Lee    @VisibleForTesting
840bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbccBryce Lee    public ActivityLifecycleItem getLifecycleStateRequest() {
8588e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian        return mLifecycleStateRequest;
8688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    }
8788e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian
88446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
89446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Set the lifecycle state in which the client should be after executing the transaction.
90446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param stateRequest A lifecycle request initialized with right parameters.
91446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
92446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
93446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mLifecycleStateRequest = stateRequest;
94446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
95446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
96446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
97446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Do what needs to be done while the transaction is being scheduled on the client side.
98446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param clientTransactionHandler Handler on the client side that will executed all operations
99446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *                                 requested by transaction items.
100446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
10188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
102446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mActivityCallbacks != null) {
103446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            final int size = mActivityCallbacks.size();
104446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            for (int i = 0; i < size; ++i) {
10588e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
106446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            }
107446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
108446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (mLifecycleStateRequest != null) {
10988e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
110446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
111446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
112446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
113446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
114446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Schedule the transaction after it was initialized. It will be send to client and all its
115446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * individual parts will be applied in the following sequence:
11688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
11788e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian     *    that needs to be done before actually scheduling the transaction for callbacks and
11888e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian     *    lifecycle state request.
119446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * 2. The transaction message is scheduled.
12088e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
12188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian     *    all callbacks and necessary lifecycle transitions.
122446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
123446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void schedule() throws RemoteException {
124446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mClient.scheduleTransaction(this);
125446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
126446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
127446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
1289c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    // ObjectPoolItem implementation
1299c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian
1309c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    private ClientTransaction() {}
1319c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian
1329c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    /** Obtain an instance initialized with provided params. */
1339c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
1349c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
1359c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        if (instance == null) {
1369c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            instance = new ClientTransaction();
1379c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        }
1389c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        instance.mClient = client;
1399c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        instance.mActivityToken = activityToken;
1409c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian
1419c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        return instance;
1429c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    }
1439c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian
1449c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    @Override
1459c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    public void recycle() {
1469c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        if (mActivityCallbacks != null) {
1479c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            int size = mActivityCallbacks.size();
1489c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            for (int i = 0; i < size; i++) {
1499c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian                mActivityCallbacks.get(i).recycle();
1509c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            }
1519c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            mActivityCallbacks.clear();
1529c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        }
1539c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        if (mLifecycleStateRequest != null) {
1549c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            mLifecycleStateRequest.recycle();
1559c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian            mLifecycleStateRequest = null;
1569c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        }
1579c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        mClient = null;
1589c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        mActivityToken = null;
1599c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        ObjectPool.recycle(this);
1609c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian    }
1619c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian
1629c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian
163446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    // Parcelable implementation
164446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
165446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Write to Parcel. */
166446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    @Override
167446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public void writeToParcel(Parcel dest, int flags) {
168446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeStrongBinder(mClient.asBinder());
169446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean writeActivityToken = mActivityToken != null;
170446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeBoolean(writeActivityToken);
171446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (writeActivityToken) {
172446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            dest.writeStrongBinder(mActivityToken);
173446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
174446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeParcelable(mLifecycleStateRequest, flags);
175446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean writeActivityCallbacks = mActivityCallbacks != null;
176446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        dest.writeBoolean(writeActivityCallbacks);
177446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (writeActivityCallbacks) {
178446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            dest.writeParcelableList(mActivityCallbacks, flags);
179446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
180446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
181446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
182446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /** Read from Parcel. */
183446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private ClientTransaction(Parcel in) {
184446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mClient = (IApplicationThread) in.readStrongBinder();
185446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean readActivityToken = in.readBoolean();
186446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (readActivityToken) {
187446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mActivityToken = in.readStrongBinder();
188446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
189446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader());
190446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final boolean readActivityCallbacks = in.readBoolean();
191446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        if (readActivityCallbacks) {
192446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            mActivityCallbacks = new ArrayList<>();
193446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            in.readParcelableList(mActivityCallbacks, getClass().getClassLoader());
194446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
195446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
196446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
197446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public static final Creator<ClientTransaction> CREATOR =
198446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            new Creator<ClientTransaction>() {
199446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        public ClientTransaction createFromParcel(Parcel in) {
200446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            return new ClientTransaction(in);
201446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
202446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
203446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        public ClientTransaction[] newArray(int size) {
204446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            return new ClientTransaction[size];
205446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        }
206446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    };
207446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
208446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    @Override
209446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    public int describeContents() {
210446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        return 0;
211446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
2126b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian
2136b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    @Override
2146b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    public boolean equals(Object o) {
2156b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        if (this == o) {
2166b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian            return true;
2176b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        }
2186b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        if (o == null || getClass() != o.getClass()) {
2196b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian            return false;
2206b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        }
2216b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        final ClientTransaction other = (ClientTransaction) o;
2226b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        return Objects.equals(mActivityCallbacks, other.mActivityCallbacks)
2236b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian                && Objects.equals(mLifecycleStateRequest, other.mLifecycleStateRequest)
2246b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian                && mClient == other.mClient
2256b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian                && mActivityToken == other.mActivityToken;
2266b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    }
2276b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian
2286b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    @Override
2296b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    public int hashCode() {
2306b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        int result = 17;
2316b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        result = 31 * result + Objects.hashCode(mActivityCallbacks);
2326b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        result = 31 * result + Objects.hashCode(mLifecycleStateRequest);
2336b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian        return result;
2346b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian    }
235446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian}
236