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