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

Commit 2b460020 authored by Malcolm Chen's avatar Malcolm Chen
Browse files

Adding cache of IMS provisioned values.

Adding cache of IMS provisioned values in ImsConfigImplBase.

Bug: 66701374
Test: unitest

Change-Id: I98f8fc12fe44a668d43464cd5f4d2abc03f29764
parent 8587adc4
Loading
Loading
Loading
Loading
+253 −12
Original line number Diff line number Diff line
@@ -16,15 +16,23 @@

package android.telephony.ims.stub;

import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.util.Log;

import com.android.ims.ImsConfig;
import com.android.ims.ImsConfigListener;
import com.android.ims.internal.IImsConfig;
import com.android.internal.annotations.VisibleForTesting;

import java.lang.ref.WeakReference;
import java.util.HashMap;


/**
 * Base implementation of ImsConfig, which implements stub versions of the methods
 * in the IImsConfig AIDL. Override the methods that your implementation of ImsConfig supports.
 * Base implementation of ImsConfig.
 * Override the methods that your implementation of ImsConfig supports.
 *
 * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
 * will break other implementations of ImsConfig maintained by other ImsServices.
@@ -34,10 +42,25 @@ import com.android.ims.internal.IImsConfig;
 * 1) Items provisioned by the operator.
 * 2) Items configured by user. Mainly service feature class.
 *
 * The inner class {@link ImsConfigStub} implements methods of IImsConfig AIDL interface.
 * The IImsConfig AIDL interface is called by ImsConfig, which may exist in many other processes.
 * ImsConfigImpl access to the configuration parameters may be arbitrarily slow, especially in
 * during initialization, or times when a lot of configuration parameters are being set/get
 * (such as during boot up or SIM card change). By providing a cache in ImsConfigStub, we can speed
 * up access to these configuration parameters, so a query to the ImsConfigImpl does not have to be
 * performed every time.
 * @hide
 */

public class ImsConfigImplBase extends IImsConfig.Stub {
public class ImsConfigImplBase {

    static final private String TAG = "ImsConfigImplBase";

    ImsConfigStub mImsConfigStub;

    public ImsConfigImplBase(Context context) {
        mImsConfigStub = new ImsConfigStub(this, context);
    }

