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

Commit dfa9bb89 authored by Amin Shaikh's avatar Amin Shaikh
Browse files

Revert "Update "Open networks available" toggle to instead open notification channel preferences."

This reverts commit 2c4b42c0.

Reason for revert: Need to use Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON to toggle the feature because system NotificationChannels cannot be disabled.
Bug: 37794067
Test: m RunSettingsRoboTests

Change-Id: I6aaad78686f4fe929fd6bcd94897341fdaf6bd23
parent b296697e
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -31,10 +31,11 @@
        android:title="@string/use_open_wifi_automatically_title"
        android:summary="@string/use_open_wifi_automatically_summary" />

    <Preference
    <SwitchPreference
            android:key="notify_open_networks"
            android:title="@string/wifi_notify_open_networks"
            android:icon="@drawable/ic_open_wifi_notifications"/>
            android:icon="@drawable/ic_open_wifi_notifications"
            android:summary="@string/wifi_notify_open_networks_summary" />

    <SwitchPreference
        android:key="wifi_cellular_data_fallback"
+0 −64
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.utils;

import android.app.INotificationManager;
import android.app.NotificationChannel;
import android.os.RemoteException;

/**
 * Wrappers around methods in {@link INotificationManager} and {@link NotificationChannel} to
 * facilitate unit testing.
 *
 * TODO: delete this class once robolectric supports Android O
 */
public class NotificationChannelHelper {
    private INotificationManager mNotificationManager;

    public NotificationChannelHelper(
            INotificationManager notificationManager) {
        mNotificationManager = notificationManager;
    }

    /**
     * Returns the notification channel settings for a app given its package name, user id, and
     * channel id.
     */
    public NotificationChannelWrapper getNotificationChannelForPackage(String pkg, int uid,
            String channelId, boolean includeDeleted) throws RemoteException {
        NotificationChannel channel = mNotificationManager.getNotificationChannelForPackage(
                pkg, uid, channelId, includeDeleted);
        return channel == null ? null : new NotificationChannelWrapper(channel);
    }

    /**
     * Wrapper around {@link NotificationChannel} to facilitate unit testing.
     *
     * TODO: delete this class once robolectric supports Android O
     */
    public class NotificationChannelWrapper {
        private NotificationChannel mChannel;

        public NotificationChannelWrapper(NotificationChannel channel) {
            mChannel = channel;
        }

        public int getImportance() {
            return mChannel.getImportance();
        }
    }
}
+6 −9
Original line number Diff line number Diff line
@@ -15,13 +15,15 @@
 */
package com.android.settings.wifi;

import android.app.INotificationManager;
import static android.content.Context.NETWORK_SCORE_SERVICE;
import static android.content.Context.WIFI_SERVICE;

import android.content.Context;
import android.content.Intent;
import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.ServiceManager;
import android.provider.SearchIndexableResource;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -32,7 +34,6 @@ import com.android.settings.network.NetworkScorerPickerPreferenceController;
import com.android.settings.network.WifiCallingPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.utils.NotificationChannelHelper;
import com.android.settings.wifi.p2p.WifiP2pPreferenceController;

