/*
|
* Copyright (C) 2017 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.oemlock;
|
|
import android.annotation.Nullable;
|
import android.content.Context;
|
import android.os.UserHandle;
|
import android.os.UserManager;
|
import android.service.persistentdata.PersistentDataBlockManager;
|
import android.util.Slog;
|
|
/**
|
* Implementation of the OEM lock using the persistent data block to communicate with the
|
* bootloader.
|
*
|
* The carrier flag is stored as a user restriction on the system user. The user flag is set in the
|
* presistent data block but depends on the carrier flag.
|
*/
|
class PersistentDataBlockLock extends OemLock {
|
private static final String TAG = "OemLock";
|
|
private Context mContext;
|
|
PersistentDataBlockLock(Context context) {
|
mContext = context;
|
}
|
|
@Override
|
@Nullable
|
String getLockName() {
|
return "";
|
}
|
|
@Override
|
void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
|
// Note: this implementation does not require a signature
|
if (signature != null) {
|
Slog.w(TAG, "Signature provided but is not being used");
|
}
|
|
// Continue using user restriction for backwards compatibility
|
UserManager.get(mContext).setUserRestriction(
|
UserManager.DISALLOW_OEM_UNLOCK, !allowed, UserHandle.SYSTEM);
|
|
if (!allowed) {
|
disallowUnlockIfNotUnlocked();
|
}
|
}
|
|
@Override
|
boolean isOemUnlockAllowedByCarrier() {
|
return !UserManager.get(mContext)
|
.hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, UserHandle.SYSTEM);
|
}
|
|
@Override
|
void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
|
// The method name is misleading as it really just means whether or not the device can be
|
// unlocked but doesn't actually do any unlocking.
|
final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
|
mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
|
if (pdbm == null) {
|
Slog.w(TAG, "PersistentDataBlock is not supported on this device");
|
return;
|
}
|
pdbm.setOemUnlockEnabled(allowedByDevice);
|
}
|
|
@Override
|
boolean isOemUnlockAllowedByDevice() {
|
final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
|
mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
|
if (pdbm == null) {
|
Slog.w(TAG, "PersistentDataBlock is not supported on this device");
|
return false;
|
}
|
return pdbm.getOemUnlockEnabled();
|
}
|
|
/**
|
* Update state to prevent the bootloader from being able to unlock the device unless the device
|
* has already been unlocked by the bootloader in which case it is too late as it would remain
|
* unlocked.
|
*/
|
private void disallowUnlockIfNotUnlocked() {
|
final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
|
mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
|
if (pdbm == null) {
|
Slog.w(TAG, "PersistentDataBlock is not supported on this device");
|
return;
|
}
|
if (pdbm.getFlashLockState() != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
|
pdbm.setOemUnlockEnabled(false);
|
}
|
}
|
}
|