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

Commit d7ff5f97 authored by Daniel Bright's avatar Daniel Bright
Browse files

Add apn throttle status notifications to QNS

* Whenever the throttling status of an APN, we notify the QNS
* Wired up the unthrottle apn indication
* The AccessNetworksManager now registers for notifications from the
  DataThrottler when the Qns binds

Test: Ran telephony tests
Test: Checked for log message in
      NetworkAvailabilityProvider#onReportApnThrottleStatusChanged
Bug: 167434852
Bug: 174850845
Merged-In: I41c04b6aa8a86fb4b392c1149f308fc092b6b766
Change-Id: I41c04b6aa8a86fb4b392c1149f308fc092b6b766
parent 93d21eb6
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ public abstract class BaseCommands implements CommandsInterface {
    protected RegistrantList mCallStateRegistrants = new RegistrantList();
    protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
    protected RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
    protected RegistrantList mApnUnthrottledRegistrants = new RegistrantList();
    @UnsupportedAppUsage
    protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
    @UnsupportedAppUsage
@@ -303,6 +304,16 @@ public abstract class BaseCommands implements CommandsInterface {
        mDataCallListChangedRegistrants.remove(h);
    }

    @Override
    public void registerForApnUnthrottled(Handler h, int what, Object obj) {
        mApnUnthrottledRegistrants.addUnique(h, what, obj);
    }

    @Override
    public void unregisterForApnUnthrottled(Handler h) {
        mApnUnthrottledRegistrants.remove(h);
    }

    @Override
    public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
        mVoiceRadioTechChangedRegistrants.addUnique(h, what, obj);
+4 −0
Original line number Diff line number Diff line
@@ -220,6 +220,10 @@ public interface CommandsInterface {
    void registerForDataCallListChanged(Handler h, int what, Object obj);
    /** Unregister from data call list changed event */
    void unregisterForDataCallListChanged(Handler h);
    /** Register for the apn unthrottled event */
    void registerForApnUnthrottled(Handler h, int what, Object obj);
    /** Unregister for apn unthrottled event */
    void unregisterForApnUnthrottled(Handler h);

    /** InCall voice privacy notifications */
    void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
+4 −2
Original line number Diff line number Diff line
@@ -296,8 +296,10 @@ public class GsmCdmaPhone extends Phone {
        // DcTracker uses ServiceStateTracker and DisplayInfoController so needs to be created
        // after they are instantiated
        for (int transport : mTransportManager.getAvailableTransports()) {
            mDcTrackers.put(transport, mTelephonyComponentFactory.inject(DcTracker.class.getName())
                    .makeDcTracker(this, transport));
            DcTracker dcTracker = mTelephonyComponentFactory.inject(DcTracker.class.getName())
                    .makeDcTracker(this, transport);
            mDcTrackers.put(transport, dcTracker);
            mTransportManager.registerDataThrottler(dcTracker.getDataThrottler());
        }

        mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
+15 −2
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_SESSION_
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SUPP_SVC_NOTIFICATION;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UNTHROTTLE_APN;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOl_CDMA_PRL_CHANGED;

@@ -86,6 +87,7 @@ import android.hardware.radio.V1_0.SuppSvcNotification;
import android.hardware.radio.V1_2.CellConnectionStatus;
import android.hardware.radio.V1_6.IRadioIndication;
import android.os.AsyncResult;
import android.os.RemoteException;
import android.sysprop.TelephonyProperties;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.AnomalyReporter;
@@ -398,8 +400,10 @@ public class RadioIndication extends IRadioIndication.Stub {
        responseDataCallListChanged(indicationType, dcList);
    }

    /**  unthrottleApn */
    public void unthrottleApn(int indicationType, String apn) {
    @Override
    public void unthrottleApn(int indicationType, String apn)
            throws RemoteException {
        responseApnUnthrottled(indicationType, apn);
    }

    public void suppSvcNotify(int indicationType, SuppSvcNotification suppSvcNotification) {
@@ -1279,4 +1283,13 @@ public class RadioIndication extends IRadioIndication.Stub {
        mRil.mDataCallListChangedRegistrants.notifyRegistrants(
                new AsyncResult(null, response, null));
    }

    private void responseApnUnthrottled(int indicationType, String apn) {
        mRil.processIndication(indicationType);

        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_UNTHROTTLE_APN, apn);

        mRil.mApnUnthrottledRegistrants.notifyRegistrants(
                new AsyncResult(null, apn, null));
    }
}
+132 −62
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
@@ -36,6 +35,7 @@ import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.Annotation.ApnType;
import android.telephony.CarrierConfigManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.ApnThrottleStatus;
import android.telephony.data.IQualifiedNetworksService;
import android.telephony.data.IQualifiedNetworksServiceCallback;
import android.telephony.data.QualifiedNetworksService;
@@ -49,7 +49,9 @@ import com.android.telephony.Rlog;
import java.io.FileDescriptor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
@@ -72,8 +74,6 @@ public class AccessNetworksManager extends Handler {
            ApnSetting.TYPE_XCAP
    };

    private static final int EVENT_BIND_QUALIFIED_NETWORKS_SERVICE = 1;

    private final Phone mPhone;

    private final CarrierConfigManager mCarrierConfigManager;
@@ -91,6 +91,8 @@ public class AccessNetworksManager extends Handler {

    private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList();

    private final Set<DataThrottler> mDataThrottlers = new HashSet<>();

    private final BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -102,11 +104,26 @@ public class AccessNetworksManager extends Handler {
                // package name can come from the carrier config. Note that we still get this event
                // even when SIM is absent.
                if (DBG) log("Carrier config changed. Try to bind qualified network service.");
                sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
                bindQualifiedNetworksService();
            }
        }
    };

    /**
     * Registers the data throttler in order to receive APN status changes.
     *
     * @param dataThrottler the data throttler to register
     */
    public void registerDataThrottler(DataThrottler dataThrottler) {
        this.post(() -> {
            QualifiedNetworksServiceConnection serviceConnection = mServiceConnection;
            this.mDataThrottlers.add(dataThrottler);
            if (serviceConnection != null) {
                serviceConnection.registerDataThrottler(dataThrottler);
            }
        });
    }

    /**
     * Represents qualified network types list on a specific APN type.
     */
@@ -144,6 +161,18 @@ public class AccessNetworksManager extends Handler {
    }

    private final class QualifiedNetworksServiceConnection implements ServiceConnection {

        /**
         * The APN throttle status callback is attached to the service connection so that they have
         * the same life cycle.
         */
        @NonNull
        private final ApnThrottleStatusChangedCallback mThrottleStatusCallback;

        QualifiedNetworksServiceConnection() {
            mThrottleStatusCallback = new ApnThrottleStatusChangedCallback();
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (DBG) log("onServiceConnected " + name);
@@ -154,16 +183,66 @@ public class AccessNetworksManager extends Handler {
                service.linkToDeath(mDeathRecipient, 0 /* flags */);
                mIQualifiedNetworksService.createNetworkAvailabilityProvider(mPhone.getPhoneId(),
                        new QualifiedNetworksServiceCallback());

                registerDataThrottlersFirstTime();

            } catch (RemoteException e) {
                mDeathRecipient.binderDied();
                loge("Remote exception. " + e);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (DBG) log("onServiceDisconnected " + name);
            unregisterForThrottleCallbacks();
            mTargetBindingPackageName = null;
        }

        /**
         * Runs on all of the data throttlers when the service is connected
         */
        private void registerDataThrottlersFirstTime() {
            post(() -> {
                for (DataThrottler dataThrottler : mDataThrottlers) {
                    dataThrottler.registerForApnThrottleStatusChanges(mThrottleStatusCallback);
                }
            });
        }

        private void registerDataThrottler(DataThrottler dataThrottler) {
            post(() -> {
                dataThrottler.registerForApnThrottleStatusChanges(mThrottleStatusCallback);
            });
        }

        private void unregisterForThrottleCallbacks() {
            post(() -> {
                for (DataThrottler dataThrottler : mDataThrottlers) {
                    dataThrottler.unregisterForApnThrottleStatusChanges(mThrottleStatusCallback);
                }
            });
        }
    }

    private class ApnThrottleStatusChangedCallback implements DataThrottler.Callback {
        @Override
        public void onApnThrottleStatusChanged(List<ApnThrottleStatus> apnThrottleStatuses) {
            post(() -> {
                try {
                    List<ApnThrottleStatus> apnThrottleStatusesBySlot =
                            apnThrottleStatuses
                                    .stream()
                                    .filter(x -> x.getSlotIndex() == mPhone.getPhoneId())
                                    .collect(Collectors.toList());

                    mIQualifiedNetworksService.reportApnThrottleStatusChanged(mPhone.getPhoneId(),
                            apnThrottleStatusesBySlot);
                } catch (Exception ex) {
                    loge("onApnThrottleStatusChanged", ex);
                }
            });
        }
    }

    private final class QualifiedNetworksServiceCallback extends
@@ -221,23 +300,7 @@ public class AccessNetworksManager extends Handler {
        } catch (PackageManager.NameNotFoundException e) {
            Rlog.e(TAG, "Package name not found: " + e.getMessage());
        }
        sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
    }

    /**
     * Handle message events
     *
     * @param msg The message to handle
     */
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EVENT_BIND_QUALIFIED_NETWORKS_SERVICE:
        bindQualifiedNetworksService();
                break;
            default:
                loge("Unhandled event " + msg.what);
        }
    }

    /**
@@ -245,6 +308,7 @@ public class AccessNetworksManager extends Handler {
     * configuration from carrier config if it exists. If not, read it from resources.
     */
    private void bindQualifiedNetworksService() {
        post(() -> {
            Intent intent = null;
            String packageName = getQualifiedNetworksServicePackageName();
            String className = getQualifiedNetworksServiceClassName();
@@ -273,7 +337,8 @@ public class AccessNetworksManager extends Handler {
                    && mIQualifiedNetworksService.asBinder().isBinderAlive()) {
                // Remove the network availability updater and then unbind the service.
                try {
                mIQualifiedNetworksService.removeNetworkAvailabilityProvider(mPhone.getPhoneId());
                    mIQualifiedNetworksService.removeNetworkAvailabilityProvider(
                            mPhone.getPhoneId());
                } catch (RemoteException e) {
                    loge("Cannot remove network availability updater. " + e);
                }
@@ -293,6 +358,7 @@ public class AccessNetworksManager extends Handler {
            } catch (Exception e) {
                loge("Cannot bind to the qualified networks service. Exception: " + e);
            }
        });
    }

    /**
@@ -417,4 +483,8 @@ public class AccessNetworksManager extends Handler {
        Rlog.e(TAG, s);
    }

    private void loge(String s, Exception ex) {
        Rlog.e(TAG, s, ex);
    }

}
Loading