Move AP Band Conversion notification to Settings

SettingsBackupAgent will send out the notification
itself instead of delegating it to WifiManager.

Bug: 144218444
Test: Removed AP Band conversion check to always trigger
notification when restoring from backup.
Follow steps at: https://developer.android.com/guide/topics/data/testingbackup
Verified that notification is displayed when restoring
from backup.
Verified that expanding notification by dragging down
shows full notification text.
Verified tapping on the notification opens the tethering
Settings page, and also dismissed the notification.

Change-Id: I729b1cbf443229687c086982d51b96f326b534e1
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index 681b494..f40d3a1 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -29,6 +29,7 @@
         "src/com/android/providers/settings/SettingsBackupAgent.java",
         "src/com/android/providers/settings/SettingsState.java",
         "src/com/android/providers/settings/SettingsHelper.java",
+        "src/com/android/providers/settings/WifiSoftApBandChangedNotifier.java",
     ],
     static_libs: [
         "androidx.test.rules",
diff --git a/packages/SettingsProvider/res/drawable/ic_wifi_settings.xml b/packages/SettingsProvider/res/drawable/ic_wifi_settings.xml
new file mode 100644
index 0000000..cb42656
--- /dev/null
+++ b/packages/SettingsProvider/res/drawable/ic_wifi_settings.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M12.584,15.93c0.026-0.194,0.044-0.397,0.044-0.608c0-0.211-0.018-0.405-0.044-0.608l1.304-1.022
+c0.115-0.088,0.15-0.256,0.071-0.397l-1.234-2.133c-0.071-0.132-0.238-0.185-0.379-0.132l-1.533,0.617
+c-0.317-0.247-0.67-0.449-1.04-0.608L9.535,9.4c-0.018-0.132-0.141-0.247-0.3-0.247H6.768c-0.15,0-0.282,0.115-0.3,0.256
+L6.23,11.048c-0.379,0.159-0.723,0.361-1.04,0.608l-1.533-0.617c-0.141-0.053-0.3,0-0.379,0.132l-1.234,2.133
+c-0.079,0.132-0.044,0.3,0.07,0.397l1.304,1.022c-0.026,0.194-0.044,0.405-0.044,0.608s0.018,0.405,0.044,0.608l-1.304,1.022
+c-0.115,0.088-0.15,0.256-0.07,0.397l1.234,2.133c0.07,0.132,0.238,0.185,0.379,0.132l1.533-0.617
+c0.317,0.247,0.67,0.449,1.04,0.608l0.238,1.639c0.018,0.15,0.15,0.256,0.3,0.256h2.467c0.159,0,0.282-0.115,0.3-0.256
+l0.238-1.639c0.379-0.15,0.723-0.361,1.04-0.608l1.533,0.617c0.141,0.053,0.3,0,0.379-0.132l1.234-2.133
+c0.071-0.132,0.044-0.3-0.07-0.397L12.584,15.93z
+M8.002,17.481c-1.19,0-2.159-0.969-2.159-2.159s0.969-2.159,2.159-2.159
+s2.159,0.969,2.159,2.159C10.161,16.512,9.191,17.481,8.002,17.481z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M16.003,12.026l5.995-7.474c-0.229-0.172-2.537-2.06-6-2.06s-5.771,1.889-6,2.06l5.995,7.469l0.005,0.01L16.003,12.026z" />
+</vector>
diff --git a/packages/SettingsProvider/res/values/strings.xml b/packages/SettingsProvider/res/values/strings.xml
index 9ca575e..3787727 100644
--- a/packages/SettingsProvider/res/values/strings.xml
+++ b/packages/SettingsProvider/res/values/strings.xml
@@ -19,4 +19,19 @@
 <resources>
     <!-- Name of the activity for Settings storage. -->
     <string name="app_label">Settings Storage</string>
+
+    <!-- A notification is shown when the user's softap config has been changed due to underlying
+     hardware restrictions. This is the notifications's title.
+     [CHAR_LIMIT=NONE] -->
+    <string name="wifi_softap_config_change">Changes to your hotspot settings</string>
+
+    <!-- A notification is shown when the user's softap config has been changed due to underlying
+         hardware restrictions. This is the notification's summary message.
+         [CHAR_LIMIT=NONE] -->
+    <string name="wifi_softap_config_change_summary">Your hotspot band has changed.</string>
+
+    <!-- A notification is shown when the user's softap config has been changed due to underlying
+         hardware restrictions. This is the notification's full message.
+         [CHAR_LIMIT=NONE] -->
+    <string name="wifi_softap_config_change_detailed">This device doesn\u2019t support your preference for 5GHz only. Instead, this device will use the 5GHz band when available.</string>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 7e60452..443288c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -895,11 +895,9 @@
             // the apBand preference
             boolean dualMode = mWifiManager.isDualModeSupported();
             int storedApBand = mWifiManager.getWifiApConfiguration().apBand;
-            if (dualMode) {
-                if (storedApBand != originalApBand) {
-                    Log.d(TAG, "restored ap configuration requires a conversion, notify the user");
-                    mWifiManager.notifyUserOfApBandConversion();
-                }
+            if (dualMode && storedApBand != originalApBand) {
+                Log.d(TAG, "restored ap configuration requires a conversion, notify the user");
+                WifiSoftApBandChangedNotifier.notifyUserOfApBandConversion(this);
             }
         } catch (IOException | BackupUtils.BadVersionException e) {
             Log.e(TAG, "Failed to unMarshal SoftAPConfiguration " + e.getMessage());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WifiSoftApBandChangedNotifier.java b/packages/SettingsProvider/src/com/android/providers/settings/WifiSoftApBandChangedNotifier.java
new file mode 100644
index 0000000..d0d4956
--- /dev/null
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WifiSoftApBandChangedNotifier.java
@@ -0,0 +1,88 @@
+/*
+ * 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.providers.settings;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+
+import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.internal.notification.SystemNotificationChannels;
+
+/**
+ * Helper class for sending notifications when the user's Soft AP Band was changed upon restore.
+ */
+public class WifiSoftApBandChangedNotifier {
+    private WifiSoftApBandChangedNotifier() {}
+
+    /**
+     * Send a notification informing the user that their' Soft AP Band was changed upon restore.
+     * When the user taps on the notification, they are taken to the Wifi Tethering page in
+     * Settings.
+     */
+    public static void notifyUserOfApBandConversion(Context context) {
+        NotificationManager notificationManager =
+                context.getSystemService(NotificationManager.class);
+
+        // create channel, or update it if it already exists
+        NotificationChannel channel = new NotificationChannel(
+                SystemNotificationChannels.NETWORK_STATUS,
+                context.getString(android.R.string.notification_channel_network_status),
+                NotificationManager.IMPORTANCE_LOW);
+        notificationManager.createNotificationChannel(channel);
+
+        notificationManager.notify(
+                SystemMessageProto.SystemMessage.NOTE_SOFTAP_CONFIG_CHANGED,
+                createConversionNotification(context));
+    }
+
+    private static Notification createConversionNotification(Context context) {
+        Resources resources = context.getResources();
+        CharSequence title = resources.getText(R.string.wifi_softap_config_change);
+        CharSequence contentSummary = resources.getText(R.string.wifi_softap_config_change_summary);
+        CharSequence content = resources.getText(R.string.wifi_softap_config_change_detailed);
+        int color = resources.getColor(
+                android.R.color.system_notification_accent_color, context.getTheme());
+
+        return new Notification.Builder(context, SystemNotificationChannels.NETWORK_STATUS)
+                .setSmallIcon(R.drawable.ic_wifi_settings)
+                .setPriority(Notification.PRIORITY_HIGH)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setContentTitle(title)
+                .setContentText(contentSummary)
+                .setContentIntent(getPendingActivity(context))
+                .setTicker(title)
+                .setShowWhen(false)
+                .setLocalOnly(true)
+                .setColor(color)
+                .setStyle(new Notification.BigTextStyle()
+                        .bigText(content)
+                        .setBigContentTitle(title)
+                        .setSummaryText(contentSummary))
+                .setAutoCancel(true)
+                .build();
+    }
+
+    private static PendingIntent getPendingActivity(Context context) {
+        Intent intent = new Intent("com.android.settings.WIFI_TETHER_SETTINGS")
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+}