Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2020 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 com.android.utils.blob; |
| 18 | |
Sudheer Shanka | c6c7994 | 2020-03-12 13:20:46 -0700 | [diff] [blame] | 19 | import static com.google.common.truth.Truth.assertThat; |
| 20 | |
| 21 | import android.app.blob.BlobHandle; |
Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 22 | import android.app.blob.BlobStoreManager; |
Sudheer Shanka | c6c7994 | 2020-03-12 13:20:46 -0700 | [diff] [blame] | 23 | import android.app.blob.LeaseInfo; |
| 24 | import android.content.Context; |
| 25 | import android.content.res.Resources; |
Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 26 | import android.os.ParcelFileDescriptor; |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 27 | import android.util.Log; |
| 28 | |
Sudheer Shanka | 8992c05 | 2020-05-26 18:10:09 -0700 | [diff] [blame] | 29 | import androidx.test.platform.app.InstrumentationRegistry; |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 30 | import androidx.test.uiautomator.UiDevice; |
Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 31 | |
| 32 | import java.io.FileInputStream; |
| 33 | import java.io.FileOutputStream; |
| 34 | import java.io.IOException; |
| 35 | import java.io.InputStream; |
| 36 | import java.io.OutputStream; |
| 37 | |
| 38 | public class Utils { |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 39 | public static final String TAG = "BlobStoreTest"; |
| 40 | |
Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 41 | public static final int BUFFER_SIZE_BYTES = 16 * 1024; |
| 42 | |
Sudheer Shanka | f80c8e5 | 2020-04-22 03:36:18 -0700 | [diff] [blame] | 43 | public static final long KB_IN_BYTES = 1000; |
| 44 | public static final long MB_IN_BYTES = KB_IN_BYTES * 1000; |
| 45 | |
Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 46 | public static void copy(InputStream in, OutputStream out, long lengthBytes) |
| 47 | throws IOException { |
| 48 | final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; |
| 49 | long bytesWrittern = 0; |
| 50 | while (bytesWrittern < lengthBytes) { |
| 51 | final int toWrite = (bytesWrittern + buffer.length <= lengthBytes) |
| 52 | ? buffer.length : (int) (lengthBytes - bytesWrittern); |
| 53 | in.read(buffer, 0, toWrite); |
| 54 | out.write(buffer, 0, toWrite); |
| 55 | bytesWrittern += toWrite; |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | public static void writeToSession(BlobStoreManager.Session session, ParcelFileDescriptor input, |
| 60 | long lengthBytes) throws IOException { |
| 61 | try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(input)) { |
| 62 | writeToSession(session, in, 0, lengthBytes); |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | public static void writeToSession(BlobStoreManager.Session session, FileInputStream in, |
| 67 | long offsetBytes, long lengthBytes) throws IOException { |
| 68 | in.getChannel().position(offsetBytes); |
| 69 | try (FileOutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream( |
| 70 | session.openWrite(offsetBytes, lengthBytes))) { |
| 71 | copy(in, out, lengthBytes); |
| 72 | } |
| 73 | } |
Sudheer Shanka | c6c7994 | 2020-03-12 13:20:46 -0700 | [diff] [blame] | 74 | |
| 75 | public static void assertLeasedBlobs(BlobStoreManager blobStoreManager, |
| 76 | BlobHandle... expectedBlobHandles) throws IOException { |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 77 | assertThat(blobStoreManager.getLeasedBlobs()).containsExactly( |
| 78 | (Object[]) expectedBlobHandles); |
Sudheer Shanka | c6c7994 | 2020-03-12 13:20:46 -0700 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | public static void assertNoLeasedBlobs(BlobStoreManager blobStoreManager) |
| 82 | throws IOException { |
| 83 | assertThat(blobStoreManager.getLeasedBlobs()).isEmpty(); |
| 84 | } |
| 85 | |
| 86 | public static void acquireLease(Context context, |
| 87 | BlobHandle blobHandle, CharSequence description) throws IOException { |
| 88 | final BlobStoreManager blobStoreManager = (BlobStoreManager) context.getSystemService( |
| 89 | Context.BLOB_STORE_SERVICE); |
| 90 | blobStoreManager.acquireLease(blobHandle, description); |
| 91 | |
| 92 | final LeaseInfo leaseInfo = blobStoreManager.getLeaseInfo(blobHandle); |
| 93 | assertLeaseInfo(leaseInfo, context.getPackageName(), 0, |
| 94 | Resources.ID_NULL, description); |
| 95 | } |
| 96 | |
| 97 | public static void acquireLease(Context context, |
| 98 | BlobHandle blobHandle, int descriptionResId) throws IOException { |
| 99 | final BlobStoreManager blobStoreManager = (BlobStoreManager) context.getSystemService( |
| 100 | Context.BLOB_STORE_SERVICE); |
| 101 | blobStoreManager.acquireLease(blobHandle, descriptionResId); |
| 102 | |
| 103 | final LeaseInfo leaseInfo = blobStoreManager.getLeaseInfo(blobHandle); |
| 104 | assertLeaseInfo(leaseInfo, context.getPackageName(), 0, |
| 105 | descriptionResId, context.getString(descriptionResId)); |
| 106 | } |
| 107 | |
| 108 | public static void acquireLease(Context context, |
| 109 | BlobHandle blobHandle, CharSequence description, |
| 110 | long expiryTimeMs) throws IOException { |
| 111 | final BlobStoreManager blobStoreManager = (BlobStoreManager) context.getSystemService( |
| 112 | Context.BLOB_STORE_SERVICE); |
| 113 | blobStoreManager.acquireLease(blobHandle, description, expiryTimeMs); |
| 114 | |
| 115 | final LeaseInfo leaseInfo = blobStoreManager.getLeaseInfo(blobHandle); |
| 116 | assertLeaseInfo(leaseInfo, context.getPackageName(), expiryTimeMs, |
| 117 | Resources.ID_NULL, description); |
| 118 | } |
| 119 | |
| 120 | public static void acquireLease(Context context, |
| 121 | BlobHandle blobHandle, int descriptionResId, |
| 122 | long expiryTimeMs) throws IOException { |
| 123 | final BlobStoreManager blobStoreManager = (BlobStoreManager) context.getSystemService( |
| 124 | Context.BLOB_STORE_SERVICE); |
| 125 | blobStoreManager.acquireLease(blobHandle, descriptionResId, expiryTimeMs); |
| 126 | |
| 127 | final LeaseInfo leaseInfo = blobStoreManager.getLeaseInfo(blobHandle); |
| 128 | assertLeaseInfo(leaseInfo, context.getPackageName(), expiryTimeMs, |
| 129 | descriptionResId, context.getString(descriptionResId)); |
| 130 | } |
| 131 | |
| 132 | public static void releaseLease(Context context, |
| 133 | BlobHandle blobHandle) throws IOException { |
| 134 | final BlobStoreManager blobStoreManager = (BlobStoreManager) context.getSystemService( |
| 135 | Context.BLOB_STORE_SERVICE); |
| 136 | blobStoreManager.releaseLease(blobHandle); |
Sudheer Shanka | c0fd5fa | 2020-03-15 23:31:37 -0700 | [diff] [blame] | 137 | try { |
| 138 | assertThat(blobStoreManager.getLeaseInfo(blobHandle)).isNull(); |
| 139 | } catch (SecurityException e) { |
| 140 | // Expected, ignore |
| 141 | } |
Sudheer Shanka | c6c7994 | 2020-03-12 13:20:46 -0700 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | private static void assertLeaseInfo(LeaseInfo leaseInfo, String packageName, |
| 145 | long expiryTimeMs, int descriptionResId, CharSequence description) { |
| 146 | assertThat(leaseInfo.getPackageName()).isEqualTo(packageName); |
| 147 | assertThat(leaseInfo.getExpiryTimeMillis()).isEqualTo(expiryTimeMs); |
| 148 | assertThat(leaseInfo.getDescriptionResId()).isEqualTo(descriptionResId); |
| 149 | assertThat(leaseInfo.getDescription()).isEqualTo(description); |
| 150 | } |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 151 | |
Sudheer Shanka | 8992c05 | 2020-05-26 18:10:09 -0700 | [diff] [blame] | 152 | public static void triggerIdleMaintenance() throws IOException { |
| 153 | runShellCmd("cmd blob_store idle-maintenance"); |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 154 | } |
| 155 | |
Sudheer Shanka | 8992c05 | 2020-05-26 18:10:09 -0700 | [diff] [blame] | 156 | public static String runShellCmd(String cmd) throws IOException { |
| 157 | final UiDevice uiDevice = UiDevice.getInstance( |
| 158 | InstrumentationRegistry.getInstrumentation()); |
| 159 | final String result = uiDevice.executeShellCommand(cmd).trim(); |
Sudheer Shanka | 90ac4a6 | 2020-05-25 15:40:21 -0700 | [diff] [blame] | 160 | Log.i(TAG, "Output of '" + cmd + "': '" + result + "'"); |
| 161 | return result; |
| 162 | } |
Sudheer Shanka | 96b4537 | 2020-02-29 16:49:27 -0800 | [diff] [blame] | 163 | } |