Stop using notification for IME switcher

InputMethodManagerService has had logic to show notifications when the
IME switcher icon cannot be shown on NavigationBar[1][2][3][4][5].

With this CL, such a fallback behavior is completely removed.  Devices
and form-factors that need a special handling need to come up with
their own solution rather than relying on this historical notification
mechanism.

 [1]: I2b9e955003c1f6703978824c947d5f322a039714
      7cfc0ed21a3fafabafb40b38a8589808ad1517af
 [2]: Id36c8c34159bea8b72557b40bcf024d401f580b6
      01065a5719414b0855da2820beb9bd4a6459ba1b
 [3]: I34a95732ef3e7c20d6549b57230c11f0c3db04d6
      d4b625994f7664666ac7b53bf6a7d79a6459b3f1
 [4]: I58421143bee25be459f4f744688b37614a750051
      f62c0b837a6d2f20b103db749c5cb46ada9f9e43
 [5]: I6ad818fc9ef08991e24c5020498243f1fc417998
      24ab9e18a74b052e4f5b8fb04c48d7f16ea071ae

Bug: 245989733
Test: atest CtsPermission2TestCases:ProtectedBroadcastsTest
Test: presubmit
Change-Id: I3b09d2b05ba9bde686b360b9f720b5d4258551c3
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index 681b46a..0489dc81 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -35,7 +35,10 @@
 
 // Manages the NotificationChannels used by the frameworks itself.
 public class SystemNotificationChannels {
-    public static String VIRTUAL_KEYBOARD  = "VIRTUAL_KEYBOARD";
+    /**
+     * @deprecated Legacy system channel, which is no longer used,
+     */
+    @Deprecated public static String VIRTUAL_KEYBOARD  = "VIRTUAL_KEYBOARD";
     public static String PHYSICAL_KEYBOARD = "PHYSICAL_KEYBOARD";
     public static String SECURITY = "SECURITY";
     public static String CAR_MODE = "CAR_MODE";
@@ -72,13 +75,6 @@
     public static void createAll(Context context) {
         final NotificationManager nm = context.getSystemService(NotificationManager.class);
         List<NotificationChannel> channelsList = new ArrayList<NotificationChannel>();
-        final NotificationChannel keyboard = new NotificationChannel(
-                VIRTUAL_KEYBOARD,
-                context.getString(R.string.notification_channel_virtual_keyboard),
-                NotificationManager.IMPORTANCE_LOW);
-        keyboard.setBlockable(true);
-        channelsList.add(keyboard);
-
         final NotificationChannel physicalKeyboardChannel = new NotificationChannel(
                 PHYSICAL_KEYBOARD,
                 context.getString(R.string.notification_channel_physical_keyboard),
@@ -237,6 +233,7 @@
     /** Remove notification channels which are no longer used */
     public static void removeDeprecated(Context context) {
         final NotificationManager nm = context.getSystemService(NotificationManager.class);
+        nm.deleteNotificationChannel(VIRTUAL_KEYBOARD);
         nm.deleteNotificationChannel(DEVICE_ADMIN_DEPRECATED);
         nm.deleteNotificationChannel(SYSTEM_CHANGES_DEPRECATED);
     }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1f23eb6..6ce31fc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -668,7 +668,6 @@
     <protected-broadcast android:name="android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED" />
     <protected-broadcast android:name="android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
     <protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
-    <protected-broadcast android:name="com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
 
     <!-- Time zone rules update intents fired by the system server -->
     <protected-broadcast android:name="com.android.intent.action.timezone.RULES_UPDATE_OPERATION" />
diff --git a/core/res/res/drawable-hdpi/ic_notification_ime_default.png b/core/res/res/drawable-hdpi/ic_notification_ime_default.png
deleted file mode 100644
index 369c88d..0000000
--- a/core/res/res/drawable-hdpi/ic_notification_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_notification_ime_default.png b/core/res/res/drawable-mdpi/ic_notification_ime_default.png
deleted file mode 100644
index 7d97eb5..0000000
--- a/core/res/res/drawable-mdpi/ic_notification_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_notification_ime_default.png b/core/res/res/drawable-xhdpi/ic_notification_ime_default.png
deleted file mode 100644
index 900801a..0000000
--- a/core/res/res/drawable-xhdpi/ic_notification_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_ime_default.png b/core/res/res/drawable-xxhdpi/ic_notification_ime_default.png
deleted file mode 100644
index 6c8222e..0000000
--- a/core/res/res/drawable-xxhdpi/ic_notification_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5f99113..d0fca8b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -741,9 +741,6 @@
     <!-- Text shown in place of notification contents when the notification is hidden on a secure lockscreen -->
     <string name="notification_hidden_text">New notification</string>
 
-    <!-- Text shown when viewing channel settings for notifications related to the virtual keyboard -->
-    <string name="notification_channel_virtual_keyboard">Virtual keyboard</string>
-
     <!-- Text shown when viewing channel settings for notifications related to the hardware keyboard -->
     <string name="notification_channel_physical_keyboard">Physical keyboard</string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b94d799..fc55ed2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1992,7 +1992,6 @@
   <java-symbol type="color" name="config_defaultNotificationColor" />
   <java-symbol type="color" name="decor_view_status_guard" />
   <java-symbol type="color" name="decor_view_status_guard_light" />
-  <java-symbol type="drawable" name="ic_notification_ime_default" />
   <java-symbol type="drawable" name="ic_menu_refresh" />
   <java-symbol type="drawable" name="ic_settings" />
   <java-symbol type="drawable" name="ic_voice_search" />
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index a94bfe2..12e7226 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -61,7 +61,7 @@
 
     // Notify the user that they should select an input method
     // Package: android
-    NOTE_SELECT_INPUT_METHOD = 8;
+    NOTE_SELECT_INPUT_METHOD = 8 [deprecated = true];
 
     // Notify the user about limited functionality before decryption
     // Package: android
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 76331fd..76495b1 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -58,7 +58,6 @@
 import android.accessibilityservice.AccessibilityService;
 import android.annotation.AnyThread;
 import android.annotation.BinderThread;
-import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
 import android.annotation.DurationMillisLong;
 import android.annotation.EnforcePermission;
@@ -69,9 +68,6 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentProvider;
@@ -94,7 +90,6 @@
 import android.media.AudioManagerInternal;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
@@ -170,8 +165,6 @@
 import com.android.internal.inputmethod.StartInputFlags;
 import com.android.internal.inputmethod.StartInputReason;
 import com.android.internal.inputmethod.UnbindReason;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ConcurrentUtils;
@@ -255,13 +248,6 @@
     private static final String HANDLER_THREAD_NAME = "android.imms";
 
     /**
-     * A protected broadcast intent action for internal use for {@link PendingIntent} in
-     * the notification.
-     */
-    private static final String ACTION_SHOW_INPUT_METHOD_PICKER =
-            "com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER";
-
-    /**
      * When set, {@link #startInputUncheckedLocked} will return
      * {@link InputBindResult#NO_EDITOR} instead of starting an IME connection
      * unless {@link StartInputFlags#IS_TEXT_EDITOR} is set. This behavior overrides
@@ -334,13 +320,8 @@
     @GuardedBy("ImfLock.class")
     private int mDisplayIdToShowIme = INVALID_DISPLAY;
 
-    // Ongoing notification
-    private NotificationManager mNotificationManager;
     @Nullable private StatusBarManagerInternal mStatusBarManagerInternal;
-    private final Notification.Builder mImeSwitcherNotification;
-    private final PendingIntent mImeSwitchPendingIntent;
     private boolean mShowOngoingImeSwitcherForPhones;
-    private boolean mNotificationShown;
     @GuardedBy("ImfLock.class")
     private final HandwritingModeController mHwController;
     @GuardedBy("ImfLock.class")
@@ -1253,17 +1234,6 @@
                 return;
             } else if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
                 onActionLocaleChanged();
-            } else if (ACTION_SHOW_INPUT_METHOD_PICKER.equals(action)) {
-                // ACTION_SHOW_INPUT_METHOD_PICKER action is a protected-broadcast and it is
-                // guaranteed to be send only from the system, so that there is no need for extra
-                // security check such as
-                // {@link #canShowInputMethodPickerLocked(IInputMethodClient)}.
-                mHandler.obtainMessage(
-                        MSG_SHOW_IM_SUBTYPE_PICKER,
-                        // TODO(b/120076400): Design and implement IME switcher for heterogeneous
-                        // navbar configuration.
-                        InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES,
-                        DEFAULT_DISPLAY).sendToTarget();
             } else {
                 Slog.w(TAG, "Unexpected intent " + intent);
             }
@@ -1720,27 +1690,8 @@
 
         mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime);
 
-        Bundle extras = new Bundle();
-        extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true);
-        @ColorInt final int accentColor = mContext.getColor(
-                com.android.internal.R.color.system_notification_accent_color);
-        mImeSwitcherNotification =
-                new Notification.Builder(mContext, SystemNotificationChannels.VIRTUAL_KEYBOARD)
-                        .setSmallIcon(com.android.internal.R.drawable.ic_notification_ime_default)
-                        .setWhen(0)
-                        .setOngoing(true)
-                        .addExtras(extras)
-                        .setCategory(Notification.CATEGORY_SYSTEM)
-                        .setColor(accentColor);
-
-        Intent intent = new Intent(ACTION_SHOW_INPUT_METHOD_PICKER)
-                .setPackage(mContext.getPackageName());
-        mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_IMMUTABLE);
-
         mShowOngoingImeSwitcherForPhones = false;
 
-        mNotificationShown = false;
         final int userId = mActivityManagerInternal.getCurrentUserId();
 
         mLastSwitchUserId = userId;
@@ -1939,7 +1890,6 @@
                 final int currentUserId = mSettings.getCurrentUserId();
                 mSettings.switchCurrentUser(currentUserId,
                         !mUserManagerInternal.isUserUnlockingOrUnlocked(currentUserId));
-                mNotificationManager = mContext.getSystemService(NotificationManager.class);
                 mStatusBarManagerInternal =
                         LocalServices.getService(StatusBarManagerInternal.class);
                 hideStatusBarIconLocked();
@@ -1977,7 +1927,6 @@
                 broadcastFilterForSystemUser.addAction(Intent.ACTION_USER_ADDED);
                 broadcastFilterForSystemUser.addAction(Intent.ACTION_USER_REMOVED);
                 broadcastFilterForSystemUser.addAction(Intent.ACTION_LOCALE_CHANGED);
-                broadcastFilterForSystemUser.addAction(ACTION_SHOW_INPUT_METHOD_PICKER);
                 mContext.registerReceiver(new ImmsBroadcastReceiverForSystemUser(),
                         broadcastFilterForSystemUser);
 
@@ -3159,41 +3108,6 @@
                 mStatusBarManagerInternal.setImeWindowStatus(mCurTokenDisplayId,
                         getCurTokenLocked(), vis, backDisposition, needsToShowImeSwitcher);
             }
-            final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked());
-            if (imi != null && needsToShowImeSwitcher) {
-                // Used to load label
-                final CharSequence title = mRes.getText(
-                        com.android.internal.R.string.select_input_method);
-                final int currentUserId = mSettings.getCurrentUserId();
-                final Context userAwareContext = mContext.getUserId() == currentUserId
-                        ? mContext
-                        : mContext.createContextAsUser(UserHandle.of(currentUserId), 0 /* flags */);
-                final CharSequence summary = InputMethodUtils.getImeAndSubtypeDisplayName(
-                        userAwareContext, imi, mCurrentSubtype);
-                mImeSwitcherNotification.setContentTitle(title)
-                        .setContentText(summary)
-                        .setContentIntent(mImeSwitchPendingIntent);
-                // TODO(b/120076400): Figure out what is the best behavior
-                if ((mNotificationManager != null)
-                        && !mWindowManagerInternal.hasNavigationBar(DEFAULT_DISPLAY)) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "--- show notification: label =  " + summary);
-                    }
-                    mNotificationManager.notifyAsUser(null,
-                            SystemMessage.NOTE_SELECT_INPUT_METHOD,
-                            mImeSwitcherNotification.build(), UserHandle.ALL);
-                    mNotificationShown = true;
-                }
-            } else {
-                if (mNotificationShown && mNotificationManager != null) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "--- hide notification");
-                    }
-                    mNotificationManager.cancelAsUser(null,
-                            SystemMessage.NOTE_SELECT_INPUT_METHOD, UserHandle.ALL);
-                    mNotificationShown = false;
-                }
-            }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index c7ff8ca..ebf9237d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -179,16 +179,6 @@
         }
     }
 
