• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.window;
18 
19 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
20 
21 import android.annotation.CallSuper;
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.UserIdInt;
26 import android.app.ActivityThread;
27 import android.os.Parcel;
28 import android.os.Parcelable;
29 import android.view.IWindowManager;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 import com.android.server.LocalServices;
33 import com.android.window.flags.Flags;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.util.Objects;
38 
39 /**
40  * Represents a setting request that can be applied as part of a batch to avoid multiple
41  * configuration updates.
42  *
43  * @hide
44  */
45 public abstract class ConfigurationChangeSetting implements Parcelable {
46     /* The type of the setting for creating from a parcel. */
47     public static final int SETTING_TYPE_UNKNOWN = -1;
48     public static final int SETTING_TYPE_DISPLAY_DENSITY = 0;
49     public static final int SETTING_TYPE_FONT_SCALE = 1;
50 
51     @IntDef(prefix = {"SETTING_TYPE_"}, value = {
52             SETTING_TYPE_UNKNOWN,
53             SETTING_TYPE_DISPLAY_DENSITY,
54             SETTING_TYPE_FONT_SCALE
55     })
56     @Retention(RetentionPolicy.SOURCE)
57     public @interface SettingType {
58     }
59 
60     @SettingType
61     private final int mSettingType;
62 
ConfigurationChangeSetting(@ettingType int settingType)63     private ConfigurationChangeSetting(@SettingType int settingType) {
64         if (!Flags.condenseConfigurationChangeForSimpleMode()) {
65             throw new IllegalStateException(
66                     "ConfigurationChangeSetting cannot be instantiated because the "
67                             + "condenseConfigurationChangeForSimpleMode flag is not enabled. "
68                             + "Please ensure this flag is enabled.");
69         }
70         mSettingType = settingType;
71     }
72 
73     @CallSuper
74     @Override
writeToParcel(@onNull Parcel dest, int flags)75     public void writeToParcel(@NonNull Parcel dest, int flags) {
76         dest.writeInt(mSettingType);
77     }
78 
79     public static final Creator<ConfigurationChangeSetting> CREATOR = new CreatorImpl();
80 
81     /**
82      * Implementation of the {@link Parcelable.Creator} for {@link ConfigurationChangeSetting}.
83      *
84      * <p>Creates {@link ConfigurationChangeSetting} objects from a {@link Parcel}, handling
85      * system/client processes. System process delegates creation to the server-side implementation.
86      *
87      * @hide
88      */
89     @VisibleForTesting(visibility = PRIVATE)
90     public static class CreatorImpl implements Creator<ConfigurationChangeSetting> {
91         private final boolean mIsSystem;
92 
CreatorImpl()93         private CreatorImpl() {
94             this(ActivityThread.isSystem());
95         }
96 
97         @VisibleForTesting(visibility = PRIVATE)
CreatorImpl(boolean isSystem)98         public CreatorImpl(boolean isSystem) {
99             mIsSystem = isSystem;
100         }
101 
102         @Override
createFromParcel(@onNull Parcel in)103         public ConfigurationChangeSetting createFromParcel(@NonNull Parcel in) {
104             final int settingType = in.readInt();
105             if (mIsSystem) {
106                 return LocalServices.getService(ConfigurationChangeSettingInternal.class)
107                         .createImplFromParcel(settingType, in);
108             }
109             switch (settingType) {
110                 case SETTING_TYPE_DISPLAY_DENSITY:
111                     return DensitySetting.CREATOR.createFromParcel(in);
112                 case SETTING_TYPE_FONT_SCALE:
113                     return FontScaleSetting.CREATOR.createFromParcel(in);
114                 default:
115                     throw new IllegalArgumentException("Unknown setting type " + settingType);
116             }
117         }
118 
119         @Override
newArray(int size)120         public ConfigurationChangeSetting[] newArray(int size) {
121             return new ConfigurationChangeSetting[size];
122         }
123     }
124 
125     @Override
describeContents()126     public int describeContents() {
127         return 0;
128     }
129 
130     /**
131      * Applies the specific setting request to the system.
132      *
133      * <p>This method should handle the logic for modifying system settings or making other
134      * adjustments to achieve the intended configuration change. It is called within the
135      * context of a batch update, where multiple {@link ConfigurationChangeSetting} instances
136      * might be applied sequentially.
137      *
138      * @param userId The user for which to apply the setting
139      * @hide Only for use within the system server.
140      * @see IWindowManager#setConfigurationChangeSettingsForUser(ConfigurationChangeSetting[], int)
141      */
apply(@serIdInt int userId)142     public void apply(@UserIdInt int userId) {
143         // no-op in client process, the apply will be executed in server side.
144     }
145 
146     /**
147      * Interface for server side implementation of {@link ConfigurationChangeSetting}.
148      *
149      * @hide Only for use within the system server.
150      */
151     public interface ConfigurationChangeSettingInternal {
152         /**
153          * Create server side {@link ConfigurationChangeSetting} implementation from parcel.
154          *
155          * @param settingType the type of {@link ConfigurationChangeSetting}.
156          * @param in          the {@link Parcel} to read data from.
157          * @return server side {@link ConfigurationChangeSetting} implementation.
158          */
159         @NonNull
createImplFromParcel(@ettingType int settingType, @NonNull Parcel in)160         ConfigurationChangeSetting createImplFromParcel(@SettingType int settingType,
161                 @NonNull Parcel in);
162     }
163 
164     /**
165      * Represents a request to change the display density.
166      *
167      * @hide
168      */
169     public static class DensitySetting extends ConfigurationChangeSetting {
170         protected final int mDisplayId;
171         protected final int mDensity;
172 
173         /**
174          * Constructs a {@link DensitySetting}.
175          *
176          * @param density The new display density.
177          * @hide
178          */
DensitySetting(int displayId, int density)179         public DensitySetting(int displayId, int density) {
180             super(SETTING_TYPE_DISPLAY_DENSITY);
181             mDisplayId = displayId;
182             mDensity = density;
183         }
184 
DensitySetting(@onNull Parcel in)185         protected DensitySetting(@NonNull Parcel in) {
186             this(in.readInt(), in.readInt());
187         }
188 
189         @Override
writeToParcel(@onNull Parcel dest, int flags)190         public void writeToParcel(@NonNull Parcel dest, int flags) {
191             super.writeToParcel(dest, flags);
192             dest.writeInt(mDisplayId);
193             dest.writeInt(mDensity);
194         }
195 
196         public static final Creator<DensitySetting> CREATOR = new Creator<>() {
197             @Override
198             public DensitySetting createFromParcel(@NonNull Parcel in) {
199                 return new DensitySetting(in);
200             }
201 
202             @Override
203             public DensitySetting[] newArray(int size) {
204                 return new DensitySetting[size];
205             }
206         };
207 
208         @Override
equals(@ullable Object obj)209         public boolean equals(@Nullable Object obj) {
210             if (!(obj instanceof DensitySetting other)) {
211                 return false;
212             }
213             return mDisplayId == other.mDisplayId && mDensity == other.mDensity;
214         }
215 
216         @Override
hashCode()217         public int hashCode() {
218             return Objects.hash(mDisplayId, mDensity);
219         }
220     }
221 
222     /**
223      * Represents a request to change the font scale.
224      *
225      * @hide
226      */
227     public static class FontScaleSetting extends ConfigurationChangeSetting {
228         protected final float mFontScaleFactor;
229 
230         /**
231          * Constructs a {@code FontScaleSetting}.
232          *
233          * @param fontScaleFactor The new font scale factor.
234          * @hide
235          */
FontScaleSetting(float fontScaleFactor)236         public FontScaleSetting(float fontScaleFactor) {
237             super(SETTING_TYPE_FONT_SCALE);
238             mFontScaleFactor = fontScaleFactor;
239         }
240 
FontScaleSetting(@onNull Parcel in)241         protected FontScaleSetting(@NonNull Parcel in) {
242             this(in.readFloat());
243         }
244 
245         @Override
writeToParcel(@onNull Parcel dest, int flags)246         public void writeToParcel(@NonNull Parcel dest, int flags) {
247             super.writeToParcel(dest, flags);
248             dest.writeFloat(mFontScaleFactor);
249         }
250 
251         public static final Creator<FontScaleSetting> CREATOR = new Creator<>() {
252             @Override
253             public FontScaleSetting createFromParcel(@NonNull Parcel in) {
254                 return new FontScaleSetting(in);
255             }
256 
257             @Override
258             public FontScaleSetting[] newArray(int size) {
259                 return new FontScaleSetting[size];
260             }
261         };
262 
263         @Override
equals(@ullable Object obj)264         public boolean equals(@Nullable Object obj) {
265             if (!(obj instanceof FontScaleSetting other)) {
266                 return false;
267             }
268             return Float.compare(mFontScaleFactor, other.mFontScaleFactor) == 0;
269         }
270 
271         @Override
hashCode()272         public int hashCode() {
273             return Objects.hash(mFontScaleFactor);
274         }
275     }
276 }
277