1 /*
2  * Copyright 2019 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 package android.app.servertransaction;
17 
18 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
19 
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.app.ActivityClient;
23 import android.app.ActivityThread.ActivityClientRecord;
24 import android.app.ClientTransactionHandler;
25 import android.os.IBinder;
26 import android.os.Parcel;
27 import android.os.Trace;
28 
29 /**
30  * Top resumed activity changed callback.
31  * @hide
32  */
33 public class TopResumedActivityChangeItem extends ActivityTransactionItem {
34 
35     private boolean mOnTop;
36 
37     @Override
execute(ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions)38     public void execute(ClientTransactionHandler client, ActivityClientRecord r,
39             PendingTransactionActions pendingActions) {
40         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
41         client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
42         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
43     }
44 
45     @Override
postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions)46     public void postExecute(ClientTransactionHandler client, IBinder token,
47             PendingTransactionActions pendingActions) {
48         if (mOnTop) {
49             return;
50         }
51 
52         // The loss of top resumed state can always be reported immediately in postExecute
53         // because only three cases are possible:
54         // 1. Activity is in RESUMED state now and it just handled the callback in #execute().
55         // 2. Activity wasn't RESUMED yet, which means that it didn't receive the top state yet.
56         // 3. Activity is PAUSED or in other lifecycle state after PAUSED. In this case top resumed
57         // state loss was already called right before pausing.
58         ActivityClient.getInstance().activityTopResumedStateLost();
59     }
60 
61 
62     // ObjectPoolItem implementation
63 
TopResumedActivityChangeItem()64     private TopResumedActivityChangeItem() {}
65 
66     /** Obtain an instance initialized with provided params. */
obtain(boolean onTop)67     public static TopResumedActivityChangeItem obtain(boolean onTop) {
68         TopResumedActivityChangeItem instance =
69                 ObjectPool.obtain(TopResumedActivityChangeItem.class);
70         if (instance == null) {
71             instance = new TopResumedActivityChangeItem();
72         }
73         instance.mOnTop = onTop;
74 
75         return instance;
76     }
77 
78     @Override
recycle()79     public void recycle() {
80         mOnTop = false;
81         ObjectPool.recycle(this);
82     }
83 
84 
85     // Parcelable implementation
86 
87     /** Write to Parcel. */
88     @Override
writeToParcel(Parcel dest, int flags)89     public void writeToParcel(Parcel dest, int flags) {
90         dest.writeBoolean(mOnTop);
91     }
92 
93     /** Read from Parcel. */
TopResumedActivityChangeItem(Parcel in)94     private TopResumedActivityChangeItem(Parcel in) {
95         mOnTop = in.readBoolean();
96     }
97 
98     public static final @NonNull Creator<TopResumedActivityChangeItem> CREATOR =
99             new Creator<TopResumedActivityChangeItem>() {
100         public TopResumedActivityChangeItem createFromParcel(Parcel in) {
101             return new TopResumedActivityChangeItem(in);
102         }
103 
104         public TopResumedActivityChangeItem[] newArray(int size) {
105             return new TopResumedActivityChangeItem[size];
106         }
107     };
108 
109     @Override
equals(@ullable Object o)110     public boolean equals(@Nullable Object o) {
111         if (this == o) {
112             return true;
113         }
114         if (o == null || getClass() != o.getClass()) {
115             return false;
116         }
117         final TopResumedActivityChangeItem other = (TopResumedActivityChangeItem) o;
118         return mOnTop == other.mOnTop;
119     }
120 
121     @Override
hashCode()122     public int hashCode() {
123         int result = 17;
124         result = 31 * result + (mOnTop ? 1 : 0);
125         return result;
126     }
127 
128     @Override
toString()129     public String toString() {
130         return "TopResumedActivityChangeItem{onTop=" + mOnTop + "}";
131     }
132 }
133