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.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
20 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
21 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
22 
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.app.ActivityThread.ActivityClientRecord;
26 import android.app.ClientTransactionHandler;
27 import android.app.ResultInfo;
28 import android.app.compat.CompatChanges;
29 import android.compat.annotation.ChangeId;
30 import android.compat.annotation.EnabledAfter;
31 import android.compat.annotation.UnsupportedAppUsage;
32 import android.os.Build;
33 import android.os.Parcel;
34 import android.os.Parcelable;
35 import android.os.Trace;
36 
37 import java.util.List;
38 import java.util.Objects;
39 
40 /**
41  * Activity result delivery callback.
42  * @hide
43  */
44 public class ActivityResultItem extends ActivityTransactionItem {
45 
46     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
47     private List<ResultInfo> mResultInfoList;
48 
49     /**
50      * Correct the lifecycle of activity result after {@link android.os.Build.VERSION_CODES#S} to
51      * guarantee that an activity gets activity result just before resume.
52      */
53     @ChangeId
54     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S)
55     public static final long CALL_ACTIVITY_RESULT_BEFORE_RESUME = 78294732L;
56 
57     @Override
getPostExecutionState()58     public int getPostExecutionState() {
59         return CompatChanges.isChangeEnabled(CALL_ACTIVITY_RESULT_BEFORE_RESUME)
60                 ? ON_RESUME : UNDEFINED;
61     }
62 
63     @Override
execute(ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions)64     public void execute(ClientTransactionHandler client, ActivityClientRecord r,
65             PendingTransactionActions pendingActions) {
66         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
67         client.handleSendResult(r, mResultInfoList, "ACTIVITY_RESULT");
68         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
69     }
70 
71 
72     // ObjectPoolItem implementation
73 
ActivityResultItem()74     private ActivityResultItem() {}
75 
76     /** Obtain an instance initialized with provided params. */
obtain(List<ResultInfo> resultInfoList)77     public static ActivityResultItem obtain(List<ResultInfo> resultInfoList) {
78         ActivityResultItem instance = ObjectPool.obtain(ActivityResultItem.class);
79         if (instance == null) {
80             instance = new ActivityResultItem();
81         }
82         instance.mResultInfoList = resultInfoList;
83 
84         return instance;
85     }
86 
87     @Override
recycle()88     public void recycle() {
89         mResultInfoList = null;
90         ObjectPool.recycle(this);
91     }
92 
93 
94     // Parcelable implementation
95 
96     /** Write to Parcel. */
97     @Override
writeToParcel(Parcel dest, int flags)98     public void writeToParcel(Parcel dest, int flags) {
99         dest.writeTypedList(mResultInfoList, flags);
100     }
101 
102     /** Read from Parcel. */
ActivityResultItem(Parcel in)103     private ActivityResultItem(Parcel in) {
104         mResultInfoList = in.createTypedArrayList(ResultInfo.CREATOR);
105     }
106 
107     public static final @NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
108             new Parcelable.Creator<ActivityResultItem>() {
109         public ActivityResultItem createFromParcel(Parcel in) {
110             return new ActivityResultItem(in);
111         }
112 
113         public ActivityResultItem[] newArray(int size) {
114             return new ActivityResultItem[size];
115         }
116     };
117 
118     @Override
equals(@ullable Object o)119     public boolean equals(@Nullable Object o) {
120         if (this == o) {
121             return true;
122         }
123         if (o == null || getClass() != o.getClass()) {
124             return false;
125         }
126         final ActivityResultItem other = (ActivityResultItem) o;
127         return Objects.equals(mResultInfoList, other.mResultInfoList);
128     }
129 
130     @Override
hashCode()131     public int hashCode() {
132         return mResultInfoList.hashCode();
133     }
134 
135     @Override
toString()136     public String toString() {
137         return "ActivityResultItem{resultInfoList=" + mResultInfoList + "}";
138     }
139 }
140