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 import static android.view.Display.INVALID_DISPLAY;
21 
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.app.ActivityThread.ActivityClientRecord;
25 import android.app.ClientTransactionHandler;
26 import android.content.res.CompatibilityInfo;
27 import android.content.res.Configuration;
28 import android.os.IBinder;
29 import android.os.Parcel;
30 import android.os.Trace;
31 
32 import java.util.Objects;
33 
34 /**
35  * Activity configuration changed callback.
36  * @hide
37  */
38 public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
39 
40     private Configuration mConfiguration;
41 
42     @Override
preExecute(android.app.ClientTransactionHandler client, IBinder token)43     public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
44         CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
45         // Notify the client of an upcoming change in the token configuration. This ensures that
46         // batches of config change items only process the newest configuration.
47         client.updatePendingActivityConfiguration(token, mConfiguration);
48     }
49 
50     @Override
execute(ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions)51     public void execute(ClientTransactionHandler client, ActivityClientRecord r,
52             PendingTransactionActions pendingActions) {
53         // TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
54         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
55         client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
56         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
57     }
58 
59 
60     // ObjectPoolItem implementation
61 
ActivityConfigurationChangeItem()62     private ActivityConfigurationChangeItem() {}
63 
64     /** Obtain an instance initialized with provided params. */
obtain(@onNull Configuration config)65     public static ActivityConfigurationChangeItem obtain(@NonNull Configuration config) {
66         if (config == null) {
67             throw new IllegalArgumentException("Config must not be null.");
68         }
69 
70         ActivityConfigurationChangeItem instance =
71                 ObjectPool.obtain(ActivityConfigurationChangeItem.class);
72         if (instance == null) {
73             instance = new ActivityConfigurationChangeItem();
74         }
75         instance.mConfiguration = config;
76 
77         return instance;
78     }
79 
80     @Override
recycle()81     public void recycle() {
82         mConfiguration = Configuration.EMPTY;
83         ObjectPool.recycle(this);
84     }
85 
86 
87     // Parcelable implementation
88 
89     /** Write to Parcel. */
90     @Override
writeToParcel(Parcel dest, int flags)91     public void writeToParcel(Parcel dest, int flags) {
92         dest.writeTypedObject(mConfiguration, flags);
93     }
94 
95     /** Read from Parcel. */
ActivityConfigurationChangeItem(Parcel in)96     private ActivityConfigurationChangeItem(Parcel in) {
97         mConfiguration = in.readTypedObject(Configuration.CREATOR);
98     }
99 
100     public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
101             new Creator<ActivityConfigurationChangeItem>() {
102         public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
103             return new ActivityConfigurationChangeItem(in);
104         }
105 
106         public ActivityConfigurationChangeItem[] newArray(int size) {
107             return new ActivityConfigurationChangeItem[size];
108         }
109     };
110 
111     @Override
equals(@ullable Object o)112     public boolean equals(@Nullable Object o) {
113         if (this == o) {
114             return true;
115         }
116         if (o == null || getClass() != o.getClass()) {
117             return false;
118         }
119         final ActivityConfigurationChangeItem other = (ActivityConfigurationChangeItem) o;
120         return Objects.equals(mConfiguration, other.mConfiguration);
121     }
122 
123     @Override
hashCode()124     public int hashCode() {
125         return mConfiguration.hashCode();
126     }
127 
128     @Override
toString()129     public String toString() {
130         return "ActivityConfigurationChange{config=" + mConfiguration + "}";
131     }
132 }
133