blob: 2474b2aa91848b9726138104914dbf252612ece8 [file] [log] [blame]
/*
* 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);
}
}
}