ADD: Utility class UserHandles.

This commit is contained in:
Oasis 2018-09-06 17:10:34 +08:00
parent 6927694377
commit 478ebe89db
2 changed files with 102 additions and 0 deletions

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2016 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.oasisfeng.android.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;
/**
* Denotes that the annotated element is a multi-user user ID. This is
* <em>not</em> the same as a UID.
*/
@Retention(SOURCE)
@Target({METHOD, PARAMETER, FIELD})
public @interface UserIdInt {
}

View File

@ -0,0 +1,68 @@
package com.oasisfeng.android.os;
import android.os.Parcel;
import android.os.UserHandle;
import android.util.Pair;
import com.oasisfeng.android.annotation.UserIdInt;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.N;
/**
* Created by Oasis on 2018-9-6.
*/
public class UserHandles {
private static Pair<Integer, UserHandle> sCache = null; // Must before SYSTEM
/**
* Enable multi-user related side effects. Set this to false if
* there are problems with single user use-cases.
*/
private static final boolean MU_ENABLED = true;
/**
* Range of uids allocated for a user.
*/
public static final int PER_USER_RANGE = 100000;
/** A user id constant to indicate the "system" user of the device */
public static final @UserIdInt int USER_SYSTEM = 0;
/** A user handle to indicate the "system" user of the device */
public static final UserHandle SYSTEM = of(USER_SYSTEM);
public static UserHandle getUserHandleForUid(final int uid) {
return SDK_INT >= N ? UserHandle.getUserHandleForUid(uid) : of(getUserId(uid));
}
public static UserHandle of(final @UserIdInt int userId) {
if (userId == USER_SYSTEM) return SYSTEM;
final Pair<Integer, UserHandle> cache = sCache;
if (cache != null && cache.first == userId) return cache.second;
final Parcel parcel = Parcel.obtain();
try {
final int begin = parcel.dataPosition();
parcel.writeInt(userId);
parcel.setDataPosition(begin);
final UserHandle user = UserHandle.CREATOR.createFromParcel(parcel);
sCache = new Pair<>(userId, user);
return user;
} finally {
parcel.recycle();
}
}
/**
* Returns the user id for a given uid.
*/
public static @UserIdInt int getUserId(final int uid) {
if (MU_ENABLED) {
return uid / PER_USER_RANGE;
} else {
return USER_SYSTEM;
}
}
}