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

Commit a4d5aeb0 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Have a role to give any app SMS access

The qualified holders are any app that requests a SMS permission.

This role is used to handle apps that are broken by disabling SMS
access during dogfooding.

Test: Gave youtube app the role and saw sms access granted.
Bug: 110557011
Change-Id: I20d48097e36d4f2ae4767d1eab039b3b5cad703c
parent 1026a102
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -570,6 +570,8 @@
    <string name="role_label_call_companion">Call companion app</string>
    <!-- Label for the assist app role. [CHAR LIMIT=30] -->
    <string name="role_label_assistant">Assist app</string>
    <!-- Label for the temporary workaround to give any app SMS access. [CHAR LIMIT=unlimited] -->
    <string name="role_label_temporary_sms_access" translatable="false">WON\'T BE RELEASED: SMS access app</string>

    <!-- Dialog body explaining that the app just selected by the user will not work after a reboot until the user enters their credentials, such as a PIN or password. [CHAR LIMIT=NONE] -->
    <string name="encryption_unaware_confirmation_message">Note: If you restart your device and have a screen lock set, this app can\u2019t start until you unlock your device.</string>
+10 −0
Original line number Diff line number Diff line
@@ -478,4 +478,14 @@
        </permissions>
    </role>

    <!-- STOPSHIP: Allow any app to access SMS -->
    <role
        name="android.app.role.TEMPORARY_SMS_ACCESS"
        behavior="TemporarySmsAccessRoleBehavior"
        exclusive="false"
        label="@string/role_label_temporary_sms_access">
        <permissions>
            <permission-set name="sms" />
        </permissions>
    </role>
</roles>
+94 −0
Original line number Diff line number Diff line
/*
 * 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.packageinstaller.role.model;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.ArraySet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * STOPSHIP: Temporary workaround: Allow any app to access SMS
 */
public class TemporarySmsAccessRoleBehavior implements RoleBehavior {

    /**
     * If the package requesting any SMS permission?
     *
     * @param pkg The package that might request the permission
     *
     * @return {@code true} iff the package requests any SMS permission
     */
    private boolean isRequestingSMSPermission(@NonNull PackageInfo pkg) {
        String[] requestedPermsArr = pkg.requestedPermissions;
        if (requestedPermsArr == null) {
            return false;
        }

        ArraySet<String> requestedPerms = new ArraySet<>(requestedPermsArr.length);
        Collections.addAll(requestedPerms, requestedPermsArr);

        return requestedPerms.contains(Manifest.permission.SEND_SMS)
                || requestedPerms.contains(Manifest.permission.RECEIVE_SMS)
                || requestedPerms.contains(Manifest.permission.READ_SMS)
                || requestedPerms.contains(Manifest.permission.RECEIVE_WAP_PUSH)
                || requestedPerms.contains(Manifest.permission.RECEIVE_MMS)
                || requestedPerms.contains(Manifest.permission.READ_CELL_BROADCASTS);
    }

    @Nullable
    @Override
    public List<String> getQualifyingPackagesAsUser(@NonNull Role role, @NonNull UserHandle user,
            @NonNull Context context) {
        List<PackageInfo> pkgs = context.getPackageManager().getInstalledPackagesAsUser(
                PackageManager.GET_PERMISSIONS, user.getIdentifier());

        ArrayList<String> qualifyingPkgs = new ArrayList<>();
        int numPkgs = pkgs.size();
        for (int i = 0; i < numPkgs; i++) {
            if (isRequestingSMSPermission(pkgs.get(i))) {
                qualifyingPkgs.add(pkgs.get(i).packageName);
            }
        }

        return qualifyingPkgs;
    }

    @Nullable
    @Override
    public Boolean isPackageQualified(@NonNull Role role, @NonNull String packageName,
            @NonNull Context context) {
        PackageInfo pkg;
        try {
            pkg = context.getPackageManager().getPackageInfo(packageName,
                    PackageManager.GET_PERMISSIONS);
        } catch (PackageManager.NameNotFoundException ignored) {
            return false;
        }

        return isRequestingSMSPermission(pkg);
    }
}