/*
 * Copyright (C) 2018 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.server.wm;

import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.android.internal.os.BackgroundThread;
import com.android.internal.util.function.pooled.PooledLambda;

import java.util.ArrayList;

/**
 * Multi-cast implementation of {@link ActivityMetricsLaunchObserver}.
 *
 * <br /><br />
 * If this class is called through the {@link ActivityMetricsLaunchObserver} interface,
 * then the call is forwarded to all registered observers at the time.
 *
 * <br /><br />
 * All calls are invoked asynchronously in-order on a background thread. This fulfills the
 * sequential ordering guarantee in {@link ActivityMetricsLaunchObserverRegistry}.
 *
 * @see ActivityTaskManagerInternal#getLaunchObserverRegistry()
 */
class LaunchObserverRegistryImpl implements
        ActivityMetricsLaunchObserverRegistry, ActivityMetricsLaunchObserver {
    private final ArrayList<ActivityMetricsLaunchObserver> mList = new ArrayList<>();

    /**
     * All calls are posted to a handler because:
     *
     * 1. We don't know how long the observer will take to handle this call and we don't want
     *    to block the WM critical section on it.
     * 2. We don't know the lock ordering of the observer so we don't want to expose a chance
     *    of deadlock.
     */
    private final Handler mHandler;

    public LaunchObserverRegistryImpl(Looper looper) {
        mHandler = new Handler(looper);
    }

    @Override
    public void registerLaunchObserver(ActivityMetricsLaunchObserver launchObserver) {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleRegisterLaunchObserver, this, launchObserver));
    }

    @Override
    public void unregisterLaunchObserver(ActivityMetricsLaunchObserver launchObserver) {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleUnregisterLaunchObserver, this, launchObserver));
    }

    @Override
    public void onIntentStarted(Intent intent) {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleOnIntentStarted, this, intent));
    }

    @Override
    public void onIntentFailed() {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleOnIntentFailed, this));
    }

    @Override
    public void onActivityLaunched(
            @ActivityRecordProto byte[] activity,
            int temperature) {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleOnActivityLaunched,
                this, activity, temperature));
    }

    @Override
    public void onActivityLaunchCancelled(
        @ActivityRecordProto byte[] activity) {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleOnActivityLaunchCancelled, this, activity));
    }

    @Override
    public void onActivityLaunchFinished(
        @ActivityRecordProto byte[] activity) {
        mHandler.sendMessage(PooledLambda.obtainMessage(
                LaunchObserverRegistryImpl::handleOnActivityLaunchFinished, this, activity));
    }

    // Use PooledLambda.obtainMessage to invoke below methods. Every method reference must be
    // unbound (i.e. not capture any variables explicitly or implicitly) to fulfill the
    // singleton-lambda requirement.

    private void handleRegisterLaunchObserver(ActivityMetricsLaunchObserver observer) {
        mList.add(observer);
    }

    private void handleUnregisterLaunchObserver(ActivityMetricsLaunchObserver observer) {
        mList.remove(observer);
    }

    private void handleOnIntentStarted(Intent intent) {
        // Traverse start-to-end to meet the registerLaunchObserver multi-cast order guarantee.
        for (int i = 0; i < mList.size(); i++) {
             ActivityMetricsLaunchObserver o = mList.get(i);
             o.onIntentStarted(intent);
        }
    }

    private void handleOnIntentFailed() {
        // Traverse start-to-end to meet the registerLaunchObserver multi-cast order guarantee.
        for (int i = 0; i < mList.size(); i++) {
             ActivityMetricsLaunchObserver o = mList.get(i);
             o.onIntentFailed();
        }
    }

    private void handleOnActivityLaunched(
            @ActivityRecordProto byte[] activity,
            @Temperature int temperature) {
        // Traverse start-to-end to meet the registerLaunchObserver multi-cast order guarantee.
        for (int i = 0; i < mList.size(); i++) {
             ActivityMetricsLaunchObserver o = mList.get(i);
             o.onActivityLaunched(activity, temperature);
        }
    }

    private void handleOnActivityLaunchCancelled(
            @ActivityRecordProto byte[] activity) {
        // Traverse start-to-end to meet the registerLaunchObserver multi-cast order guarantee.
        for (int i = 0; i < mList.size(); i++) {
             ActivityMetricsLaunchObserver o = mList.get(i);
             o.onActivityLaunchCancelled(activity);
        }
    }

    private void handleOnActivityLaunchFinished(
            @ActivityRecordProto byte[] activity) {
        // Traverse start-to-end to meet the registerLaunchObserver multi-cast order guarantee.
        for (int i = 0; i < mList.size(); i++) {
            ActivityMetricsLaunchObserver o = mList.get(i);
            o.onActivityLaunchFinished(activity);
        }
    }
}
