private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) {
   if (imi != null) {
     if (DEBUG) {
       Log.d(TAG, "Update icons of IME: " + imi.getPackageName());
       if (subtype != null) {
         Log.d(TAG, "subtype =" + subtype.getLocale() + "," + subtype.getMode());
       }
     }
     if (subtype != null) {
       return mPackageManager.getDrawable(
           imi.getPackageName(), subtype.getIconResId(), imi.getServiceInfo().applicationInfo);
     } else if (imi.getSubtypeCount() > 0) {
       return mPackageManager.getDrawable(
           imi.getPackageName(),
           imi.getSubtypeAt(0).getIconResId(),
           imi.getServiceInfo().applicationInfo);
     } else {
       try {
         return mPackageManager
             .getApplicationInfo(imi.getPackageName(), 0)
             .loadIcon(mPackageManager);
       } catch (PackageManager.NameNotFoundException e) {
         Log.w(TAG, "IME can't be found: " + imi.getPackageName());
       }
     }
   }
   return null;
 }
示例#2
0
 public static boolean checkIfSubtypeBelongsToThisIme(Context context, InputMethodSubtype ims) {
   final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context);
   final int count = myImi.getSubtypeCount();
   for (int i = 0; i < count; i++) {
     final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
     if (subtype.equals(ims)) {
       return true;
     }
   }
   return false;
 }
示例#3
0
 public static boolean checkIfSubtypeBelongsToThisImeAndEnabled(
     Context context, InputMethodSubtype ims) {
   final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context);
   final InputMethodManager imm = getInputMethodManager(context);
   // TODO: Cache all subtypes of this IME for optimization
   final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(myImi, true);
   for (final InputMethodSubtype subtype : subtypes) {
     if (subtype.equals(ims)) {
       return true;
     }
   }
   return false;
 }
示例#4
0
 public static InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(
     Context context, String localeString, String keyboardLayoutSetName) {
   final InputMethodInfo imi = getInputMethodInfoOfThisIme(context);
   final int count = imi.getSubtypeCount();
   for (int i = 0; i < count; i++) {
     final InputMethodSubtype subtype = imi.getSubtypeAt(i);
     final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
     if (localeString.equals(subtype.getLocale()) && keyboardLayoutSetName.equals(layoutName)) {
       return subtype;
     }
   }
   return null;
 }
 private CharSequence getSubtypeName(InputMethodInfo imi, InputMethodSubtype subtype) {
   if (imi == null || subtype == null) return null;
   if (DEBUG) {
     Log.d(
         TAG,
         "Get text from: "
             + imi.getPackageName()
             + subtype.getNameResId()
             + imi.getServiceInfo().applicationInfo);
   }
   return subtype.getDisplayName(
       mContext, imi.getPackageName(), imi.getServiceInfo().applicationInfo);
 }
