/*
 * Copyright (C) 2020 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 static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;

import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.SurfaceControl;
import android.window.IDisplayAreaOrganizer;
import android.window.IDisplayAreaOrganizerController;

import java.util.HashMap;

public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerController.Stub {
    private static final String TAG = "DisplayAreaOrganizerController";

    final ActivityTaskManagerService mService;
    private final WindowManagerGlobalLock mGlobalLock;
    private final HashMap<Integer, IDisplayAreaOrganizer> mOrganizersByFeatureIds = new HashMap();

    private class DeathRecipient implements IBinder.DeathRecipient {
        int mFeature;
        IDisplayAreaOrganizer mOrganizer;

        DeathRecipient(IDisplayAreaOrganizer organizer, int feature) {
            mOrganizer = organizer;
            mFeature = feature;
        }

        @Override
        public void binderDied() {
            synchronized (mGlobalLock) {
                mOrganizersByFeatureIds.remove(mFeature);
                mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
                    if (da.mOrganizer != mOrganizer) return;
                    da.setOrganizer(null);
                });
            }
        }
    }

    DisplayAreaOrganizerController(ActivityTaskManagerService atm) {
        mService = atm;
        mGlobalLock = atm.mGlobalLock;
    }

    private void enforceStackPermission(String func) {
        mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
    }

    @Override
    public void registerOrganizer(IDisplayAreaOrganizer organizer, int feature) {
        enforceStackPermission("registerOrganizer()");
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                if (mOrganizersByFeatureIds.get(feature) != null) {
                    throw new IllegalStateException(
                            "Replacing existing organizer currently unsupported");
                }

                final DeathRecipient dr = new DeathRecipient(organizer, feature);
                try {
                    organizer.asBinder().linkToDeath(dr, 0);
                } catch (RemoteException e) {
                    // Oh well...
                }
                mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
                    if (da.mFeatureId != feature) return;
                    da.setOrganizer(organizer);
                });

                mOrganizersByFeatureIds.put(feature, organizer);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public void unregisterOrganizer(IDisplayAreaOrganizer organizer) {
        enforceStackPermission("unregisterTaskOrganizer()");
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                mOrganizersByFeatureIds.entrySet().removeIf(
                        entry -> entry.getValue().asBinder() == organizer.asBinder());

                mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
                    if (da.mOrganizer != organizer) return;
                    da.setOrganizer(null);
                });
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) {
        try {
            SurfaceControl outSurfaceControl = new SurfaceControl(da.getSurfaceControl());
            organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo(), outSurfaceControl);
        } catch (RemoteException e) {
            // Oh well...
        }
    }

    void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) {
        try {
            organizer.onDisplayAreaVanished(da.getDisplayAreaInfo());
        } catch (RemoteException e) {
            // Oh well...
        }
    }

    void onDisplayAreaInfoChanged(IDisplayAreaOrganizer organizer, DisplayArea da) {
        try {
            organizer.onDisplayAreaInfoChanged(da.getDisplayAreaInfo());
        } catch (RemoteException e) {
            // Oh well...
        }
    }
}
