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

Commit bc7c591e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add special app access UI based on roles."

parents 152ddff6 b20a16b1
Loading
Loading
Loading
Loading
+14 −0
Original line number Original line Diff line number Diff line
@@ -155,6 +155,20 @@
        <activity android:name="com.android.packageinstaller.role.ui.DefaultAppActivity"
        <activity android:name="com.android.packageinstaller.role.ui.DefaultAppActivity"
                  android:theme="@style/Settings" />
                  android:theme="@style/Settings" />


        <activity android:name="com.android.packageinstaller.role.ui.SpecialAppAccessListActivity"
                  android:label="@string/special_app_access"
                  android:permission="android.permission.MANAGE_ROLE_HOLDERS"
                  android:theme="@style/Settings">
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.MANAGE_SPECIAL_APP_ACCESSES" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <!-- TODO: STOPSHIP: Override other Settings intents. -->
        <activity android:name="com.android.packageinstaller.role.ui.SpecialAppAccessActivity"
                  android:theme="@style/Settings" />

        <provider android:name="com.android.packageinstaller.permission.service.PermissionSearchIndexablesProvider"
        <provider android:name="com.android.packageinstaller.permission.service.PermissionSearchIndexablesProvider"
            android:authorities="com.android.permissioncontroller"
            android:authorities="com.android.permissioncontroller"
            android:multiprocess="false"
            android:multiprocess="false"
+13 −0
Original line number Original line Diff line number Diff line
@@ -504,6 +504,19 @@
    <!-- Label when there are no apps available for a default app [CHAR LIMIT=30] -->
    <!-- Label when there are no apps available for a default app [CHAR LIMIT=30] -->
    <string name="default_app_no_apps">No apps</string>
    <string name="default_app_no_apps">No apps</string>


    <!-- Title for page of managing special app access. [CHAR LIMIT=30] -->
    <string name="special_app_access">Special app access</string>

    <!-- TODO: STOPSHIP: I cannot find its value in Settings. -->
    <!-- Help URI, special app access [DO NOT TRANSLATE] -->
    <string name="help_uri_special_app_access" translatable="false"></string>

    <!-- Label when there is no special app access [CHAR LIMIT=30] -->
    <string name="no_special_app_access">No special app access</string>

    <!-- Label when there are no apps available for a special app access [CHAR LIMIT=30] -->
    <string name="special_app_access_no_apps">No apps</string>

    <!-- TODO: STOPSHIP: Migrate all default app titles from packages/apps/Settings/res/values/strings.xml . -->
    <!-- TODO: STOPSHIP: Migrate all default app titles from packages/apps/Settings/res/values/strings.xml . -->


    <!-- Label for the dialer role. [CHAR LIMIT=30] -->
    <!-- Label for the dialer role. [CHAR LIMIT=30] -->
+72 −0
Original line number Original line 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.ui;

import android.content.Context;
import android.util.AttributeSet;

import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;

/**
 * {@link SwitchPreference} with {@link AppIconPreference.Mixin}.
 */
public class AppIconSwitchPreference extends SwitchPreference {

    private AppIconPreference.Mixin mMixin;

    public AppIconSwitchPreference(@NonNull Context context) {
        super(context);

        init();
    }

    public AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        init();
    }

    public AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
            @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    public AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs,
            @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        init();
    }

    private void init() {
        mMixin = new AppIconPreference.Mixin(getContext());
    }

    @Override
    public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);

        mMixin.onBindViewHolder(holder);
    }
}
+24 −26
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Log;
import android.util.Pair;


import androidx.annotation.NonNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Nullable;
@@ -32,7 +33,6 @@ import androidx.lifecycle.ViewModelProviders;
import androidx.preference.Preference;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;