示例#6
0
  private static boolean hasMultipleEnabledSubtypes(
      Context context,
      final boolean shouldIncludeAuxiliarySubtypes,
      List<InputMethodInfo> imiList) {
    final InputMethodManager imm = getInputMethodManager(context);

    // Number of the filtered IMEs
    int filteredImisCount = 0;

    for (InputMethodInfo imi : imiList) {
      // We can return true immediately after we find two or more filtered IMEs.
      if (filteredImisCount > 1) return true;
      final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true);
      // IMEs that have no subtypes should be counted.
      if (subtypes.isEmpty()) {
        ++filteredImisCount;
        continue;
      }

      int auxCount = 0;
      for (InputMethodSubtype subtype : subtypes) {
        if (subtype.isAuxiliary()) {
          ++auxCount;
        }
      }
      final int nonAuxCount = subtypes.size() - auxCount;

      // IMEs that have one or more non-auxiliary subtypes should be counted.
      // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
      // subtypes should be counted as well.
      if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
        ++filteredImisCount;
        continue;
      }
    }

    if (filteredImisCount > 1) {
      return true;
    }
    final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(null, true);
    int keyboardCount = 0;
    // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's
    // both explicitly and implicitly enabled input method subtype.
    // (The current IME should be LatinIME.)
    for (InputMethodSubtype subtype : subtypes) {
      if (KEYBOARD_MODE.equals(subtype.getMode())) {
        ++keyboardCount;
      }
    }
    return keyboardCount > 1;
  }
    public SubtypeLocaleAdapter(Context context) {
      super(context, android.R.layout.simple_spinner_item);
      setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

      final TreeSet<SubtypeLocaleItem> items = new TreeSet<SubtypeLocaleItem>();
      final InputMethodInfo imi = ImfUtils.getInputMethodInfoOfThisIme(context);
      final int count = imi.getSubtypeCount();
      for (int i = 0; i < count; i++) {
        final InputMethodSubtype subtype = imi.getSubtypeAt(i);
        if (subtype.containsExtraValueKey(ASCII_CAPABLE)) {
          items.add(createItem(context, subtype.getLocale()));
        }
      }
      // TODO: Should filter out already existing combinations of locale and layout.
      addAll(items);
    }
 private View createInputMethodItem(final InputMethodInfo imi, final InputMethodSubtype subtype) {
   final CharSequence subtypeName;
   if (subtype == null || subtype.overridesImplicitlyEnabledSubtype()) {
     subtypeName = null;
   } else {
     subtypeName = getSubtypeName(imi, subtype);
   }
   final CharSequence imiName = getIMIName(imi);
   final Drawable icon = getSubtypeIcon(imi, subtype);
   final View view = View.inflate(mContext, R.layout.system_bar_input_methods_item, null);
   final ImageView subtypeIcon = (ImageView) view.findViewById(R.id.item_icon);
   final TextView itemTitle = (TextView) view.findViewById(R.id.item_title);
   final TextView itemSubtitle = (TextView) view.findViewById(R.id.item_subtitle);
   final ImageView settingsIcon = (ImageView) view.findViewById(R.id.item_settings_icon);
   final View subtypeView = view.findViewById(R.id.item_subtype);
   if (subtypeName == null) {
     itemTitle.setText(imiName);
     itemSubtitle.setVisibility(View.GONE);
   } else {
     itemTitle.setText(subtypeName);
     itemSubtitle.setVisibility(View.VISIBLE);
     itemSubtitle.setText(imiName);
   }
   subtypeIcon.setImageDrawable(icon);
   subtypeIcon.setContentDescription(itemTitle.getText());
   final String settingsActivity = imi.getSettingsActivity();
   if (!TextUtils.isEmpty(settingsActivity)) {
     settingsIcon.setOnClickListener(
         new View.OnClickListener() {
           @Override
           public void onClick(View arg0) {
             Intent intent = new Intent(Intent.ACTION_MAIN);
             intent.setClassName(imi.getPackageName(), settingsActivity);
             intent.setFlags(
                 Intent.FLAG_ACTIVITY_NEW_TASK
                     | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
             startActivity(intent);
             closePanel(true);
           }
         });
   } else {
     // Do not show the settings icon if the IME does not have a settings preference
     view.findViewById(R.id.item_vertical_separator).setVisibility(View.GONE);
     settingsIcon.setVisibility(View.GONE);
   }
   mRadioViewAndImiMap.put(
       subtypeView, new Pair<InputMethodInfo, InputMethodSubtype>(imi, subtype));
   subtypeView.setOnClickListener(
       new View.OnClickListener() {
         @Override
         public void onClick(View v) {
           Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype = updateRadioButtonsByView(v);
           closePanel(false);
           setInputMethodAndSubtype(imiAndSubtype.first, imiAndSubtype.second);
         }
       });
   return view;
 }
 private static String getEnabledSubtypesLabel(
     Context context, InputMethodManager imm, InputMethodInfo imi) {
   if (context == null || imm == null || imi == null) return null;
   final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true);
   final StringBuilder sb = new StringBuilder();
   final int N = subtypes.size();
   for (int i = 0; i < N; ++i) {
     final InputMethodSubtype subtype = subtypes.get(i);
     if (sb.length() > 0) {
       sb.append(", ");
     }
     sb.append(
         subtype.getDisplayName(
             context, imi.getPackageName(), imi.getServiceInfo().applicationInfo));
   }
   return sb.toString();
 }
