1 /* 2 * Copyright 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 package com.android.cts.blob.helper; 17 18 import static android.os.storage.StorageManager.UUID_DEFAULT; 19 20 import static com.android.utils.blob.Utils.TAG; 21 import static com.android.utils.blob.Utils.writeToSession; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import android.app.Service; 26 import android.app.blob.BlobHandle; 27 import android.app.blob.BlobStoreManager; 28 import android.app.usage.StorageStats; 29 import android.app.usage.StorageStatsManager; 30 import android.content.Intent; 31 import android.content.pm.PackageManager.NameNotFoundException; 32 import android.os.IBinder; 33 import android.os.LimitExceededException; 34 import android.os.Parcel; 35 import android.os.ParcelFileDescriptor; 36 import android.os.Process; 37 import android.os.RemoteException; 38 import android.util.Log; 39 40 import com.android.cts.blob.ICommandReceiver; 41 import com.android.utils.blob.Utils; 42 43 import java.io.IOException; 44 import java.util.concurrent.CompletableFuture; 45 import java.util.concurrent.ExecutionException; 46 import java.util.concurrent.TimeUnit; 47 import java.util.concurrent.TimeoutException; 48 49 public class BlobStoreTestService extends Service { 50 @Override onBind(Intent intent)51 public IBinder onBind(Intent intent) { 52 return new CommandReceiver(); 53 } 54 55 private class CommandReceiver extends ICommandReceiver.Stub { 56 @Override commit(BlobHandle blobHandle, ParcelFileDescriptor input, int accessTypeFlags, long timeoutSec, long size)57 public int commit(BlobHandle blobHandle, ParcelFileDescriptor input, int accessTypeFlags, 58 long timeoutSec, long size) { 59 final BlobStoreManager blobStoreManager = getSystemService( 60 BlobStoreManager.class); 61 try { 62 final long sessionId = blobStoreManager.createSession(blobHandle); 63 try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) { 64 writeToSession(session, input, size); 65 if ((accessTypeFlags & ICommandReceiver.FLAG_ACCESS_TYPE_PUBLIC) != 0) { 66 session.allowPublicAccess(); 67 } 68 69 Log.d(TAG, "Committing session: " + sessionId + "; blob: " + blobHandle); 70 final CompletableFuture<Integer> callback = new CompletableFuture<>(); 71 session.commit(getMainExecutor(), callback::complete); 72 return callback.get(timeoutSec, TimeUnit.SECONDS); 73 } 74 } catch (IOException | InterruptedException | TimeoutException | ExecutionException e) { 75 throw new IllegalStateException(e); 76 } 77 } 78 79 @Override openBlob(BlobHandle blobHandle)80 public ParcelFileDescriptor openBlob(BlobHandle blobHandle) { 81 final BlobStoreManager blobStoreManager = getSystemService( 82 BlobStoreManager.class); 83 try { 84 return blobStoreManager.openBlob(blobHandle); 85 } catch (IOException e) { 86 throw new IllegalStateException(e); 87 } 88 } 89 90 @Override openSession(long sessionId)91 public void openSession(long sessionId) { 92 final BlobStoreManager blobStoreManager = getSystemService( 93 BlobStoreManager.class); 94 try { 95 try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) { 96 assertThat(session).isNotNull(); 97 } 98 } catch (IOException e) { 99 throw new IllegalStateException(e); 100 } 101 } 102 103 @Override acquireLease(BlobHandle blobHandle)104 public void acquireLease(BlobHandle blobHandle) { 105 final BlobStoreManager blobStoreManager = getSystemService( 106 BlobStoreManager.class); 107 try { 108 Utils.acquireLease(BlobStoreTestService.this, blobHandle, "Test description"); 109 assertThat(blobStoreManager.getLeasedBlobs()).contains(blobHandle); 110 } catch (IOException | LimitExceededException e) { 111 throw new IllegalStateException(e); 112 } 113 } 114 115 @Override releaseLease(BlobHandle blobHandle)116 public void releaseLease(BlobHandle blobHandle) { 117 final BlobStoreManager blobStoreManager = getSystemService( 118 BlobStoreManager.class); 119 try { 120 Utils.releaseLease(BlobStoreTestService.this, blobHandle); 121 assertThat(blobStoreManager.getLeasedBlobs()).doesNotContain(blobHandle); 122 } catch (IOException e) { 123 throw new IllegalStateException(e); 124 } 125 } 126 127 @Override queryStatsForPackage()128 public StorageStats queryStatsForPackage() { 129 final StorageStatsManager storageStatsManager = getSystemService( 130 StorageStatsManager.class); 131 try { 132 return storageStatsManager 133 .queryStatsForPackage(UUID_DEFAULT, getPackageName(), getUser()); 134 } catch (IOException | NameNotFoundException e) { 135 throw new IllegalStateException(e); 136 } 137 } 138 139 @Override queryStatsForUid()140 public StorageStats queryStatsForUid() { 141 final StorageStatsManager storageStatsManager = getSystemService( 142 StorageStatsManager.class); 143 try { 144 return storageStatsManager 145 .queryStatsForUid(UUID_DEFAULT, Process.myUid()); 146 } catch (IOException e) { 147 throw new IllegalStateException(e); 148 } 149 } 150 151 @Override onTransact(int code, Parcel data, Parcel reply, int flags)152 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 153 throws RemoteException { 154 try { 155 return super.onTransact(code, data, reply, flags); 156 } catch (AssertionError e) { 157 throw new IllegalStateException(e); 158 } 159 } 160 } 161 } 162