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

Commit 046afd7a authored by Rambo Wang's avatar Rambo Wang Committed by Automerger Merge Worker
Browse files

Merge "Introduce CarrierConfigChangeListener API to monitor CC change" am:...

Merge "Introduce CarrierConfigChangeListener API to monitor CC change" am: e302b2a3 am: 0aa2cf77

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2467181



Change-Id: I24c38bc15af5d17b438fa8c18a0175e211ba3f38
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 0f2c312a 0aa2cf77
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -41276,6 +41276,8 @@ package android.telephony {
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, "carrier privileges"}) public android.os.PersistableBundle getConfigForSubId(int, @NonNull java.lang.String...);
    method public static boolean isConfigForIdentifiedCarrier(android.os.PersistableBundle);
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyConfigChangedForSubId(int);
    method public void registerCarrierConfigChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.CarrierConfigManager.CarrierConfigChangeListener);
    method public void unregisterCarrierConfigChangeListener(@NonNull android.telephony.CarrierConfigManager.CarrierConfigChangeListener);
    field public static final String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
    field public static final int CARRIER_NR_AVAILABILITY_NSA = 1; // 0x1
    field public static final int CARRIER_NR_AVAILABILITY_SA = 2; // 0x2
@@ -41590,6 +41592,10 @@ package android.telephony {
    field public static final String KEY_PREFIX = "bsf.";
  }
  public static interface CarrierConfigManager.CarrierConfigChangeListener {
    method public void onCarrierConfigChanged(int, int, int, int);
  }
  public static final class CarrierConfigManager.Gps {
    field public static final String KEY_PERSIST_LPP_MODE_BOOL = "gps.persist_lpp_mode_bool";
    field public static final String KEY_PREFIX = "gps.";
+101 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.listeners.ListenerExecutor;
import com.android.internal.telephony.ICarrierConfigChangeListener;
import com.android.internal.telephony.ICarrierPrivilegesCallback;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
@@ -54,8 +55,10 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

@@ -89,6 +92,14 @@ public class TelephonyRegistryManager {
            IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap
            = new HashMap<>();

    /**
     * A mapping between {@link CarrierConfigManager.CarrierConfigChangeListener} and its callback
     * ICarrierConfigChangeListener.
     */
    private final ConcurrentHashMap<CarrierConfigManager.CarrierConfigChangeListener,
                ICarrierConfigChangeListener>
            mCarrierConfigChangeListenerMap = new ConcurrentHashMap<>();


    /** @hide **/
    public TelephonyRegistryManager(@NonNull Context context) {
@@ -1409,4 +1420,94 @@ public class TelephonyRegistryManager {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Register a {@link android.telephony.CarrierConfigManager.CarrierConfigChangeListener} to get
     * notification when carrier configurations have changed.
     *
     * @param executor The executor on which the callback will be executed.
     * @param listener The CarrierConfigChangeListener to be registered with.
     */
    public void addCarrierConfigChangedListener(
            @NonNull @CallbackExecutor Executor executor,
            @NonNull CarrierConfigManager.CarrierConfigChangeListener listener) {
        Objects.requireNonNull(executor, "Executor should be non-null.");
        Objects.requireNonNull(listener, "Listener should be non-null.");
        if (mCarrierConfigChangeListenerMap.get(listener) != null) {
            Log.e(TAG, "registerCarrierConfigChangeListener: listener already present");
            return;
        }

        ICarrierConfigChangeListener callback = new ICarrierConfigChangeListener.Stub() {
            @Override
            public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
                    int specificCarrierId) {
                Log.d(TAG, "onCarrierConfigChanged call in ICarrierConfigChangeListener callback");
                final long identify = Binder.clearCallingIdentity();
                try {
                    executor.execute(() -> listener.onCarrierConfigChanged(slotIndex, subId,
                            carrierId, specificCarrierId));
                } finally {
                    Binder.restoreCallingIdentity(identify);
                }
            }
        };

        try {
            sRegistry.addCarrierConfigChangeListener(callback,
                    mContext.getOpPackageName(), mContext.getAttributionTag());
            mCarrierConfigChangeListenerMap.put(listener, callback);
        } catch (RemoteException re) {
            // system server crashes
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Unregister to stop the notification when carrier configurations changed.
     *
     * @param listener The CarrierConfigChangeListener to be unregistered with.
     */
    public void removeCarrierConfigChangedListener(
            @NonNull CarrierConfigManager.CarrierConfigChangeListener listener) {
        Objects.requireNonNull(listener, "Listener should be non-null.");
        if (mCarrierConfigChangeListenerMap.get(listener) == null) {
            Log.e(TAG, "removeCarrierConfigChangedListener: listener was not present");
            return;
        }

        try {
            sRegistry.removeCarrierConfigChangeListener(
                    mCarrierConfigChangeListenerMap.get(listener), mContext.getOpPackageName());
            mCarrierConfigChangeListenerMap.remove(listener);
        } catch (RemoteException re) {
            // System sever crashes
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Notify the registrants the carrier configurations have changed.
     *
     * @param slotIndex         The SIM slot index on which to monitor and get notification.
     * @param subId             The subscription on the SIM slot. May be
     *                          {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
     * @param carrierId         The optional carrier Id, may be
     *                          {@link TelephonyManager#UNKNOWN_CARRIER_ID}.
     * @param specificCarrierId The optional specific carrier Id, may be {@link
     *                          TelephonyManager#UNKNOWN_CARRIER_ID}.
     */
    public void notifyCarrierConfigChanged(int slotIndex, int subId, int carrierId,
            int specificCarrierId) {
        // Only validate slotIndex, all others are optional and allowed to be invalid
        if (!SubscriptionManager.isValidPhoneId(slotIndex)) {
            Log.e(TAG, "notifyCarrierConfigChanged, ignored: invalid slotIndex " + slotIndex);
            return;
        }
        try {
            sRegistry.notifyCarrierConfigChanged(slotIndex, subId, carrierId, specificCarrierId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }
}
+21 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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;

oneway interface ICarrierConfigChangeListener {
    void onCarrierConfigChanged(int slotIndex, int subId, int carrierId, int specificCarrierId);
}
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.emergency.EmergencyNumber;
import com.android.internal.telephony.ICarrierConfigChangeListener;
import com.android.internal.telephony.ICarrierPrivilegesCallback;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
@@ -109,4 +110,8 @@ interface ITelephonyRegistry {
            int phoneId, in List<String> privilegedPackageNames, in int[] privilegedUids);
    void notifyCarrierServiceChanged(int phoneId, in String packageName, int uid);

    void addCarrierConfigChangeListener(ICarrierConfigChangeListener listener,
            String pkg, String featureId);
    void removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener, String pkg);
    void notifyCarrierConfigChanged(int phoneId, int subId, int carrierId, int specificCarrierId);
}
+83 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import android.util.Pair;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.ICarrierConfigChangeListener;
import com.android.internal.telephony.ICarrierPrivilegesCallback;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.IPhoneStateListener;
@@ -154,6 +155,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
        IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
        IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback;
        ICarrierPrivilegesCallback carrierPrivilegesCallback;
        ICarrierConfigChangeListener carrierConfigChangeListener;

        int callerUid;
        int callerPid;
@@ -182,6 +184,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
            return carrierPrivilegesCallback != null;
        }

        boolean matchCarrierConfigChangeListener() {
            return carrierConfigChangeListener != null;
        }

        boolean canReadCallLog() {
            try {
                return TelephonyPermissions.checkReadCallLog(
@@ -200,6 +206,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
                    + " onOpportunisticSubscriptionsChangedListenererCallback="
                    + onOpportunisticSubscriptionsChangedListenerCallback
                    + " carrierPrivilegesCallback=" + carrierPrivilegesCallback
                    + " carrierConfigChangeListener=" + carrierConfigChangeListener
                    + " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}";
        }
    }
@@ -2955,6 +2962,82 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
        }
    }

    @Override
    public void addCarrierConfigChangeListener(ICarrierConfigChangeListener listener,
            String pkg, String featureId) {
        final int callerUserId = UserHandle.getCallingUserId();
        mAppOps.checkPackage(Binder.getCallingUid(), pkg);
        if (VDBG) {
            log("addCarrierConfigChangeListener pkg=" + pii(pkg) + " uid=" + Binder.getCallingUid()
                    + " myUserId=" + UserHandle.myUserId() + " callerUerId" + callerUserId
                    + " listener=" + listener + " listener.asBinder=" + listener.asBinder());
        }

        synchronized (mRecords) {
            IBinder b = listener.asBinder();
            boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
                    Process.myUid());
            Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);

            if (r == null) {
                loge("Can not create Record instance!");
                return;
            }

            r.context = mContext;
            r.carrierConfigChangeListener = listener;
            r.callingPackage = pkg;
            r.callingFeatureId = featureId;
            r.callerUid = Binder.getCallingUid();
            r.callerPid = Binder.getCallingPid();
            r.eventList = new ArraySet<>();
            if (DBG) {
                log("addCarrierConfigChangeListener:  Register r=" + r);
            }
        }
    }

    @Override
    public void removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener,
            String pkg) {
        if (DBG) log("removeCarrierConfigChangeListener listener=" + listener + ", pkg=" + pkg);
        mAppOps.checkPackage(Binder.getCallingUid(), pkg);
        remove(listener.asBinder());
    }

    @Override
    public void notifyCarrierConfigChanged(int phoneId, int subId, int carrierId,
            int specificCarrierId) {
        if (!validatePhoneId(phoneId)) {
            throw new IllegalArgumentException("Invalid phoneId: " + phoneId);
        }
        if (!checkNotifyPermission("notifyCarrierConfigChanged")) {
            loge("Caller has no notify permission!");
            return;
        }
        if (VDBG) {
            log("notifyCarrierConfigChanged: phoneId=" + phoneId + ", subId=" + subId
                    + ", carrierId=" + carrierId + ", specificCarrierId=" + specificCarrierId);
        }

        synchronized (mRecords) {
            mRemoveList.clear();
            for (Record r : mRecords) {
                // Listeners are "global", neither per-slot nor per-sub, so no idMatch check here
                if (!r.matchCarrierConfigChangeListener()) {
                    continue;
                }
                try {
                    r.carrierConfigChangeListener.onCarrierConfigChanged(phoneId, subId, carrierId,
                            specificCarrierId);
                } catch (RemoteException re) {
                    mRemoveList.add(r.binder);
                }
            }
            handleRemoveListLocked();
        }
    }

    @NeverCompile // Avoid size overhead of debugging code.
    @Override
    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Loading