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

Commit 857cdf53 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6294963 from 30c99155 to rvc-release

Change-Id: I9cb7c1a20de14075a459b54a71f41f8986c5f49e
parents c49bead1 30c99155
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -118,13 +118,6 @@
            </intent-filter>
        </activity>

        <activity android:name="com.android.permissioncontroller.permission.ui.AdjustUserSensitiveActivity"
                  android:configChanges="orientation|keyboardHidden|screenSize"
                  android:label="@string/adjust_user_sensitive_title"
                  android:theme="@style/Settings"
                  android:exported="false"
                  android:permission="android.permission.GRANT_RUNTIME_PERMISSIONS" />

        <activity android:name="com.android.permissioncontroller.permission.ui.ManagePermissionsActivityTrampoline"
                  android:excludeFromRecents="true"
                  android:noHistory="true"
+0 −101
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.permissioncontroller.permission.data;

import static android.content.Context.MODE_PRIVATE;

import static com.android.permissioncontroller.Constants.FORCED_USER_SENSITIVE_UIDS_KEY;
import static com.android.permissioncontroller.Constants.PREFERENCES_FILE;
import static com.android.permissioncontroller.permission.utils.Utils.getParentUserContext;

import android.app.Application;
import android.content.SharedPreferences;
import android.util.SparseIntArray;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;

import com.android.permissioncontroller.Constants;

import java.util.Set;

/**
 * Live data of the uids that should always be considered user sensitive.
 *
 * <p>This returns a {@link SparseIntArray}. The uids are the keys, ignore the values.
 *
 * <p>Data source: {@link Constants#FORCED_USER_SENSITIVE_UIDS_KEY} shared preference.
 */
public class ForcedUserSensitiveUidsLiveData extends LiveData<SparseIntArray> implements
        SharedPreferences.OnSharedPreferenceChangeListener {
    private static ForcedUserSensitiveUidsLiveData sInstance;

    private final SharedPreferences mPrefs;

    /**
     * Get a (potentially shared) live data.
     *
     * @param application The application context
     *
     * @return The live data
     */
    @MainThread
    public static ForcedUserSensitiveUidsLiveData get(@NonNull Application application) {
        if (sInstance == null) {
            sInstance = new ForcedUserSensitiveUidsLiveData(application);
        }

        return sInstance;
    }

    private ForcedUserSensitiveUidsLiveData(@NonNull Application application) {
        mPrefs = getParentUserContext(application).getSharedPreferences(PREFERENCES_FILE,
                MODE_PRIVATE);
    }

    @Override
    protected void onActive() {
        onSharedPreferenceChanged(mPrefs, FORCED_USER_SENSITIVE_UIDS_KEY);
        mPrefs.registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    protected void onInactive() {
        mPrefs.unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(FORCED_USER_SENSITIVE_UIDS_KEY)) {
            Set<String> overridesStr = sharedPreferences.getStringSet(
                    FORCED_USER_SENSITIVE_UIDS_KEY, null);

            if (overridesStr == null) {
                setValue(new SparseIntArray(0));
                return;
            }

            SparseIntArray overrides = new SparseIntArray(overridesStr.size());
            for (String override : overridesStr) {
                overrides.put(Integer.valueOf(override), 0);
            }

            setValue(overrides);
        }
    }
}
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.permissioncontroller.permission.data

import android.content.Intent
import android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE
import android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE
import com.android.permissioncontroller.PermissionControllerApplication
import kotlinx.coroutines.Job

/**
 * A livedata which stores a list of package names of packages which have launcher icons.
 */