import com.android.packageinstaller.permission.utils.IconDrawableFactory;
import com.android.packageinstaller.permission.utils.IconDrawableFactory;
import com.android.packageinstaller.permission.utils.Utils;
import com.android.packageinstaller.permission.utils.Utils;
@@ -99,8 +99,9 @@ public class DefaultAppFragment extends SettingsFragment


        mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, mUser,
        mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, mUser,
                activity.getApplication())).get(DefaultAppViewModel.class);
                activity.getApplication())).get(DefaultAppViewModel.class);
        mViewModel.getRoleLiveData().observe(this, this::onRoleInfoChanged);
        mViewModel.getRoleLiveData().observe(this, this::onRoleChanged);
        mViewModel.getAddRoleHolderStateLiveData().observe(this, this::onAddRoleHolderStateChanged);
        mViewModel.getManageRoleHolderStateLiveData().observe(this,
                this::onManageRoleHolderStateChanged);
    }
    }


    @Override
    @Override
@@ -109,7 +110,8 @@ public class DefaultAppFragment extends SettingsFragment
        return R.string.default_app_no_apps;
        return R.string.default_app_no_apps;
    }
    }


    private void onRoleInfoChanged(@NonNull RoleInfo roleInfo) {
    private void onRoleChanged(
            @NonNull List<Pair<ApplicationInfo, Boolean>> qualifyingApplications) {
        PreferenceManager preferenceManager = getPreferenceManager();
        PreferenceManager preferenceManager = getPreferenceManager();
        Context context = preferenceManager.getContext();
        Context context = preferenceManager.getContext();


@@ -127,16 +129,15 @@ public class DefaultAppFragment extends SettingsFragment
            }
            }
        }
        }


        List<ApplicationInfo> qualifyingApplicationInfos = roleInfo.getQualifyingApplicationInfos();
        int qualifyingApplicationsSize = qualifyingApplications.size();
        List<String> holderPackageNames = roleInfo.getHolderPackageNames();
        for (int i = 0; i < qualifyingApplicationsSize; i++) {
        int qualifyingApplicationInfosSize = qualifyingApplicationInfos.size();
            Pair<ApplicationInfo, Boolean> qualifyingApplication = qualifyingApplications.get(i);
        for (int i = 0; i < qualifyingApplicationInfosSize; i++) {
            ApplicationInfo qualifyingApplicationInfo = qualifyingApplication.first;
            ApplicationInfo qualifyingApplicationInfo = qualifyingApplicationInfos.get(i);
            boolean isHolderPackage = qualifyingApplication.second;


            TwoStatePreference preference = (TwoStatePreference) oldPreferences.get(
            AppIconRadioButtonPreference preference = (AppIconRadioButtonPreference)
                    qualifyingApplicationInfo.packageName);
                    oldPreferences.get(qualifyingApplicationInfo.packageName);
            if (preference == null) {
            if (preference == null) {
                // TODO: STOPSHIP: Support multiple role holders.
                preference = new AppIconRadioButtonPreference(context);
                preference = new AppIconRadioButtonPreference(context);
                preference.setKey(qualifyingApplicationInfo.packageName);
                preference.setKey(qualifyingApplicationInfo.packageName);
                preference.setIcon(IconDrawableFactory.getBadgedIcon(context,
                preference.setIcon(IconDrawableFactory.getBadgedIcon(context,
@@ -144,11 +145,11 @@ public class DefaultAppFragment extends SettingsFragment
                                qualifyingApplicationInfo.uid)));
                                qualifyingApplicationInfo.uid)));
                preference.setTitle(Utils.getAppLabel(qualifyingApplicationInfo, context));
                preference.setTitle(Utils.getAppLabel(qualifyingApplicationInfo, context));
                preference.setPersistent(false);
                preference.setPersistent(false);
                preference.setOnPreferenceChangeListener((preference2, newValue) -> false);
                preference.setOnPreferenceClickListener(this);
                preference.setOnPreferenceClickListener(this);
            }
            }


            preference.setChecked(holderPackageNames.contains(
            preference.setChecked(isHolderPackage);
                    qualifyingApplicationInfo.packageName));


            // TODO: Ordering?
            // TODO: Ordering?
            preferenceScreen.addPreference(preference);
            preferenceScreen.addPreference(preference);
