/*
 * 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 android.os.image;

import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.gsi.GsiProgress;
import android.os.RemoteException;

/**
 * The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the
 * installation, the device can reboot into this image with a new created /data. This image will
 * last until the next reboot and then the device will go back to the original image. However the
 * installed image and the new created /data are not deleted but disabled. Thus the application can
 * either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to
 * delete it completely. In other words, there are three device states: no installation, installed
 * and running. The procedure to install a DynamicSystem starts with a {@link #startInstallation},
 * followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is
 * complete, the device state changes from no installation to the installed state and a followed
 * reboot will change its state to running. Note one instance of DynamicSystem can exist on a given
 * device thus the {@link #startInstallation} will fail if the device is currently running a
 * DynamicSystem.
 *
 * @hide
 */
@SystemService(Context.DYNAMIC_SYSTEM_SERVICE)
public class DynamicSystemManager {
    private static final String TAG = "DynamicSystemManager";

    private final IDynamicSystemService mService;

    /** {@hide} */
    public DynamicSystemManager(IDynamicSystemService service) {
        mService = service;
    }

    /** The DynamicSystemManager.Session represents a started session for the installation. */
    public class Session {
        private Session() {}
        /**
         * Write a chunk of the DynamicSystem system image
         *
         * @return {@code true} if the call succeeds. {@code false} if there is any native runtime
         *     error.
         */
        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
        public boolean write(byte[] buf) {
            try {
                return mService.write(buf);
            } catch (RemoteException e) {
                throw new RuntimeException(e.toString());
            }
        }

        /**
         * Finish write and make device to boot into the it after reboot.
         *
         * @return {@code true} if the call succeeds. {@code false} if there is any native runtime
         *     error.
         */
        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
        public boolean commit() {
            try {
                return mService.commit();
            } catch (RemoteException e) {
                throw new RuntimeException(e.toString());
            }
        }
    }
    /**
     * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller
     * may use another thread to call the getStartProgress() to get the progress.
     *
     * @param systemSize system size in bytes
     * @param userdataSize userdata size in bytes
     * @return {@code true} if the call succeeds. {@code false} either the device does not contain
     *     enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be
     *     true.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public Session startInstallation(long systemSize, long userdataSize) {
        try {
            if (mService.startInstallation(systemSize, userdataSize)) {
                return new Session();
            } else {
                return null;
            }
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Query the progress of the current installation operation. This can be called while the
     * installation is in progress.
     *
     * @return GsiProgress GsiProgress { int status; long bytes_processed; long total_bytes; } The
     *     status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or
     *     IGsiService.STATUS_COMPLETE.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public GsiProgress getInstallationProgress() {
        try {
            return mService.getInstallationProgress();
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Abort the installation process. Note this method must be called in a thread other than the
     * one calling the startInstallation method as the startInstallation method will not return
     * until it is finished.
     *
     * @return {@code true} if the call succeeds. {@code false} if there is no installation
     *     currently.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean abort() {
        try {
            return mService.abort();
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /** @return {@code true} if the device is running a dynamic system */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean isInUse() {
        try {
            return mService.isInUse();
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /** @return {@code true} if the device has a dynamic system installed */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean isInstalled() {
        try {
            return mService.isInstalled();
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /** @return {@code true} if the device has a dynamic system enabled */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean isEnabled() {
        try {
            return mService.isEnabled();
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Remove DynamicSystem installation if present
     *
     * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean remove() {
        try {
            return mService.remove();
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Enable or disable DynamicSystem.
     * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
    public boolean setEnable(boolean enable) {
        try {
            return mService.setEnable(enable);
        } catch (RemoteException e) {
            throw new RuntimeException(e.toString());
        }
    }
}
