/*
 * Copyright (C) 2012 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 android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.IUpdateLock;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.TokenWatcher;
import android.os.UpdateLock;
import android.util.Slog;

import java.io.FileDescriptor;
import java.io.PrintWriter;

public class UpdateLockService extends IUpdateLock.Stub {
    static final boolean DEBUG = false;
    static final String TAG = "UpdateLockService";

    // signatureOrSystem required to use update locks
    static final String PERMISSION = "android.permission.UPDATE_LOCK";

    Context mContext;
    LockWatcher mLocks;

    class LockWatcher extends TokenWatcher {
        LockWatcher(Handler h, String tag) {
            super(h, tag);
        }

        public void acquired() {
            if (DEBUG) {
                Slog.d(TAG, "first acquire; broadcasting convenient=false");
            }
            sendLockChangedBroadcast(false);
        }
        public void released() {
            if (DEBUG) {
                Slog.d(TAG, "last release; broadcasting convenient=true");
            }
            sendLockChangedBroadcast(true);
        }
    }

    UpdateLockService(Context context) {
        mContext = context;
        mLocks = new LockWatcher(new Handler(), "UpdateLocks");

        // Consider just-booting to be a reasonable time to allow
        // interruptions for update installation etc.
        sendLockChangedBroadcast(true);
    }

    void sendLockChangedBroadcast(boolean state) {
        // Safe early during boot because this broadcast only goes to registered receivers.
        long oldIdent = Binder.clearCallingIdentity();
        try {
            Intent intent = new Intent(UpdateLock.UPDATE_LOCK_CHANGED)
                    .putExtra(UpdateLock.NOW_IS_CONVENIENT, state)
                    .putExtra(UpdateLock.TIMESTAMP, System.currentTimeMillis())
                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
            mContext.sendStickyBroadcast(intent);
        } finally {
            Binder.restoreCallingIdentity(oldIdent);
        }
    }

    @Override
    public void acquireUpdateLock(IBinder token, String tag) throws RemoteException {
        if (DEBUG) {
            Slog.d(TAG, "acquire(" + token + ") by " + makeTag(tag));
        }

        mContext.enforceCallingOrSelfPermission(PERMISSION, "acquireUpdateLock");
        mLocks.acquire(token, makeTag(tag));
    }

    @Override
    public void releaseUpdateLock(IBinder token) throws RemoteException {
        if (DEBUG) {
            Slog.d(TAG, "release(" + token + ')');
        }

        mContext.enforceCallingOrSelfPermission(PERMISSION, "releaseUpdateLock");
        mLocks.release(token);
    };

    private String makeTag(String tag) {
        return "{tag=" + tag
                + " uid=" + Binder.getCallingUid()
                + " pid=" + Binder.getCallingPid() + '}';
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump update lock service from from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
        }

        mLocks.dump(pw);
    }
}
