diff options
author | Ruslan Tkhakokhov <rthakohov@google.com> | 2019-10-07 14:40:40 +0100 |
---|---|---|
committer | Al Sutton <alsutton@google.com> | 2019-10-16 08:58:01 +0000 |
commit | 004e85f798dc88265edffebeba66da4efaeb2735 (patch) | |
tree | 2cdf9a14531ded14fa1d9703c9c7346892ebe14a /packages/EncryptedLocalTransport/src | |
parent | d0844929a335bfe2df33e3257acc35d217659d66 (diff) |
Route EncryptedLocalTransport KV backup/restore through encryption code
Bug: 142227548
Test: Verify the device boots successfully
Verify EncryptedLocalTransport APK is present
Verify manual backup/restore using bmgr for LocalTransport and EncryptedLocalTransport
For LocalTransport (unencrypted) and EncryptedLocalTransport:
atest CtsBackupTestCases
atest CtsBackupHostTestCases
atest GtsBackupTestCases
atest GtsBackupHostTestCases
Change-Id: Iac3a8a50d7f761442a4b784cfba3a980e900dd7f
Diffstat (limited to 'packages/EncryptedLocalTransport/src')
2 files changed, 156 insertions, 0 deletions
diff --git a/packages/EncryptedLocalTransport/src/com/android/encryptedlocaltransport/EncryptedLocalTransport.java b/packages/EncryptedLocalTransport/src/com/android/encryptedlocaltransport/EncryptedLocalTransport.java new file mode 100644 index 000000000000..3dd453e83ab8 --- /dev/null +++ b/packages/EncryptedLocalTransport/src/com/android/encryptedlocaltransport/EncryptedLocalTransport.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2019 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.encryptedlocaltransport; + +import android.app.backup.BackupTransport; +import android.app.backup.RestoreDescription; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.os.ParcelFileDescriptor; +import android.system.ErrnoException; +import android.system.Os; +import android.system.StructStat; +import android.util.Log; + +import com.android.localtransport.LocalTransport; +import com.android.localtransport.LocalTransportParameters; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +public class EncryptedLocalTransport extends LocalTransport { + private static final String TAG = "EncryptedLocalTransport"; + private static final int BACKUP_BUFFER_SIZE = 32 * 1024; // 32 KB. + + public EncryptedLocalTransport(Context context, + LocalTransportParameters parameters) { + super(context, parameters); + } + + @Override + public int performBackup( + PackageInfo packageInfo, ParcelFileDescriptor data, int flags) { + File packageFile; + try { + StructStat stat = Os.fstat(data.getFileDescriptor()); + if (stat.st_size > KEY_VALUE_BACKUP_SIZE_QUOTA) { + Log.w(TAG, "New datastore size " + stat.st_size + + " exceeds quota " + KEY_VALUE_BACKUP_SIZE_QUOTA); + return TRANSPORT_QUOTA_EXCEEDED; + } + } catch (ErrnoException e) { + Log.w(TAG, "Failed to stat the backup input file: ", e); + return BackupTransport.TRANSPORT_ERROR; + } + + clearBackupData(packageInfo); + + try (InputStream in = new FileInputStream(data.getFileDescriptor())) { + packageFile = new File(mCurrentSetIncrementalDir, packageInfo.packageName); + Files.copy(in, packageFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + Log.w(TAG, "Failed to save backup data to file: ", e); + return BackupTransport.TRANSPORT_ERROR; + } + + return TRANSPORT_OK; + } + + @Override + public int getRestoreData(ParcelFileDescriptor outFd) { + if (mRestorePackages == null) { + throw new IllegalStateException("startRestore not called"); + } + if (mRestorePackage < 0) { + throw new IllegalStateException("nextRestorePackage not called"); + } + if (mRestoreType != RestoreDescription.TYPE_KEY_VALUE) { + throw new IllegalStateException("getRestoreData(fd) for non-key/value dataset"); + } + + try(OutputStream out = new FileOutputStream(outFd.getFileDescriptor())) { + File packageFile = new File(mRestoreSetIncrementalDir, + mRestorePackages[mRestorePackage].packageName); + Files.copy(packageFile.toPath(), out); + } catch (IOException e) { + Log.d(TAG, "Failed to transfer restore data: " + e); + return BackupTransport.TRANSPORT_ERROR; + } + + return BackupTransport.TRANSPORT_OK; + } + + @Override + protected boolean hasRestoreDataForPackage(String packageName) { + File contents = (new File(mRestoreSetIncrementalDir, packageName)); + return contents.exists() && contents.length() != 0; + + } +} diff --git a/packages/EncryptedLocalTransport/src/com/android/encryptedlocaltransport/EncryptedLocalTransportService.java b/packages/EncryptedLocalTransport/src/com/android/encryptedlocaltransport/EncryptedLocalTransportService.java new file mode 100644 index 000000000000..952f90d8b11f --- /dev/null +++ b/packages/EncryptedLocalTransport/src/com/android/encryptedlocaltransport/EncryptedLocalTransportService.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 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.encryptedlocaltransport; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +import com.android.localtransport.LocalTransportParameters; + +public class EncryptedLocalTransportService extends Service { + private static EncryptedLocalTransport sTransport = null; + + @Override + public void onCreate() { + if (sTransport == null) { + LocalTransportParameters parameters = + new LocalTransportParameters(getMainThreadHandler(), getContentResolver()); + sTransport = new EncryptedLocalTransport(this, parameters); + } + sTransport.getParameters().start(); + } + + @Override + public void onDestroy() { + sTransport.getParameters().stop(); + } + + @Override + public IBinder onBind(Intent intent) { + return sTransport.getBinder(); + } +} |