Loading src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceController.java +37 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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 = Loading @@ -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; Loading src/com/android/settings/notification/zen/ZenRulePreference.java +1 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading tests/robotests/src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceControllerTest.java 0 → 100644 +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 Loading
src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceController.java +37 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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 = Loading @@ -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; Loading
src/com/android/settings/notification/zen/ZenRulePreference.java +1 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading
tests/robotests/src/com/android/settings/notification/zen/AbstractZenModeAutomaticRulePreferenceControllerTest.java 0 → 100644 +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