Loading src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +4 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.settings.deviceinfo.simstatus.EidStatus; import com.android.settings.deviceinfo.simstatus.SimEidPreferenceController; import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceController; import com.android.settings.deviceinfo.simstatus.SlotSimStatus; import com.android.settings.flags.Flags; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.core.AbstractPreferenceController; Loading Loading @@ -130,6 +131,9 @@ public class MyDeviceInfoFragment extends DashboardFragment controllers.add(new UptimePreferenceController(context, lifecycle)); Consumer<String> imeiInfoList = imeiKey -> { if (Flags.catalystMyDeviceInfoPrefScreen()) { return; } ImeiInfoPreferenceController imeiRecord = new ImeiInfoPreferenceController(context, imeiKey); imeiRecord.init(fragment, slotSimStatus); Loading src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoScreen.kt +14 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,10 @@ import android.content.Context import android.os.Build import android.provider.Settings import com.android.settings.R import com.android.settings.deviceinfo.imei.ImeiPreference import com.android.settings.flags.Flags import com.android.settings.wifi.utils.activeModemCount import com.android.settingslib.metadata.PreferenceCategory import com.android.settingslib.metadata.PreferenceIconProvider import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.ProvidePreferenceScreen Loading Loading @@ -53,7 +56,17 @@ class MyDeviceInfoScreen : override fun fragmentClass() = MyDeviceInfoFragment::class.java override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) {} override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) { +PreferenceCategory( "device_detail_category", R.string.my_device_info_device_details_category_title, ) += { val activeModemCount = context.activeModemCount for (i in 0 until activeModemCount) { +ImeiPreference(context, i, activeModemCount) order (i + 33) } } } override fun hasCompleteHierarchy() = false Loading src/com/android/settings/deviceinfo/imei/ImeiInfoDialogFragment.java +10 −4 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.deviceinfo.PhoneNumberUtil; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.deviceinfo.PhoneNumberUtil; import java.util.Arrays; import java.util.stream.IntStream; Loading @@ -47,15 +47,21 @@ public class ImeiInfoDialogFragment extends InstrumentedDialogFragment { private View mRootView; /** Start the dialog and display it on screen. */ public static void show(@NonNull Fragment host, int slotId, String dialogTitle) { final FragmentManager manager = host.getChildFragmentManager(); if (manager.findFragmentByTag(TAG) == null) { show(host.getChildFragmentManager(), slotId, dialogTitle); } /** Start the dialog and display it on screen. */ public static void show(@NonNull FragmentManager childFragmentManager, int slotId, @NonNull String dialogTitle) { if (childFragmentManager.findFragmentByTag(TAG) == null) { final Bundle bundle = new Bundle(); bundle.putInt(SLOT_ID_BUNDLE_KEY, slotId); bundle.putString(DIALOG_TITLE_BUNDLE_KEY, dialogTitle); final ImeiInfoDialogFragment dialog = new ImeiInfoDialogFragment(); dialog.setArguments(bundle); dialog.show(manager, TAG); dialog.show(childFragmentManager, TAG); } } Loading src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java +8 −0 Original line number Diff line number Diff line Loading @@ -35,10 +35,15 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.deviceinfo.simstatus.SlotSimStatus; import com.android.settings.flags.Flags; /** * Controller that manages preference for single and multi sim devices. * * @deprecated Since PHONE_TYPE_CDMA has been deprecated in TelephonyManager, this controller * will be deprecated and removed after V. */ @Deprecated(forRemoval = true) public class ImeiInfoPreferenceController extends BasePreferenceController { private static final String TAG = "ImeiInfoPreferenceController"; Loading Loading @@ -131,6 +136,9 @@ public class ImeiInfoPreferenceController extends BasePreferenceController { @Override public int getAvailabilityStatus() { if (Flags.catalystMyDeviceInfoPrefScreen()) { return UNSUPPORTED_ON_DEVICE; } if (!Utils.isMobileDataCapable(mContext) && !Utils.isVoiceCapable(mContext)) { return UNSUPPORTED_ON_DEVICE; } Loading src/com/android/settings/deviceinfo/imei/ImeiPreference.kt 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.deviceinfo.imei import android.content.Context import android.util.Log import androidx.preference.Preference import com.android.settings.R import com.android.settings.Utils import com.android.settings.wifi.utils.isAdminUser import com.android.settings.wifi.utils.telephonyManager import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.PreferenceTitleProvider import com.android.settingslib.preference.PreferenceBinding import com.android.settingslib.preference.PreferenceBindingPlaceholder /** * Preference to show IMEI information for single and multi modem devices. */ class ImeiPreference( context: Context, private val slotIndex: Int, private val activeModemCount: Int, ) : PreferenceMetadata, PreferenceBinding, PreferenceBindingPlaceholder, PreferenceLifecycleProvider, PreferenceTitleProvider, PreferenceSummaryProvider, PreferenceAvailabilityProvider { private val imei: String = context.getImei() private val formattedTitle: String = context.getFormattedTitle() override val key: String get() = KEY_PREFIX + "${slotIndex + 1}" override fun isAvailable(context: Context): Boolean = context.isAdminUser == true && (Utils.isMobileDataCapable(context) || Utils.isVoiceCapable(context)) override fun getTitle(context: Context): CharSequence? = formattedTitle override fun getSummary(context: Context): CharSequence? = imei override fun bind(preference: Preference, metadata: PreferenceMetadata) { super.bind(preference, metadata) preference.isCopyingEnabled = true } override fun onCreate(context: PreferenceLifecycleContext) { context.requirePreference<Preference>(key).onPreferenceClickListener = Preference.OnPreferenceClickListener { ImeiInfoDialogFragment.show(context.childFragmentManager, slotIndex, formattedTitle) return@OnPreferenceClickListener true } } private fun Context.getImei(): String = telephonyManager?.getImei(slotIndex) ?: run { Log.e(TAG, "Failed to get IMEI for slot $slotIndex") "" } private fun Context.getFormattedTitle(): String = if (activeModemCount <= 1) { getString(R.string.status_imei) } else { val isPrimary = imei == telephonyManager?.primaryImei val titleId = if (isPrimary) R.string.imei_multi_sim_primary else R.string.imei_multi_sim getString(titleId, slotIndex + 1) } companion object { private const val TAG = "ImeiPreference" const val KEY_PREFIX = "imei_info" } } Loading
src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +4 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.settings.deviceinfo.simstatus.EidStatus; import com.android.settings.deviceinfo.simstatus.SimEidPreferenceController; import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceController; import com.android.settings.deviceinfo.simstatus.SlotSimStatus; import com.android.settings.flags.Flags; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.core.AbstractPreferenceController; Loading Loading @@ -130,6 +131,9 @@ public class MyDeviceInfoFragment extends DashboardFragment controllers.add(new UptimePreferenceController(context, lifecycle)); Consumer<String> imeiInfoList = imeiKey -> { if (Flags.catalystMyDeviceInfoPrefScreen()) { return; } ImeiInfoPreferenceController imeiRecord = new ImeiInfoPreferenceController(context, imeiKey); imeiRecord.init(fragment, slotSimStatus); Loading
src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoScreen.kt +14 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,10 @@ import android.content.Context import android.os.Build import android.provider.Settings import com.android.settings.R import com.android.settings.deviceinfo.imei.ImeiPreference import com.android.settings.flags.Flags import com.android.settings.wifi.utils.activeModemCount import com.android.settingslib.metadata.PreferenceCategory import com.android.settingslib.metadata.PreferenceIconProvider import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.ProvidePreferenceScreen Loading Loading @@ -53,7 +56,17 @@ class MyDeviceInfoScreen : override fun fragmentClass() = MyDeviceInfoFragment::class.java override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) {} override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) { +PreferenceCategory( "device_detail_category", R.string.my_device_info_device_details_category_title, ) += { val activeModemCount = context.activeModemCount for (i in 0 until activeModemCount) { +ImeiPreference(context, i, activeModemCount) order (i + 33) } } } override fun hasCompleteHierarchy() = false Loading
src/com/android/settings/deviceinfo/imei/ImeiInfoDialogFragment.java +10 −4 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.deviceinfo.PhoneNumberUtil; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.deviceinfo.PhoneNumberUtil; import java.util.Arrays; import java.util.stream.IntStream; Loading @@ -47,15 +47,21 @@ public class ImeiInfoDialogFragment extends InstrumentedDialogFragment { private View mRootView; /** Start the dialog and display it on screen. */ public static void show(@NonNull Fragment host, int slotId, String dialogTitle) { final FragmentManager manager = host.getChildFragmentManager(); if (manager.findFragmentByTag(TAG) == null) { show(host.getChildFragmentManager(), slotId, dialogTitle); } /** Start the dialog and display it on screen. */ public static void show(@NonNull FragmentManager childFragmentManager, int slotId, @NonNull String dialogTitle) { if (childFragmentManager.findFragmentByTag(TAG) == null) { final Bundle bundle = new Bundle(); bundle.putInt(SLOT_ID_BUNDLE_KEY, slotId); bundle.putString(DIALOG_TITLE_BUNDLE_KEY, dialogTitle); final ImeiInfoDialogFragment dialog = new ImeiInfoDialogFragment(); dialog.setArguments(bundle); dialog.show(manager, TAG); dialog.show(childFragmentManager, TAG); } } Loading
src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java +8 −0 Original line number Diff line number Diff line Loading @@ -35,10 +35,15 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.deviceinfo.simstatus.SlotSimStatus; import com.android.settings.flags.Flags; /** * Controller that manages preference for single and multi sim devices. * * @deprecated Since PHONE_TYPE_CDMA has been deprecated in TelephonyManager, this controller * will be deprecated and removed after V. */ @Deprecated(forRemoval = true) public class ImeiInfoPreferenceController extends BasePreferenceController { private static final String TAG = "ImeiInfoPreferenceController"; Loading Loading @@ -131,6 +136,9 @@ public class ImeiInfoPreferenceController extends BasePreferenceController { @Override public int getAvailabilityStatus() { if (Flags.catalystMyDeviceInfoPrefScreen()) { return UNSUPPORTED_ON_DEVICE; } if (!Utils.isMobileDataCapable(mContext) && !Utils.isVoiceCapable(mContext)) { return UNSUPPORTED_ON_DEVICE; } Loading
src/com/android/settings/deviceinfo/imei/ImeiPreference.kt 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.deviceinfo.imei import android.content.Context import android.util.Log import androidx.preference.Preference import com.android.settings.R import com.android.settings.Utils import com.android.settings.wifi.utils.isAdminUser import com.android.settings.wifi.utils.telephonyManager import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.PreferenceTitleProvider import com.android.settingslib.preference.PreferenceBinding import com.android.settingslib.preference.PreferenceBindingPlaceholder /** * Preference to show IMEI information for single and multi modem devices. */ class ImeiPreference( context: Context, private val slotIndex: Int, private val activeModemCount: Int, ) : PreferenceMetadata, PreferenceBinding, PreferenceBindingPlaceholder, PreferenceLifecycleProvider, PreferenceTitleProvider, PreferenceSummaryProvider, PreferenceAvailabilityProvider { private val imei: String = context.getImei() private val formattedTitle: String = context.getFormattedTitle() override val key: String get() = KEY_PREFIX + "${slotIndex + 1}" override fun isAvailable(context: Context): Boolean = context.isAdminUser == true && (Utils.isMobileDataCapable(context) || Utils.isVoiceCapable(context)) override fun getTitle(context: Context): CharSequence? = formattedTitle override fun getSummary(context: Context): CharSequence? = imei override fun bind(preference: Preference, metadata: PreferenceMetadata) { super.bind(preference, metadata) preference.isCopyingEnabled = true } override fun onCreate(context: PreferenceLifecycleContext) { context.requirePreference<Preference>(key).onPreferenceClickListener = Preference.OnPreferenceClickListener { ImeiInfoDialogFragment.show(context.childFragmentManager, slotIndex, formattedTitle) return@OnPreferenceClickListener true } } private fun Context.getImei(): String = telephonyManager?.getImei(slotIndex) ?: run { Log.e(TAG, "Failed to get IMEI for slot $slotIndex") "" } private fun Context.getFormattedTitle(): String = if (activeModemCount <= 1) { getString(R.string.status_imei) } else { val isPrimary = imei == telephonyManager?.primaryImei val titleId = if (isPrimary) R.string.imei_multi_sim_primary else R.string.imei_multi_sim getString(titleId, slotIndex + 1) } companion object { private const val TAG = "ImeiPreference" const val KEY_PREFIX = "imei_info" } }