1 /* 2 * Copyright (C) 2023 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.settingslib.fuelgauge; 18 19 import android.accessibilityservice.AccessibilityServiceInfo; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.os.SystemProperties; 25 import android.os.UserManager; 26 import android.provider.Settings; 27 import android.util.ArraySet; 28 import android.util.Log; 29 import android.view.accessibility.AccessibilityManager; 30 31 import androidx.annotation.Nullable; 32 import androidx.annotation.VisibleForTesting; 33 34 import java.util.List; 35 36 public final class BatteryUtils { 37 private static final String TAG = "BatteryUtils"; 38 39 /** The key to get the time to full from Settings.Global */ 40 public static final String GLOBAL_TIME_TO_FULL_MILLIS = "time_to_full_millis"; 41 42 /** The system property key to check whether the charging string v2 is enabled or not. */ 43 public static final String PROPERTY_CHARGING_STRING_V2_KEY = "charging_string.apply_v2"; 44 45 /** Gets the latest sticky battery intent from the Android system. */ getBatteryIntent(Context context)46 public static Intent getBatteryIntent(Context context) { 47 return context.registerReceiver( 48 /*receiver=*/ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 49 } 50 51 /** Gets the current active accessibility related packages. */ getA11yPackageNames(Context context)52 public static ArraySet<String> getA11yPackageNames(Context context) { 53 context = context.getApplicationContext(); 54 final ArraySet<String> packageNames = new ArraySet<>(); 55 final String defaultTtsPackageName = Settings.Secure.getString( 56 context.getContentResolver(), Settings.Secure.TTS_DEFAULT_SYNTH); 57 if (defaultTtsPackageName != null) { 58 packageNames.add(defaultTtsPackageName); 59 } 60 // Checks the current active packages. 61 final AccessibilityManager accessibilityManager = 62 context.getSystemService(AccessibilityManager.class); 63 if (!accessibilityManager.isEnabled()) { 64 return packageNames; 65 } 66 final List<AccessibilityServiceInfo> serviceInfoList = 67 accessibilityManager.getEnabledAccessibilityServiceList( 68 AccessibilityServiceInfo.FEEDBACK_ALL_MASK); 69 if (serviceInfoList == null || serviceInfoList.isEmpty()) { 70 return packageNames; 71 } 72 for (AccessibilityServiceInfo serviceInfo : serviceInfoList) { 73 final ComponentName serviceComponent = ComponentName.unflattenFromString( 74 serviceInfo.getId()); 75 if (serviceComponent != null) { 76 packageNames.add(serviceComponent.getPackageName()); 77 } 78 } 79 return packageNames; 80 } 81 82 /** Returns true if current user is a work profile user. */ isWorkProfile(Context context)83 public static boolean isWorkProfile(Context context) { 84 final UserManager userManager = context.getSystemService(UserManager.class); 85 return userManager.isManagedProfile() && !userManager.isSystemUser(); 86 } 87 88 /** Returns true if current user is a private profile user. */ isPrivateProfile(Context context)89 public static boolean isPrivateProfile(Context context) { 90 final UserManager userManager = context.getSystemService(UserManager.class); 91 return userManager.isPrivateProfile(); 92 } 93 94 /** Returns true if current user is an additional profile user. */ isAdditionalProfile(Context context)95 public static boolean isAdditionalProfile(Context context) { 96 if (isWorkProfile(context)) { 97 Log.d(TAG, "Current user is a work profile user."); 98 return true; 99 } else if (isPrivateProfile(context)) { 100 Log.d(TAG, "Current user is a private profile user."); 101 return true; 102 } 103 return false; 104 } 105 106 private static Boolean sChargingStringV2Enabled = null; 107 108 /** Returns {@code true} if the charging string v2 is enabled. */ isChargingStringV2Enabled()109 public static boolean isChargingStringV2Enabled() { 110 if (sChargingStringV2Enabled == null) { 111 sChargingStringV2Enabled = 112 SystemProperties.getBoolean(PROPERTY_CHARGING_STRING_V2_KEY, false); 113 } 114 return sChargingStringV2Enabled; 115 } 116 117 118 /** Used to override the system property to enable or reset for charging string V2. */ 119 @VisibleForTesting setChargingStringV2Enabled(Boolean enabled)120 public static void setChargingStringV2Enabled(Boolean enabled) { 121 setChargingStringV2Enabled(enabled, true /* updateProperty */); 122 } 123 124 /** Used to override the system property to enable or reset for charging string V2. */ 125 @VisibleForTesting setChargingStringV2Enabled( @ullable Boolean enabled, boolean updateProperty)126 public static void setChargingStringV2Enabled( 127 @Nullable Boolean enabled, boolean updateProperty) { 128 if (updateProperty) { 129 SystemProperties.set( 130 BatteryUtils.PROPERTY_CHARGING_STRING_V2_KEY, 131 enabled == null ? "" : String.valueOf(enabled)); 132 } 133 BatteryUtils.sChargingStringV2Enabled = enabled; 134 } 135 } 136