Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3aa1f650 authored by Eugene Susla's avatar Eugene Susla Committed by android-build-merger
Browse files

Merge "Check for uses-feature in Companion APIs" into oc-dev am: 7575fa76

am: 0f88845e

Change-Id: Ib5272433ce9af4356eb57c50235b488e3f2e2d5a
parents 8d7b1c9c 0f88845e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -168,6 +168,13 @@ public class ArrayUtils {
        return array == null || array.length == 0;
    }

    /**
     * Length of the given array or 0 if it's null.
     */
    public static int size(@Nullable Object[] array) {
        return array == null ? 0 : array.length;
    }

    /**
     * Checks that value is present as at least one of the elements of the array.
     * @param array the array to check in
+26 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.NetworkPolicyManager;
@@ -203,13 +204,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
            checkNotNull(request, "Request cannot be null");
            checkNotNull(callback, "Callback cannot be null");
            checkCallerIsSystemOr(callingPackage);
            int userId = getCallingUserId();
            checkUsesFeature(callingPackage, userId);
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                //TODO bindServiceAsUser
                getContext().bindService(
                getContext().bindServiceAsUser(
                        new Intent().setComponent(SERVICE_TO_BIND_TO),
                        createServiceConnection(request, callback, callingPackage),
                        Context.BIND_AUTO_CREATE);
                        Context.BIND_AUTO_CREATE,
                        UserHandle.of(userId));
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }
@@ -219,6 +222,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
        public List<String> getAssociations(String callingPackage, int userId)
                throws RemoteException {
            checkCallerIsSystemOr(callingPackage, userId);
            checkUsesFeature(callingPackage, getCallingUserId());
            return CollectionUtils.map(
                    readAllAssociations(userId, callingPackage),
                    a -> a.deviceAddress);
@@ -230,6 +234,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
                throws RemoteException {
            checkNotNull(deviceMacAddress);
            checkCallerIsSystemOr(callingPackage);
            checkUsesFeature(callingPackage, getCallingUserId());
            updateAssociations(associations -> CollectionUtils.remove(associations,
                    new Association(getCallingUserId(), deviceMacAddress, callingPackage)));
        }
@@ -282,11 +287,24 @@ public class CompanionDeviceManagerService extends SystemService implements Bind

        private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
            checkCallerIsSystemOr(callingPackage);
            checkState(!ArrayUtils.isEmpty(readAllAssociations(getCallingUserId(), callingPackage)),
            int userId = getCallingUserId();
            checkState(!ArrayUtils.isEmpty(readAllAssociations(userId, callingPackage)),
                    "App must have an association before calling this API");
        }
            checkUsesFeature(callingPackage, userId);
        }

        private void checkUsesFeature(String pkg, int userId) {
            FeatureInfo[] reqFeatures = getPackageInfo(pkg, userId).reqFeatures;
            String requiredFeature = PackageManager.FEATURE_COMPANION_DEVICE_SETUP;
            int numFeatures = ArrayUtils.size(reqFeatures);
            for (int i = 0; i < numFeatures; i++) {
                if (requiredFeature.equals(reqFeatures[i].name)) return;
            }
            throw new IllegalStateException("Must declare uses-feature "
                    + requiredFeature
                    + " in manifest to use this API");
        }
    }

    private int getCallingUserId() {
        return UserHandle.getUserId(Binder.getCallingUid());
@@ -398,7 +416,9 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
        return Binder.withCleanCallingIdentity(() -> {
            try {
                return getContext().getPackageManager().getPackageInfoAsUser(
                        packageName, PackageManager.GET_PERMISSIONS, userId);
                        packageName,
                        PackageManager.GET_PERMISSIONS | PackageManager.GET_CONFIGURATIONS,
                        userId);
            } catch (PackageManager.NameNotFoundException e) {
                Slog.e(LOG_TAG, "Failed to get PackageInfo for package " + packageName, e);
                return null;