• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.servertransaction;
18 
19 import static android.app.servertransaction.TransactionExecutorHelper.getActivityName;
20 
21 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
22 
23 import static java.util.Objects.requireNonNull;
24 
25 import android.annotation.CallSuper;
26 import android.annotation.NonNull;
27 import android.annotation.Nullable;
28 import android.app.ActivityThread.ActivityClientRecord;
29 import android.app.ClientTransactionHandler;
30 import android.os.IBinder;
31 import android.os.Parcel;
32 
33 import com.android.internal.annotations.VisibleForTesting;
34 
35 import java.io.PrintWriter;
36 import java.util.Objects;
37 
38 /**
39  * An activity-targeting callback message to a client that can be scheduled and executed.
40  * It also provides nullity-free version of
41  * {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)} for child class
42  * to inherit.
43  *
44  * @see ClientTransaction
45  * @see ClientTransactionItem
46  * @see com.android.server.wm.ClientLifecycleManager
47  * @hide
48  */
49 public abstract class ActivityTransactionItem extends ClientTransactionItem {
50 
51     /** Target client activity. */
52     @NonNull
53     private final IBinder mActivityToken;
54 
ActivityTransactionItem(@onNull IBinder activityToken)55     public ActivityTransactionItem(@NonNull IBinder activityToken) {
56         mActivityToken = requireNonNull(activityToken);
57     }
58 
59     @Override
execute(@onNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions)60     public final void execute(@NonNull ClientTransactionHandler client,
61             @NonNull PendingTransactionActions pendingActions) {
62         final ActivityClientRecord r = getActivityClientRecord(client);
63         execute(client, r, pendingActions);
64     }
65 
66     /**
67      * Like {@link #execute(ClientTransactionHandler, PendingTransactionActions)},
68      * but take non-null {@link ActivityClientRecord} as a parameter.
69      */
70     @VisibleForTesting(visibility = PACKAGE)
execute(@onNull ClientTransactionHandler client, @NonNull ActivityClientRecord r, @NonNull PendingTransactionActions pendingActions)71     public abstract void execute(@NonNull ClientTransactionHandler client,
72             @NonNull ActivityClientRecord r, @NonNull PendingTransactionActions pendingActions);
73 
74     /**
75      * Gets the {@link ActivityClientRecord} instance that this transaction item is for.
76      * @param client Target client handler.
77      * @return The {@link ActivityClientRecord} instance that this transaction item is for.
78      */
79     @NonNull
getActivityClientRecord(@onNull ClientTransactionHandler client)80     final ActivityClientRecord getActivityClientRecord(@NonNull ClientTransactionHandler client) {
81         final ActivityClientRecord r = client.getActivityClient(getActivityToken());
82         if (r == null) {
83             throw new IllegalArgumentException("Activity client record must not be null to execute "
84                     + "transaction item: " + this);
85         }
86         if (client.getActivity(getActivityToken()) == null) {
87             throw new IllegalArgumentException("Activity must not be null to execute "
88                     + "transaction item: " + this);
89         }
90         return r;
91     }
92 
93     @VisibleForTesting(visibility = PACKAGE)
94     @NonNull
95     @Override
getActivityToken()96     public IBinder getActivityToken() {
97         return mActivityToken;
98     }
99 
100     // Parcelable implementation
101 
102     /** Writes to Parcel. */
103     @CallSuper
104     @Override
writeToParcel(@onNull Parcel dest, int flags)105     public void writeToParcel(@NonNull Parcel dest, int flags) {
106         dest.writeStrongBinder(mActivityToken);
107     }
108 
109     /** Reads from Parcel. */
ActivityTransactionItem(@onNull Parcel in)110     ActivityTransactionItem(@NonNull Parcel in) {
111         this(in.readStrongBinder());
112     }
113 
114     @Override
dump(@onNull String prefix, @NonNull PrintWriter pw, @NonNull ClientTransactionHandler transactionHandler)115     void dump(@NonNull String prefix, @NonNull PrintWriter pw,
116             @NonNull ClientTransactionHandler transactionHandler) {
117         super.dump(prefix, pw, transactionHandler);
118         pw.append(prefix).append("Target activity: ")
119                 .println(getActivityName(mActivityToken, transactionHandler));
120     }
121 
122     // Subclass must override and call super.equals to compare the mActivityToken.
123     @SuppressWarnings("EqualsGetClass")
124     @CallSuper
125     @Override
equals(@ullable Object o)126     public boolean equals(@Nullable Object o) {
127         if (this == o) {
128             return true;
129         }
130         if (o == null || getClass() != o.getClass()) {
131             return false;
132         }
133         final ActivityTransactionItem other = (ActivityTransactionItem) o;
134         return Objects.equals(mActivityToken, other.mActivityToken);
135     }
136 
137     @CallSuper
138     @Override
hashCode()139     public int hashCode() {
140         return Objects.hashCode(mActivityToken);
141     }
142 
143     @CallSuper
144     @Override
toString()145     public String toString() {
146         return "mActivityToken=" + mActivityToken;
147     }
148 }
149