1cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi/*
2cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * Copyright (C) 2017 The Android Open Source Project
3cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi *
4cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * Licensed under the Apache License, Version 2.0 (the "License");
5cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * you may not use this file except in compliance with the License.
6cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * You may obtain a copy of the License at
7cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi *
8cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi *      http://www.apache.org/licenses/LICENSE-2.0
9cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi *
10cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * Unless required by applicable law or agreed to in writing, software
11cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * distributed under the License is distributed on an "AS IS" BASIS,
12cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * See the License for the specific language governing permissions and
14cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * limitations under the License.
15cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi */
16cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
17cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishipackage android.app.usage;
18cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
19cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishiimport android.annotation.NonNull;
20cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishiimport android.annotation.Nullable;
21cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishiimport android.annotation.SystemApi;
22cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishiimport android.os.Parcel;
23cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishiimport android.os.Parcelable;
24cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
25cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishiimport com.android.internal.util.Preconditions;
26cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
27e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishiimport java.util.Objects;
28e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi
29cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi/**
30e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi * CacheQuotaHint represents a triplet of a uid, the volume UUID it is stored upon, and
31cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * its usage stats. When processed, it obtains a cache quota as defined by the system which
32cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * allows apps to understand how much cache to use.
33cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi * {@hide}
34cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi */
35cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi@SystemApi
36cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishipublic final class CacheQuotaHint implements Parcelable {
37cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public static final long QUOTA_NOT_SET = -1;
38cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    private final String mUuid;
39cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    private final int mUid;
40cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    private final UsageStats mUsageStats;
41cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    private final long mQuota;
42cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
43cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    /**
44cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi     * Create a new request.
45cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi     * @param builder A builder for this object.
46cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi     */
47cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public CacheQuotaHint(Builder builder) {
48cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        this.mUuid = builder.mUuid;
49cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        this.mUid = builder.mUid;
50cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        this.mUsageStats = builder.mUsageStats;
51cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        this.mQuota = builder.mQuota;
52cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
53cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
54cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public String getVolumeUuid() {
55cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        return mUuid;
56cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
57cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
58cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public int getUid() {
59cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        return mUid;
60cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
61cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
62cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public long getQuota() {
63cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        return mQuota;
64cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
65cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
66cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public UsageStats getUsageStats() {
67cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        return mUsageStats;
68cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
69cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
70cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    @Override
71cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public void writeToParcel(Parcel dest, int flags) {
72cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        dest.writeString(mUuid);
73cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        dest.writeInt(mUid);
74cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        dest.writeLong(mQuota);
75cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        dest.writeParcelable(mUsageStats, 0);
76cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
77cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
78cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    @Override
79cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public int describeContents() {
80cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        return 0;
81cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
82cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
83e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi    @Override
84e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi    public boolean equals(Object o) {
85e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi        if (o instanceof CacheQuotaHint) {
86e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi            final CacheQuotaHint other = (CacheQuotaHint) o;
87e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi            return Objects.equals(mUuid, other.mUuid)
88e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi                    && Objects.equals(mUsageStats, other.mUsageStats)
89e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi                    && mUid == other.mUid && mQuota == other.mQuota;
90e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi        }
91e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi
92e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi        return false;
93e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi    }
94e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi
95e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi    @Override
96e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi    public int hashCode() {
97e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi        return Objects.hash(this.mUuid, this.mUid, this.mUsageStats, this.mQuota);
98e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi    }
99e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi
100cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public static final class Builder {
101cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        private String mUuid;
102cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        private int mUid;
103cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        private UsageStats mUsageStats;
104cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        private long mQuota;
105cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
106cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public Builder() {
107cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
108cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
109cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public Builder(CacheQuotaHint hint) {
110cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            setVolumeUuid(hint.getVolumeUuid());
111cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            setUid(hint.getUid());
112cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            setUsageStats(hint.getUsageStats());
113cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            setQuota(hint.getQuota());
114cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
115cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
116cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public @NonNull Builder setVolumeUuid(@Nullable String uuid) {
117cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            mUuid = uuid;
118cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            return this;
119cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
120cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
121cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public @NonNull Builder setUid(int uid) {
122e40da3c1b7d4eb810b6f067075dbbb011d02a379Daniel Nishi            Preconditions.checkArgumentNonnegative(uid, "Proposed uid was negative.");
123cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            mUid = uid;
124cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            return this;
125cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
126cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
127cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public @NonNull Builder setUsageStats(@Nullable UsageStats stats) {
128cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            mUsageStats = stats;
129cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            return this;
130cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
131cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
132cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public @NonNull Builder setQuota(long quota) {
133cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            Preconditions.checkArgument((quota >= QUOTA_NOT_SET));
134cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            mQuota = quota;
135cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            return this;
136cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
137cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
138cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        public @NonNull CacheQuotaHint build() {
139cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            return new CacheQuotaHint(this);
140cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi        }
141cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    }
142cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
143cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi    public static final Parcelable.Creator<CacheQuotaHint> CREATOR =
144cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            new Creator<CacheQuotaHint>() {
145cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                @Override
146cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                public CacheQuotaHint createFromParcel(Parcel in) {
147cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                    final Builder builder = new Builder();
148cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                    return builder.setVolumeUuid(in.readString())
149cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                            .setUid(in.readInt())
150cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                            .setQuota(in.readLong())
151cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                            .setUsageStats(in.readParcelable(UsageStats.class.getClassLoader()))
152cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                            .build();
153cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                }
154cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi
155cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                @Override
156cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                public CacheQuotaHint[] newArray(int size) {
157cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                    return new CacheQuotaHint[size];
158cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi                }
159cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi            };
160cf9d19e030830fd808d59f1c97edf65e66f675d6Daniel Nishi}
161