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

Commit 13e3442d authored by Brad Ebinger's avatar Brad Ebinger Committed by Automerger Merge Worker
Browse files

Move to a push model of querying ImsFeature Binders am: 31f7026e am:...

Move to a push model of querying ImsFeature Binders am: 31f7026e am: 48d40027 am: 809e2b08 am: d75fe5d7

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/net/ims/+/1426022

Change-Id: I8ac0bec876f16e66a6ea84ae7f0761c649dc9518
parents 6d49f5cf d75fe5d7
Loading
Loading
Loading
Loading
+29 −146
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.ims;

import android.annotation.Nullable;
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
@@ -29,11 +28,7 @@ import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.Log;

import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.HandlerExecutor;

import java.util.concurrent.Executor;

/**
 * Base class of MmTelFeatureConnection and RcsFeatureConnection.
@@ -41,51 +36,26 @@ import java.util.concurrent.Executor;
public abstract class FeatureConnection {
    protected static final String TAG = "FeatureConnection";

    public interface IFeatureUpdate {
        /**
         * Called when the ImsFeature has changed its state. Use
         * {@link ImsFeature#getFeatureState()} to get the new state.
         */
        void notifyStateChanged();

        /**
         * Called when the ImsFeature has become unavailable due to the binder switching or app
         * crashing. A new ImsServiceProxy should be requested for that feature.
         */
        void notifyUnavailable();
    }

    protected static boolean sImsSupportedOnDevice = true;

    protected final int mSlotId;
    protected Context mContext;
    protected IBinder mBinder;
    @VisibleForTesting
    public Executor mExecutor;

    // We are assuming the feature is available when started.
    protected volatile boolean mIsAvailable = true;
    // ImsFeature Status from the ImsService. Cached.
    protected Integer mFeatureStateCached = null;
    protected IFeatureUpdate mStatusCallback;
    protected IImsRegistration mRegistrationBinder;
    protected IImsConfig mConfigBinder;
    protected long mFeatureCapabilities;
    private final IImsRegistration mRegistrationBinder;
    private final IImsConfig mConfigBinder;
    protected final Object mLock = new Object();

    public FeatureConnection(Context context, int slotId) {
    public FeatureConnection(Context context, int slotId, IImsConfig c, IImsRegistration r) {
        mSlotId = slotId;
        mContext = context;

        // Callbacks should be scheduled on the main thread.
        if (context.getMainLooper() != null) {
            mExecutor = context.getMainExecutor();
        } else {
            // Fallback to the current thread.
            if (Looper.myLooper() == null) {
                Looper.prepare();
            }
            mExecutor = new HandlerExecutor(new Handler(Looper.myLooper()));
        }
        mRegistrationBinder = r;
        mConfigBinder = c;
    }

    protected TelephonyManager getTelephonyManager() {
@@ -128,57 +98,12 @@ public abstract class FeatureConnection {
        synchronized (mLock) {
            if (mIsAvailable) {
                mIsAvailable = false;
                mRegistrationBinder = null;
                if (mBinder != null) {
                    mBinder.unlinkToDeath(mDeathRecipient, 0);
                }
                if (mStatusCallback != null) {
                    Log.d(TAG, "onRemovedOrDied: notifyUnavailable");
                    mStatusCallback.notifyUnavailable();
                    // Unlink because this FeatureConnection should no longer send callbacks.
                    mStatusCallback = null;
                }
            }
        }
    }

    /**
     * The listener for ImsManger and RcsFeatureManager to receive IMS feature status changed.
     * @param callback Callback that will fire when the feature status has changed.
     */
    public void setStatusCallback(IFeatureUpdate callback) {
        mStatusCallback = callback;
            }

    @VisibleForTesting
    public IImsServiceFeatureCallback getListener() {
        return mListenerBinder;
        }

    /**
     * The callback to receive ImsFeature status changed.
     */
    private final IImsServiceFeatureCallback mListenerBinder =
        new IImsServiceFeatureCallback.Stub() {
            @Override
            public void imsFeatureCreated(int slotId, int feature) {
                mExecutor.execute(() -> {
                    handleImsFeatureCreatedCallback(slotId, feature);
                });
            }
            @Override
            public void imsFeatureRemoved(int slotId, int feature) {
                mExecutor.execute(() -> {
                    handleImsFeatureRemovedCallback(slotId, feature);
                });
            }
            @Override
            public void imsStatusChanged(int slotId, int feature, int status) {
                mExecutor.execute(() -> {
                    handleImsStatusChangedCallback(slotId, feature, status);
                });
    }
        };

    public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTech()
            throws RemoteException {
@@ -192,41 +117,10 @@ public abstract class FeatureConnection {
    }

    public @Nullable IImsRegistration getRegistration() {
        synchronized (mLock) {
            // null if cache is invalid;
            if (mRegistrationBinder != null) {
                return mRegistrationBinder;
            }
        }
        // We don't want to synchronize on a binder call to another process.
        IImsRegistration regBinder = getRegistrationBinder();
        synchronized (mLock) {
            // mRegistrationBinder may have changed while we tried to get the registration
            // interface.
            if (mRegistrationBinder == null) {
                mRegistrationBinder = regBinder;
            }
        }
        return mRegistrationBinder;
    }

    public @Nullable
    IImsConfig getConfig() {
        synchronized (mLock) {
            // null if cache is invalid;
            if (mConfigBinder != null) {
                return mConfigBinder;
            }
        }
        // We don't want to synchronize on a binder call to another process.
        IImsConfig configBinder = getConfigBinder();
        synchronized (mLock) {
            // mRegistrationBinder may have changed while we tried to get the registration
            // interface.
            if (mConfigBinder == null) {
                mConfigBinder = configBinder;
            }
        }
    public @Nullable IImsConfig getConfig() {
        return mConfigBinder;
    }

@@ -260,6 +154,27 @@ public abstract class FeatureConnection {
        return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
    }

    public void updateFeatureState(int state) {
        synchronized (mLock) {
            mFeatureStateCached = state;
        }
    }

    public long getFeatureCapabilties() {
        synchronized (mLock) {
            return mFeatureCapabilities;
        }
    }

    public void updateFeatureCapabilities(long caps) {
        synchronized (mLock) {
            if (mFeatureCapabilities != caps) {
                mFeatureCapabilities = caps;
                onFeatureCapabilitiesUpdated(caps);
            }
        }
    }

    /**
     * @return an integer describing the current Feature Status, defined in
     * {@link ImsFeature.ImsState}.
@@ -284,42 +199,10 @@ public abstract class FeatureConnection {
        return state;
    }

    /**
     * An ImsFeature has been created for this FeatureConnection for the associated
     * {@link ImsFeature.FeatureType}.
     * @param slotId The slot ID associated with the event.
     * @param feature The {@link ImsFeature.FeatureType} associated with the event.
     */
    protected abstract void handleImsFeatureCreatedCallback(int slotId, int feature);

    /**
     * An ImsFeature has been removed for this FeatureConnection for the associated
     * {@link ImsFeature.FeatureType}.
     * @param slotId The slot ID associated with the event.
     * @param feature The {@link ImsFeature.FeatureType} associated with the event.
     */
    protected abstract void handleImsFeatureRemovedCallback(int slotId, int feature);

    /**
     * The status of an ImsFeature has changed for the associated {@link ImsFeature.FeatureType}.
     * @param slotId The slot ID associated with the event.
     * @param feature The {@link ImsFeature.FeatureType} associated with the event.
     * @param status The new {@link ImsFeature.ImsState} associated with the ImsFeature
     */
    protected abstract void handleImsStatusChangedCallback(int slotId, int feature, int status);

    /**
     * Internal method used to retrieve the feature status from the corresponding ImsService.
     */
    protected abstract Integer retrieveFeatureState();

    /**
     * @return The ImsRegistration instance associated with the FeatureConnection.
     */
    protected abstract IImsRegistration getRegistrationBinder();

    /**
     * @return The ImsRegistration instance associated with the FeatureConnection.
     */
    protected abstract IImsConfig getConfigBinder();
    protected abstract void onFeatureCapabilitiesUpdated(long capabilities);
}
+207 −174

File changed.

Preview size limit exceeded, changes collapsed.

+72 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2019 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.ims;

import android.os.IBinder;
import android.telephony.ims.ImsService;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.feature.ImsFeature;

import com.android.ims.internal.IImsServiceFeatureCallback;

/**
 * Interface used by Manager interfaces that will use a {@link FeatureConnector} to connect to
 * remote ImsFeature Binder interfaces.
 */
public interface FeatureUpdates {
    /**
     * Register a calback for the slot specified so that the FeatureConnector can notify its
     * listener of changes.
     * @param slotId The slot the callback is registered for.
     * @param cb The callback that the FeatureConnector will use to update its state and notify
     *           its callback of changes.
     * @param oneShot True if this callback should only be registered for one update (feature is
     *                available or not), false if this listener should be persistent.
     */
    void registerFeatureCallback(int slotId, IImsServiceFeatureCallback cb, boolean oneShot);

    /**
     * Unregister a previously registered callback due to the FeatureConnector disconnecting.
     * <p>
     * This does not need to be called if the callback was previously registered for a one
     * shot result.
     * @param cb The callback to unregister.
     */
    void unregisterFeatureCallback(IImsServiceFeatureCallback cb);

    /**
     * Associate this Manager instance with the IMS Binder interfaces specified. This is usually
     * done by creating a FeatureConnection instance with these interfaces.
     */
    void associate(IBinder feature, IImsConfig c, IImsRegistration r);

    /**
     * Invalidate the previously associated Binder interfaces set in {@link #associate}.
     */
    void invalidate();

    /**
     * Update the state of the remote ImsFeature associated with this Manager instance.
     */
    void updateFeatureState(@ImsFeature.ImsState int state);

    /**
     * Update the capabilities of the remove ImsFeature associated with this Manager instance.
     */
    void updateFeatureCapabilities(@ImsService.ImsServiceCapability long capabilities);
}
 No newline at end of file
+0 −24
Original line number Diff line number Diff line
/*
 * Copyright (c) 2019 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.ims;

public interface IFeatureConnector<T> {
    int getImsServiceState() throws ImsException;
    void addNotifyStatusChangedCallbackIfAvailable(FeatureConnection.IFeatureUpdate callback)
            throws android.telephony.ims.ImsException;
    void removeNotifyStatusChangedCallback(FeatureConnection.IFeatureUpdate callback);
}
 No newline at end of file
+438 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading