// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.photo_picker;

import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;

import org.chromium.base.CommandLine;
import org.chromium.base.Log;
import org.chromium.base.PathUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.chrome.browser.init.ChromeBrowserInitializer;

import java.io.FileDescriptor;
import java.io.IOException;

/**
 * A service to accept requests to take image file contents and decode them.
 */
@MainDex
public class DecoderService extends Service {
    // The keys for the bundle when passing data to and from this service.
    static final String KEY_FILE_DESCRIPTOR = "file_descriptor";
    static final String KEY_FILE_PATH = "file_path";
    static final String KEY_IMAGE_BITMAP = "image_bitmap";
    static final String KEY_SIZE = "size";
    static final String KEY_SUCCESS = "success";
    static final String KEY_DECODE_TIME = "decode_time";

    // A tag for logging error messages.
    private static final String TAG = "ImageDecoder";

    // Whether the native library and the sandbox have been initialized.
    private boolean mNativeLibraryAndSandboxInitialized;

    @Override
    public void onCreate() {
        // DecoderService does not require flags, but LibraryLoader.ensureInitialized() checks for
        // --enable-low-end-device-mode. Rather than forwarding the flags from the browser process,
        // just assume no flags.
        if (!CommandLine.isInitialized()) {
            CommandLine.init(null);
        }
        try {
            // The decoder service relies on PathUtils.
            ThreadUtils.runOnUiThreadBlocking(() -> {
                PathUtils.setPrivateDataDirectorySuffix(
                        ChromeBrowserInitializer.PRIVATE_DATA_DIRECTORY_SUFFIX);
            });

            LibraryLoader.get(LibraryProcessType.PROCESS_CHILD).ensureInitialized();
            nativeInitializePhotoPickerSandbox();

            mNativeLibraryAndSandboxInitialized = true;
        } catch (ProcessInitException e) {
            Log.e(TAG, "Unable to initialize the native library and sandbox", e);
        }

        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private final IDecoderService.Stub mBinder = new IDecoderService.Stub() {
        @Override
        public void decodeImage(Bundle payload, IDecoderServiceCallback callback) {
            Bundle bundle = null;
            String filePath = "";
            int size = 0;
            try {
                filePath = payload.getString(KEY_FILE_PATH);
                ParcelFileDescriptor pfd = payload.getParcelable(KEY_FILE_DESCRIPTOR);
                size = payload.getInt(KEY_SIZE);

                // Setup a minimum viable response to parent process. Will be fleshed out
                // further below.
                bundle = new Bundle();
                bundle.putString(KEY_FILE_PATH, filePath);
                bundle.putBoolean(KEY_SUCCESS, false);

                if (!mNativeLibraryAndSandboxInitialized) {
                    Log.e(TAG, "Decode failed %s (size: %d): no sandbox", filePath, size);
                    sendReply(callback, bundle); // Sends SUCCESS == false;
                    return;
                }

                FileDescriptor fd = pfd.getFileDescriptor();

                long begin = SystemClock.elapsedRealtime();
                Bitmap bitmap = BitmapUtils.decodeBitmapFromFileDescriptor(fd, size);
                long decodeTime = SystemClock.elapsedRealtime() - begin;

                try {
                    pfd.close();
                } catch (IOException e) {
                    Log.e(TAG, "Closing failed " + filePath + " (size: " + size + ") " + e);
                }

                if (bitmap == null) {
                    Log.e(TAG, "Decode failed " + filePath + " (size: " + size + ")");
                    sendReply(callback, bundle); // Sends SUCCESS == false;
                    return;
                }

                // The most widely supported, easiest, and reasonably efficient method is to
                // decode to an immutable bitmap and just return the bitmap over binder. It
                // will internally memcpy itself to ashmem and then just send over the file
                // descriptor. In the receiving process it will just leave the bitmap on
                // ashmem since it's immutable and carry on.
                bundle.putParcelable(KEY_IMAGE_BITMAP, bitmap);
                bundle.putBoolean(KEY_SUCCESS, true);
                bundle.putLong(KEY_DECODE_TIME, decodeTime);
                sendReply(callback, bundle);
                bitmap.recycle();
            } catch (Exception e) {
                // This service has no UI and maintains no state so if it crashes on
                // decoding a photo, it is better UX to eat the exception instead of showing
                // a crash dialog and discarding other requests that have already been sent.
                Log.e(TAG,
                        "Unexpected error during decoding " + filePath + " (size: " + size + ") "
                                + e);

                if (bundle != null) sendReply(callback, bundle);
            }
        }

        private void sendReply(IDecoderServiceCallback callback, Bundle bundle) {
            try {
                callback.onDecodeImageDone(bundle);
            } catch (RemoteException remoteException) {
                Log.e(TAG, "Remote error while replying: " + remoteException);
            }
        }
    };

    // Initializes the seccomp-bpf sandbox when it's supported by the device. Records the sandbox
    // status to the Android.SeccompStatus.PhotoPickerSandbox histogram.
    private static native void nativeInitializePhotoPickerSandbox();
}
