/*
 * Copyright (C) 2017 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.autofill;

import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;

import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.ICancellationSignal;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.service.autofill.AutofillService;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
import android.service.autofill.IFillCallback;
import android.service.autofill.ISaveCallback;
import android.service.autofill.SaveRequest;
import android.text.format.DateUtils;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.HandlerCaller;
import com.android.server.FgThread;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;

/**
 * This class represents a remote fill service. It abstracts away the binding
 * and unbinding from the remote implementation.
 *
 * <p>Clients can call methods of this class without worrying about when and
 * how to bind/unbind/timeout. All state of this class is modified on a handler
 * thread.
 */
final class RemoteFillService implements DeathRecipient {
    private static final String LOG_TAG = "RemoteFillService";

    // How long after the last interaction with the service we would unbind
    private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;

    // How long after we make a remote request to a fill service we timeout
    private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;

    private final Context mContext;

    private final ComponentName mComponentName;

    private final Intent mIntent;

    private final FillServiceCallbacks mCallbacks;

    private final int mUserId;

    private final ServiceConnection mServiceConnection = new RemoteServiceConnection();

    private final HandlerCaller mHandler;

    private IAutoFillService mAutoFillService;

    private boolean mBinding;

    private boolean mDestroyed;

    private boolean mServiceDied;

    private boolean mCompleted;

    private PendingRequest mPendingRequest;