-    static CharSequence getImeAndSubtypeDisplayName(Context context, InputMethodInfo imi,
-            InputMethodSubtype subtype) {
-        final CharSequence imiLabel = imi.loadLabel(context.getPackageManager());
-        return subtype != null
-                ? TextUtils.concat(subtype.getDisplayName(context,
-                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
-                                (TextUtils.isEmpty(imiLabel) ? "" : " - " + imiLabel))
-                : imiLabel;
-    }
-
     /**
      * Returns true if a package name belongs to a UID.
      *
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 32feb6c..c206a15 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -613,15 +613,6 @@
             @NonNull IBinder imeTargetWindowToken);
 
     /**
-     * Returns the presence of a software navigation bar on the specified display.
-     *
-     * @param displayId the id of display to check if there is a software navigation bar.
-     * @return {@code true} if there is a software navigation. {@code false} otherwise, including
-     *         the case when the specified display does not exist.
-     */
-    public abstract boolean hasNavigationBar(int displayId);
-
-    /**
       * Returns true when the hardware keyboard is available.
       */
     public abstract boolean isHardKeyboardAvailable();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c17af30..a5cd8a9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7917,11 +7917,6 @@
         }
 
         @Override
-        public boolean hasNavigationBar(int displayId) {
-            return WindowManagerService.this.hasNavigationBar(displayId);
-        }
-
-        @Override
         public boolean isHardKeyboardAvailable() {
             synchronized (mGlobalLock) {
                 return mHardKeyboardAvailable;