/*
 * Copyright (C) 2014 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;

import java.util.Calendar;

import android.app.ActivityManagerNative;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.util.Slog;

public class MountServiceIdler extends JobService {
    private static final String TAG = "MountServiceIdler";

    private static ComponentName sIdleService =
            new ComponentName("android", MountServiceIdler.class.getName());

    private static int MOUNT_JOB_ID = 808;

    private boolean mStarted;
    private JobParameters mJobParams;
    private Runnable mFinishCallback = new Runnable() {
        @Override
        public void run() {
            Slog.i(TAG, "Got mount service completion callback");
            synchronized (mFinishCallback) {
                if (mStarted) {
                    jobFinished(mJobParams, false);
                    mStarted = false;
                }
            }
            // ... and try again tomorrow
            scheduleIdlePass(MountServiceIdler.this);
        }
    };

    @Override
    public boolean onStartJob(JobParameters params) {
        // First have the activity manager do its idle maintenance.  (Yes this job
        // is really more than just mount, some day it should be renamed to be system
        // idleer).
        try {
            ActivityManagerNative.getDefault().performIdleMaintenance();
        } catch (RemoteException e) {
        }
        // The mount service will run an fstrim operation asynchronously
        // on a designated separate thread, so we provide it with a callback
        // that lets us cleanly end our idle timeslice.  It's safe to call
        // finishIdle() from any thread.
        mJobParams = params;
        MountService ms = MountService.sSelf;
        if (ms != null) {
            synchronized (mFinishCallback) {
                mStarted = true;
            }
            ms.runIdleMaintenance(mFinishCallback);
        }
        return ms != null;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        // Once we kick off the fstrim we aren't actually interruptible; just note
        // that we don't need to call jobFinished(), and let everything happen in
        // the callback from the mount service.
        synchronized (mFinishCallback) {
            mStarted = false;
        }
        return false;
    }

    /**
     * Schedule the idle job that will ping the mount service
     */
    public static void scheduleIdlePass(Context context) {
        JobScheduler tm = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);

        Calendar calendar = tomorrowMidnight();
        final long timeToMidnight = calendar.getTimeInMillis() - System.currentTimeMillis();

        JobInfo.Builder builder = new JobInfo.Builder(MOUNT_JOB_ID, sIdleService);
        builder.setRequiresDeviceIdle(true);
        builder.setRequiresCharging(true);
        builder.setMinimumLatency(timeToMidnight);
        tm.schedule(builder.build());
    }

    private static Calendar tomorrowMidnight() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 3);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return calendar;
    }
}
