1 /*
2  * Copyright 2017 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.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.app.ActivityClient;
24 import android.app.ActivityManager;
25 import android.app.ActivityThread.ActivityClientRecord;
26 import android.app.ClientTransactionHandler;
27 import android.os.IBinder;
28 import android.os.Parcel;
29 import android.os.Trace;
30 
31 /**
32  * Request to move an activity to resumed state.
33  * @hide
34  */
35 public class ResumeActivityItem extends ActivityLifecycleItem {
36 
37     private static final String TAG = "ResumeActivityItem";
38 
39     private int mProcState;
40     private boolean mUpdateProcState;
41     private boolean mIsForward;
42     // Whether we should send compat fake focus when the activity is resumed. This is needed
43     // because some game engines wait to get focus before drawing the content of the app.
44     private boolean mShouldSendCompatFakeFocus;
45 
46     @Override
preExecute(ClientTransactionHandler client, IBinder token)47     public void preExecute(ClientTransactionHandler client, IBinder token) {
48         if (mUpdateProcState) {
49             client.updateProcessState(mProcState, false);
50         }
51     }
52 
53     @Override
execute(ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions)54     public void execute(ClientTransactionHandler client, ActivityClientRecord r,
55             PendingTransactionActions pendingActions) {
56         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
57         client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
58                 mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
59         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
60     }
61 
62     @Override
postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions)63     public void postExecute(ClientTransactionHandler client, IBinder token,
64             PendingTransactionActions pendingActions) {
65         // TODO(lifecycler): Use interface callback instead of actual implementation.
66         ActivityClient.getInstance().activityResumed(token, client.isHandleSplashScreenExit(token));
67     }
68 
69     @Override
getTargetState()70     public int getTargetState() {
71         return ON_RESUME;
72     }
73 
74 
75     // ObjectPoolItem implementation
76 
ResumeActivityItem()77     private ResumeActivityItem() {}
78 
79     /** Obtain an instance initialized with provided params. */
obtain(int procState, boolean isForward, boolean shouldSendCompatFakeFocus)80     public static ResumeActivityItem obtain(int procState, boolean isForward,
81             boolean shouldSendCompatFakeFocus) {
82         ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
83         if (instance == null) {
84             instance = new ResumeActivityItem();
85         }
86         instance.mProcState = procState;
87         instance.mUpdateProcState = true;
88         instance.mIsForward = isForward;
89         instance.mShouldSendCompatFakeFocus = shouldSendCompatFakeFocus;
90 
91         return instance;
92     }
93 
94     /** Obtain an instance initialized with provided params. */
obtain(boolean isForward, boolean shouldSendCompatFakeFocus)95     public static ResumeActivityItem obtain(boolean isForward, boolean shouldSendCompatFakeFocus) {
96         ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
97         if (instance == null) {
98             instance = new ResumeActivityItem();
99         }
100         instance.mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
101         instance.mUpdateProcState = false;
102         instance.mIsForward = isForward;
103         instance.mShouldSendCompatFakeFocus = shouldSendCompatFakeFocus;
104 
105         return instance;
106     }
107 
108     @Override
recycle()109     public void recycle() {
110         super.recycle();
111         mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
112         mUpdateProcState = false;
113         mIsForward = false;
114         mShouldSendCompatFakeFocus = false;
115         ObjectPool.recycle(this);
116     }
117 
118 
119     // Parcelable implementation
120 
121     /** Write to Parcel. */
122     @Override
writeToParcel(Parcel dest, int flags)123     public void writeToParcel(Parcel dest, int flags) {
124         dest.writeInt(mProcState);
125         dest.writeBoolean(mUpdateProcState);
126         dest.writeBoolean(mIsForward);
127         dest.writeBoolean(mShouldSendCompatFakeFocus);
128     }
129 
130     /** Read from Parcel. */
ResumeActivityItem(Parcel in)131     private ResumeActivityItem(Parcel in) {
132         mProcState = in.readInt();
133         mUpdateProcState = in.readBoolean();
134         mIsForward = in.readBoolean();
135         mShouldSendCompatFakeFocus = in.readBoolean();
136     }
137 
138     public static final @NonNull Creator<ResumeActivityItem> CREATOR =
139             new Creator<ResumeActivityItem>() {
140         public ResumeActivityItem createFromParcel(Parcel in) {
141             return new ResumeActivityItem(in);
142         }
143 
144         public ResumeActivityItem[] newArray(int size) {
145             return new ResumeActivityItem[size];
146         }
147     };
148 
149     @Override
equals(@ullable Object o)150     public boolean equals(@Nullable Object o) {
151         if (this == o) {
152             return true;
153         }
154         if (o == null || getClass() != o.getClass()) {
155             return false;
156         }
157         final ResumeActivityItem other = (ResumeActivityItem) o;
158         return mProcState == other.mProcState && mUpdateProcState == other.mUpdateProcState
159                 && mIsForward == other.mIsForward
160                 && mShouldSendCompatFakeFocus == other.mShouldSendCompatFakeFocus;
161     }
162 
163     @Override
hashCode()164     public int hashCode() {
165         int result = 17;
166         result = 31 * result + mProcState;
167         result = 31 * result + (mUpdateProcState ? 1 : 0);
168         result = 31 * result + (mIsForward ? 1 : 0);
169         result = 31 * result + (mShouldSendCompatFakeFocus ? 1 : 0);
170         return result;
171     }
172 
173     @Override
toString()174     public String toString() {
175         return "ResumeActivityItem{procState=" + mProcState
176                 + ",updateProcState=" + mUpdateProcState + ",isForward=" + mIsForward
177                 + ",shouldSendCompatFakeFocus=" + mShouldSendCompatFakeFocus + "}";
178     }
179 }
180