    public interface FillServiceCallbacks {
        void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, int serviceUid,
                @NonNull String servicePackageName);
        void onFillRequestFailure(@Nullable CharSequence message,
                @NonNull String servicePackageName);
        void onSaveRequestSuccess(@NonNull String servicePackageName);
        void onSaveRequestFailure(@Nullable CharSequence message,
                @NonNull String servicePackageName);
        void onServiceDied(RemoteFillService service);
    }

    public RemoteFillService(Context context, ComponentName componentName,
            int userId, FillServiceCallbacks callbacks) {
        mContext = context;
        mCallbacks = callbacks;
        mComponentName = componentName;
        mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName);
        mUserId = userId;
        mHandler = new MyHandler(context);
    }

    public void destroy() {
        mHandler.obtainMessage(MyHandler.MSG_DESTROY).sendToTarget();
    }

    private void handleDestroy() {
        if (mPendingRequest != null) {
            mPendingRequest.cancel();
            mPendingRequest = null;
        }
        ensureUnbound();
        mDestroyed = true;
    }

    @Override
    public void binderDied() {
        mHandler.obtainMessage(MyHandler.MSG_BINDER_DIED).sendToTarget();
    }

    private void handleBinderDied() {
        if (mAutoFillService != null) {
            mAutoFillService.asBinder().unlinkToDeath(this, 0);
        }
        mAutoFillService = null;
        mServiceDied = true;
        mCallbacks.onServiceDied(this);
    }

    /**
     * Cancel the currently pending request.
     *
     * <p>This can be used when the request is unnecessary or will be superceeded by a request that
     * will soon be queued.
     *
     * @return the id of the canceled request, or {@link FillRequest#INVALID_REQUEST_ID} if no
     *         {@link PendingFillRequest} was canceled.
     */
    public int cancelCurrentRequest() {
        if (mDestroyed) {
            return INVALID_REQUEST_ID;
        }

        int requestId = INVALID_REQUEST_ID;
        if (mPendingRequest != null) {
            if (mPendingRequest instanceof PendingFillRequest) {
                requestId = ((PendingFillRequest) mPendingRequest).mRequest.getId();
            }

            mPendingRequest.cancel();
            mPendingRequest = null;
        }

        return requestId;
    }

    public void onFillRequest(@NonNull FillRequest request) {
        cancelScheduledUnbind();
        final PendingFillRequest pendingRequest = new PendingFillRequest(request, this);
        mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, pendingRequest).sendToTarget();
    }

    public void onSaveRequest(@NonNull SaveRequest request) {
        cancelScheduledUnbind();
        final PendingSaveRequest pendingRequest = new PendingSaveRequest(request, this);
        mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, pendingRequest).sendToTarget();
    }

    // Note: we are dumping without a lock held so this is a bit racy but
    // adding a lock to a class that offloads to a handler thread would
    // mean adding a lock adding overhead to normal runtime operation.
    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
        String tab = "  ";
        pw.append(prefix).append("service:").println();
        pw.append(prefix).append(tab).append("userId=")
                .append(String.valueOf(mUserId)).println();
        pw.append(prefix).append(tab).append("componentName=")
                .append(mComponentName.flattenToString()).println();
        pw.append(prefix).append(tab).append("destroyed=")
                .append(String.valueOf(mDestroyed)).println();
        pw.append(prefix).append(tab).append("bound=")
                .append(String.valueOf(isBound())).println();
        pw.append(prefix).append(tab).append("hasPendingRequest=")
                .append(String.valueOf(mPendingRequest != null)).println();
        pw.println();
    }

    private void cancelScheduledUnbind() {
        mHandler.removeMessages(MyHandler.MSG_UNBIND);
    }

    private void scheduleUnbind() {
        cancelScheduledUnbind();
        Message message = mHandler.obtainMessage(MyHandler.MSG_UNBIND);
        mHandler.sendMessageDelayed(message, TIMEOUT_IDLE_BIND_MILLIS);
    }

    private void handleUnbind() {
        ensureUnbound();
    }

    private void handlePendingRequest(PendingRequest pendingRequest) {
        if (mDestroyed || mCompleted) {
            return;
        }
        if (!isBound()) {
            if (mPendingRequest != null) {
                mPendingRequest.cancel();
            }
            mPendingRequest = pendingRequest;
            ensureBound();
        } else {
            if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] handlePendingRequest()");
            pendingRequest.run();
            if (pendingRequest.isFinal()) {
                mCompleted = true;
            }
        }
    }

    private boolean isBound() {
        return mAutoFillService != null;
    }

    private void ensureBound() {
        if (isBound() || mBinding) {
            return;
        }
        if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
        mBinding = true;

        boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection,
                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
                new UserHandle(mUserId));

        if (!willBind) {
            if (sDebug) Slog.d(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent);
            mBinding = false;

            if (!mServiceDied) {
                handleBinderDied();
            }
        }
    }

    private void ensureUnbound() {
        if (!isBound() && !mBinding) {
            return;
        }
        if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureUnbound()");
        mBinding = false;
        if (isBound()) {
            try {
                mAutoFillService.onConnectedStateChanged(false);
            } catch (Exception e) {
                Slog.w(LOG_TAG, "Exception calling onDisconnected(): " + e);
            }
            if (mAutoFillService != null) {
                mAutoFillService.asBinder().unlinkToDeath(this, 0);
                mAutoFillService = null;
            }
        }
        mContext.unbindService(mServiceConnection);
    }

    private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
            int callingUid, int requestFlags, FillResponse response) {
        mHandler.getHandler().post(() -> {
            if (handleResponseCallbackCommon(pendingRequest)) {
                mCallbacks.onFillRequestSuccess(requestFlags, response, callingUid,
                        mComponentName.getPackageName());
            }
        });
    }

    private void dispatchOnFillRequestFailure(PendingRequest pendingRequest,
            CharSequence message) {
        mHandler.getHandler().post(() -> {
            if (handleResponseCallbackCommon(pendingRequest)) {
                mCallbacks.onFillRequestFailure(message, mComponentName.getPackageName());
            }
        });
    }

    private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest) {
        mHandler.getHandler().post(() -> {
            if (handleResponseCallbackCommon(pendingRequest)) {
                mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName());
            }
        });
    }

    private void dispatchOnSaveRequestFailure(PendingRequest pendingRequest,
            CharSequence message) {
        mHandler.getHandler().post(() -> {
            if (handleResponseCallbackCommon(pendingRequest)) {
                mCallbacks.onSaveRequestFailure(message, mComponentName.getPackageName());
            }
        });
    }

    private boolean handleResponseCallbackCommon(PendingRequest pendingRequest) {
        if (mDestroyed) {
            return false;
        }
        if (mPendingRequest == pendingRequest) {
            mPendingRequest = null;
        }
        if (mPendingRequest == null) {
            scheduleUnbind();
        }
        return true;
    }

    private class RemoteServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (mDestroyed || !mBinding) {
                mContext.unbindService(mServiceConnection);
                return;
            }
            mBinding = false;
            mAutoFillService = IAutoFillService.Stub.asInterface(service);
            try {
                service.linkToDeath(RemoteFillService.this, 0);
            } catch (RemoteException re) {
                handleBinderDied();
                return;
            }
            try {
                mAutoFillService.onConnectedStateChanged(true);
            } catch (RemoteException e) {
                Slog.w(LOG_TAG, "Exception calling onConnected(): " + e);
            }

            if (mPendingRequest != null) {
                PendingRequest pendingRequest = mPendingRequest;
                mPendingRequest = null;
                handlePendingRequest(pendingRequest);
            }

            mServiceDied = false;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBinding = true;
            mAutoFillService = null;
        }
    }

    private final class MyHandler extends HandlerCaller {
        public static final int MSG_DESTROY = 1;
        public static final int MSG_BINDER_DIED = 2;
        public static final int MSG_UNBIND = 3;
        public static final int MSG_ON_PENDING_REQUEST = 4;

        public MyHandler(Context context) {
            // Cannot use lambda - doesn't compile
            super(context, FgThread.getHandler().getLooper(), new Callback() {
                @Override
                public void executeMessage(Message message) {
                    if (mDestroyed) {
                        Slog.w(LOG_TAG, "Not handling " + message + " as service for "
                                + mComponentName + " is already destroyed");
                        return;
                    }
                    switch (message.what) {
                        case MSG_DESTROY: {
                            handleDestroy();
                        } break;

                        case MSG_BINDER_DIED: {
                            handleBinderDied();
                        } break;

                        case MSG_UNBIND: {
                            handleUnbind();
                        } break;

                        case MSG_ON_PENDING_REQUEST: {
                            handlePendingRequest((PendingRequest) message.obj);
                        } break;
                    }
                }
            }, false);
        }
    }

    private static abstract class PendingRequest implements Runnable {
        protected final Object mLock = new Object();
        private final WeakReference<RemoteFillService> mWeakService;

        private final Runnable mTimeoutTrigger;
        private final Handler mServiceHandler;

        @GuardedBy("mLock")
        private boolean mCancelled;

        @GuardedBy("mLock")
        private boolean mCompleted;

        PendingRequest(RemoteFillService service) {
            mWeakService = new WeakReference<>(service);
            mServiceHandler = service.mHandler.getHandler();
            mTimeoutTrigger = () -> {
                synchronized (mLock) {
                    if (mCancelled) {
                        return;
                    }
                    mCompleted = true;
                }

                Slog.w(LOG_TAG, getClass().getSimpleName() + " timed out");
                final RemoteFillService remoteService = mWeakService.get();
                if (remoteService != null) {
                    fail(remoteService);
                }
            };
            mServiceHandler.postAtTime(mTimeoutTrigger,
                    SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
        }

        protected RemoteFillService getService() {
            return mWeakService.get();
        }

        /**
         * Sub-classes must call this method when the remote service finishes, i.e., when it
         * called {@code onFill...} or {@code onSave...}.
         *
         * @return {@code false} in the service is already finished, {@code true} otherwise.
         */
        protected final boolean finish() {
            synchronized (mLock) {
                if (mCompleted || mCancelled) {
                    return false;
                }
                mCompleted = true;
            }
            mServiceHandler.removeCallbacks(mTimeoutTrigger);
            return true;
        }

        protected boolean isCancelledLocked() {
            return mCancelled;
        }

        /**
         * Cancels the service.
         *
         * @return {@code false} if service is already canceled, {@code true} otherwise.
         */
        boolean cancel() {
            synchronized (mLock) {
                if (mCancelled || mCompleted) {
                    return false;
                }
                mCancelled = true;
            }

            mServiceHandler.removeCallbacks(mTimeoutTrigger);
            return true;
        }

        /**
         * Called by the self-destructure timeout when the AutofilllService didn't reply to the
         * request on time.
         */
        abstract void fail(RemoteFillService remoteService);

        /**
         * @return whether this request leads to a final state where no
         * other requests can be made.
         */
        boolean isFinal() {
            return false;
        }
    }

    private static final class PendingFillRequest extends PendingRequest {
        private final FillRequest mRequest;
        private final IFillCallback mCallback;
        private ICancellationSignal mCancellation;

        public PendingFillRequest(FillRequest request, RemoteFillService service) {
            super(service);
            mRequest = request;

            mCallback = new IFillCallback.Stub() {
                @Override
                public void onCancellable(ICancellationSignal cancellation) {
                    synchronized (mLock) {
                        final boolean cancelled;
                        synchronized (mLock) {
                            mCancellation = cancellation;
                            cancelled = isCancelledLocked();
                        }
                        if (cancelled) {
                            try {
                                cancellation.cancel();
                            } catch (RemoteException e) {
                                Slog.e(LOG_TAG, "Error requesting a cancellation", e);
                            }
                        }
                    }
                }

                @Override
                public void onSuccess(FillResponse response) {
                    if (!finish()) return;

                    final RemoteFillService remoteService = getService();
                    if (remoteService != null) {
                        remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this,
                                getCallingUid(), request.getFlags(), response);
                    }
                }

                @Override
                public void onFailure(CharSequence message) {
                    if (!finish()) return;

                    final RemoteFillService remoteService = getService();
                    if (remoteService != null) {
                        remoteService.dispatchOnFillRequestFailure(
                                PendingFillRequest.this, message);
                    }
                }
            };
        }

        @Override
        void fail(RemoteFillService remoteService) {
            remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null);
        }

        @Override
        public void run() {
            final RemoteFillService remoteService = getService();
            if (remoteService != null) {
                try {
                    remoteService.mAutoFillService.onFillRequest(mRequest, mCallback);
                } catch (RemoteException e) {
                    Slog.e(LOG_TAG, "Error calling on fill request", e);

                    remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null);
                }
            }
        }

        @Override
        public boolean cancel() {
            if (!super.cancel()) return false;

            final ICancellationSignal cancellation = mCancellation;
            if (cancellation != null) {
                try {
                    cancellation.cancel();
                } catch (RemoteException e) {
                    Slog.e(LOG_TAG, "Error cancelling a fill request", e);
                }
            }
            return true;
        }
    }

    private static final class PendingSaveRequest extends PendingRequest {
        private final SaveRequest mRequest;
        private final ISaveCallback mCallback;

        public PendingSaveRequest(@NonNull SaveRequest request,
                @NonNull RemoteFillService service) {
            super(service);
            mRequest = request;

            mCallback = new ISaveCallback.Stub() {
                @Override
                public void onSuccess() {
                    if (!finish()) return;

                    final RemoteFillService remoteService = getService();
                    if (remoteService != null) {
                        remoteService.dispatchOnSaveRequestSuccess(PendingSaveRequest.this);
                    }
                }

                @Override
                public void onFailure(CharSequence message) {
                    if (!finish()) return;

                    final RemoteFillService remoteService = getService();
                    if (remoteService != null) {
                        remoteService.dispatchOnSaveRequestFailure(PendingSaveRequest.this,
                                message);
                    }
                }
            };
        }

        @Override
        void fail(RemoteFillService remoteService) {
            remoteService.dispatchOnSaveRequestFailure(PendingSaveRequest.this, null);
        }

        @Override
        public void run() {
            final RemoteFillService remoteService = getService();
            if (remoteService != null) {
                try {
                    remoteService.mAutoFillService.onSaveRequest(mRequest, mCallback);
                } catch (RemoteException e) {
                    Slog.e(LOG_TAG, "Error calling on save request", e);

                    remoteService.dispatchOnFillRequestFailure(PendingSaveRequest.this, null);
                }
            }
        }

        @Override
        public boolean isFinal() {
            return true;
        }
    }
}