object LauncherPackagesLiveData : SmartAsyncMediatorLiveData<Set<String>>(),
    PackageBroadcastReceiver.PackageBroadcastListener {

    private val LAUNCHER_INTENT = Intent(Intent.ACTION_MAIN, null)
        .addCategory(Intent.CATEGORY_LAUNCHER)

    override suspend fun loadDataAndPostValue(job: Job) {
        val launcherPkgs = mutableSetOf<String>()
        for (info in PermissionControllerApplication.get().packageManager.queryIntentActivities(
            LAUNCHER_INTENT, MATCH_DIRECT_BOOT_AWARE or MATCH_DIRECT_BOOT_UNAWARE)) {
            launcherPkgs.add(info.activityInfo.packageName)
        }

        postValue(launcherPkgs)
    }

    override fun onPackageUpdate(packageName: String) {
        updateIfActive()
    }

    override fun onActive() {
        super.onActive()
        updateIfActive()
        PackageBroadcastReceiver.addAllCallback(this)
    }

    override fun onInactive() {
        super.onInactive()
        PackageBroadcastReceiver.removeAllCallback(this)
    }
}
 No newline at end of file
+0 −100
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.permissioncontroller.permission.data;

import static android.os.UserHandle.getUserHandleForUid;

import static com.android.permissioncontroller.permission.utils.Utils.FLAGS_ALWAYS_USER_SENSITIVE;

import android.app.Application;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.UserHandle;
import android.util.ArrayMap;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.lifecycle.MediatorLiveData;

import java.util.ArrayList;

/**
 * Live data of packages that are not fully user sensitive by default.
 *
 * <p>Data source: {@link UidToSensitivityLiveData}
 */
public class NonSensitivePackagesLiveData extends MediatorLiveData<ArrayList<ApplicationInfo>> {
    private static NonSensitivePackagesLiveData sInstance;

    /**
     * Get a (potentially shared) live data.
     *
     * @param application The application context
     *
     * @return The live data
     */
    @MainThread
    public static NonSensitivePackagesLiveData get(@NonNull Application application) {
        if (sInstance == null) {
            sInstance = new NonSensitivePackagesLiveData(application);
        }

        return sInstance;
    }

    private NonSensitivePackagesLiveData(@NonNull Application application) {
        UidToSensitivityLiveData uidLiveData = UidToSensitivityLiveData.get(application);

        addSource(uidLiveData, uidToSensitivity -> AsyncTask.execute(() -> {
            PackageManager pm = application.getPackageManager();

            ArrayList<ApplicationInfo> pkgs = new ArrayList<>();

            int numUids = uidToSensitivity.size();
            for (int uidNum = 0; uidNum < numUids; uidNum++) {
                int uid = uidToSensitivity.keyAt(uidNum);
                UserHandle user = getUserHandleForUid(uid);
                ArrayMap<String, Integer> sensitivity = uidToSensitivity.valueAt(uidNum);

                int numPerms = sensitivity.size();
                for (int permNum = 0; permNum < numPerms; permNum++) {
                    if (sensitivity.valueAt(permNum) != FLAGS_ALWAYS_USER_SENSITIVE) {
                        String[] uidPkgs = pm.getPackagesForUid(uid);

                        if (uidPkgs != null) {
                            for (String pkg : uidPkgs) {
                                ApplicationInfo appInfo;
                                try {
                                    appInfo = pm.getApplicationInfoAsUser(pkg, 0, user);
                                } catch (PackageManager.NameNotFoundException e) {
                                    continue;
                                }

                                pkgs.add(appInfo);
                            }
                        }
                        break;
                    }
                }

            }

            postValue(pkgs);
        }));
    }
}
+0 −186
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.permissioncontroller.permission.data;

import static com.android.permissioncontroller.permission.utils.Utils.FLAGS_ALWAYS_USER_SENSITIVE;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Process;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;

import com.android.permissioncontroller.AsyncTaskLiveData;
import com.android.permissioncontroller.permission.utils.ArrayUtils;
import com.android.permissioncontroller.permission.utils.Utils;

import java.util.List;
import java.util.Set;

/**
 * Live data of the user sensitivity of all uids that belong to a given user
 *
 * <p>Data source: system server
 */
