/*
 * 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.TokenWatcher;
import android.os.UpdateLock;
import android.os.UserHandle;
import android.util.Slog;

import com.android.internal.util.DumpUtils;

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.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
        } 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 (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
        mLocks.dump(pw);
    }
}