import java.util.ArrayList;
@@ -72,18 +73,14 @@ public class ConfigureWifiSettings extends DashboardFragment {
    protected List<PreferenceController> getPreferenceControllers(Context context) {
        final NetworkScoreManagerWrapper networkScoreManagerWrapper =
                new NetworkScoreManagerWrapper(context.getSystemService(NetworkScoreManager.class));
        final NotificationChannelHelper notificationChannelHelper =
                new NotificationChannelHelper(INotificationManager.Stub.asInterface(
                        ServiceManager.getService(Context.NOTIFICATION_SERVICE)));
        final WifiManager wifiManager = context.getSystemService(WifiManager.class);
        mUseOpenWifiPreferenceController = new UseOpenWifiPreferenceController(context, this,
                networkScoreManagerWrapper, getLifecycle());
        final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        final List<PreferenceController> controllers = new ArrayList<>();
        controllers.add(new WifiWakeupPreferenceController(context, getLifecycle()));
        controllers.add(new NetworkScorerPickerPreferenceController(context,
                networkScoreManagerWrapper));
        controllers.add(new NotifyOpenNetworksPreferenceController(context,
                networkScoreManagerWrapper, notificationChannelHelper, getPackageManager()));
        controllers.add(new NotifyOpenNetworksPreferenceController(context, getLifecycle()));
        controllers.add(mUseOpenWifiPreferenceController);
        controllers.add(new WifiSleepPolicyPreferenceController(context));
        controllers.add(new WifiInfoPreferenceController(context, getLifecycle(), wifiManager));
+75 −63
Original line number Diff line number Diff line
@@ -16,56 +16,61 @@

package com.android.settings.wifi;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.NetworkScorerAppData;
import android.os.RemoteException;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
import com.android.settings.R;

import com.android.settings.core.PreferenceController;
import com.android.settings.network.NetworkScoreManagerWrapper;
import com.android.settings.utils.NotificationChannelHelper;
import com.android.settings.utils.NotificationChannelHelper.NotificationChannelWrapper;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.OnPause;
import com.android.settings.core.lifecycle.events.OnResume;

/**
 * {@link PreferenceController} that shows whether we should notify user when open network is
 * available. The preference links to {@link NotificationChannel} settings.
 * {@link PreferenceController} that controls whether we should notify user when open network is
 * available.
 */
public class NotifyOpenNetworksPreferenceController extends PreferenceController {
public class NotifyOpenNetworksPreferenceController extends PreferenceController implements
        LifecycleObserver, OnResume, OnPause {

    private static final String TAG = "OpenNetworks";
    private static final String KEY_NOTIFY_OPEN_NETWORKS = "notify_open_networks";
    private SettingObserver mSettingObserver;

    private NetworkScoreManagerWrapper mNetworkScoreManager;
    private NotificationChannelHelper mNotificationChannelHelper;
    private PackageManager mPackageManager;

    public NotifyOpenNetworksPreferenceController(
            Context context,
            NetworkScoreManagerWrapper networkScoreManager,
            NotificationChannelHelper notificationChannelHelper,
            PackageManager packageManager) {
    public NotifyOpenNetworksPreferenceController(Context context, Lifecycle lifecycle) {
        super(context);
        mNetworkScoreManager = networkScoreManager;
        mNotificationChannelHelper = notificationChannelHelper;
        mPackageManager = packageManager;
        lifecycle.addObserver(this);
    }

    @Override
    public String getPreferenceKey() {
        return KEY_NOTIFY_OPEN_NETWORKS;
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mSettingObserver = new SettingObserver(screen.findPreference(KEY_NOTIFY_OPEN_NETWORKS));
    }

    @Override
    public void onResume() {
        if (mSettingObserver != null) {
            mSettingObserver.register(mContext.getContentResolver(), true /* register */);
        }
    }

    @Override
    public void onPause() {
        if (mSettingObserver != null) {
            mSettingObserver.register(mContext.getContentResolver(), false /* register */);
        }
    }

    @Override
    public boolean isAvailable() {
        return getNotificationChannel() != null;
        return true;
    }

    @Override
@@ -73,50 +78,57 @@ public class NotifyOpenNetworksPreferenceController extends PreferenceController
        if (!TextUtils.equals(preference.getKey(), KEY_NOTIFY_OPEN_NETWORKS)) {
            return false;
        }
        NetworkScorerAppData scorer = mNetworkScoreManager.getActiveScorer();
        if (scorer == null) {
        if (!(preference instanceof SwitchPreference)) {
            return false;
        }

        Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
        intent.putExtra(Settings.EXTRA_CHANNEL_ID,
                scorer.getNetworkAvailableNotificationChannelId());
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, scorer.getRecommendationServicePackageName());
        mContext.startActivity(intent);
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
                ((SwitchPreference) preference).isChecked() ? 1 : 0);
        return true;
    }

    @Override
    public String getPreferenceKey() {
        return KEY_NOTIFY_OPEN_NETWORKS;
    }

    @Override
    public void updateState(Preference preference) {
        NotificationChannelWrapper channel = getNotificationChannel();
        if (channel == null) {
            preference.setSummary(null);
        if (!(preference instanceof SwitchPreference)) {
            return;
        }
        final SwitchPreference notifyOpenNetworks = (SwitchPreference) preference;
        notifyOpenNetworks.setChecked(Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
        notifyOpenNetworks.setEnabled(Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1);
    }

    class SettingObserver extends ContentObserver {
        private final Uri NETWORK_RECOMMENDATIONS_ENABLED_URI =
                Settings.Global.getUriFor(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED);

        private final Preference mPreference;

        public SettingObserver(Preference preference) {
            super(new Handler());
            mPreference = preference;
        }

        public void register(ContentResolver cr, boolean register) {
            if (register) {
                cr.registerContentObserver(NETWORK_RECOMMENDATIONS_ENABLED_URI, false, this);
            } else {
            preference.setSummary(channel.getImportance() != NotificationManager.IMPORTANCE_NONE ?
                    R.string.notification_toggle_on : R.string.notification_toggle_off);
        }
    }

    @Nullable
    private NotificationChannelWrapper getNotificationChannel() {
        NetworkScorerAppData scorer = mNetworkScoreManager.getActiveScorer();
        if (scorer == null) {
            return null;
        }
        String packageName = scorer.getRecommendationServicePackageName();
        String channelId = scorer.getNetworkAvailableNotificationChannelId();
        if (packageName == null || channelId == null) {
            return null;
        }
        try {
            return mNotificationChannelHelper.getNotificationChannelForPackage(
                    packageName,
                    mPackageManager.getPackageUid(packageName, 0 /* flags */),
                    channelId,
                    false /* includeDeleted */ );
        } catch (RemoteException | PackageManager.NameNotFoundException e) {
            Log.d(TAG, "Failed to get notification channel.", e);
            return null;
                cr.unregisterContentObserver(this);
            }
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            if (NETWORK_RECOMMENDATIONS_ENABLED_URI.equals(uri)) {
                updateState(mPreference);
            }
        }
    }
}
+39 −94
Original line number Diff line number Diff line
@@ -16,29 +16,26 @@

package com.android.settings.wifi;

import static android.provider.Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED;
import static android.provider.Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.when;

import android.app.NotificationManager;
import android.content.ComponentName;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.content.Context;
import android.content.pm.PackageManager;
import android.net.NetworkScorerAppData;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import com.android.settings.R;

import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.network.NetworkScoreManagerWrapper;
import com.android.settings.utils.NotificationChannelHelper;
import com.android.settings.utils.NotificationChannelHelper.NotificationChannelWrapper;
import com.android.settings.core.lifecycle.Lifecycle;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@@ -47,123 +44,71 @@ import org.robolectric.annotation.Config;
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class NotifyOpenNetworkPreferenceControllerTest {

    private static final String TEST_SCORER_PACKAGE = "Test Package";
    private static final String TEST_SCORER_CLASS = "Test Class";
    private static final String TEST_SCORER_LABEL = "Test Label";
    private static final String NOTIFICATION_ID = "Notification Id";
    private static final CharSequence NOTIFICATION_NAME = "Notification Name";

    private Context mContext;
    private NotifyOpenNetworksPreferenceController mController;
    @Mock private NetworkScoreManagerWrapper mNetworkScorer;
    @Mock private NotificationChannelHelper mNotificationChannelHelper;
    @Mock private PackageManager mPackageManager;
    @Mock private NotificationChannelWrapper mChannel;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        mController = new NotifyOpenNetworksPreferenceController(
                mContext, mNetworkScorer, mNotificationChannelHelper, mPackageManager);
        ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE, TEST_SCORER_CLASS);

        NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
                0, scorer, TEST_SCORER_LABEL, null /* enableUseOpenWifiActivity */,
                NOTIFICATION_ID);
        when(mNetworkScorer.getActiveScorer()).thenReturn(scorerAppData);
    }

    @Test
    public void testIsAvailable_shouldReturnFalseWhenScorerDoesNotExist()
            throws RemoteException {
        when(mNetworkScorer.getActiveScorer()).thenReturn(null);

        assertThat(mController.isAvailable()).isFalse();
    }

    @Test
    public void testIsAvailable_shouldReturnFalseWhenNotificationChannelIdDoesNotExist()
            throws RemoteException {
        ComponentName scorer = new ComponentName(TEST_SCORER_PACKAGE, TEST_SCORER_CLASS);
        NetworkScorerAppData scorerAppData = new NetworkScorerAppData(
                0, scorer, TEST_SCORER_LABEL, null /* enableUseOpenWifiActivity */,
                null /* networkAvailableNotificationChannelId */);
        when(mNetworkScorer.getActiveScorer()).thenReturn(scorerAppData);

        assertThat(mController.isAvailable()).isFalse();
    }

    @Test
    public void testIsAvailable_shouldReturnFalseWhenNotificationChannelDoesNotExist()
            throws RemoteException {
        when(mNotificationChannelHelper.getNotificationChannelForPackage(
                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(null);

        assertThat(mController.isAvailable()).isFalse();
        mController = new NotifyOpenNetworksPreferenceController(mContext, mock(Lifecycle.class));
    }

    @Test
    public void testIsAvailable_shouldReturnTrueWhenNotificationChannelExists()
            throws RemoteException {
        when(mNotificationChannelHelper.getNotificationChannelForPackage(
                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(mChannel);

    public void testIsAvailable_shouldAlwaysReturnTrue() {
        assertThat(mController.isAvailable()).isTrue();
    }

    @Test
    public void handlePreferenceTreeClick_nonMatchingKey_shouldDoNothing() {
        final Preference pref = new Preference(mContext);
        final SwitchPreference pref = new SwitchPreference(mContext);

        assertThat(mController.handlePreferenceTreeClick(pref)).isFalse();
    }

    @Test
    public void handlePreferenceTreeClick_nullScorer_shouldDoNothing() {
    public void handlePreferenceTreeClick_nonMatchingType_shouldDoNothing() {
        final Preference pref = new Preference(mContext);
        pref.setKey(mController.getPreferenceKey());
        when(mNetworkScorer.getActiveScorer()).thenReturn(null);

        assertThat(mController.handlePreferenceTreeClick(pref)).isFalse();
    }

    @Test
    public void handlePreferenceTreeClick_matchingKeyAndScorerExists_shouldLaunchActivity()
            throws RemoteException {
        final Preference pref = new Preference(mContext);
    public void handlePreferenceTreeClick_matchingKeyAndType_shouldUpdateSetting() {
        final SwitchPreference pref = new SwitchPreference(mContext);
        pref.setChecked(true);
        pref.setKey(mController.getPreferenceKey());
        when(mNotificationChannelHelper.getNotificationChannelForPackage(
                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(mChannel);

        assertThat(mController.handlePreferenceTreeClick(pref)).isTrue();
        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
                WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0))
                .isEqualTo(1);
    }

    @Test
    public void updateState_notificationsEnabled_shouldShowEnabledSummary() throws RemoteException {
        final Preference pref = new Preference(mContext);
        pref.setKey(mController.getPreferenceKey());
        when(mNotificationChannelHelper.getNotificationChannelForPackage(
                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(mChannel);
        when(mChannel.getImportance()).thenReturn(NotificationManager.IMPORTANCE_DEFAULT);
        mController.updateState(pref);
    public void updateState_preferenceSetCheckedAndSetEnabledWhenSettingsAreEnabled() {
        final SwitchPreference preference = mock(SwitchPreference.class);
        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
        Settings.System.putInt(mContext.getContentResolver(),
                WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1);

        mController.updateState(preference);

        assertThat(pref.getSummary()).isEqualTo(
                mContext.getString(R.string.notification_toggle_on));
        verify(preference).setChecked(true);
        verify(preference).setEnabled(true);
    }

    @Test
    public void updateState_notificationsEnabled_shouldShowDisabledSummary()
            throws RemoteException {
        final Preference pref = new Preference(mContext);
        pref.setKey(mController.getPreferenceKey());
        when(mNotificationChannelHelper.getNotificationChannelForPackage(
                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(mChannel);
        when(mChannel.getImportance()).thenReturn(NotificationManager.IMPORTANCE_NONE);
        mController.updateState(pref);
    public void updateState_preferenceSetCheckedAndSetEnabledWhenSettingsAreDisabled() {
        final SwitchPreference preference = mock(SwitchPreference.class);
        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 0);
        Settings.System.putInt(mContext.getContentResolver(),
                WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0);

        assertThat(pref.getSummary()).isEqualTo(
                mContext.getString(R.string.notification_toggle_off));
    }
        mController.updateState(preference);

        verify(preference).setChecked(false);
        verify(preference).setEnabled(false);
    }
}