PersistentDataBlockManager.java revision 66445a639dc134d09393f5069b7683ec36d4cd07
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 17package android.service.persistentdata; 18 19import android.annotation.SystemApi; 20import android.app.PendingIntent; 21import android.os.Bundle; 22import android.os.RemoteException; 23import android.util.Slog; 24 25/** 26 * Interface for reading and writing data blocks to a persistent partition. 27 * 28 * Allows writing one block at a time. Namely, each time 29 * {@link PersistentDataBlockManager#write(byte[])} 30 * is called, it will overwite the data that was previously written on the block. 31 * 32 * Clients can query the size of the currently written block via 33 * {@link PersistentDataBlockManager#getDataBlockSize()}. 34 * 35 * Clients can query the maximum size for a block via 36 * {@link PersistentDataBlockManager#getMaximumDataBlockSize()} 37 * 38 * Clients can read the currently written block by invoking 39 * {@link PersistentDataBlockManager#read()}. 40 * 41 * @hide 42 */ 43@SystemApi 44public class PersistentDataBlockManager { 45 private static final String TAG = PersistentDataBlockManager.class.getSimpleName(); 46 47 /** 48 * Broadcast action that will be called when the {@link #wipeIfAllowed(Bundle,PendingIntent)} 49 * method is called. A broadcast with this action will be sent to the package allowed to write 50 * to the persistent data block. Packages receiving this broadcasts should respond by using the 51 * {@link android.app.PendingIntent} sent in the {@link #EXTRA_WIPE_IF_ALLOWED_CALLBACK} extra. 52 */ 53 public static final String ACTION_WIPE_IF_ALLOWED 54 = "android.service.persistentdata.action.WIPE_IF_ALLOWED"; 55 56 /** 57 * A {@link android.os.Parcelable} extra of type {@link android.app.PendingIntent} used to 58 * response to {@link #wipeIfAllowed(Bundle,PendingIntent)}. This extra will set in broadcasts 59 * with an action of {@link #ACTION_WIPE_IF_ALLOWED}. 60 */ 61 public static final String EXTRA_WIPE_IF_ALLOWED_CALLBACK 62 = "android.service.persistentdata.extra.WIPE_IF_ALLOWED_CALLBACK"; 63 64 /** 65 * Result code indicating that the data block was wiped. 66 * 67 * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to 68 * {@link #wipeIfAllowed(Bundle,PendingIntent)} 69 */ 70 public static final int STATUS_SUCCESS = 0; 71 72 /** 73 * Result code indicating that a remote exception was received while processing the request. 74 * 75 * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to 76 * {@link #wipeIfAllowed(Bundle,PendingIntent)} 77 */ 78 public static final int STATUS_ERROR_REMOTE_EXCEPTION = 1; 79 80 /** 81 * Result code indicating that a network error occurred while processing the request. 82 * 83 * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to 84 * {@link #wipeIfAllowed(Bundle,PendingIntent)} 85 */ 86 public static final int STATUS_ERROR_NETWORK_ERROR = 2; 87 88 /** 89 * Result code indicating that the data block could not be cleared with the provided data. 90 * 91 * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to 92 * {@link #wipeIfAllowed(Bundle,PendingIntent)} 93 */ 94 public static final int STATUS_ERROR_NOT_COMPLIANT = 3; 95 96 private IPersistentDataBlockService sService; 97 98 public PersistentDataBlockManager(IPersistentDataBlockService service) { 99 sService = service; 100 } 101 102 /** 103 * Writes {@code data} to the persistent partition. Previously written data 104 * will be overwritten. This data will persist across factory resets. 105 * 106 * Returns the number of bytes written or -1 on error. If the block is too big 107 * to fit on the partition, returns -MAX_BLOCK_SIZE. 108 * 109 * @param data the data to write 110 */ 111 public int write(byte[] data) { 112 try { 113 return sService.write(data); 114 } catch (RemoteException e) { 115 onError("writing data"); 116 return -1; 117 } 118 } 119 120 /** 121 * Returns the data block stored on the persistent partition. 122 */ 123 public byte[] read() { 124 try { 125 return sService.read(); 126 } catch (RemoteException e) { 127 onError("reading data"); 128 return null; 129 } 130 } 131 132 /** 133 * Retrieves the size of the block currently written to the persistent partition. 134 * 135 * Return -1 on error. 136 */ 137 public int getDataBlockSize() { 138 try { 139 return sService.getDataBlockSize(); 140 } catch (RemoteException e) { 141 onError("getting data block size"); 142 return -1; 143 } 144 } 145 146 /** 147 * Retrieves the maximum size allowed for a data block. 148 * 149 * Returns -1 on error. 150 */ 151 public long getMaximumDataBlockSize() { 152 try { 153 return sService.getMaximumDataBlockSize(); 154 } catch (RemoteException e) { 155 onError("getting maximum data block size"); 156 return -1; 157 } 158 } 159 160 /** 161 * Zeroes the previously written block in its entirety. Calling this method 162 * will erase all data written to the persistent data partition. 163 */ 164 public void wipe() { 165 try { 166 sService.wipe(); 167 } catch (RemoteException e) { 168 onError("wiping persistent partition"); 169 } 170 } 171 172 /** 173 * Attempt to wipe the data block by sending a broadcast to the package allowed to modify the 174 * datablock. The allowed package can refuse to wipe the data block based on the contents of 175 * the specified bundle. This bundle may contain data used by the allowed package to wipe the 176 * partition such as account credentials or an authorization token. 177 * @param bundle data used to wipe the data block. The contents of this bundle depend on the 178 * allowed package receiving the data. 179 * @param pi intent called when attempt finished. The result code of this intent will be set 180 * to one of {@link #STATUS_SUCCESS}, {@link #STATUS_ERROR_REMOTE_EXCEPTION}, 181 * {@link #STATUS_ERROR_NETWORK_ERROR}, or {@link #STATUS_ERROR_NOT_COMPLIANT}. 182 */ 183 public void wipeIfAllowed(Bundle bundle, PendingIntent pi) { 184 if (pi == null) { 185 throw new NullPointerException(); 186 } 187 try { 188 sService.wipeIfAllowed(bundle, pi); 189 } catch (RemoteException e) { 190 onError("wiping persistent partition"); 191 } 192 } 193 194 /** 195 * Writes a byte enabling or disabling the ability to "OEM unlock" the device. 196 */ 197 public void setOemUnlockEnabled(boolean enabled) { 198 try { 199 sService.setOemUnlockEnabled(enabled); 200 } catch (RemoteException e) { 201 onError("setting OEM unlock enabled to " + enabled); 202 } 203 } 204 205 /** 206 * Returns whether or not "OEM unlock" is enabled or disabled on this device. 207 */ 208 public boolean getOemUnlockEnabled() { 209 try { 210 return sService.getOemUnlockEnabled(); 211 } catch (RemoteException e) { 212 onError("getting OEM unlock enabled bit"); 213 return false; 214 } 215 } 216 217 private void onError(String msg) { 218 Slog.v(TAG, "Remote exception while " + msg); 219 } 220} 221