1 /*
2  * Copyright (C) 2021 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.accessibilityservice;
18 
19 import android.annotation.FloatRange;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 
28 /**
29  * This class describes the magnification config for {@link AccessibilityService} to control the
30  * magnification.
31  *
32  * <p>
33  * When the magnification config uses {@link #MAGNIFICATION_MODE_DEFAULT},
34  * {@link AccessibilityService} will be able to control the activated magnifier on the display.
35  * If there is no magnifier activated, it controls the last-activated magnification mode.
36  * If there is no magnifier activated before, it controls full-screen magnifier by default.
37  * </p>
38  *
39  * <p>
40  * When the magnification config uses {@link #MAGNIFICATION_MODE_FULLSCREEN}.
41  * {@link AccessibilityService} will be able to control full-screen magnifier on the display.
42  * </p>
43  *
44  * <p>
45  * When the magnification config uses {@link #MAGNIFICATION_MODE_WINDOW} and the platform
46  * supports {@link android.content.pm.PackageManager#FEATURE_WINDOW_MAGNIFICATION} feature.
47  * {@link AccessibilityService} will be able to control window magnifier on the display.
48  * </p>
49  *
50  * <p>
51  * If the other magnification configs, scale centerX and centerY, are not set by the
52  * {@link Builder}, the configs should be current values or default values. And the center
53  * position ordinarily is the center of the screen.
54  * </p>
55  */
56 public final class MagnificationConfig implements Parcelable {
57 
58     /** The controlling magnification mode. It controls the activated magnifier. */
59     public static final int MAGNIFICATION_MODE_DEFAULT = 0;
60     /** The controlling magnification mode. It controls full-screen magnifier. */
61     public static final int MAGNIFICATION_MODE_FULLSCREEN = 1;
62     /**
63      * The controlling magnification mode. It is valid if the platform supports
64      * {@link android.content.pm.PackageManager#FEATURE_WINDOW_MAGNIFICATION} feature.
65      */
66     public static final int MAGNIFICATION_MODE_WINDOW = 2;
67 
68     /** @hide */
69     @IntDef(prefix = {"MAGNIFICATION_MODE"}, value = {
70             MAGNIFICATION_MODE_DEFAULT,
71             MAGNIFICATION_MODE_FULLSCREEN,
72             MAGNIFICATION_MODE_WINDOW,
73     })
74     @Retention(RetentionPolicy.SOURCE)
75     @interface MagnificationMode {
76     }
77 
78     private int mMode = MAGNIFICATION_MODE_DEFAULT;
79     private boolean mActivated = false;
80     private float mScale = Float.NaN;
81     private float mCenterX = Float.NaN;
82     private float mCenterY = Float.NaN;
83 
MagnificationConfig()84     private MagnificationConfig() {
85         /* do nothing */
86     }
87 
MagnificationConfig(@onNull Parcel parcel)88     private MagnificationConfig(@NonNull Parcel parcel) {
89         mMode = parcel.readInt();
90         mActivated = parcel.readBoolean();
91         mScale = parcel.readFloat();
92         mCenterX = parcel.readFloat();
93         mCenterY = parcel.readFloat();
94     }
95 
96     /**
97      * Returns the magnification mode that is the current activated mode or the controlling mode of
98      * the config.
99      *
100      * @return The magnification mode
101      */
getMode()102     public int getMode() {
103         return mMode;
104     }
105 
106     /**
107      * Returns the activated state of the controlling magnifier. The controlling magnifier can be
108      * activated even if the scale returned by {@link MagnificationConfig#getScale()} equals to 1.0.
109      *
110      * @return {@code true} if the magnifier is activated and showing on screen,
111      *         {@code false} otherwise.
112      */
isActivated()113     public boolean isActivated() {
114         return mActivated;
115     }
116 
117     /**
118      * Returns the magnification scale of the controlling magnifier
119      *
120      * @return The magnification scale
121      */
getScale()122     public float getScale() {
123         return mScale;
124     }
125 
126     /**
127      * Returns the screen-relative X coordinate of the center of the magnification viewport.
128      *
129      * @return The X coordinate
130      */
getCenterX()131     public float getCenterX() {
132         return mCenterX;
133     }
134 
135     /**
136      * Returns the screen-relative Y coordinate of the center of the magnification viewport.
137      *
138      * @return The Y coordinate
139      */
getCenterY()140     public float getCenterY() {
141         return mCenterY;
142     }
143 
144     @NonNull
145     @Override
toString()146     public String toString() {
147         StringBuilder stringBuilder = new StringBuilder("MagnificationConfig[");
148         stringBuilder.append("mode: ").append(getMode());
149         stringBuilder.append(", ");
150         stringBuilder.append("activated: ").append(isActivated());
151         stringBuilder.append(", ");
152         stringBuilder.append("scale: ").append(getScale());
153         stringBuilder.append(", ");
154         stringBuilder.append("centerX: ").append(getCenterX());
155         stringBuilder.append(", ");
156         stringBuilder.append("centerY: ").append(getCenterY());
157         stringBuilder.append("] ");
158         return stringBuilder.toString();
159     }
160 
161     @Override
describeContents()162     public int describeContents() {
163         return 0;
164     }
165 
166     @Override
writeToParcel(@onNull Parcel parcel, int flags)167     public void writeToParcel(@NonNull Parcel parcel, int flags) {
168         parcel.writeInt(mMode);
169         parcel.writeBoolean(mActivated);
170         parcel.writeFloat(mScale);
171         parcel.writeFloat(mCenterX);
172         parcel.writeFloat(mCenterY);
173     }
174 
175     /**
176      * Builder for creating {@link MagnificationConfig} objects.
177      */
178     public static final class Builder {
179 
180         private int mMode = MAGNIFICATION_MODE_DEFAULT;
181         private boolean mActivated = true;
182         private float mScale = Float.NaN;
183         private float mCenterX = Float.NaN;
184         private float mCenterY = Float.NaN;
185 
186         /**
187          * Creates a new Builder.
188          */
Builder()189         public Builder() {
190         }
191 
192         /**
193          * Sets the magnification mode.
194          *
195          * @param mode The magnification mode
196          * @return This builder
197          */
198         @NonNull
setMode(@agnificationMode int mode)199         public MagnificationConfig.Builder setMode(@MagnificationMode int mode) {
200             mMode = mode;
201             return this;
202         }
203 
204         /**
205          * Sets magnification activated state.
206          *
207          * @param activated The magnification activated state
208          * @return This builder
209          */
210         @NonNull
setActivated(boolean activated)211         public MagnificationConfig.Builder setActivated(boolean activated) {
212             mActivated = activated;
213             return this;
214         }
215 
216         /**
217          * Sets the magnification scale.
218          *
219          * @param scale The magnification scale, in the range [1, 8]
220          * @return This builder
221          */
222         @NonNull
setScale(@loatRangefrom = 1f, to = 8f) float scale)223         public MagnificationConfig.Builder setScale(@FloatRange(from = 1f, to = 8f) float scale) {
224             mScale = scale;
225             return this;
226         }
227 
228         /**
229          * Sets the X coordinate of the center of the magnification viewport.
230          * The controlling magnifier will apply the given position.
231          *
232          * @param centerX the screen-relative X coordinate around which to
233          *                center and scale that is in the range [0, screenWidth],
234          *                or {@link Float#NaN} to leave unchanged
235          * @return This builder
236          */
237         @NonNull
setCenterX(float centerX)238         public MagnificationConfig.Builder setCenterX(float centerX) {
239             mCenterX = centerX;
240             return this;
241         }
242 
243         /**
244          * Sets the Y coordinate of the center of the magnification viewport.
245          * The controlling magnifier will apply the given position.
246          *
247          * @param centerY the screen-relative Y coordinate around which to
248          *                center and scale that is in the range [0, screenHeight],
249          *                or {@link Float#NaN} to leave unchanged
250          * @return This builder
251          */
252         @NonNull
setCenterY(float centerY)253         public MagnificationConfig.Builder setCenterY(float centerY) {
254             mCenterY = centerY;
255             return this;
256         }
257 
258         /**
259          * Builds and returns a {@link MagnificationConfig}
260          */
261         @NonNull
build()262         public MagnificationConfig build() {
263             MagnificationConfig magnificationConfig = new MagnificationConfig();
264             magnificationConfig.mMode = mMode;
265             magnificationConfig.mActivated = mActivated;
266             magnificationConfig.mScale = mScale;
267             magnificationConfig.mCenterX = mCenterX;
268             magnificationConfig.mCenterY = mCenterY;
269             return magnificationConfig;
270         }
271     }
272 
273     /**
274      * @see Parcelable.Creator
275      */
276     public static final @NonNull Parcelable.Creator<MagnificationConfig> CREATOR =
277             new Parcelable.Creator<MagnificationConfig>() {
278                 public MagnificationConfig createFromParcel(Parcel parcel) {
279                     return new MagnificationConfig(parcel);
280                 }
281 
282                 public MagnificationConfig[] newArray(int size) {
283                     return new MagnificationConfig[size];
284                 }
285             };
286 }
287