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 android.telephony; 18 19 import android.annotation.NonNull; 20 import android.app.SystemServiceRegistry; 21 import android.compat.Compatibility; 22 import android.compat.annotation.ChangeId; 23 import android.compat.annotation.EnabledSince; 24 import android.content.Context; 25 import android.content.pm.PackageManager; 26 import android.os.Build; 27 import android.os.SystemProperties; 28 import android.os.TelephonyServiceManager; 29 import android.telephony.euicc.EuiccCardManager; 30 import android.telephony.euicc.EuiccManager; 31 import android.telephony.ims.ImsManager; 32 import android.telephony.satellite.SatelliteManager; 33 34 import com.android.internal.util.Preconditions; 35 36 37 /** 38 * Class for performing registration for all telephony services. 39 * 40 * @hide 41 */ 42 public class TelephonyFrameworkInitializer { 43 TelephonyFrameworkInitializer()44 private TelephonyFrameworkInitializer() { 45 } 46 47 /** 48 * Starting with {@link VANILLA_ICE_CREAM}, Telephony feature flags 49 * (e.g. {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}) are being checked before 50 * returning managers that depend on them. If the feature is missing, 51 * {@link Context#getSystemService} will return null. 52 */ 53 @ChangeId 54 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) 55 static final long ENABLE_CHECKING_TELEPHONY_FEATURES = 330583731; 56 57 private static volatile TelephonyServiceManager sTelephonyServiceManager; 58 59 /** 60 * Sets an instance of {@link TelephonyServiceManager} that allows 61 * the telephony mainline module to register/obtain telephony binder services. This is called 62 * by the platform during the system initialization. 63 * 64 * @param telephonyServiceManager instance of {@link TelephonyServiceManager} that allows 65 * the telephony mainline module to register/obtain telephony binder services. 66 */ setTelephonyServiceManager( @onNull TelephonyServiceManager telephonyServiceManager)67 public static void setTelephonyServiceManager( 68 @NonNull TelephonyServiceManager telephonyServiceManager) { 69 Preconditions.checkState(sTelephonyServiceManager == null, 70 "setTelephonyServiceManager called twice!"); 71 sTelephonyServiceManager = Preconditions.checkNotNull(telephonyServiceManager); 72 } 73 74 // Suppressing AndroidFrameworkCompatChange because we're querying vendor 75 // partition SDK level, not application's target SDK version (which BTW we 76 // also check through Compatibility framework a few lines below). 77 @SuppressWarnings("AndroidFrameworkCompatChange") hasSystemFeature(Context context, String feature)78 private static boolean hasSystemFeature(Context context, String feature) { 79 // Check SDK version of the vendor partition. 80 final int vendorApiLevel = SystemProperties.getInt( 81 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT); 82 if (vendorApiLevel < Build.VENDOR_API_2024_Q2) return true; 83 84 // Check SDK version of the client app. 85 if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES)) return true; 86 87 // Finally, check if the system feature is actually present. 88 return context.getPackageManager().hasSystemFeature(feature); 89 } 90 91 /** 92 * Called by {@link SystemServiceRegistry}'s static initializer and registers all telephony 93 * services to {@link Context}, so that {@link Context#getSystemService} can return them. 94 * 95 * @throws IllegalStateException if this is called from anywhere besides 96 * {@link SystemServiceRegistry} 97 */ registerServiceWrappers()98 public static void registerServiceWrappers() { 99 SystemServiceRegistry.registerContextAwareService( 100 Context.TELEPHONY_SERVICE, 101 TelephonyManager.class, 102 context -> new TelephonyManager(context) 103 ); 104 SystemServiceRegistry.registerContextAwareService( 105 Context.TELEPHONY_SUBSCRIPTION_SERVICE, 106 SubscriptionManager.class, 107 context -> new SubscriptionManager(context) 108 ); 109 SystemServiceRegistry.registerContextAwareService( 110 Context.CARRIER_CONFIG_SERVICE, 111 CarrierConfigManager.class, 112 context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION) 113 ? new CarrierConfigManager(context) : null 114 ); 115 SystemServiceRegistry.registerContextAwareService( 116 Context.EUICC_SERVICE, 117 EuiccManager.class, 118 context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_EUICC) 119 ? new EuiccManager(context) : null 120 ); 121 SystemServiceRegistry.registerContextAwareService( 122 Context.EUICC_CARD_SERVICE, 123 EuiccCardManager.class, 124 context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_EUICC) 125 ? new EuiccCardManager(context) : null 126 ); 127 SystemServiceRegistry.registerContextAwareService( 128 Context.TELEPHONY_IMS_SERVICE, 129 ImsManager.class, 130 context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_IMS) 131 ? new ImsManager(context) : null 132 ); 133 SystemServiceRegistry.registerContextAwareService( 134 Context.SMS_SERVICE, 135 SmsManager.class, 136 context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_MESSAGING) 137 ? SmsManager.getSmsManagerForContextAndSubscriptionId(context, 138 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) : null 139 ); 140 SystemServiceRegistry.registerContextAwareService( 141 Context.SATELLITE_SERVICE, 142 SatelliteManager.class, 143 context -> hasSystemFeature(context, PackageManager.FEATURE_TELEPHONY_SATELLITE) 144 ? new SatelliteManager(context) : null 145 ); 146 } 147 148 /** @hide */ getTelephonyServiceManager()149 public static TelephonyServiceManager getTelephonyServiceManager() { 150 return sTelephonyServiceManager; 151 } 152 } 153