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

import android.app.GrantedUriPermission;
import android.content.Intent;
import android.os.Binder;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;

import com.google.android.collect.Sets;

import java.io.PrintWriter;
import java.util.Comparator;

/**
 * Description of a permission granted to an app to access a particular URI.
 *
 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
 *
 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
 *      src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
 */
final class UriPermission {
    private static final String TAG = "UriPermission";

    public static final int STRENGTH_NONE = 0;
    public static final int STRENGTH_OWNED = 1;
    public static final int STRENGTH_GLOBAL = 2;
    public static final int STRENGTH_PERSISTABLE = 3;

    final int targetUserId;
    final String sourcePkg;
    final String targetPkg;

    /** Cached UID of {@link #targetPkg}; should not be persisted */
    final int targetUid;

    final GrantUri uri;

    /**
     * Allowed modes. All permission enforcement should use this field. Must
     * always be a combination of {@link #ownedModeFlags},
     * {@link #globalModeFlags}, {@link #persistableModeFlags}, and
     * {@link #persistedModeFlags}. Mutations <em>must</em> only be performed by
     * the owning class.
     */
    int modeFlags = 0;

    /** Allowed modes with active owner. */
    int ownedModeFlags = 0;
    /** Allowed modes without explicit owner. */
    int globalModeFlags = 0;
    /** Allowed modes that have been offered for possible persisting. */
    int persistableModeFlags = 0;

    /** Allowed modes that should be persisted across device boots. */
    int persistedModeFlags = 0;

    /**
     * Timestamp when {@link #persistedModeFlags} was first defined in
     * {@link System#currentTimeMillis()} time base.
     */
    long persistedCreateTime = INVALID_TIME;

    private static final long INVALID_TIME = Long.MIN_VALUE;

    private ArraySet<UriPermissionOwner> mReadOwners;
    private ArraySet<UriPermissionOwner> mWriteOwners;

    private String stringName;

    UriPermission(String sourcePkg, String targetPkg, int targetUid, GrantUri uri) {
        this.targetUserId = UserHandle.getUserId(targetUid);
        this.sourcePkg = sourcePkg;
        this.targetPkg = targetPkg;
        this.targetUid = targetUid;
        this.uri = uri;
    }

    private void updateModeFlags() {
        final int oldModeFlags = modeFlags;
        modeFlags = ownedModeFlags | globalModeFlags | persistableModeFlags | persistedModeFlags;

        if (Log.isLoggable(TAG, Log.VERBOSE) && (modeFlags != oldModeFlags)) {
            Slog.d(TAG,
                    "Permission for " + targetPkg + " to " + uri + " is changing from 0x"
                            + Integer.toHexString(oldModeFlags) + " to 0x"
                            + Integer.toHexString(modeFlags) + " via calling UID "
                            + Binder.getCallingUid() + " PID " + Binder.getCallingPid(),
                    new Throwable());
        }
    }

    /**
     * Initialize persisted modes as read from file. This doesn't issue any
     * global or owner grants.
     */
    void initPersistedModes(int modeFlags, long createdTime) {
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        persistableModeFlags = modeFlags;
        persistedModeFlags = modeFlags;
        persistedCreateTime = createdTime;

        updateModeFlags();
    }

    void grantModes(int modeFlags, UriPermissionOwner owner) {
        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        if (persistable) {
            persistableModeFlags |= modeFlags;
        }

        if (owner == null) {
            globalModeFlags |= modeFlags;
        } else {
            if ((modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
                addReadOwner(owner);
            }
            if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
                addWriteOwner(owner);
            }
        }

        updateModeFlags();
    }

    /**
     * @return if mode changes should trigger persisting.
     */
    boolean takePersistableModes(int modeFlags) {
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        if ((modeFlags & persistableModeFlags) != modeFlags) {
            Slog.w(TAG, "Requested flags 0x"
                    + Integer.toHexString(modeFlags) + ", but only 0x"
                    + Integer.toHexString(persistableModeFlags) + " are allowed");
            return false;
        }

        final int before = persistedModeFlags;
        persistedModeFlags |= (persistableModeFlags & modeFlags);

        if (persistedModeFlags != 0) {
            persistedCreateTime = System.currentTimeMillis();
        }

        updateModeFlags();
        return persistedModeFlags != before;
    }

    boolean releasePersistableModes(int modeFlags) {
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        final int before = persistedModeFlags;

        persistableModeFlags &= ~modeFlags;
        persistedModeFlags &= ~modeFlags;

        if (persistedModeFlags == 0) {
            persistedCreateTime = INVALID_TIME;
        }

        updateModeFlags();
        return persistedModeFlags != before;
    }

    /**
     * @return if mode changes should trigger persisting.
     */
    boolean revokeModes(int modeFlags, boolean includingOwners) {
        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        final int before = persistedModeFlags;

        if ((modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
            if (persistable) {
                persistableModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
                persistedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
            }
            globalModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
            if (mReadOwners != null && includingOwners) {
                ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
                for (UriPermissionOwner r : mReadOwners) {
                    r.removeReadPermission(this);
                }
                mReadOwners = null;
            }
        }
        if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
            if (persistable) {
                persistableModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
                persistedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
            }
            globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
            if (mWriteOwners != null && includingOwners) {
                ownedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
                for (UriPermissionOwner r : mWriteOwners) {
                    r.removeWritePermission(this);
                }
                mWriteOwners = null;
            }
        }

        if (persistedModeFlags == 0) {
            persistedCreateTime = INVALID_TIME;
        }

        updateModeFlags();
        return persistedModeFlags != before;
    }

