Loading src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java +96 −14 Original line number Diff line number Diff line Loading @@ -19,7 +19,19 @@ package com.android.settings.network.telephony; import static androidx.lifecycle.Lifecycle.Event.ON_START; import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import android.Manifest; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.service.euicc.EuiccService; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.euicc.EuiccManager; import android.text.TextUtils; import androidx.annotation.VisibleForTesting; Loading @@ -29,12 +41,12 @@ import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.internal.telephony.util.TelephonyUtils; import com.android.settings.network.MobileNetworkRepository; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.mobile.dataservice.DataServiceUtils; import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity; import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity; import com.android.settingslib.mobile.dataservice.UiccInfoEntity; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; Loading @@ -47,6 +59,9 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo private MobileNetworkRepository mMobileNetworkRepository; private List<SubscriptionInfoEntity> mSubscriptionInfoEntityList = new ArrayList<>(); private SubscriptionInfoEntity mSubscriptionInfoEntity; private static int sQueryFlag = PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DIRECT_BOOT_AUTO | PackageManager.GET_RESOLVED_FILTER; public ConvertToEsimPreferenceController(Context context, String key, Lifecycle lifecycle, LifecycleOwner lifecycleOwner, int subId) { Loading Loading @@ -83,11 +98,14 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo @Override public int getAvailabilityStatus(int subId) { return CONDITIONALLY_UNAVAILABLE; // TODO(b/262195754): Need the intent to enabled the feature. // return mSubscriptionInfoEntity != null && mSubscriptionInfoEntity.isActiveSubscriptionId // && !mSubscriptionInfoEntity.isEmbedded ? AVAILABLE // : CONDITIONALLY_UNAVAILABLE; if (findConversionSupportComponent()) { return mSubscriptionInfoEntity != null && mSubscriptionInfoEntity.isActiveSubscriptionId && !mSubscriptionInfoEntity.isEmbedded && isActiveSubscription(subId) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } return CONDITIONALLY_UNAVAILABLE; } @VisibleForTesting Loading @@ -104,6 +122,9 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo return false; } // Send intent to launch LPA Intent intent = new Intent(EuiccManager.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION); intent.putExtra("subId", mSubId); mContext.startActivity(intent); return true; } Loading @@ -115,12 +136,73 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo @Override public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) { // TODO(b/262195754): Need the intent to enabled the feature. // mSubscriptionInfoEntityList = subInfoEntityList; // mSubscriptionInfoEntityList.forEach(entity -> { // if (Integer.parseInt(entity.subId) == mSubId) { // mSubscriptionInfoEntity = entity; // update(); // } // }); mSubscriptionInfoEntityList = subInfoEntityList; mSubscriptionInfoEntityList.forEach(entity -> { if (Integer.parseInt(entity.subId) == mSubId) { mSubscriptionInfoEntity = entity; update(); } }); } private boolean isActiveSubscription(int subId) { SubscriptionManager subscriptionManager = mContext.getSystemService( SubscriptionManager.class); SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(subId); if (subInfo == null) { return false; } return true; } private boolean findConversionSupportComponent() { Intent intent = new Intent(EuiccService.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION); PackageManager packageManager = mContext.getPackageManager(); List<ResolveInfo> resolveInfoList = packageManager .queryIntentActivities(intent, sQueryFlag); if (resolveInfoList == null || resolveInfoList.isEmpty()) { return false; } for (ResolveInfo resolveInfo : resolveInfoList) { if (!isValidEuiccComponent(packageManager, resolveInfo)) { continue; } else { return true; } } return true; } private boolean isValidEuiccComponent( PackageManager packageManager, @NotNull ResolveInfo resolveInfo) { ComponentInfo componentInfo = TelephonyUtils.getComponentInfo(resolveInfo); String packageName = new ComponentName(componentInfo.packageName, componentInfo.name) .getPackageName(); // Verify that the app is privileged (via granting of a privileged permission). if (packageManager.checkPermission( Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS, packageName) != PackageManager.PERMISSION_GRANTED) { return false; } // Verify that only the system can access the component. final String permission; if (componentInfo instanceof ServiceInfo) { permission = ((ServiceInfo) componentInfo).permission; } else if (componentInfo instanceof ActivityInfo) { permission = ((ActivityInfo) componentInfo).permission; } else { return false; } if (!TextUtils.equals(permission, Manifest.permission.BIND_EUICC_SERVICE)) { return false; } // Verify that the component declares a priority. if (resolveInfo.filter == null || resolveInfo.filter.getPriority() == 0) { return false; } return true; } } Loading
src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java +96 −14 Original line number Diff line number Diff line Loading @@ -19,7 +19,19 @@ package com.android.settings.network.telephony; import static androidx.lifecycle.Lifecycle.Event.ON_START; import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import android.Manifest; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.service.euicc.EuiccService; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.euicc.EuiccManager; import android.text.TextUtils; import androidx.annotation.VisibleForTesting; Loading @@ -29,12 +41,12 @@ import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.internal.telephony.util.TelephonyUtils; import com.android.settings.network.MobileNetworkRepository; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.mobile.dataservice.DataServiceUtils; import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity; import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity; import com.android.settingslib.mobile.dataservice.UiccInfoEntity; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; Loading @@ -47,6 +59,9 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo private MobileNetworkRepository mMobileNetworkRepository; private List<SubscriptionInfoEntity> mSubscriptionInfoEntityList = new ArrayList<>(); private SubscriptionInfoEntity mSubscriptionInfoEntity; private static int sQueryFlag = PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DIRECT_BOOT_AUTO | PackageManager.GET_RESOLVED_FILTER; public ConvertToEsimPreferenceController(Context context, String key, Lifecycle lifecycle, LifecycleOwner lifecycleOwner, int subId) { Loading Loading @@ -83,11 +98,14 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo @Override public int getAvailabilityStatus(int subId) { return CONDITIONALLY_UNAVAILABLE; // TODO(b/262195754): Need the intent to enabled the feature. // return mSubscriptionInfoEntity != null && mSubscriptionInfoEntity.isActiveSubscriptionId // && !mSubscriptionInfoEntity.isEmbedded ? AVAILABLE // : CONDITIONALLY_UNAVAILABLE; if (findConversionSupportComponent()) { return mSubscriptionInfoEntity != null && mSubscriptionInfoEntity.isActiveSubscriptionId && !mSubscriptionInfoEntity.isEmbedded && isActiveSubscription(subId) ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; } return CONDITIONALLY_UNAVAILABLE; } @VisibleForTesting Loading @@ -104,6 +122,9 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo return false; } // Send intent to launch LPA Intent intent = new Intent(EuiccManager.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION); intent.putExtra("subId", mSubId); mContext.startActivity(intent); return true; } Loading @@ -115,12 +136,73 @@ public class ConvertToEsimPreferenceController extends TelephonyBasePreferenceCo @Override public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) { // TODO(b/262195754): Need the intent to enabled the feature. // mSubscriptionInfoEntityList = subInfoEntityList; // mSubscriptionInfoEntityList.forEach(entity -> { // if (Integer.parseInt(entity.subId) == mSubId) { // mSubscriptionInfoEntity = entity; // update(); // } // }); mSubscriptionInfoEntityList = subInfoEntityList; mSubscriptionInfoEntityList.forEach(entity -> { if (Integer.parseInt(entity.subId) == mSubId) { mSubscriptionInfoEntity = entity; update(); } }); } private boolean isActiveSubscription(int subId) { SubscriptionManager subscriptionManager = mContext.getSystemService( SubscriptionManager.class); SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(subId); if (subInfo == null) { return false; } return true; } private boolean findConversionSupportComponent() { Intent intent = new Intent(EuiccService.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION); PackageManager packageManager = mContext.getPackageManager(); List<ResolveInfo> resolveInfoList = packageManager .queryIntentActivities(intent, sQueryFlag); if (resolveInfoList == null || resolveInfoList.isEmpty()) { return false; } for (ResolveInfo resolveInfo : resolveInfoList) { if (!isValidEuiccComponent(packageManager, resolveInfo)) { continue; } else { return true; } } return true; } private boolean isValidEuiccComponent( PackageManager packageManager, @NotNull ResolveInfo resolveInfo) { ComponentInfo componentInfo = TelephonyUtils.getComponentInfo(resolveInfo); String packageName = new ComponentName(componentInfo.packageName, componentInfo.name) .getPackageName(); // Verify that the app is privileged (via granting of a privileged permission). if (packageManager.checkPermission( Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS, packageName) != PackageManager.PERMISSION_GRANTED) { return false; } // Verify that only the system can access the component. final String permission; if (componentInfo instanceof ServiceInfo) { permission = ((ServiceInfo) componentInfo).permission; } else if (componentInfo instanceof ActivityInfo) { permission = ((ActivityInfo) componentInfo).permission; } else { return false; } if (!TextUtils.equals(permission, Manifest.permission.BIND_EUICC_SERVICE)) { return false; } // Verify that the component declares a priority. if (resolveInfo.filter == null || resolveInfo.filter.getPriority() == 0) { return false; } return true; } }