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