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

Commit 18bbda7e authored by Hyunho's avatar Hyunho
Browse files

Enalbe the convert to eSIM menu

Bug : b/314881248
Test: manual done
Change-Id: Ib320cf3b3fc06ccf46be98f8c7afbe480df3bb79
parent 1a7a4d24
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;
    }
}