1 /* 2 * Copyright (C) 2019 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.server.wm; 18 19 import static android.hardware.display.DisplayManager.DeviceConfig.KEY_HIGH_REFRESH_RATE_BLACKLIST; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.content.res.Resources; 24 import android.provider.DeviceConfig; 25 import android.util.ArraySet; 26 27 import com.android.internal.R; 28 import com.android.internal.annotations.VisibleForTesting; 29 import com.android.internal.os.BackgroundThread; 30 import com.android.server.wm.utils.DeviceConfigInterface; 31 32 import java.io.PrintWriter; 33 34 /** 35 * A Blacklist for packages that should force the display out of high refresh rate. 36 */ 37 class HighRefreshRateBlacklist { 38 39 private final ArraySet<String> mBlacklistedPackages = new ArraySet<>(); 40 @NonNull 41 private final String[] mDefaultBlacklist; 42 private final Object mLock = new Object(); 43 44 private DeviceConfigInterface mDeviceConfig; 45 private OnPropertiesChangedListener mListener = new OnPropertiesChangedListener(); 46 create(@onNull Resources r)47 static HighRefreshRateBlacklist create(@NonNull Resources r) { 48 return new HighRefreshRateBlacklist(r, DeviceConfigInterface.REAL); 49 } 50 51 @VisibleForTesting HighRefreshRateBlacklist(Resources r, DeviceConfigInterface deviceConfig)52 HighRefreshRateBlacklist(Resources r, DeviceConfigInterface deviceConfig) { 53 mDefaultBlacklist = r.getStringArray(R.array.config_highRefreshRateBlacklist); 54 mDeviceConfig = deviceConfig; 55 mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, 56 BackgroundThread.getExecutor(), mListener); 57 final String property = mDeviceConfig.getProperty(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, 58 KEY_HIGH_REFRESH_RATE_BLACKLIST); 59 updateBlacklist(property); 60 } 61 updateBlacklist(@ullable String property)62 private void updateBlacklist(@Nullable String property) { 63 synchronized (mLock) { 64 mBlacklistedPackages.clear(); 65 if (property != null) { 66 String[] packages = property.split(","); 67 for (String pkg : packages) { 68 String pkgName = pkg.trim(); 69 if (!pkgName.isEmpty()) { 70 mBlacklistedPackages.add(pkgName); 71 } 72 } 73 } else { 74 // If there's no config, or the config has been deleted, fallback to the device's 75 // default blacklist 76 for (String pkg : mDefaultBlacklist) { 77 mBlacklistedPackages.add(pkg); 78 } 79 } 80 } 81 } 82 isBlacklisted(String packageName)83 boolean isBlacklisted(String packageName) { 84 synchronized (mLock) { 85 return mBlacklistedPackages.contains(packageName); 86 } 87 } dump(PrintWriter pw)88 void dump(PrintWriter pw) { 89 pw.println("High Refresh Rate Blacklist"); 90 pw.println(" Packages:"); 91 synchronized (mLock) { 92 for (String pkg : mBlacklistedPackages) { 93 pw.println(" " + pkg); 94 } 95 } 96 } 97 98 /** Used to prevent WmTests leaking issues. */ 99 @VisibleForTesting dispose()100 void dispose() { 101 mDeviceConfig.removeOnPropertiesChangedListener(mListener); 102 mDeviceConfig = null; 103 mBlacklistedPackages.clear(); 104 } 105 106 private class OnPropertiesChangedListener implements DeviceConfig.OnPropertiesChangedListener { onPropertiesChanged(@onNull DeviceConfig.Properties properties)107 public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { 108 if (properties.getKeyset().contains(KEY_HIGH_REFRESH_RATE_BLACKLIST)) { 109 updateBlacklist( 110 properties.getString(KEY_HIGH_REFRESH_RATE_BLACKLIST, null /*default*/)); 111 } 112 } 113 } 114 } 115 116