Add stub for uploading call composer pics
Add functionality only to receive the picture from the dialer app,
leaving the actual upload as a TODO.
Bug: 175435766
Test: atest CallComposerTest
Change-Id: I523b157d5204f7a25e7f42ac6cd8bf8ca1f02b74
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index c0f2816..8d665cb 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -26,6 +26,7 @@
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.PendingIntent;
+import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -192,7 +193,10 @@
import com.android.services.telephony.TelephonyConnectionService;
import com.android.telephony.Rlog;
+import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -202,7 +206,10 @@
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
@@ -6918,6 +6925,84 @@
}
@Override
+ public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
+ ParcelFileDescriptor fd, ResultReceiver callback) {
+ try {
+ if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
+ Binder.getCallingUid())) {
+ throw new SecurityException("Package uid and package name do not match: "
+ + "uid=" + Binder.getCallingUid() + ", packageName=" + callingPackage);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new SecurityException("Package name invalid:" + callingPackage);
+ }
+ RoleManager rm = mApp.getSystemService(RoleManager.class);
+ List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
+ if (!dialerRoleHolders.contains(callingPackage)) {
+ throw new SecurityException("App must be the dialer role holder to"
+ + " upload a call composer pic");
+ }
+
+ Executors.newSingleThreadExecutor().execute(() -> {
+ ByteArrayOutputStream output = new ByteArrayOutputStream(
+ (int) TelephonyManager.getMaximumCallComposerPictureSize());
+ InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
+ boolean readUntilEnd = false;
+ int totalBytesRead = 0;
+ byte[] buffer = new byte[16 * 1024];
+ while (true) {
+ int numRead;
+ try {
+ numRead = input.read(buffer);
+ } catch (IOException e) {
+ try {
+ fd.checkError();
+ callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
+ null);
+ } catch (IOException e1) {
+ // This means that the other side closed explicitly with an error. If this
+ // happens, log and ignore.
+ loge("Remote end of call composer picture pipe closed: " + e1);
+ }
+ break;
+ }
+ if (numRead == -1) {
+ readUntilEnd = true;
+ break;
+ }
+ totalBytesRead += numRead;
+ if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
+ loge("Too many bytes read for call composer picture: " + totalBytesRead);
+ try {
+ input.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ break;
+ }
+ output.write(buffer, 0, numRead);
+ }
+ // Generally, the remote end will close the file descriptors. The only case where we
+ // close is above, where the picture size is too big.
+
+ try {
+ fd.checkError();
+ } catch (IOException e) {
+ loge("Remote end for call composer closed with an error: " + e);
+ return;
+ }
+
+ // TODO: pass along the bytes read to the carrier somehow
+
+ ParcelUuid result = new ParcelUuid(UUID.randomUUID());
+ // TODO: cache this uuid that's been associated with the picture
+ Bundle outputResult = new Bundle();
+ outputResult.putParcelable(TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, result);
+ callback.send(-1, outputResult);
+ });
+ }
+
+ @Override
public void enableVideoCalling(boolean enable) {
final Phone defaultPhone = getDefaultPhone();
enforceModifyPermission();