Loading api/current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -2992,9 +2992,7 @@ package android.accessibilityservice { method public int getNonInteractiveUiTimeoutMillis(); method public android.content.pm.ResolveInfo getResolveInfo(); method public String getSettingsActivityName(); method @Nullable public android.graphics.drawable.Drawable loadAnimatedImage(@NonNull android.content.Context); method public String loadDescription(android.content.pm.PackageManager); method @Nullable public String loadHtmlDescription(@NonNull android.content.pm.PackageManager); method public CharSequence loadSummary(android.content.pm.PackageManager); method public void setInteractiveUiTimeoutMillis(@IntRange(from=0) int); method public void setNonInteractiveUiTimeoutMillis(@IntRange(from=0) int); core/java/android/accessibilityservice/AccessibilityServiceInfo.java +6 −109 Original line number Diff line number Diff line Loading @@ -16,19 +16,19 @@ package android.accessibilityservice; import static android.accessibilityservice.util.AccessibilityUtils.getFilteredHtmlText; import static android.accessibilityservice.util.AccessibilityUtils.loadSafeAnimatedImage; import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; Loading Loading @@ -62,7 +62,6 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * This class describes an {@link AccessibilityService}. The system notifies an Loading Loading @@ -554,13 +553,6 @@ public class AccessibilityServiceInfo implements Parcelable { */ private int mHtmlDescriptionRes; // Used for html description of accessibility service. The <img> src tag must follow the // prefix rule. e.g. <img src="R.drawable.fileName"/> private static final String IMG_PREFIX = "R.drawable."; private static final String ANCHOR_TAG = "a"; private static final List<String> UNSUPPORTED_TAG_LIST = new ArrayList<>( Collections.singletonList(ANCHOR_TAG)); /** * Creates a new instance. */ Loading Loading @@ -810,6 +802,8 @@ public class AccessibilityServiceInfo implements Parcelable { * </p> * @return The animated image drawable, or null if the resource is invalid or the image * exceed the screen size. * * @hide */ @Nullable public Drawable loadAnimatedImage(@NonNull Context context) { Loading Loading @@ -937,6 +931,8 @@ public class AccessibilityServiceInfo implements Parcelable { * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> * </p> * @return The localized and restricted html description. * * @hide */ @Nullable public String loadHtmlDescription(@NonNull PackageManager packageManager) { Loading Loading @@ -1421,103 +1417,4 @@ public class AccessibilityServiceInfo implements Parcelable { return new AccessibilityServiceInfo[size]; } }; /** * Gets the filtered html string for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It filters * the <img> tag which do not meet the custom specification and the <a> tag. * * @param text the target text is html format. * @return the filtered html string. * * @hide */ public static @NonNull String getFilteredHtmlText(@NonNull String text) { final String replacementStart = "<invalidtag "; final String replacementEnd = "</invalidtag>"; for (String tag : UNSUPPORTED_TAG_LIST) { final String regexStart = "(?i)<" + tag + "(\\s+|>)"; final String regexEnd = "(?i)</" + tag + "\\s*>"; text = Pattern.compile(regexStart).matcher(text).replaceAll(replacementStart); text = Pattern.compile(regexEnd).matcher(text).replaceAll(replacementEnd); } final String regexInvalidImgTag = "(?i)<img\\s+(?!src\\s*=\\s*\"(?-i)" + IMG_PREFIX + ")"; text = Pattern.compile(regexInvalidImgTag).matcher(text).replaceAll( replacementStart); return text; } /** * Loads the animated image for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It checks the resource * whether to exceed the screen size. * * @param context the current context. * @param applicationInfo the current application. * @param resId the animated image resource id. * @return the animated image which is safe. * * @hide */ @Nullable public static Drawable loadSafeAnimatedImage(@NonNull Context context, @NonNull ApplicationInfo applicationInfo, @StringRes int resId) { if (resId == /* invalid */ 0) { return null; } final PackageManager packageManager = context.getPackageManager(); final String packageName = applicationInfo.packageName; final Drawable bannerDrawable = packageManager.getDrawable(packageName, resId, applicationInfo); if (bannerDrawable == null) { return null; } final boolean isImageWidthOverScreenLength = bannerDrawable.getIntrinsicWidth() > getScreenWidthPixels(context); final boolean isImageHeightOverScreenLength = bannerDrawable.getIntrinsicHeight() > getScreenHeightPixels(context); return (isImageWidthOverScreenLength || isImageHeightOverScreenLength) ? null : bannerDrawable; } /** * Gets the width of the screen. * * @param context the current context. * @return the width of the screen in term of pixels. * * @hide */ private static int getScreenWidthPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenWidthDp = resources.getConfiguration().screenWidthDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenWidthDp, resources.getDisplayMetrics())); } /** * Gets the height of the screen. * * @param context the current context. * @return the height of the screen in term of pixels. * * @hide */ private static int getScreenHeightPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenHeightDp = resources.getConfiguration().screenHeightDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp, resources.getDisplayMetrics())); } } core/java/android/accessibilityservice/AccessibilityShortcutInfo.java +7 −113 Original line number Diff line number Diff line Loading @@ -16,14 +16,15 @@ package android.accessibilityservice; import static android.accessibilityservice.util.AccessibilityUtils.getFilteredHtmlText; import static android.accessibilityservice.util.AccessibilityUtils.loadSafeAnimatedImage; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; Loading @@ -31,17 +32,12 @@ import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * Activities of interest to users with accessibility needs may request to be targets of the Loading Loading @@ -94,13 +90,6 @@ public final class AccessibilityShortcutInfo { */ private final int mHtmlDescriptionRes; // Used for html description of accessibility service. The <img> src tag must follow the // prefix rule. e.g. <img src="R.drawable.fileName"/> private static final String IMG_PREFIX = "R.drawable."; private static final String ANCHOR_TAG = "a"; private static final List<String> UNSUPPORTED_TAG_LIST = new ArrayList<>( Collections.singletonList(ANCHOR_TAG)); /** * Creates a new instance. * Loading Loading @@ -221,6 +210,8 @@ public final class AccessibilityShortcutInfo { * * @return The animated image drawable, or null if the resource is invalid or the image * exceed the screen size. * * @hide */ @Nullable public Drawable loadAnimatedImage(@NonNull Context context) { Loading @@ -236,6 +227,8 @@ public final class AccessibilityShortcutInfo { * It filters the <img> tag which do not meet the custom specification and the <a> tag. * * @return The localized and restricted html description. * * @hide */ @Nullable public String loadHtmlDescription(@NonNull PackageManager packageManager) { Loading Loading @@ -305,103 +298,4 @@ public final class AccessibilityShortcutInfo { stringBuilder.append("]"); return stringBuilder.toString(); } /** * Gets the filtered html string for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It filters * the <img> tag which do not meet the custom specification and the <a> tag. * * @param text the target text is html format. * @return the filtered html string. * * @hide */ public static @NonNull String getFilteredHtmlText(@NonNull String text) { final String replacementStart = "<invalidtag "; final String replacementEnd = "</invalidtag>"; for (String tag : UNSUPPORTED_TAG_LIST) { final String regexStart = "(?i)<" + tag + "(\\s+|>)"; final String regexEnd = "(?i)</" + tag + "\\s*>"; text = Pattern.compile(regexStart).matcher(text).replaceAll(replacementStart); text = Pattern.compile(regexEnd).matcher(text).replaceAll(replacementEnd); } final String regexInvalidImgTag = "(?i)<img\\s+(?!src\\s*=\\s*\"(?-i)" + IMG_PREFIX + ")"; text = Pattern.compile(regexInvalidImgTag).matcher(text).replaceAll( replacementStart); return text; } /** * Loads the animated image for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It checks the resource * whether to exceed the screen size. * * @param context the current context. * @param applicationInfo the current application. * @param resId the animated image resource id. * @return the animated image which is safe. * * @hide */ @Nullable public static Drawable loadSafeAnimatedImage(@NonNull Context context, @NonNull ApplicationInfo applicationInfo, @StringRes int resId) { if (resId == /* invalid */ 0) { return null; } final PackageManager packageManager = context.getPackageManager(); final String packageName = applicationInfo.packageName; final Drawable bannerDrawable = packageManager.getDrawable(packageName, resId, applicationInfo); if (bannerDrawable == null) { return null; } final boolean isImageWidthOverScreenLength = bannerDrawable.getIntrinsicWidth() > getScreenWidthPixels(context); final boolean isImageHeightOverScreenLength = bannerDrawable.getIntrinsicHeight() > getScreenHeightPixels(context); return (isImageWidthOverScreenLength || isImageHeightOverScreenLength) ? null : bannerDrawable; } /** * Gets the width of the screen. * * @param context the current context. * @return the width of the screen in term of pixels. * * @hide */ private static int getScreenWidthPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenWidthDp = resources.getConfiguration().screenWidthDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenWidthDp, resources.getDisplayMetrics())); } /** * Gets the height of the screen. * * @param context the current context. * @return the height of the screen in term of pixels. * * @hide */ private static int getScreenHeightPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenHeightDp = resources.getConfiguration().screenHeightDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp, resources.getDisplayMetrics())); } } core/java/android/accessibilityservice/util/AccessibilityUtils.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.accessibilityservice.util; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.util.TypedValue; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * Collection of utilities for accessibility service. * * @hide */ public final class AccessibilityUtils { private AccessibilityUtils() {} // Used for html description of accessibility service. The <img> src tag must follow the // prefix rule. e.g. <img src="R.drawable.fileName"/> private static final String IMG_PREFIX = "R.drawable."; private static final String ANCHOR_TAG = "a"; private static final List<String> UNSUPPORTED_TAG_LIST = new ArrayList<>( Collections.singletonList(ANCHOR_TAG)); /** * Gets the filtered html string for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It filters * the <img> tag which do not meet the custom specification and the <a> tag. * * @param text the target text is html format. * @return the filtered html string. */ public static @NonNull String getFilteredHtmlText(@NonNull String text) { final String replacementStart = "<invalidtag "; final String replacementEnd = "</invalidtag>"; for (String tag : UNSUPPORTED_TAG_LIST) { final String regexStart = "(?i)<" + tag + "(\\s+|>)"; final String regexEnd = "(?i)</" + tag + "\\s*>"; text = Pattern.compile(regexStart).matcher(text).replaceAll(replacementStart); text = Pattern.compile(regexEnd).matcher(text).replaceAll(replacementEnd); } final String regexInvalidImgTag = "(?i)<img\\s+(?!src\\s*=\\s*\"(?-i)" + IMG_PREFIX + ")"; text = Pattern.compile(regexInvalidImgTag).matcher(text).replaceAll( replacementStart); return text; } /** * Loads the animated image for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It checks the resource * whether to exceed the screen size. * * @param context the current context. * @param applicationInfo the current application. * @param resId the animated image resource id. * @return the animated image which is safe. */ @Nullable public static Drawable loadSafeAnimatedImage(@NonNull Context context, @NonNull ApplicationInfo applicationInfo, @StringRes int resId) { if (resId == /* invalid */ 0) { return null; } final PackageManager packageManager = context.getPackageManager(); final String packageName = applicationInfo.packageName; final Drawable bannerDrawable = packageManager.getDrawable(packageName, resId, applicationInfo); if (bannerDrawable == null) { return null; } final boolean isImageWidthOverScreenLength = bannerDrawable.getIntrinsicWidth() > getScreenWidthPixels(context); final boolean isImageHeightOverScreenLength = bannerDrawable.getIntrinsicHeight() > getScreenHeightPixels(context); return (isImageWidthOverScreenLength || isImageHeightOverScreenLength) ? null : bannerDrawable; } /** * Gets the width of the screen. * * @param context the current context. * @return the width of the screen in term of pixels. */ private static int getScreenWidthPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenWidthDp = resources.getConfiguration().screenWidthDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenWidthDp, resources.getDisplayMetrics())); } /** * Gets the height of the screen. * * @param context the current context. * @return the height of the screen in term of pixels. */ private static int getScreenHeightPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenHeightDp = resources.getConfiguration().screenHeightDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp, resources.getDisplayMetrics())); } } Loading
api/current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -2992,9 +2992,7 @@ package android.accessibilityservice { method public int getNonInteractiveUiTimeoutMillis(); method public android.content.pm.ResolveInfo getResolveInfo(); method public String getSettingsActivityName(); method @Nullable public android.graphics.drawable.Drawable loadAnimatedImage(@NonNull android.content.Context); method public String loadDescription(android.content.pm.PackageManager); method @Nullable public String loadHtmlDescription(@NonNull android.content.pm.PackageManager); method public CharSequence loadSummary(android.content.pm.PackageManager); method public void setInteractiveUiTimeoutMillis(@IntRange(from=0) int); method public void setNonInteractiveUiTimeoutMillis(@IntRange(from=0) int);
core/java/android/accessibilityservice/AccessibilityServiceInfo.java +6 −109 Original line number Diff line number Diff line Loading @@ -16,19 +16,19 @@ package android.accessibilityservice; import static android.accessibilityservice.util.AccessibilityUtils.getFilteredHtmlText; import static android.accessibilityservice.util.AccessibilityUtils.loadSafeAnimatedImage; import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; Loading Loading @@ -62,7 +62,6 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * This class describes an {@link AccessibilityService}. The system notifies an Loading Loading @@ -554,13 +553,6 @@ public class AccessibilityServiceInfo implements Parcelable { */ private int mHtmlDescriptionRes; // Used for html description of accessibility service. The <img> src tag must follow the // prefix rule. e.g. <img src="R.drawable.fileName"/> private static final String IMG_PREFIX = "R.drawable."; private static final String ANCHOR_TAG = "a"; private static final List<String> UNSUPPORTED_TAG_LIST = new ArrayList<>( Collections.singletonList(ANCHOR_TAG)); /** * Creates a new instance. */ Loading Loading @@ -810,6 +802,8 @@ public class AccessibilityServiceInfo implements Parcelable { * </p> * @return The animated image drawable, or null if the resource is invalid or the image * exceed the screen size. * * @hide */ @Nullable public Drawable loadAnimatedImage(@NonNull Context context) { Loading Loading @@ -937,6 +931,8 @@ public class AccessibilityServiceInfo implements Parcelable { * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> * </p> * @return The localized and restricted html description. * * @hide */ @Nullable public String loadHtmlDescription(@NonNull PackageManager packageManager) { Loading Loading @@ -1421,103 +1417,4 @@ public class AccessibilityServiceInfo implements Parcelable { return new AccessibilityServiceInfo[size]; } }; /** * Gets the filtered html string for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It filters * the <img> tag which do not meet the custom specification and the <a> tag. * * @param text the target text is html format. * @return the filtered html string. * * @hide */ public static @NonNull String getFilteredHtmlText(@NonNull String text) { final String replacementStart = "<invalidtag "; final String replacementEnd = "</invalidtag>"; for (String tag : UNSUPPORTED_TAG_LIST) { final String regexStart = "(?i)<" + tag + "(\\s+|>)"; final String regexEnd = "(?i)</" + tag + "\\s*>"; text = Pattern.compile(regexStart).matcher(text).replaceAll(replacementStart); text = Pattern.compile(regexEnd).matcher(text).replaceAll(replacementEnd); } final String regexInvalidImgTag = "(?i)<img\\s+(?!src\\s*=\\s*\"(?-i)" + IMG_PREFIX + ")"; text = Pattern.compile(regexInvalidImgTag).matcher(text).replaceAll( replacementStart); return text; } /** * Loads the animated image for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It checks the resource * whether to exceed the screen size. * * @param context the current context. * @param applicationInfo the current application. * @param resId the animated image resource id. * @return the animated image which is safe. * * @hide */ @Nullable public static Drawable loadSafeAnimatedImage(@NonNull Context context, @NonNull ApplicationInfo applicationInfo, @StringRes int resId) { if (resId == /* invalid */ 0) { return null; } final PackageManager packageManager = context.getPackageManager(); final String packageName = applicationInfo.packageName; final Drawable bannerDrawable = packageManager.getDrawable(packageName, resId, applicationInfo); if (bannerDrawable == null) { return null; } final boolean isImageWidthOverScreenLength = bannerDrawable.getIntrinsicWidth() > getScreenWidthPixels(context); final boolean isImageHeightOverScreenLength = bannerDrawable.getIntrinsicHeight() > getScreenHeightPixels(context); return (isImageWidthOverScreenLength || isImageHeightOverScreenLength) ? null : bannerDrawable; } /** * Gets the width of the screen. * * @param context the current context. * @return the width of the screen in term of pixels. * * @hide */ private static int getScreenWidthPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenWidthDp = resources.getConfiguration().screenWidthDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenWidthDp, resources.getDisplayMetrics())); } /** * Gets the height of the screen. * * @param context the current context. * @return the height of the screen in term of pixels. * * @hide */ private static int getScreenHeightPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenHeightDp = resources.getConfiguration().screenHeightDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp, resources.getDisplayMetrics())); } }
core/java/android/accessibilityservice/AccessibilityShortcutInfo.java +7 −113 Original line number Diff line number Diff line Loading @@ -16,14 +16,15 @@ package android.accessibilityservice; import static android.accessibilityservice.util.AccessibilityUtils.getFilteredHtmlText; import static android.accessibilityservice.util.AccessibilityUtils.loadSafeAnimatedImage; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; Loading @@ -31,17 +32,12 @@ import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * Activities of interest to users with accessibility needs may request to be targets of the Loading Loading @@ -94,13 +90,6 @@ public final class AccessibilityShortcutInfo { */ private final int mHtmlDescriptionRes; // Used for html description of accessibility service. The <img> src tag must follow the // prefix rule. e.g. <img src="R.drawable.fileName"/> private static final String IMG_PREFIX = "R.drawable."; private static final String ANCHOR_TAG = "a"; private static final List<String> UNSUPPORTED_TAG_LIST = new ArrayList<>( Collections.singletonList(ANCHOR_TAG)); /** * Creates a new instance. * Loading Loading @@ -221,6 +210,8 @@ public final class AccessibilityShortcutInfo { * * @return The animated image drawable, or null if the resource is invalid or the image * exceed the screen size. * * @hide */ @Nullable public Drawable loadAnimatedImage(@NonNull Context context) { Loading @@ -236,6 +227,8 @@ public final class AccessibilityShortcutInfo { * It filters the <img> tag which do not meet the custom specification and the <a> tag. * * @return The localized and restricted html description. * * @hide */ @Nullable public String loadHtmlDescription(@NonNull PackageManager packageManager) { Loading Loading @@ -305,103 +298,4 @@ public final class AccessibilityShortcutInfo { stringBuilder.append("]"); return stringBuilder.toString(); } /** * Gets the filtered html string for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It filters * the <img> tag which do not meet the custom specification and the <a> tag. * * @param text the target text is html format. * @return the filtered html string. * * @hide */ public static @NonNull String getFilteredHtmlText(@NonNull String text) { final String replacementStart = "<invalidtag "; final String replacementEnd = "</invalidtag>"; for (String tag : UNSUPPORTED_TAG_LIST) { final String regexStart = "(?i)<" + tag + "(\\s+|>)"; final String regexEnd = "(?i)</" + tag + "\\s*>"; text = Pattern.compile(regexStart).matcher(text).replaceAll(replacementStart); text = Pattern.compile(regexEnd).matcher(text).replaceAll(replacementEnd); } final String regexInvalidImgTag = "(?i)<img\\s+(?!src\\s*=\\s*\"(?-i)" + IMG_PREFIX + ")"; text = Pattern.compile(regexInvalidImgTag).matcher(text).replaceAll( replacementStart); return text; } /** * Loads the animated image for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It checks the resource * whether to exceed the screen size. * * @param context the current context. * @param applicationInfo the current application. * @param resId the animated image resource id. * @return the animated image which is safe. * * @hide */ @Nullable public static Drawable loadSafeAnimatedImage(@NonNull Context context, @NonNull ApplicationInfo applicationInfo, @StringRes int resId) { if (resId == /* invalid */ 0) { return null; } final PackageManager packageManager = context.getPackageManager(); final String packageName = applicationInfo.packageName; final Drawable bannerDrawable = packageManager.getDrawable(packageName, resId, applicationInfo); if (bannerDrawable == null) { return null; } final boolean isImageWidthOverScreenLength = bannerDrawable.getIntrinsicWidth() > getScreenWidthPixels(context); final boolean isImageHeightOverScreenLength = bannerDrawable.getIntrinsicHeight() > getScreenHeightPixels(context); return (isImageWidthOverScreenLength || isImageHeightOverScreenLength) ? null : bannerDrawable; } /** * Gets the width of the screen. * * @param context the current context. * @return the width of the screen in term of pixels. * * @hide */ private static int getScreenWidthPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenWidthDp = resources.getConfiguration().screenWidthDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenWidthDp, resources.getDisplayMetrics())); } /** * Gets the height of the screen. * * @param context the current context. * @return the height of the screen in term of pixels. * * @hide */ private static int getScreenHeightPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenHeightDp = resources.getConfiguration().screenHeightDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp, resources.getDisplayMetrics())); } }
core/java/android/accessibilityservice/util/AccessibilityUtils.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.accessibilityservice.util; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.util.TypedValue; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; /** * Collection of utilities for accessibility service. * * @hide */ public final class AccessibilityUtils { private AccessibilityUtils() {} // Used for html description of accessibility service. The <img> src tag must follow the // prefix rule. e.g. <img src="R.drawable.fileName"/> private static final String IMG_PREFIX = "R.drawable."; private static final String ANCHOR_TAG = "a"; private static final List<String> UNSUPPORTED_TAG_LIST = new ArrayList<>( Collections.singletonList(ANCHOR_TAG)); /** * Gets the filtered html string for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It filters * the <img> tag which do not meet the custom specification and the <a> tag. * * @param text the target text is html format. * @return the filtered html string. */ public static @NonNull String getFilteredHtmlText(@NonNull String text) { final String replacementStart = "<invalidtag "; final String replacementEnd = "</invalidtag>"; for (String tag : UNSUPPORTED_TAG_LIST) { final String regexStart = "(?i)<" + tag + "(\\s+|>)"; final String regexEnd = "(?i)</" + tag + "\\s*>"; text = Pattern.compile(regexStart).matcher(text).replaceAll(replacementStart); text = Pattern.compile(regexEnd).matcher(text).replaceAll(replacementEnd); } final String regexInvalidImgTag = "(?i)<img\\s+(?!src\\s*=\\s*\"(?-i)" + IMG_PREFIX + ")"; text = Pattern.compile(regexInvalidImgTag).matcher(text).replaceAll( replacementStart); return text; } /** * Loads the animated image for * {@link android.accessibilityservice.AccessibilityServiceInfo} and * {@link android.accessibilityservice.AccessibilityShortcutInfo}. It checks the resource * whether to exceed the screen size. * * @param context the current context. * @param applicationInfo the current application. * @param resId the animated image resource id. * @return the animated image which is safe. */ @Nullable public static Drawable loadSafeAnimatedImage(@NonNull Context context, @NonNull ApplicationInfo applicationInfo, @StringRes int resId) { if (resId == /* invalid */ 0) { return null; } final PackageManager packageManager = context.getPackageManager(); final String packageName = applicationInfo.packageName; final Drawable bannerDrawable = packageManager.getDrawable(packageName, resId, applicationInfo); if (bannerDrawable == null) { return null; } final boolean isImageWidthOverScreenLength = bannerDrawable.getIntrinsicWidth() > getScreenWidthPixels(context); final boolean isImageHeightOverScreenLength = bannerDrawable.getIntrinsicHeight() > getScreenHeightPixels(context); return (isImageWidthOverScreenLength || isImageHeightOverScreenLength) ? null : bannerDrawable; } /** * Gets the width of the screen. * * @param context the current context. * @return the width of the screen in term of pixels. */ private static int getScreenWidthPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenWidthDp = resources.getConfiguration().screenWidthDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenWidthDp, resources.getDisplayMetrics())); } /** * Gets the height of the screen. * * @param context the current context. * @return the height of the screen in term of pixels. */ private static int getScreenHeightPixels(@NonNull Context context) { final Resources resources = context.getResources(); final int screenHeightDp = resources.getConfiguration().screenHeightDp; return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp, resources.getDisplayMetrics())); } }