1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net; 18 19 import android.annotation.Nullable; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.os.UserHandle; 23 import android.util.ArraySet; 24 import android.util.Range; 25 26 import java.util.Collection; 27 import java.util.Set; 28 29 /** 30 * An inclusive range of UIDs. 31 * 32 * @hide 33 */ 34 public final class UidRange implements Parcelable { 35 public final int start; 36 public final int stop; 37 UidRange(int startUid, int stopUid)38 public UidRange(int startUid, int stopUid) { 39 if (startUid < 0) throw new IllegalArgumentException("Invalid start UID."); 40 if (stopUid < 0) throw new IllegalArgumentException("Invalid stop UID."); 41 if (startUid > stopUid) throw new IllegalArgumentException("Invalid UID range."); 42 start = startUid; 43 stop = stopUid; 44 } 45 46 /** Creates a UidRange for the specified user. */ createForUser(UserHandle user)47 public static UidRange createForUser(UserHandle user) { 48 final UserHandle nextUser = UserHandle.of(user.getIdentifier() + 1); 49 final int start = user.getUid(0 /* appId */); 50 final int end = nextUser.getUid(0 /* appId */) - 1; 51 return new UidRange(start, end); 52 } 53 54 /** Returns the smallest user Id which is contained in this UidRange */ getStartUser()55 public int getStartUser() { 56 return UserHandle.getUserHandleForUid(start).getIdentifier(); 57 } 58 59 /** Returns the largest user Id which is contained in this UidRange */ getEndUser()60 public int getEndUser() { 61 return UserHandle.getUserHandleForUid(stop).getIdentifier(); 62 } 63 64 /** Returns whether the UidRange contains the specified UID. */ contains(int uid)65 public boolean contains(int uid) { 66 return start <= uid && uid <= stop; 67 } 68 69 /** 70 * Returns the count of UIDs in this range. 71 */ count()72 public int count() { 73 return 1 + stop - start; 74 } 75 76 /** 77 * @return {@code true} if this range contains every UID contained by the {@code other} range. 78 */ containsRange(UidRange other)79 public boolean containsRange(UidRange other) { 80 return start <= other.start && other.stop <= stop; 81 } 82 83 @Override hashCode()84 public int hashCode() { 85 int result = 17; 86 result = 31 * result + start; 87 result = 31 * result + stop; 88 return result; 89 } 90 91 @Override equals(@ullable Object o)92 public boolean equals(@Nullable Object o) { 93 if (this == o) { 94 return true; 95 } 96 if (o instanceof UidRange) { 97 UidRange other = (UidRange) o; 98 return start == other.start && stop == other.stop; 99 } 100 return false; 101 } 102 103 @Override toString()104 public String toString() { 105 return start + "-" + stop; 106 } 107 108 // Implement the Parcelable interface 109 // TODO: Consider making this class no longer parcelable, since all users are likely in the 110 // system server. 111 @Override describeContents()112 public int describeContents() { 113 return 0; 114 } 115 116 @Override writeToParcel(Parcel dest, int flags)117 public void writeToParcel(Parcel dest, int flags) { 118 dest.writeInt(start); 119 dest.writeInt(stop); 120 } 121 122 public static final @android.annotation.NonNull Creator<UidRange> CREATOR = 123 new Creator<UidRange>() { 124 @Override 125 public UidRange createFromParcel(Parcel in) { 126 int start = in.readInt(); 127 int stop = in.readInt(); 128 129 return new UidRange(start, stop); 130 } 131 @Override 132 public UidRange[] newArray(int size) { 133 return new UidRange[size]; 134 } 135 }; 136 137 /** 138 * Returns whether any of the UidRange in the collection contains the specified uid 139 * 140 * @param ranges The collection of UidRange to check 141 * @param uid the uid in question 142 * @return {@code true} if the uid is contained within the ranges, {@code false} otherwise 143 * 144 * @see UidRange#contains(int) 145 */ containsUid(Collection<UidRange> ranges, int uid)146 public static boolean containsUid(Collection<UidRange> ranges, int uid) { 147 if (ranges == null) return false; 148 for (UidRange range : ranges) { 149 if (range.contains(uid)) { 150 return true; 151 } 152 } 153 return false; 154 } 155 156 /** 157 * Convert a set of {@code Range<Integer>} to a set of {@link UidRange}. 158 */ 159 @Nullable fromIntRanges(@ullable Set<Range<Integer>> ranges)160 public static ArraySet<UidRange> fromIntRanges(@Nullable Set<Range<Integer>> ranges) { 161 if (null == ranges) return null; 162 163 final ArraySet<UidRange> uids = new ArraySet<>(); 164 for (Range<Integer> range : ranges) { 165 uids.add(new UidRange(range.getLower(), range.getUpper())); 166 } 167 return uids; 168 } 169 170 /** 171 * Convert a set of {@link UidRange} to a set of {@code Range<Integer>}. 172 */ 173 @Nullable toIntRanges(@ullable Set<UidRange> ranges)174 public static ArraySet<Range<Integer>> toIntRanges(@Nullable Set<UidRange> ranges) { 175 if (null == ranges) return null; 176 177 final ArraySet<Range<Integer>> uids = new ArraySet<>(); 178 for (UidRange range : ranges) { 179 uids.add(new Range<Integer>(range.start, range.stop)); 180 } 181 return uids; 182 } 183 } 184