1 /* 2 * Copyright (C) 2017 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.compatibility.common.util; 18 19 import android.content.Context; 20 import android.content.pm.FeatureInfo; 21 import android.content.pm.PackageManager; 22 import android.content.res.Configuration; 23 import android.os.Build; 24 25 import androidx.test.InstrumentationRegistry; 26 27 import java.util.HashSet; 28 import java.util.Set; 29 30 /** 31 * Device-side utility class for detecting system features 32 */ 33 public class FeatureUtil { 34 35 public static final String ARC_FEATURE = "org.chromium.arc"; 36 public static final String ARC_DEVICE_MANAGEMENT_FEATURE = "org.chromium.arc.device_management"; 37 public static final String AUTOMOTIVE_FEATURE = "android.hardware.type.automotive"; 38 public static final String LEANBACK_FEATURE = "android.software.leanback"; 39 public static final String LOW_RAM_FEATURE = "android.hardware.ram.low"; 40 public static final String TELEPHONY_FEATURE = "android.hardware.telephony"; 41 public static final String TV_FEATURE = "android.hardware.type.television"; 42 public static final String WATCH_FEATURE = "android.hardware.type.watch"; 43 public static final String XR_FEATURE = "android.software.xr.immersive"; 44 45 46 /** Returns true if the device has a given system feature */ hasSystemFeature(String feature)47 public static boolean hasSystemFeature(String feature) { 48 return getPackageManager().hasSystemFeature(feature); 49 } 50 51 /** Returns true if the device has any feature in a given collection of system features */ hasAnySystemFeature(String... features)52 public static boolean hasAnySystemFeature(String... features) { 53 PackageManager pm = getPackageManager(); 54 for (String feature : features) { 55 if (pm.hasSystemFeature(feature)) { 56 return true; 57 } 58 } 59 return false; 60 } 61 62 /** Returns true if the device has all features in a given collection of system features */ hasAllSystemFeatures(String... features)63 public static boolean hasAllSystemFeatures(String... features) { 64 PackageManager pm = getPackageManager(); 65 for (String feature : features) { 66 if (!pm.hasSystemFeature(feature)) { 67 return false; 68 } 69 } 70 return true; 71 } 72 73 /** Returns all system features of the device */ getAllFeatures()74 public static Set<String> getAllFeatures() { 75 Set<String> allFeatures = new HashSet<String>(); 76 for (FeatureInfo fi : getPackageManager().getSystemAvailableFeatures()) { 77 allFeatures.add(fi.name); 78 } 79 return allFeatures; 80 } 81 82 /** Returns {@code true} if device is an ARC++ device. */ isArc()83 public static boolean isArc() { 84 return hasAnySystemFeature(ARC_FEATURE, ARC_DEVICE_MANAGEMENT_FEATURE); 85 } 86 87 /** Returns true if the device has feature TV_FEATURE or feature LEANBACK_FEATURE */ isTV()88 public static boolean isTV() { 89 return hasAnySystemFeature(TV_FEATURE, LEANBACK_FEATURE); 90 } 91 92 /** Returns true if the device has feature WATCH_FEATURE */ isWatch()93 public static boolean isWatch() { 94 return hasSystemFeature(WATCH_FEATURE); 95 } 96 97 /** Returns true if the device has feature AUTOMOTIVE_FEATURE */ isAutomotive()98 public static boolean isAutomotive() { 99 return hasSystemFeature(AUTOMOTIVE_FEATURE); 100 } 101 isVrHeadset()102 public static boolean isVrHeadset() { 103 int maskedUiMode = (getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK); 104 return (maskedUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET); 105 } 106 107 /** Returns true if the device has feature XR_FEATURE */ isXrHeadset()108 public static boolean isXrHeadset() { 109 return hasSystemFeature(XR_FEATURE); 110 } 111 112 /** Returns true if the device is a low ram device: 113 * 1. API level >= O_MR1 114 * 2. device has feature LOW_RAM_FEATURE 115 */ isLowRam()116 public static boolean isLowRam() { 117 return ApiLevelUtil.isAtLeast(Build.VERSION_CODES.O_MR1) && 118 hasSystemFeature(LOW_RAM_FEATURE); 119 } 120 getContext()121 private static Context getContext() { 122 return InstrumentationRegistry.getInstrumentation().getTargetContext(); 123 } 124 getPackageManager()125 private static PackageManager getPackageManager() { 126 return getContext().getPackageManager(); 127 } 128 getConfiguration()129 private static Configuration getConfiguration() { 130 return getContext().getResources().getConfiguration(); 131 } 132 133 /** Returns true if the device has feature TELEPHONY_FEATURE */ hasTelephony()134 public static boolean hasTelephony() { 135 return hasSystemFeature(TELEPHONY_FEATURE); 136 } 137 138 /** Returns true if the device has feature FEATURE_MICROPHONE */ hasMicrophone()139 public static boolean hasMicrophone() { 140 return hasSystemFeature(getPackageManager().FEATURE_MICROPHONE); 141 } 142 } 143