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

Commit 316cd96b authored by Yuri Lin's avatar Yuri Lin Committed by Android (Google) Code Review
Browse files

Merge "Validate config activities with their rule owners" into rvc-dev

parents 8fada38f b161a3b8
Loading
Loading
Loading
Loading
+37 −17
Original line number Diff line number Diff line
@@ -26,8 +26,11 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.provider.Settings;
import android.service.notification.ConditionProviderService;
import android.util.Log;
import android.util.Slog;

import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
@@ -36,6 +39,7 @@ import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;

import java.util.Map;
import java.util.Objects;

abstract public class AbstractZenModeAutomaticRulePreferenceController extends
        AbstractZenModePreferenceController implements PreferenceControllerMixin {
@@ -92,7 +96,7 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
                ? ci.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE)
                : ci.metaData.getString(NotificationManager.META_DATA_AUTOMATIC_RULE_TYPE);

        final ComponentName configurationActivity = getSettingsActivity(null, ci);
        final ComponentName configurationActivity = getSettingsActivity(pm, null, ci);
        if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
            final ZenRuleInfo ri = new ZenRuleInfo();
            ri.serviceComponent =
@@ -110,29 +114,45 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
        return null;
    }

    protected static ComponentName getSettingsActivity(AutomaticZenRule rule, ComponentInfo ci) {
    protected static ComponentName getSettingsActivity(PackageManager pm, AutomaticZenRule rule,
            ComponentInfo ci) {
        String owner = rule != null ? rule.getPackageName() : ci.packageName;
        ComponentName settingsActivity = null;
        // prefer config activity on the rule itself; fallback to manifest definition
        if (rule != null && rule.getConfigurationActivity() != null) {
            return rule.getConfigurationActivity();
        }
            settingsActivity = rule.getConfigurationActivity();
        } else {
            if (ci == null) {
            return null;
        }
                settingsActivity = null;
            } else if (ci instanceof ActivityInfo) {
                // new activity backed rule
        if (ci instanceof ActivityInfo) {
            return new ComponentName(ci.packageName, ci.name);
        }
                settingsActivity = new ComponentName(ci.packageName, ci.name);
            } else if (ci.metaData != null) {
                // old service backed rule
        if (ci.metaData != null) {
                final String configurationActivity = ci.metaData.getString(
                        ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
                if (configurationActivity != null) {
                return ComponentName.unflattenFromString(configurationActivity);
                    settingsActivity = ComponentName.unflattenFromString(configurationActivity);
                }
            }

        }
        if (settingsActivity == null || owner == null) {
            return settingsActivity;
        }
        try {
            int ownerUid = pm.getPackageUid(owner, 0);
            int configActivityOwnerUid = pm.getPackageUid(settingsActivity.getPackageName(), 0);
            if (ownerUid == configActivityOwnerUid) {
                return settingsActivity;
            } else {
                Log.w(TAG, "Config activity not in owner package for " + rule.getName());
                return null;
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Failed to find config activity");
            return null;
        }
    }

    public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
        ZenRuleInfo mRuleInfo;
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ public class ZenRulePreference extends TwoTargetPreference {
                : isEvent ? ZenModeEventRuleSettings.ACTION : "";
        ComponentInfo si = mServiceListing.findService(rule.getOwner());
        ComponentName settingsActivity = AbstractZenModeAutomaticRulePreferenceController.
                getSettingsActivity(rule, si);
                getSettingsActivity(mPm, rule, si);
        mIntent = AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
                settingsActivity, mId);
        if (mIntent.resolveActivity(mPm) == null) {
+169 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.settings.notification.zen;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.when;

import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.service.notification.ConditionProviderService;
import android.service.notification.ZenPolicy;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

@RunWith(RobolectricTestRunner.class)
public class AbstractZenModeAutomaticRulePreferenceControllerTest {

    @Mock
    private PackageManager mPm;
    private Context mContext;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
    }

    @Test
    public void testGetSettingsActivity_configActivity() throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule("name", null,
                new ComponentName(mContext.getPackageName(), "test"),  Uri.EMPTY,
                new ZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
        rule.setPackageName(mContext.getPackageName());

        when(mPm.getPackageUid(null, 0)).thenReturn(-1);
        when(mPm.getPackageUid(mContext.getPackageName(), 0)).thenReturn(1);

        ComponentName actual = AbstractZenModeAutomaticRulePreferenceController
                .getSettingsActivity(mPm, rule, null);

        assertThat(actual).isEqualTo(new ComponentName(mContext.getPackageName(), "test"));
    }

    @Test
    public void testGetSettingsActivity_configActivity_wrongPackage() throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule("name", null,
                new ComponentName("another", "test"),  Uri.EMPTY,
                new ZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
        rule.setPackageName(mContext.getPackageName());

        when(mPm.getPackageUid(null, 0)).thenReturn(-1);
        when(mPm.getPackageUid(mContext.getPackageName(), 0)).thenReturn(1);

        ComponentName actual = AbstractZenModeAutomaticRulePreferenceController
                .getSettingsActivity(mPm, rule, null);

        assertThat(actual).isNull();
    }

    @Test
    public void testGetSettingsActivity_configActivity_unspecifiedOwner() throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule("name", null,
                new ComponentName("another", "test"),  Uri.EMPTY,
                new ZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);

        when(mPm.getPackageUid(null, 0)).thenReturn(-1);
        when(mPm.getPackageUid(mContext.getPackageName(), 0)).thenReturn(1);

        ComponentName actual = AbstractZenModeAutomaticRulePreferenceController
                .getSettingsActivity(mPm, rule, null);

        assertThat(actual).isEqualTo(new ComponentName("another", "test"));
    }

    @Test
    public void testGetSettingsActivity_cps() throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule("name",
                new ComponentName(mContext.getPackageName(), "service"), null, Uri.EMPTY,
                new ZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
        rule.setPackageName(mContext.getPackageName());

        ComponentInfo ci = new ComponentInfo();
        ci.packageName = mContext.getPackageName();
        ci.metaData = new Bundle();
        ci.metaData.putString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY,
                ComponentName.flattenToShortString(
                        new ComponentName(mContext.getPackageName(), "activity")));

        when(mPm.getPackageUid(null, 0)).thenReturn(-1);
        when(mPm.getPackageUid(mContext.getPackageName(), 0)).thenReturn(1);

        ComponentName actual = AbstractZenModeAutomaticRulePreferenceController
                .getSettingsActivity(mPm, rule, ci);

        assertThat(actual).isEqualTo(new ComponentName(mContext.getPackageName(), "activity"));
    }

    @Test
    public void testGetSettingsActivity_cps_wrongPackage() throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule("name",
                new ComponentName(mContext.getPackageName(), "service"), null, Uri.EMPTY,
                new ZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
        rule.setPackageName("other");

        ComponentInfo ci = new ComponentInfo();
        ci.packageName = mContext.getPackageName();
        ci.metaData = new Bundle();
        ci.metaData.putString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY,
                ComponentName.flattenToShortString(
                        new ComponentName(mContext.getPackageName(), "activity")));

        when(mPm.getPackageUid(null, 0)).thenReturn(-1);
        when(mPm.getPackageUid(mContext.getPackageName(), 0)).thenReturn(1);

        ComponentName actual = AbstractZenModeAutomaticRulePreferenceController
                .getSettingsActivity(mPm, rule, ci);

        assertThat(actual).isNull();
    }

    @Test
    public void testGetSettingsActivity_cps_unspecifiedPackage() throws Exception {
        AutomaticZenRule rule = new AutomaticZenRule("name",
                new ComponentName(mContext.getPackageName(), "service"), null, Uri.EMPTY,
                new ZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);

        ComponentInfo ci = new ComponentInfo();
        ci.packageName = mContext.getPackageName();
        ci.metaData = new Bundle();
        ci.metaData.putString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY,
                ComponentName.flattenToShortString(
                        new ComponentName(mContext.getPackageName(), "activity")));

        when(mPm.getPackageUid(null, 0)).thenReturn(-1);
        when(mPm.getPackageUid(mContext.getPackageName(), 0)).thenReturn(1);

        ComponentName actual = AbstractZenModeAutomaticRulePreferenceController
                .getSettingsActivity(mPm, rule, ci);

        assertThat(actual).isEqualTo(new ComponentName(mContext.getPackageName(), "activity"));
    }
}
 No newline at end of file