1 /* 2 * Copyright (C) 2020 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 com.android.tools.idea.validator; 18 19 import com.android.tools.idea.validator.ValidatorData.Level; 20 import com.android.tools.idea.validator.ValidatorData.Policy; 21 import com.android.tools.idea.validator.ValidatorData.Type; 22 import com.android.tools.layoutlib.annotations.NotNull; 23 import com.android.tools.layoutlib.annotations.Nullable; 24 import com.android.tools.layoutlib.annotations.VisibleForTesting; 25 26 import android.view.View; 27 28 import java.awt.image.BufferedImage; 29 import java.util.EnumSet; 30 31 /** 32 * Main class for validating layout. 33 */ 34 public class LayoutValidator { 35 36 public static final ValidatorData.Policy DEFAULT_POLICY = new Policy( 37 EnumSet.of(Type.ACCESSIBILITY, Type.RENDER), 38 EnumSet.of(Level.ERROR, Level.WARNING, Level.INFO, Level.VERBOSE)); 39 40 private static ValidatorData.Policy sPolicy = DEFAULT_POLICY; 41 42 private static boolean sPaused = false; 43 44 private static boolean sSaveCroppedImages = false; 45 46 private static boolean sObtainCharacterLocations = true; 47 48 /** 49 * @return true if validator is paused. False otherwise. 50 */ isPaused()51 public static boolean isPaused() { 52 return sPaused; 53 } 54 55 /** 56 * Pause or resume validator. {@link RenderParamsFlags#FLAG_ENABLE_LAYOUT_VALIDATOR} must be 57 * enabled. 58 * @param paused true if validator should be paused. False to resume. 59 */ setPaused(boolean paused)60 public static void setPaused(boolean paused) { 61 sPaused = paused; 62 } 63 shouldSaveCroppedImages()64 public static boolean shouldSaveCroppedImages() { 65 return sSaveCroppedImages; 66 } 67 68 /** 69 * For Debugging purpose. Save all cropped images used by atf if enabled. 70 * @param save 71 */ setSaveCroppedImages(boolean save)72 public static void setSaveCroppedImages(boolean save) { 73 sSaveCroppedImages = save; 74 } 75 76 /** 77 * Indicates whether text character locations should be requested. 78 * 79 * @param obtainCharacterLocations true if text character locations should be requested. 80 */ setObtainCharacterLocations(boolean obtainCharacterLocations)81 public static void setObtainCharacterLocations(boolean obtainCharacterLocations) { 82 sObtainCharacterLocations = obtainCharacterLocations; 83 } 84 85 /** 86 * @return true if text character locations should be requested. 87 */ obtainCharacterLocations()88 public static boolean obtainCharacterLocations() { 89 return sObtainCharacterLocations; 90 } 91 92 /** 93 * Validate the layout using the default policy. 94 * Precondition: View must be attached to the window. 95 * 96 * Used for testing. 97 * 98 * @return The validation results. If no issue is found it'll return empty result. 99 */ 100 @NotNull 101 @VisibleForTesting validate( @otNull View view, @Nullable BufferedImage image, float scaleX, float scaleY)102 public static ValidatorResult validate( 103 @NotNull View view, 104 @Nullable BufferedImage image, 105 float scaleX, 106 float scaleY) { 107 if (!sPaused && view.isAttachedToWindow()) { 108 ValidatorHierarchy hierarchy = ValidatorUtil.buildHierarchy( 109 sPolicy, 110 view, 111 image, 112 scaleX, 113 scaleY); 114 return ValidatorUtil.generateResults(sPolicy, hierarchy); 115 } 116 // TODO: Add non-a11y layout validation later. 117 return new ValidatorResult.Builder().build(); 118 } 119 120 /** 121 * Build the hierarchy necessary for validating the layout. 122 * The operation is quick thus can be used frequently. 123 * 124 * @return The hierarchy to be used for validation. 125 */ 126 @NotNull buildHierarchy( @otNull View view, @Nullable BufferedImage image, float scaleX, float scaleY)127 public static ValidatorHierarchy buildHierarchy( 128 @NotNull View view, 129 @Nullable BufferedImage image, 130 float scaleX, 131 float scaleY) { 132 if (!sPaused && view.isAttachedToWindow()) { 133 return ValidatorUtil.buildHierarchy( 134 sPolicy, 135 view, 136 image, 137 scaleX, 138 scaleY); 139 } 140 return new ValidatorHierarchy(); 141 } 142 143 /** 144 * @return The validator result that matches the hierarchy 145 */ 146 @NotNull validate(@otNull ValidatorHierarchy hierarchy)147 public static ValidatorResult validate(@NotNull ValidatorHierarchy hierarchy) { 148 return ValidatorUtil.generateResults(sPolicy, hierarchy); 149 } 150 151 /** 152 * Update the policy with which to run the validation call. 153 * @param policy new policy. 154 */ updatePolicy(@otNull ValidatorData.Policy policy)155 public static void updatePolicy(@NotNull ValidatorData.Policy policy) { 156 sPolicy = policy; 157 } 158 } 159