示例#10
0
  @SuppressWarnings("deprecation") // InputMethodSubtype.getLocale() deprecated in API 24
  private void recordKeyboardLocaleUma() {
    InputMethodManager imm =
        (InputMethodManager) mAppContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    List<InputMethodInfo> ims = imm.getEnabledInputMethodList();
    ArrayList<String> uniqueLanguages = new ArrayList<>();
    for (InputMethodInfo method : ims) {
      List<InputMethodSubtype> submethods = imm.getEnabledInputMethodSubtypeList(method, true);
      for (InputMethodSubtype submethod : submethods) {
        if (submethod.getMode().equals("keyboard")) {
          String language = submethod.getLocale().split("_")[0];
          if (!uniqueLanguages.contains(language)) {
            uniqueLanguages.add(language);
          }
        }
      }
    }
    RecordHistogram.recordCountHistogram("InputMethod.ActiveCount", uniqueLanguages.size());

    InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype();
    Locale systemLocale = Locale.getDefault();
    if (currentSubtype != null && currentSubtype.getLocale() != null && systemLocale != null) {
      String keyboardLanguage = currentSubtype.getLocale().split("_")[0];
      boolean match = systemLocale.getLanguage().equalsIgnoreCase(keyboardLanguage);
      RecordHistogram.recordBooleanHistogram("InputMethod.MatchesSystemLanguage", match);
    }
  }
  /**
   * Method adapted from com.android.inputmethod.latin.Utils
   *
   * @param imm The input method manager
   * @param shouldIncludeAuxiliarySubtypes
   * @return true if we have multiple IMEs to choose from
   */
  private boolean hasMultipleEnabledIMEsOrSubtypes(
      InputMethodManager imm, final boolean shouldIncludeAuxiliarySubtypes) {
    final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();

    // Number of the filtered IMEs
    int filteredImisCount = 0;

    for (InputMethodInfo imi : enabledImis) {
      // We can return true immediately after we find two or more filtered IMEs.
      if (filteredImisCount > 1) return true;
      final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true);
      // IMEs that have no subtypes should be counted.
      if (subtypes.isEmpty()) {
        ++filteredImisCount;
        continue;
      }

      int auxCount = 0;
      for (InputMethodSubtype subtype : subtypes) {
        if (subtype.isAuxiliary()) {
          ++auxCount;
        }
      }
      final int nonAuxCount = subtypes.size() - auxCount;

      // IMEs that have one or more non-auxiliary subtypes should be counted.
      // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
      // subtypes should be counted as well.
      if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
        ++filteredImisCount;
        continue;
      }
    }

    return filteredImisCount > 1
        // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
        // input method subtype (The current IME should be LatinIME.)
        || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
  }
 public void setSubtype(InputMethodSubtype subtype) {
   mPreviousSubtype = mSubtype;
   mSubtype = subtype;
   if (isIncomplete()) {
     setTitle(null);
     setDialogTitle(R.string.add_style);
     setKey(KEY_NEW_SUBTYPE);
   } else {
     final String displayName =
         SubtypeLocale.getSubtypeDisplayName(subtype, getContext().getResources());
     setTitle(displayName);
     setDialogTitle(displayName);
     setKey(
         KEY_PREFIX
             + subtype.getLocale()
             + "_"
             + SubtypeLocale.getKeyboardLayoutSetName(subtype));
   }
 }
 @Override
 protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
   final Context context = builder.getContext();
   builder.setCancelable(true).setOnCancelListener(this);
   if (isIncomplete()) {
     builder
         .setPositiveButton(R.string.add, this)
         .setNegativeButton(android.R.string.cancel, this);
   } else {
     builder
         .setPositiveButton(R.string.save, this)
         .setNeutralButton(android.R.string.cancel, this)
         .setNegativeButton(R.string.remove, this);
     final SubtypeLocaleItem localeItem =
         SubtypeLocaleAdapter.createItem(context, mSubtype.getLocale());
     final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(mSubtype);
     setSpinnerPosition(mSubtypeLocaleSpinner, localeItem);
     setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem);
   }
 }
示例#14
0
 @Override
 public String toString() {
   return String.format(
       "[%s %s:%s %s%d %s %s %s%s%s%s%s%s%s%s]",
       elementIdToName(mElementId),
       mLocale,
       mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
       (mOrientation == 1 ? "port" : "land"),
       mWidth,
       modeName(mMode),
       imeAction(),
       (navigateNext() ? "navigateNext" : ""),
       (navigatePrevious() ? "navigatePrevious" : ""),
       (mClobberSettingsKey ? " clobberSettingsKey" : ""),
       (passwordInput() ? " passwordInput" : ""),
       (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
       (mHasShortcutKey ? " hasShortcutKey" : ""),
       (mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""),
       (isMultiLine() ? "isMultiLine" : ""));
 }
 private InputMethodSubtype findDuplicatedSubtype(InputMethodSubtype subtype) {
   final String localeString = subtype.getLocale();
   final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
   return ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
       getActivity(), localeString, keyboardLayoutSetName);
 }
 public boolean hasBeenModified() {
   return mSubtype != null && !mSubtype.equals(mPreviousSubtype);
 }