    /**
     * Gets the value for ims service/capabilities parameters from the provisioned
@@ -46,7 +69,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
     * @return value in Integer format.
     */
    @Override
    public int getProvisionedValue(int item) throws RemoteException {
        return -1;
    }
@@ -58,7 +80,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
     * @return value in String format.
     */
    @Override
    public String getProvisionedStringValue(int item) throws RemoteException {
        return null;
    }
@@ -72,7 +93,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param value in Integer format.
     * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
     */
    @Override
    public int setProvisionedValue(int item, int value) throws RemoteException {
        return ImsConfig.OperationStatusConstants.FAILED;
    }
@@ -86,7 +106,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param value in String format.
     * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
     */
    @Override
    public int setProvisionedStringValue(int item, String value) throws RemoteException {
        return ImsConfig.OperationStatusConstants.FAILED;
    }
@@ -100,7 +119,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
     * @param listener feature value returned asynchronously through listener.
     */
    @Override
    public void getFeatureValue(int feature, int network, ImsConfigListener listener)
            throws RemoteException {
    }
@@ -115,7 +133,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param value as defined in com.android.ims.ImsConfig#FeatureValueConstants.
     * @param listener, provided if caller needs to be notified for set result.
     */
    @Override
    public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener)
            throws RemoteException {
    }
@@ -124,7 +141,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * Gets the value for IMS VoLTE provisioned.
     * This should be the same as the operator provisioned value if applies.
     */
    @Override
    public boolean getVolteProvisioned() throws RemoteException {
        return false;
    }
@@ -134,7 +150,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     *
     * @param listener Video quality value returned asynchronously through listener.
     */
    @Override
    public void getVideoQuality(ImsConfigListener listener) throws RemoteException {
    }

@@ -144,7 +159,233 @@ public class ImsConfigImplBase extends IImsConfig.Stub {
     * @param quality, defines the value of video quality.
     * @param listener, provided if caller needs to be notified for set result.
     */
    @Override
    public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException {
    }

    public IImsConfig getIImsConfig() { return mImsConfigStub; }

    /**
     * Updates provisioning value and notifies the framework of the change.
     * Doesn't call #setProvisionedValue and assumes the result succeeded.
     * This should only be used by modem when they implicitly changed provisioned values.
     *
     * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
     * @param value in Integer format.
     */
    public final void notifyProvisionedValueChanged(int item, int value) {
        mImsConfigStub.updateCachedValue(item, value, true);
    }

    /**
     * Updates provisioning value and notifies the framework of the change.
     * Doesn't call #setProvisionedValue and assumes the result succeeded.
     * This should only be used by modem when they implicitly changed provisioned values.
     *
     * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
     * @param value in String format.
     */
    public final void notifyProvisionedValueChanged(int item, String value) {
        mImsConfigStub.updateCachedValue(item, value, true);
    }

    /**
     * Implements the IImsConfig AIDL interface, which is called by potentially many processes
     * in order to get/set configuration parameters.
     *
     * It holds an object of ImsConfigImplBase class which is usually extended by ImsConfigImpl
     * with actual implementations from vendors. This class caches provisioned values from
     * ImsConfigImpl layer because queries through ImsConfigImpl can be slow. When query goes in,
     * it first checks cache layer. If missed, it will call the vendor implementation of
     * ImsConfigImplBase API.
     * and cache the return value if the set succeeds.
     *
     * Provides APIs to get/set the IMS service feature/capability/parameters.
     * The config items include:
     * 1) Items provisioned by the operator.
     * 2) Items configured by user. Mainly service feature class.
     *
     * @hide
     */
    @VisibleForTesting
    static public class ImsConfigStub extends IImsConfig.Stub {
        Context mContext;
        WeakReference<ImsConfigImplBase> mImsConfigImplBaseWeakReference;
        private HashMap<Integer, Integer> mProvisionedIntValue = new HashMap<>();
        private HashMap<Integer, String> mProvisionedStringValue = new HashMap<>();

        @VisibleForTesting
        public ImsConfigStub(ImsConfigImplBase imsConfigImplBase, Context context) {
            mContext = context;
            mImsConfigImplBaseWeakReference =
                    new WeakReference<ImsConfigImplBase>(imsConfigImplBase);
        }

        /**
         * Gets the value for ims service/capabilities parameters. It first checks its local cache,
         * if missed, it will call ImsConfigImplBase.getProvisionedValue.
         * Synchronous blocking call.
         *
         * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
         * @return value in Integer format.
         */
        @Override
        public synchronized int getProvisionedValue(int item) throws RemoteException {
            if (mProvisionedIntValue.containsKey(item)) {
                return mProvisionedIntValue.get(item);
            } else {
                int retVal = getImsConfigImpl().getProvisionedValue(item);
                if (retVal != ImsConfig.OperationStatusConstants.UNKNOWN) {
                    updateCachedValue(item, retVal, false);
                }
                return retVal;
            }
        }

        /**
         * Gets the value for ims service/capabilities parameters. It first checks its local cache,
         * if missed, it will call #ImsConfigImplBase.getProvisionedValue.
         * Synchronous blocking call.
         *
         * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
         * @return value in String format.
         */
        @Override
        public synchronized String getProvisionedStringValue(int item) throws RemoteException {
            if (mProvisionedIntValue.containsKey(item)) {
                return mProvisionedStringValue.get(item);
            } else {
                String retVal = getImsConfigImpl().getProvisionedStringValue(item);
                if (retVal != null) {
                    updateCachedValue(item, retVal, false);
                }
                return retVal;
            }
        }

        /**
         * Sets the value for IMS service/capabilities parameters by the operator device
         * management entity. It sets the config item value in the provisioned storage
         * from which the master value is derived, and write it into local cache.
         * Synchronous blocking call.
         *
         * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
         * @param value in Integer format.
         * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
         */
        @Override
        public synchronized int setProvisionedValue(int item, int value) throws RemoteException {
            mProvisionedIntValue.remove(item);
            int retVal = getImsConfigImpl().setProvisionedValue(item, value);
            if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) {
                updateCachedValue(item, retVal, true);
            } else {
                Log.d(TAG, "Set provision value of " + item +
                        " to " + value + " failed with error code " + retVal);
            }

            return retVal;
        }

        /**
         * Sets the value for IMS service/capabilities parameters by the operator device
         * management entity. It sets the config item value in the provisioned storage
         * from which the master value is derived, and write it into local cache.
         * Synchronous blocking call.
         *
         * @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
         * @param value in String format.
         * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
         */
        @Override
        public synchronized int setProvisionedStringValue(int item, String value)
                throws RemoteException {
            mProvisionedStringValue.remove(item);
            int retVal = getImsConfigImpl().setProvisionedStringValue(item, value);
            if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) {
                updateCachedValue(item, retVal, true);
            }

            return retVal;
        }