    /**
     * Return strength of this permission grant for the given flags.
     */
    public int getStrength(int modeFlags) {
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        if ((persistableModeFlags & modeFlags) == modeFlags) {
            return STRENGTH_PERSISTABLE;
        } else if ((globalModeFlags & modeFlags) == modeFlags) {
            return STRENGTH_GLOBAL;
        } else if ((ownedModeFlags & modeFlags) == modeFlags) {
            return STRENGTH_OWNED;
        } else {
            return STRENGTH_NONE;
        }
    }

    private void addReadOwner(UriPermissionOwner owner) {
        if (mReadOwners == null) {
            mReadOwners = Sets.newArraySet();
            ownedModeFlags |= Intent.FLAG_GRANT_READ_URI_PERMISSION;
            updateModeFlags();
        }
        if (mReadOwners.add(owner)) {
            owner.addReadPermission(this);
        }
    }

    /**
     * Remove given read owner, updating {@Link #modeFlags} as needed.
     */
    void removeReadOwner(UriPermissionOwner owner) {
        if (!mReadOwners.remove(owner)) {
            Slog.wtf(TAG, "Unknown read owner " + owner + " in " + this);
        }
        if (mReadOwners.size() == 0) {
            mReadOwners = null;
            ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
            updateModeFlags();
        }
    }

    private void addWriteOwner(UriPermissionOwner owner) {
        if (mWriteOwners == null) {
            mWriteOwners = Sets.newArraySet();
            ownedModeFlags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
            updateModeFlags();
        }
        if (mWriteOwners.add(owner)) {
            owner.addWritePermission(this);
        }
    }

    /**
     * Remove given write owner, updating {@Link #modeFlags} as needed.
     */
    void removeWriteOwner(UriPermissionOwner owner) {
        if (!mWriteOwners.remove(owner)) {
            Slog.wtf(TAG, "Unknown write owner " + owner + " in " + this);
        }
        if (mWriteOwners.size() == 0) {
            mWriteOwners = null;
            ownedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
            updateModeFlags();
        }
    }

    @Override
    public String toString() {
        if (stringName != null) {
            return stringName;
        }
        StringBuilder sb = new StringBuilder(128);
        sb.append("UriPermission{");
        sb.append(Integer.toHexString(System.identityHashCode(this)));
        sb.append(' ');
        sb.append(uri);
        sb.append('}');
        return stringName = sb.toString();
    }

    void dump(PrintWriter pw, String prefix) {
        pw.print(prefix);
        pw.print("targetUserId=" + targetUserId);
        pw.print(" sourcePkg=" + sourcePkg);
        pw.println(" targetPkg=" + targetPkg);

        pw.print(prefix);
        pw.print("mode=0x" + Integer.toHexString(modeFlags));
        pw.print(" owned=0x" + Integer.toHexString(ownedModeFlags));
        pw.print(" global=0x" + Integer.toHexString(globalModeFlags));
        pw.print(" persistable=0x" + Integer.toHexString(persistableModeFlags));
        pw.print(" persisted=0x" + Integer.toHexString(persistedModeFlags));
        if (persistedCreateTime != INVALID_TIME) {
            pw.print(" persistedCreate=" + persistedCreateTime);
        }
        pw.println();

        if (mReadOwners != null) {
            pw.print(prefix);
            pw.println("readOwners:");
            for (UriPermissionOwner owner : mReadOwners) {
                pw.print(prefix);
                pw.println("  * " + owner);
            }
        }
        if (mWriteOwners != null) {
            pw.print(prefix);
            pw.println("writeOwners:");
            for (UriPermissionOwner owner : mReadOwners) {
                pw.print(prefix);
                pw.println("  * " + owner);
            }
        }
    }

    public static class PersistedTimeComparator implements Comparator<UriPermission> {
        @Override
        public int compare(UriPermission lhs, UriPermission rhs) {
            return Long.compare(lhs.persistedCreateTime, rhs.persistedCreateTime);
        }
    }

    /**
     * Snapshot of {@link UriPermission} with frozen
     * {@link UriPermission#persistedModeFlags} state.
     */
    public static class Snapshot {
        final int targetUserId;
        final String sourcePkg;
        final String targetPkg;
        final GrantUri uri;
        final int persistedModeFlags;
        final long persistedCreateTime;

        private Snapshot(UriPermission perm) {
            this.targetUserId = perm.targetUserId;
            this.sourcePkg = perm.sourcePkg;
            this.targetPkg = perm.targetPkg;
            this.uri = perm.uri;
            this.persistedModeFlags = perm.persistedModeFlags;
            this.persistedCreateTime = perm.persistedCreateTime;
        }
    }

    public Snapshot snapshot() {
        return new Snapshot(this);
    }

    public android.content.UriPermission buildPersistedPublicApiObject() {
        return new android.content.UriPermission(uri.uri, persistedModeFlags, persistedCreateTime);
    }

    public GrantedUriPermission buildGrantedUriPermission() {
        return new GrantedUriPermission(uri.uri, targetPkg);
    }
}
