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.service.persistentdata;
18 
19 import android.annotation.IntDef;
20 import android.annotation.RequiresPermission;
21 import android.annotation.SuppressLint;
22 import android.annotation.SystemApi;
23 import android.annotation.SystemService;
24 import android.content.Context;
25 import android.os.RemoteException;
26 import android.service.oemlock.OemLockManager;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 
31 /**
32  * Interface for reading and writing data blocks to a persistent partition.
33  *
34  * Allows writing one block at a time. Namely, each time
35  * {@link PersistentDataBlockManager#write(byte[])}
36  * is called, it will overwite the data that was previously written on the block.
37  *
38  * Clients can query the size of the currently written block via
39  * {@link PersistentDataBlockManager#getDataBlockSize()}.
40  *
41  * Clients can query the maximum size for a block via
42  * {@link PersistentDataBlockManager#getMaximumDataBlockSize()}
43  *
44  * Clients can read the currently written block by invoking
45  * {@link PersistentDataBlockManager#read()}.
46  *
47  * @hide
48  */
49 @SystemApi
50 @SystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE)
51 public class PersistentDataBlockManager {
52     private static final String TAG = PersistentDataBlockManager.class.getSimpleName();
53     private IPersistentDataBlockService sService;
54 
55     /**
56      * Indicates that the device's bootloader lock state is UNKNOWN.
57      */
58     public static final int FLASH_LOCK_UNKNOWN = -1;
59     /**
60      * Indicates that the device's bootloader is UNLOCKED.
61      */
62     public static final int FLASH_LOCK_UNLOCKED = 0;
63     /**
64      * Indicates that the device's bootloader is LOCKED.
65      */
66     public static final int FLASH_LOCK_LOCKED = 1;
67 
68     @IntDef(prefix = { "FLASH_LOCK_" }, value = {
69             FLASH_LOCK_UNKNOWN,
70             FLASH_LOCK_LOCKED,
71             FLASH_LOCK_UNLOCKED,
72     })
73     @Retention(RetentionPolicy.SOURCE)
74     public @interface FlashLockState {}
75 
76     /** @hide */
PersistentDataBlockManager(IPersistentDataBlockService service)77     public PersistentDataBlockManager(IPersistentDataBlockService service) {
78         sService = service;
79     }
80 
81     /**
82      * Writes {@code data} to the persistent partition. Previously written data
83      * will be overwritten. This data will persist across factory resets.
84      *
85      * Returns the number of bytes written or -1 on error. If the block is too big
86      * to fit on the partition, returns -MAX_BLOCK_SIZE.
87      *
88      * {@link #wipe} will block any further {@link #write} operation until reboot,
89      * in which case -1 will be returned.
90      *
91      * @param data the data to write
92      */
93     @SuppressLint("Doclava125")
write(byte[] data)94     public int write(byte[] data) {
95         try {
96             return sService.write(data);
97         } catch (RemoteException e) {
98             throw e.rethrowFromSystemServer();
99         }
100     }
101 
102     /**
103      * Returns the data block stored on the persistent partition.
104      */
105     @SuppressLint("Doclava125")
read()106     public byte[] read() {
107         try {
108             return sService.read();
109         } catch (RemoteException e) {
110             throw e.rethrowFromSystemServer();
111         }
112     }
113 
114     /**
115      * Retrieves the size of the block currently written to the persistent partition.
116      *
117      * Return -1 on error.
118      */
119     @RequiresPermission(android.Manifest.permission.ACCESS_PDB_STATE)
getDataBlockSize()120     public int getDataBlockSize() {
121         try {
122             return sService.getDataBlockSize();
123         } catch (RemoteException e) {
124             throw e.rethrowFromSystemServer();
125         }
126     }
127 
128     /**
129      * Retrieves the maximum size allowed for a data block.
130      *
131      * Returns -1 on error.
132      */
133     @SuppressLint("Doclava125")
getMaximumDataBlockSize()134     public long getMaximumDataBlockSize() {
135         try {
136             return sService.getMaximumDataBlockSize();
137         } catch (RemoteException e) {
138             throw e.rethrowFromSystemServer();
139         }
140     }
141 
142     /**
143      * Zeroes the previously written block in its entirety. Calling this method
144      * will erase all data written to the persistent data partition.
145      * It will also prevent any further {@link #write} operation until reboot,
146      * in order to prevent a potential race condition. See b/30352311.
147      */
148     @RequiresPermission(android.Manifest.permission.OEM_UNLOCK_STATE)
wipe()149     public void wipe() {
150         try {
151             sService.wipe();
152         } catch (RemoteException e) {
153             throw e.rethrowFromSystemServer();
154         }
155     }
156 
157     /**
158      * Writes a byte enabling or disabling the ability to "OEM unlock" the device.
159      *
160      * @deprecated use {@link OemLockManager#setOemUnlockAllowedByUser(boolean)} instead.
161      */
162     @RequiresPermission(android.Manifest.permission.OEM_UNLOCK_STATE)
setOemUnlockEnabled(boolean enabled)163     public void setOemUnlockEnabled(boolean enabled) {
164         try {
165             sService.setOemUnlockEnabled(enabled);
166         } catch (RemoteException e) {
167             throw e.rethrowFromSystemServer();
168         }
169     }
170 
171     /**
172      * Returns whether or not "OEM unlock" is enabled or disabled on this device.
173      *
174      * @deprecated use {@link OemLockManager#isOemUnlockAllowedByUser()} instead.
175      */
176     @RequiresPermission(anyOf = {
177             android.Manifest.permission.READ_OEM_UNLOCK_STATE,
178             android.Manifest.permission.OEM_UNLOCK_STATE
179     })
getOemUnlockEnabled()180     public boolean getOemUnlockEnabled() {
181         try {
182             return sService.getOemUnlockEnabled();
183         } catch (RemoteException e) {
184             throw e.rethrowFromSystemServer();
185         }
186     }
187 
188     /**
189      * Retrieves available information about this device's flash lock state.
190      *
191      * @return {@link #FLASH_LOCK_LOCKED} if device bootloader is locked,
192      * {@link #FLASH_LOCK_UNLOCKED} if device bootloader is unlocked, or {@link #FLASH_LOCK_UNKNOWN}
193      * if this information cannot be ascertained on this device.
194      */
195     @RequiresPermission(anyOf = {
196             android.Manifest.permission.READ_OEM_UNLOCK_STATE,
197             android.Manifest.permission.OEM_UNLOCK_STATE
198     })
199     @FlashLockState
getFlashLockState()200     public int getFlashLockState() {
201         try {
202             return sService.getFlashLockState();
203         } catch (RemoteException e) {
204             throw e.rethrowFromSystemServer();
205         }
206     }
207 }
208