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 590447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian /** Get the target client of the transaction. */ 600447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian public IApplicationThread getClient() { 610447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian return mClient; 620447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian } 630447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian 64446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian /** 65446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Add a message to the end of the sequence of callbacks. 66446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @param activityCallback A single message that can contain a lifecycle request/callback. 67446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */ 68446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public void addCallback(ClientTransactionItem activityCallback) { 69446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (mActivityCallbacks == null) { 70446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mActivityCallbacks = new ArrayList<>(); 71446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 72446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mActivityCallbacks.add(activityCallback); 73446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 74446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 7588e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian /** Get the list of callbacks. */ 7688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian @Nullable 7788e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian List<ClientTransactionItem> getCallbacks() { 7888e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian return mActivityCallbacks; 7988e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian } 8088e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian 8188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian /** Get the target activity. */ 8288e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian @Nullable 8388e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian public IBinder getActivityToken() { 8488e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian return mActivityToken; 8588e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian } 8688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian 8788e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian /** Get the target state lifecycle request. */ 880bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbccBryce Lee @VisibleForTesting 890bd8d42c0a2e28d99d4ed29a93fa2443b7b1bbccBryce Lee public ActivityLifecycleItem getLifecycleStateRequest() { 9088e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian return mLifecycleStateRequest; 9188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian } 9288e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian 93446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian /** 94446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Set the lifecycle state in which the client should be after executing the transaction. 95446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @param stateRequest A lifecycle request initialized with right parameters. 96446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */ 97446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) { 98446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mLifecycleStateRequest = stateRequest; 99446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 100446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 101446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian /** 102446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Do what needs to be done while the transaction is being scheduled on the client side. 103446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @param clientTransactionHandler Handler on the client side that will executed all operations 104446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * requested by transaction items. 105446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */ 10688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) { 107446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (mActivityCallbacks != null) { 108446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian final int size = mActivityCallbacks.size(); 109446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian for (int i = 0; i < size; ++i) { 11088e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken); 111446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 112446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 113446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (mLifecycleStateRequest != null) { 11488e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken); 115446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 116446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 117446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 118446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian /** 119446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Schedule the transaction after it was initialized. It will be send to client and all its 120446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * individual parts will be applied in the following sequence: 12188e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work 12288e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian * that needs to be done before actually scheduling the transaction for callbacks and 12388e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian * lifecycle state request. 124446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * 2. The transaction message is scheduled. 12588e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes 12688e05cb84427c23bb2e23626968f2e8431b6f273Andrii Kulian * all callbacks and necessary lifecycle transitions. 127446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */ 128446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public void schedule() throws RemoteException { 129446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mClient.scheduleTransaction(this); 130446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 131446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 132446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 1339c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian // ObjectPoolItem implementation 1349c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian 1359c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian private ClientTransaction() {} 1369c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian 1379c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian /** Obtain an instance initialized with provided params. */ 1389c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) { 1399c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class); 1409c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian if (instance == null) { 1419c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian instance = new ClientTransaction(); 1429c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian } 1439c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian instance.mClient = client; 1449c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian instance.mActivityToken = activityToken; 1459c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian 1469c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian return instance; 1479c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian } 1489c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian 1499c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian @Override 1509c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian public void recycle() { 1519c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian if (mActivityCallbacks != null) { 1529c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian int size = mActivityCallbacks.size(); 1539c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian for (int i = 0; i < size; i++) { 1549c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian mActivityCallbacks.get(i).recycle(); 1559c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian } 1569c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian mActivityCallbacks.clear(); 1579c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian } 1589c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian if (mLifecycleStateRequest != null) { 1599c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian mLifecycleStateRequest.recycle(); 1609c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian mLifecycleStateRequest = null; 1619c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian } 1629c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian mClient = null; 1639c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian mActivityToken = null; 1649c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian ObjectPool.recycle(this); 1659c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian } 1669c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian 1679c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian 168446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian // Parcelable implementation 169446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 170446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian /** Write to Parcel. */ 171446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian @Override 172446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public void writeToParcel(Parcel dest, int flags) { 173446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian dest.writeStrongBinder(mClient.asBinder()); 174446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian final boolean writeActivityToken = mActivityToken != null; 175446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian dest.writeBoolean(writeActivityToken); 176446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (writeActivityToken) { 177446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian dest.writeStrongBinder(mActivityToken); 178446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 179446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian dest.writeParcelable(mLifecycleStateRequest, flags); 180446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian final boolean writeActivityCallbacks = mActivityCallbacks != null; 181446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian dest.writeBoolean(writeActivityCallbacks); 182446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (writeActivityCallbacks) { 183446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian dest.writeParcelableList(mActivityCallbacks, flags); 184446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 185446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 186446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 187446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian /** Read from Parcel. */ 188446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian private ClientTransaction(Parcel in) { 189446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mClient = (IApplicationThread) in.readStrongBinder(); 190446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian final boolean readActivityToken = in.readBoolean(); 191446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (readActivityToken) { 192446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mActivityToken = in.readStrongBinder(); 193446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 194446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader()); 195446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian final boolean readActivityCallbacks = in.readBoolean(); 196446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian if (readActivityCallbacks) { 197446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian mActivityCallbacks = new ArrayList<>(); 198446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian in.readParcelableList(mActivityCallbacks, getClass().getClassLoader()); 199446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 200446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 201446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 202446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public static final Creator<ClientTransaction> CREATOR = 203446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian new Creator<ClientTransaction>() { 204446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public ClientTransaction createFromParcel(Parcel in) { 205446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian return new ClientTransaction(in); 206446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 207446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 208446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public ClientTransaction[] newArray(int size) { 209446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian return new ClientTransaction[size]; 210446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 211446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian }; 212446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian 213446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian @Override 214446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian public int describeContents() { 215446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian return 0; 216446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian } 2176b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian 2186b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian @Override 2196b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian public boolean equals(Object o) { 2206b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian if (this == o) { 2216b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian return true; 2226b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian } 2236b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian if (o == null || getClass() != o.getClass()) { 2246b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian return false; 2256b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian } 2266b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian final ClientTransaction other = (ClientTransaction) o; 2276b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian return Objects.equals(mActivityCallbacks, other.mActivityCallbacks) 2286b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian && Objects.equals(mLifecycleStateRequest, other.mLifecycleStateRequest) 2296b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian && mClient == other.mClient 2306b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian && mActivityToken == other.mActivityToken; 2316b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian } 2326b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian 2336b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian @Override 2346b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian public int hashCode() { 2356b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian int result = 17; 2366b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian result = 31 * result + Objects.hashCode(mActivityCallbacks); 2376b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian result = 31 * result + Objects.hashCode(mLifecycleStateRequest); 2386b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian return result; 2396b9d3a1400fea76f7c6be535b332a27cb21522b3Andrii Kulian } 240446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian} 241