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

Commit b7f64511 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12368321 from eb4a22b1 to 24Q4-release

Change-Id: Ia0b970a1d2d9f0f1b27ba087f800b539d5acebcc
parents 3a7b59cf eb4a22b1
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -720,6 +720,9 @@ message SatelliteController {
    optional int32 count_of_satellite_access_check_fail = 28;
    optional bool is_provisioned = 29;
    optional int32 carrier_id = 30;
    optional int32 count_of_satellite_allowed_state_changed_events = 31;
    optional int32 count_of_successful_location_queries = 32;
    optional int32 count_of_failed_location_queries = 33;
}

message SatelliteSession {
@@ -818,6 +821,7 @@ message CarrierRoamingSatelliteControllerStats {
    optional int32 satellite_session_gap_avg_sec = 6;
    optional int32 satellite_session_gap_max_sec = 7;
    optional int32 carrier_id = 8;
    optional bool is_device_entitled = 9;
}

message SatelliteEntitlement {
@@ -846,4 +850,5 @@ message SatelliteAccessController {
    repeated string country_codes = 8;
    optional int32 config_data_source = 9;
    optional int32 carrier_id = 10;
    optional int32 triggering_event = 11;
}
+1 −1
Original line number Diff line number Diff line
@@ -3195,7 +3195,7 @@ public class DataNetworkController extends Handler {
                telephonyNetworkRequest, DataEvaluationReason.DATA_RETRY);
        if (!evaluation.containsDisallowedReasons()) {
            DataProfile dataProfile = dataSetupRetryEntry.dataProfile;
            if (dataProfile == null) {
            if (dataProfile == null || !mDataProfileManager.isDataProfileCompatible(dataProfile)) {
                dataProfile = evaluation.getCandidateDataProfile();
            }
            if (dataProfile != null) {
+2 −0
Original line number Diff line number Diff line
@@ -831,6 +831,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                        }
                        case CMD_DOWNLOAD_SUBSCRIPTION: {
                            DownloadRequest request = (DownloadRequest) message.obj;
                            EuiccSession.get().startSession(EuiccSession.DOWNLOAD);
                            mEuiccService.downloadSubscription(slotId,
                                    request.mPortIndex,
                                    request.mSubscription,
@@ -845,6 +846,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                                                    .onDownloadComplete(result);
                                                onCommandEnd(callback);
                                            });
                                            EuiccSession.get().endSession(EuiccSession.DOWNLOAD);
                                        }
                                    });
                            break;
+141 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.internal.telephony.euicc;

import android.util.ArraySet;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.uicc.euicc.apdu.ApduSender;
import com.android.telephony.Rlog;

import java.util.Set;

/**
 * A eUICC transaction session aims to optimize multiple back-to-back EuiccPort API calls by only
 * open and close a logical channel once.
 *
 * <p>This class is thread-safe.
 */
public class EuiccSession {
    private static final String TAG = "EuiccSession";

    // **** Well known session IDs, see #startSession() ****
    public static final String DOWNLOAD = "DOWNLOAD";

    @GuardedBy("EuiccSession.class")
    private static EuiccSession sInstance;

    public static synchronized EuiccSession get() {
        if (sInstance == null) {
            sInstance = new EuiccSession();
        }
        return sInstance;
    }

    @GuardedBy("this")
    private final Set<String> mSessions = new ArraySet<>();

    @GuardedBy("this")
    private final Set<ApduSender> mApduSenders = new ArraySet<>();

    /**
     * Marks the start of a eUICC transaction session.
     *
     * <p>A session means a long-open logical channel (see {@link ApduSender}) used to
     * send multiple APDUs for one action e.g. {@link EuiccController#downloadSubscription()}.
     * Those APDUs can be send by one or multiple {@link EuiccCardController} methods.
     *
     * <p>Ideally a session should correespond to one phoneId and hence just one logical channel.
     * But many {@link EuiccCardController} methods uses first available port and is not specific
     * to a phoneId. So EuiccController cannot choose one phoneId to use. Hence a session has to
     * be not specific to phoneId, i.e. for DSDS device both phoneId's will be in a session.
     *
     * <p>If called multiple times with different {@code sessionId}'s, the session is truly closed
     * when the all sessions are ended. See {@link #endSession()}.
     *
     * @param sessionId The session ID.
     */
    public void startSession(String sessionId) {
        if (!Flags.optimizationApduSender()) {
            // Other methods in this class is no-op if no session started.
            // Do not add flag to other methods, so if the flag gets turned off,
            // the session can be ended properly.
            return;
        }
        Rlog.i(TAG, "startSession: " + sessionId);
        synchronized(this) {
            mSessions.add(sessionId);
        }
    }

    /** Returns {@code true} if there is at least one session ongoing. */
    public boolean hasSession() {
        boolean hasSession;
        synchronized(this) {
            hasSession = !mSessions.isEmpty();
        }
        Rlog.i(TAG, "hasSession: " + hasSession);
        return hasSession;
    }

    /**
     * Notes that a logical channel may be opened by the {@code apduSender}, which will
     * be used to close the channel when session ends (see {@link #endSession()}).
     *
     * <p>No-op if no session ongoing (see {@link #hasSession()}).
     *
     * @param apduSender The ApduSender that will open the channel.
     */
    public void noteChannelOpen(ApduSender apduSender) {
        Rlog.i(TAG, "noteChannelOpen: " + apduSender);
        synchronized(this) {
            if (hasSession()) {
                mApduSenders.add(apduSender);
            }
        }
    }

    /**
     * Marks the end of a eUICC transaction session. If this ends the last ongoing session,
     * try to close the logical channel using the noted {@code apduSender}
     * (see {@link #noteChannelOpen()}).
     *
     * @param sessionId The session ID.
     */
    public void endSession(String sessionId) {
        Rlog.i(TAG, "endSession: " + sessionId);
        ApduSender[] apduSenders = new ApduSender[0];
        synchronized(this) {
            boolean sessionRemoved = mSessions.remove(sessionId);
            // sessionRemoved is false if the `sessionId` was never started or there was
            // no session at all i.e. `sessions` is empty. Don't bother invoke `apduSender`.
            if (sessionRemoved && mSessions.isEmpty()) {
                // copy mApduSenders to a local variable so we don't call closeAnyOpenChannel()
                // which can take time in synchronized block.
                apduSenders = mApduSenders.toArray(apduSenders);
                mApduSenders.clear();
            }
        }
        for (ApduSender apduSender : apduSenders) {
            apduSender.closeAnyOpenChannel();
        }
    }

    @VisibleForTesting
    public EuiccSession() {}
}
+8 −3
Original line number Diff line number Diff line
@@ -1477,7 +1477,10 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                satelliteController.countOfDisallowedSatelliteAccess,
                satelliteController.countOfSatelliteAccessCheckFail,
                satelliteController.isProvisioned,
                satelliteController.carrierId);
                satelliteController.carrierId,
                satelliteController.countOfSatelliteAllowedStateChangedEvents,
                satelliteController.countOfSuccessfulLocationQueries,
                satelliteController.countOfFailedLocationQueries);
    }

    private static StatsEvent buildStatsEvent(SatelliteSession satelliteSession) {
@@ -1591,7 +1594,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                stats.satelliteSessionGapMinSec,
                stats.satelliteSessionGapAvgSec,
                stats.satelliteSessionGapMaxSec,
                stats.carrierId);
                stats.carrierId,
                stats.isDeviceEntitled);
    }

    private static StatsEvent buildStatsEvent(SatelliteEntitlement stats) {
@@ -1624,7 +1628,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                stats.resultCode,
                stats.countryCodes,
                stats.configDataSource,
                stats.carrierId);
                stats.carrierId,
                stats.triggeringEvent);
    }

    /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
Loading