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