@@ -157,32 +158,29 @@ public class DefaultAppFragment extends SettingsFragment
        updateState();
        updateState();
    }
    }


    private void onAddRoleHolderStateChanged(int state) {
    private void onManageRoleHolderStateChanged(int state) {
        AddRoleHolderStateLiveData addRoleHolderStateLiveData =
        ManageRoleHolderStateLiveData liveData = mViewModel.getManageRoleHolderStateLiveData();
                mViewModel.getAddRoleHolderStateLiveData();
        switch (state) {
        switch (state) {
            case AddRoleHolderStateLiveData.STATE_SUCCESS:
            case ManageRoleHolderStateLiveData.STATE_SUCCESS:
                addRoleHolderStateLiveData.resetState();
                liveData.resetState();
                break;
                break;
            case AddRoleHolderStateLiveData.STATE_FAILURE:
            case ManageRoleHolderStateLiveData.STATE_FAILURE:
                // TODO: STOPSHIP: Notify user.
                // TODO: STOPSHIP: Notify user.
                addRoleHolderStateLiveData.resetState();
                liveData.resetState();
                break;
                break;
        }
        }
    }
    }


    @Override
    @Override
    public boolean onPreferenceClick(@NonNull Preference preference) {
    public boolean onPreferenceClick(@NonNull Preference preference) {
        AddRoleHolderStateLiveData addRoleHolderStateLiveData =
        ManageRoleHolderStateLiveData liveData = mViewModel.getManageRoleHolderStateLiveData();
                mViewModel.getAddRoleHolderStateLiveData();
        if (liveData.getValue() != ManageRoleHolderStateLiveData.STATE_IDLE) {
        if (addRoleHolderStateLiveData.getValue() != AddRoleHolderStateLiveData.STATE_IDLE) {
            Log.i(LOG_TAG, "Trying to set default app while another request is on-going");
            Log.i(LOG_TAG, "Trying to set default app while another request is on-going");
            return true;
            return true;
        }
        }


        String packageName = preference.getKey();
        String packageName = preference.getKey();
        addRoleHolderStateLiveData.addRoleHolderAsUser(mRoleName, packageName, mUser,
        liveData.manageRoleHolderAsUser(mRoleName, packageName, mUser, true, requireContext());
                requireContext());
        return true;
        return true;
    }
    }
}
}
+2 −3
Original line number Original line Diff line number Diff line
@@ -50,7 +50,7 @@ public class DefaultAppListFragment extends SettingsFragment


    private static final String PREFERENCE_KEY_WORK_CATEGORY = "work_category";
    private static final String PREFERENCE_KEY_WORK_CATEGORY = "work_category";


    private RoleListViewModel mViewModel;
    private DefaultAppListViewModel mViewModel;


    /**
    /**
     * Create a new instance of this fragment.
     * Create a new instance of this fragment.
@@ -66,8 +66,7 @@ public class DefaultAppListFragment extends SettingsFragment
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        super.onActivityCreated(savedInstanceState);


        mViewModel = ViewModelProviders.of(this, new RoleListViewModel.Factory(true,
        mViewModel = ViewModelProviders.of(this).get(DefaultAppListViewModel.class);
                requireActivity().getApplication())).get(RoleListViewModel.class);
        mViewModel.getLiveData().observe(this, roleItems -> onRoleListChanged());
        mViewModel.getLiveData().observe(this, roleItems -> onRoleListChanged());
        if (mViewModel.hasWorkProfile()) {
        if (mViewModel.hasWorkProfile()) {
            mViewModel.getWorkLiveData().observe(this, roleItems -> onRoleListChanged());
            mViewModel.getWorkLiveData().observe(this, roleItems -> onRoleListChanged());
Loading