Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a413cc8 authored by Hyunho Shin's avatar Hyunho Shin Committed by Android (Google) Code Review
Browse files

Merge "Enalbe the convert to eSIM menu" into main

parents b85f4de6 18bbda7e
Loading
Loading
Loading
Loading
+96 −14
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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) {
@@ -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
@@ -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;
    }

@@ -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;
    }
}