public class PerUserUidToSensitivityLiveData extends
        AsyncTaskLiveData<SparseArray<ArrayMap<String, Integer>>> {
    private static final SparseArray<PerUserUidToSensitivityLiveData> sInstances =
            new SparseArray<>();

    private final Context mContext;
    private final UserHandle mUser;

    /** Monitors changes to the packages for a user */
    private final BroadcastReceiver mPackageMonitor = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            loadValue();
        }
    };

    /**
     * Get a (potentially shared) live data.
     *
     * @param user The user to get the data for
     * @param application The application context
     *
     * @return The live data
     */
    @MainThread
    public static PerUserUidToSensitivityLiveData get(@NonNull UserHandle user,
            @NonNull Application application) {
        PerUserUidToSensitivityLiveData instance = sInstances.get(user.getIdentifier());
        if (instance == null) {
            instance = new PerUserUidToSensitivityLiveData(user, application);
            sInstances.put(user.getIdentifier(), instance);
        }

        return instance;
    }

    private PerUserUidToSensitivityLiveData(@NonNull UserHandle user,
            @NonNull Application application) {
        mUser = user;

        try {
            mContext = application.createPackageContextAsUser(application.getPackageName(), 0,
                    user);
        } catch (PackageManager.NameNotFoundException cannotHappen) {
            throw new IllegalStateException(cannotHappen);
        }
    }

    @Override
    protected void onActive() {
        loadValue();
        mContext.registerReceiver(mPackageMonitor, new IntentFilter(Intent.ACTION_PACKAGE_CHANGED));
    }

    @Override
    protected void onInactive() {
        mContext.unregisterReceiver(mPackageMonitor);
    }

    @Override
    public SparseArray<ArrayMap<String, Integer>> loadValueInBackground() {
        PackageManager pm = mContext.getPackageManager();
        List<PackageInfo> pkgs = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
        Set<String> platformPerms = Utils.getPlatformPermissions();
        ArraySet<String> pkgsWithLauncherIcon = Utils.getLauncherPackages(mContext);

        // uid -> permission -> flags
        SparseArray<ArrayMap<String, Integer>> uidsPermissions = new SparseArray<>();

        // Collect the flags and store it in 'uidsPermissions'
        int numPkgs = pkgs.size();
        for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
            PackageInfo pkg = pkgs.get(pkgNum);
            boolean pkgHasLauncherIcon = pkgsWithLauncherIcon.contains(pkg.packageName);
            boolean pkgIsSystemApp = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;

            // permission -> flags
            ArrayMap<String, Integer> uidPermissions = uidsPermissions.get(pkg.applicationInfo.uid);
            if (uidPermissions == null) {
                uidPermissions = new ArrayMap<>();
                uidsPermissions.put(pkg.applicationInfo.uid, uidPermissions);
            }

            for (String perm : platformPerms) {
                if (!ArrayUtils.contains(pkg.requestedPermissions, perm)) {
                    continue;
                }

                /*
                 * Permissions are considered user sensitive for a package, when
                 * - the package has a launcher icon, or
                 * - the permission is not pre-granted, or
                 * - the package is not a system app (i.e. not preinstalled)
                 *
                 * If two packages share a UID there can be two cases:
                 * - for well known UIDs: if the permission for any package is non-user sensitive,
                 *                        it is non-sensitive. I.e. prefer to hide
                 * - for non system UIDs: if the permission for any package is user sensitive, it is
                 *                        user sensitive. I.e. prefer to show
                 */
                Integer previousFlagsInt = uidPermissions.get(perm);
                int previousFlags;
                if (pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID) {
                    previousFlags = previousFlagsInt == null
                            ? FLAGS_ALWAYS_USER_SENSITIVE
                            : previousFlagsInt;
                } else {
                    previousFlags = previousFlagsInt == null ? 0 : previousFlagsInt;
                }

                int flags;
                if (pkgIsSystemApp && !pkgHasLauncherIcon) {
                    boolean permGrantedByDefault = (pm.getPermissionFlags(perm, pkg.packageName,
                            mUser) & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0;

                    if (permGrantedByDefault) {
                        flags = 0;
                    } else {
                        flags = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED;
                    }
                } else {
                    flags = FLAGS_ALWAYS_USER_SENSITIVE;
                }

                if (pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID) {
                    flags &= previousFlags;
                } else {
                    flags |= previousFlags;
                }

                uidPermissions.put(perm, flags);
            }
        }

        return uidsPermissions;
    }
}
Loading