        /**
         * Wrapper function to call ImsConfigImplBase.getFeatureValue.
         */
        @Override
        public void getFeatureValue(int feature, int network, ImsConfigListener listener)
                throws RemoteException {
            getImsConfigImpl().getFeatureValue(feature, network, listener);
        }

        /**
         * Wrapper function to call ImsConfigImplBase.setFeatureValue.
         */
        @Override
        public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener)
                throws RemoteException {
            getImsConfigImpl().setFeatureValue(feature, network, value, listener);
        }

        /**
         * Wrapper function to call ImsConfigImplBase.getVolteProvisioned.
         */
        @Override
        public boolean getVolteProvisioned() throws RemoteException {
            return getImsConfigImpl().getVolteProvisioned();
        }

        /**
         * Wrapper function to call ImsConfigImplBase.getVideoQuality.
         */
        @Override
        public void getVideoQuality(ImsConfigListener listener) throws RemoteException {
            getImsConfigImpl().getVideoQuality(listener);
        }

        /**
         * Wrapper function to call ImsConfigImplBase.setVideoQuality.
         */
        @Override
        public void setVideoQuality(int quality, ImsConfigListener listener)
                throws RemoteException {
            getImsConfigImpl().setVideoQuality(quality, listener);
        }

        private ImsConfigImplBase getImsConfigImpl() throws RemoteException {
            ImsConfigImplBase ref = mImsConfigImplBaseWeakReference.get();
            if (ref == null) {
                throw new RemoteException("Fail to get ImsConfigImpl");
            } else {
                return ref;
            }
        }

        private void sendImsConfigChangedIntent(int item, int value) {
            sendImsConfigChangedIntent(item, Integer.toString(value));
        }

        private void sendImsConfigChangedIntent(int item, String value) {
            Intent configChangedIntent = new Intent(ImsConfig.ACTION_IMS_CONFIG_CHANGED);
            configChangedIntent.putExtra(ImsConfig.EXTRA_CHANGED_ITEM, item);
            configChangedIntent.putExtra(ImsConfig.EXTRA_NEW_VALUE, value);
            if (mContext != null) {
                mContext.sendBroadcast(configChangedIntent);
            }
        }

        protected synchronized void updateCachedValue(int item, int value, boolean notifyChange) {
            mProvisionedIntValue.put(item, value);
            if (notifyChange) {
                sendImsConfigChangedIntent(item, value);
            }
        }

        protected synchronized void updateCachedValue(
                int item, String value, boolean notifyChange) {
            mProvisionedStringValue.put(item, value);
            if (notifyChange) {
                sendImsConfigChangedIntent(item, value);
            }
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -619,6 +619,7 @@ public class ImsConfig {
            Rlog.d(TAG, "setProvisionedValue(): item = " + item +
                    " value = " + value + " ret = " + ret);
        }

        return ret;
    }

@@ -647,6 +648,7 @@ public class ImsConfig {
            Rlog.d(TAG, "setProvisionedStringValue(): item = " + item +
                    ", value =" + value);
        }

        return ret;
    }