Пример #1
0
    /**
     * Create a key with the given top-left coordinate and extract its attributes from the XML
     * parser.
     *
     * @param res resources associated with the caller's context
     * @param parent the row that this key belongs to. The row must already be attached to a {@link
     *     Keyboard}.
     * @param x the x coordinate of the top-left
     * @param y the y coordinate of the top-left
     * @param parser the XML parser containing the attributes for this key
     */
    public Key(
        Context askContext,
        Resources res,
        Row parent,
        KeyboardDimens keyboardDimens,
        int x,
        int y,
        XmlResourceParser parser) {
      this(parent, keyboardDimens);
      final Resources askResources = askContext.getResources();
      SparseIntArray attributeIdMap = parent.parent.attributeIdMap;
      this.x = x;
      this.y = y;

      // setting up some defaults
      width = Math.min(keyboardDimens.getKeyMaxWidth(), parent.defaultWidth);
      height =
          KeyboardSupport.getKeyHeightFromHeightCode(
              keyboardDimens,
              parent.defaultHeightCode,
              askResources.getConfiguration().orientation);
      gap = parent.defaultHorizontalGap;
      codes = null;
      iconPreview = null;
      popupCharacters = null;
      popupResId = 0;
      repeatable = false;
      showPreview = true;
      dynamicEmblem = KEY_EMBLEM_NONE;
      modifier = false;
      sticky = false;

      // loading data from XML
      int[] remoteKeyboardLayoutStyleable = parent.parent.remoteKeyboardLayoutStyleable;
      TypedArray a =
          res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable);
      int n = a.getIndexCount();
      for (int i = 0; i < n; i++) {
        final int remoteIndex = a.getIndex(i);
        final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]);
        setDataFromTypedArray(parent, keyboardDimens, askResources, a, remoteIndex, localAttrId);
      }
      a.recycle();
      this.x += gap;

      int[] remoteKeyboardKeyLayoutStyleable = parent.parent.remoteKeyboardKeyLayoutStyleable;
      a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardKeyLayoutStyleable);
      n = a.getIndexCount();
      for (int i = 0; i < n; i++) {
        final int remoteIndex = a.getIndex(i);
        final int localAttrId = attributeIdMap.get(remoteKeyboardKeyLayoutStyleable[remoteIndex]);
        setDataFromTypedArray(parent, keyboardDimens, askResources, a, remoteIndex, localAttrId);
      }
      externalResourcePopupLayout = popupResId != 0;
      if (codes == null && !TextUtils.isEmpty(label)) {
        codes = new int[] {label.charAt(0)};
      }
      a.recycle();
    }
Пример #2
0
 public Row(Context askContext, Resources res, Keyboard parent, XmlResourceParser parser) {
   this.parent = parent;
   // some defaults
   defaultWidth = parent.mDefaultWidth;
   defaultHeightCode = parent.mDefaultHeightCode;
   defaultHorizontalGap = parent.mDefaultHorizontalGap;
   verticalGap = parent.getVerticalGap();
   // now reading from the XML
   SparseIntArray attributeIdMap = parent.attributeIdMap;
   int[] remoteKeyboardLayoutStyleable = parent.remoteKeyboardLayoutStyleable;
   TypedArray a =
       res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable);
   int n = a.getIndexCount();
   for (int i = 0; i < n; i++) {
     final int remoteIndex = a.getIndex(i);
     final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]);
     try {
       switch (localAttrId) {
         case android.R.attr.keyWidth:
           defaultWidth =
               getDimensionOrFraction(
                   a, remoteIndex, parent.mDisplayWidth, parent.mDefaultWidth);
           break;
         case android.R.attr.keyHeight:
           defaultHeightCode = getKeyHeightCode(a, remoteIndex, parent.mDefaultHeightCode);
           break;
         case android.R.attr.horizontalGap:
           defaultHorizontalGap =
               getDimensionOrFraction(
                   a, remoteIndex, parent.mDisplayWidth, parent.mDefaultHorizontalGap);
           break;
       }
     } catch (Exception e) {
       Log.w(TAG, "Failed to set data from XML!", e);
     }
   }
   a.recycle();
   int[] remoteKeyboardRowLayoutStyleable = parent.remoteKeyboardRowLayoutStyleable;
   a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardRowLayoutStyleable);
   n = a.getIndexCount();
   for (int i = 0; i < n; i++) {
     final int remoteIndex = a.getIndex(i);
     final int localAttrId = attributeIdMap.get(remoteKeyboardRowLayoutStyleable[remoteIndex]);
     try {
       switch (localAttrId) {
         case android.R.attr.rowEdgeFlags:
           rowEdgeFlags = a.getInt(remoteIndex, 0);
           break;
         case android.R.attr.keyboardMode:
           mode = a.getResourceId(remoteIndex, 0);
           break;
       }
     } catch (Exception e) {
       Log.w(TAG, "Failed to set data from XML!", e);
     }
   }
   a.recycle();
 }
 @SuppressWarnings("unchecked")
 public synchronized T inflate(XmlPullParser parser, P root, boolean attachToRoot) {
   final AttributeSet attrs = Xml.asAttributeSet(parser);
   T result = (T) root;
   try {
     int type;
     while ((type = parser.next()) != XmlPullParser.START_TAG
         && type != XmlPullParser.END_DOCUMENT) {;
     }
     if (type != XmlPullParser.START_TAG) {
       throw new InflateException(parser.getPositionDescription() + ": No start tag found!");
     }
     T xmlRoot = createItemFromTag(parser, parser.getName(), attrs);
     result = (T) onMergeRoots(root, attachToRoot, (P) xmlRoot);
     rInflate(parser, result, attrs);
   } catch (InflateException e) {
     throw e;
   } catch (XmlPullParserException e) {
     InflateException ex = new InflateException(e.getMessage());
     ex.initCause(e);
     throw ex;
   } catch (IOException e) {
     InflateException ex =
         new InflateException(parser.getPositionDescription() + ": " + e.getMessage());
     ex.initCause(e);
     throw ex;
   }
   return result;
 }
Пример #4
0
 private void parseKeyStyle(final XmlPullParser parser, final boolean skip)
     throws XmlPullParserException, IOException {
   final AttributeSet attr = Xml.asAttributeSet(parser);
   final TypedArray keyStyleAttr =
       mResources.obtainAttributes(attr, R.styleable.Keyboard_KeyStyle);
   final TypedArray keyAttrs = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
   try {
     if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName)) {
       throw new XmlParseUtils.ParseException(
           "<" + TAG_KEY_STYLE + "/> needs styleName attribute", parser);
     }
     if (DEBUG) {
       startEndTag(
           "<%s styleName=%s />%s",
           TAG_KEY_STYLE,
           keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName),
           skip ? " skipped" : "");
     }
     if (!skip) {
       mParams.mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser);
     }
   } finally {
     keyStyleAttr.recycle();
     keyAttrs.recycle();
   }
   XmlParseUtils.checkEndTag(TAG_KEY_STYLE, parser);
 }
  public static AnimatedVectorDrawable create(Context c, Resources resources, int rid) {
    try {
      final XmlPullParser parser = resources.getXml(rid);
      final AttributeSet attrs = Xml.asAttributeSet(parser);
      int type;
      while ((type = parser.next()) != XmlPullParser.START_TAG
          && type != XmlPullParser.END_DOCUMENT) {
        // Empty loop
      }
      if (type != XmlPullParser.START_TAG) {
        throw new XmlPullParserException("No start tag found");
      } else if (!ANIMATED_VECTOR.equals(parser.getName())) {
        throw new IllegalArgumentException("root node must start with: " + ANIMATED_VECTOR);
      }

      final AnimatedVectorDrawable drawable = new AnimatedVectorDrawable();
      drawable.inflate(c, resources, parser, attrs, null);

      return drawable;
    } catch (XmlPullParserException e) {
      Log.e(LOGTAG, "parser error", e);
    } catch (IOException e) {
      Log.e(LOGTAG, "parser error", e);
    }
    return null;
  }
 private Intent parseAlias(XmlPullParser xmlpullparser)
     throws XmlPullParserException, IOException
 {
     android.util.AttributeSet attributeset = Xml.asAttributeSet(xmlpullparser);
     Intent intent = null;
     int i;
     do
         i = xmlpullparser.next();
     while (i != 1 && i != 2);
     String s = xmlpullparser.getName();
     if (!"alias".equals(s))
         throw new RuntimeException((new StringBuilder()).append("Alias meta-data must start with <alias> tag; found").append(s).append(" at ").append(xmlpullparser.getPositionDescription()).toString());
     int j = xmlpullparser.getDepth();
     do
     {
         int k;
         do
         {
             k = xmlpullparser.next();
             if (k == 1 || k == 3 && xmlpullparser.getDepth() <= j)
                 return intent;
         } while (k == 3 || k == 4);
         if ("intent".equals(xmlpullparser.getName()))
         {
             Intent intent1 = Intent.parseIntent(getResources(), xmlpullparser, attributeset);
             if (intent == null)
                 intent = intent1;
         } else
         {
             XmlUtils.skipCurrentTag(xmlpullparser);
         }
     } while (true);
 }
Пример #7
0
 private AttributeSet getAttributeSet(int resourceId) {
   final XmlResourceParser parser = mContext.getResources().getXml(resourceId);
   try {
     XmlUtils.beginDocument(parser, "RelativeLayout");
   } catch (Exception e) {
     fail("Found unexpected loading process error before invoking generateLayoutParams.");
   }
   final AttributeSet attr = Xml.asAttributeSet(parser);
   assertNotNull(attr);
   return attr;
 }
Пример #8
0
  private void loadUnreadSupportShortcuts() {
    long start = System.currentTimeMillis();
    if (LauncherLog.DEBUG_PERFORMANCE) {
      LauncherLog.d(TAG, "loadUnreadSupportShortcuts begin: start = " + start);
    }

    // Clear all previous parsed unread shortcuts.
    UNREAD_SUPPORT_SHORTCUTS.clear();

    try {
      XmlResourceParser parser = mContext.getResources().getXml(R.xml.unread_support_shortcuts);
      AttributeSet attrs = Xml.asAttributeSet(parser);
      XmlUtils.beginDocument(parser, TAG_UNREADSHORTCUTS);

      final int depth = parser.getDepth();

      int type = -1;
      while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
          && type != XmlPullParser.END_DOCUMENT) {

        if (type != XmlPullParser.START_TAG) {
          continue;
        }

        TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.UnreadShortcut);
        synchronized (LOG_LOCK) {
          UNREAD_SUPPORT_SHORTCUTS.add(
              new UnreadSupportShortcut(
                  a.getString(R.styleable.UnreadShortcut_unreadPackageName),
                  a.getString(R.styleable.UnreadShortcut_unreadClassName),
                  a.getString(R.styleable.UnreadShortcut_unreadKey),
                  a.getInt(R.styleable.UnreadShortcut_unreadType, 0)));
        }
        a.recycle();
      }
    } catch (XmlPullParserException e) {
      LauncherLog.w(TAG, "Got XmlPullParserException while parsing unread shortcuts.", e);
    } catch (IOException e) {
      LauncherLog.w(TAG, "Got IOException while parsing unread shortcuts.", e);
    }
    sUnreadSupportShortcutsNum = UNREAD_SUPPORT_SHORTCUTS.size();
    if (LauncherLog.DEBUG_PERFORMANCE) {
      LauncherLog.d(
          TAG,
          "loadUnreadSupportShortcuts end: time used = "
              + (System.currentTimeMillis() - start)
              + ",sUnreadSupportShortcutsNum = "
              + sUnreadSupportShortcutsNum
              + getUnreadSupportShortcutInfo());
    }
  }
  /**
   * Inflate a menu hierarchy from the specified XML resource. Throws {@link InflateException} if
   * there is an error.
   *
   * @param menuRes Resource ID for an XML layout resource to load (e.g., <code>R.menu.main_activity
   *     </code>)
   * @param menu The Menu to inflate into. The items and submenus will be added to this Menu.
   */
  public void inflate(int menuRes, Menu menu) {
    XmlResourceParser parser = null;
    try {
      parser = mContext.getResources().getLayout(menuRes);
      AttributeSet attrs = Xml.asAttributeSet(parser);

      parseMenu(parser, attrs, menu);
    } catch (XmlPullParserException e) {
      throw new InflateException("Error inflating menu XML", e);
    } catch (IOException e) {
      throw new InflateException("Error inflating menu XML", e);
    } finally {
      if (parser != null) parser.close();
    }
  }
Пример #10
0
  private AttributeSet getAttributeSet(int resourceId) {
    final XmlResourceParser parser = getContext().getResources().getXml(resourceId);

    try {
      XmlUtils.beginDocument(parser, "RelativeLayout");
    } catch (XmlPullParserException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    final AttributeSet attr = Xml.asAttributeSet(parser);
    assertNotNull(attr);
    return attr;
  }
Пример #11
0
 private KeyboardRow parseRowAttributes(final XmlPullParser parser) throws XmlPullParserException {
   final AttributeSet attr = Xml.asAttributeSet(parser);
   final TypedArray keyboardAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard);
   try {
     if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap)) {
       throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "horizontalGap");
     }
     if (keyboardAttr.hasValue(R.styleable.Keyboard_verticalGap)) {
       throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "verticalGap");
     }
     return new KeyboardRow(mResources, mParams, parser, mCurrentY);
   } finally {
     keyboardAttr.recycle();
   }
 }
Пример #12
0
  private void parseIncludeInternal(
      final XmlPullParser parser, final KeyboardRow row, final boolean skip)
      throws XmlPullParserException, IOException {
    if (skip) {
      XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
      if (DEBUG) startEndTag("</%s> skipped", TAG_INCLUDE);
      return;
    }
    final AttributeSet attr = Xml.asAttributeSet(parser);
    final TypedArray keyboardAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Include);
    final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
    int keyboardLayout = 0;
    try {
      XmlParseUtils.checkAttributeExists(
          keyboardAttr,
          R.styleable.Keyboard_Include_keyboardLayout,
          "keyboardLayout",
          TAG_INCLUDE,
          parser);
      keyboardLayout = keyboardAttr.getResourceId(R.styleable.Keyboard_Include_keyboardLayout, 0);
      if (row != null) {
        // Override current x coordinate.
        row.setXPos(row.getKeyX(keyAttr));
        // Push current Row attributes and update with new attributes.
        row.pushRowAttributes(keyAttr);
      }
    } finally {
      keyboardAttr.recycle();
      keyAttr.recycle();
    }

    XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
    if (DEBUG) {
      startEndTag(
          "<%s keyboardLayout=%s />", TAG_INCLUDE, mResources.getResourceEntryName(keyboardLayout));
    }
    final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout);
    try {
      parseMerge(parserForInclude, row, skip);
    } finally {
      if (row != null) {
        // Restore Row attributes.
        row.popRowAttributes();
      }
      parserForInclude.close();
    }
  }
Пример #13
0
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Test constructor(s) of {@link ImageView}",
            method = "ImageView",
            args = {android.content.Context.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Test constructor(s) of {@link ImageView}",
            method = "ImageView",
            args = {android.content.Context.class, android.util.AttributeSet.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Test constructor(s) of {@link ImageView}",
            method = "ImageView",
            args = {android.content.Context.class, android.util.AttributeSet.class, int.class}
        )
    })
    @ToBeFixed(bug = "1417734", explanation = "ImageView#ImageView(Context, AttributeSet) and " +
            "ImageView#ImageView(Context, AttributeSet, int)" +
            " should check whether the input Context is null")
    public void testConstructor() {
        new ImageView(mActivity);

        new ImageView(mActivity, null);

        new ImageView(mActivity, null, 0);

        XmlPullParser parser = mActivity.getResources().getXml(R.layout.imageview_layout);
        AttributeSet attrs = Xml.asAttributeSet(parser);
        new ImageView(mActivity, attrs);
        new ImageView(mActivity, attrs, 0);

        try {
            new ImageView(null, null);
            fail("should throw NullPointerException.");
        } catch (NullPointerException e) {
        }

        try {
            new ImageView(null, null, 0);
            fail("should throw NullPointerException.");
        } catch (NullPointerException e) {
        }
    }
 private ServiceInfo<AuthenticatorDescription> parseServiceInfo(ResolveInfo service)
     throws XmlPullParserException, IOException {
   android.content.pm.ServiceInfo si = service.serviceInfo;
   ComponentName componentName = new ComponentName(si.packageName, si.name);
   PackageManager pm = this.mContext.getPackageManager();
   XmlResourceParser parser = null;
   try {
     parser = si.loadXmlMetaData(pm, this.mMetaDataName);
     if (parser == null) {
       throw new XmlPullParserException("No " + this.mMetaDataName + " meta-data");
     }
     AttributeSet attrs = Xml.asAttributeSet(parser);
     int type;
     do {
       type = parser.next();
       if (type == 1) {
         break;
       }
     } while (type != 2);
     if (this.mAttributesName.equals(parser.getName())) {
       ServiceInfo<AuthenticatorDescription> serviceInfo;
       AuthenticatorDescription v =
           parseServiceAttributes(
               pm.getResourcesForApplication(si.applicationInfo), si.packageName, attrs);
       if (v == null) {
         serviceInfo = null;
         if (parser != null) {
           parser.close();
         }
       } else {
         serviceInfo = new ServiceInfo(v, componentName, service.serviceInfo.applicationInfo.uid);
         if (parser != null) {
           parser.close();
         }
       }
       return serviceInfo;
     }
     throw new XmlPullParserException(
         "Meta-data does not start with " + this.mAttributesName + " tag");
   } catch (NameNotFoundException e) {
     throw new XmlPullParserException("Unable to load resources for pacakge " + si.packageName);
   } catch (Throwable th) {
     if (parser != null) {
       parser.close();
     }
   }
 }
Пример #15
0
  public boolean onCreateActionMode(ActionMode mode, Menu menu) {

    mActionMode = mode;

    // First inflate the menu - default action
    mode.getMenuInflater().inflate(mMenuResId, menu);

    // Now, parse the menu
    XmlResourceParser parser = mContext.getResources().getXml(mMenuResId);
    try {
      int eventType = parser.getEventType();
      while (eventType != XmlResourceParser.END_DOCUMENT) {
        if (eventType == XmlResourceParser.START_TAG) {
          int id = parser.getAttributeResourceValue(Binder.ANDROID_NAMESPACE, "id", -1);
          MenuItem mi = menu.findItem(id);
          if (mi != null) {
            String nodeName = parser.getName();
            if (id > 0) {
              AttributeSet attrs = Xml.asAttributeSet(parser);
              AbsMenuBridge item = null;
              if ("item".equals(nodeName)) {
                item = new MenuItemBridge(id, attrs, mContext, mModel, this);
              } else if ("group".equals(nodeName)) {
                item = new MenuGroupBridge(id, attrs, mContext, mModel, this);
              }
              if (item != null) {
                items.put(id, item);
              }
            }
          }
        }
        eventType = parser.next();
      }
    } catch (XmlPullParserException e) {
      e.printStackTrace();
    } catch (IOException ex) {
      ex.printStackTrace();
    }

    for (AbsMenuBridge item : items.values()) {
      item.onCreateOptionItem(menu);
      item.onPrepareOptionItem(menu);
    }
    return true;
  }
  @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "getIntrinsicWidth",
        args = {}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "getIntrinsicHeight",
        args = {}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "inflate",
        args = {
          android.content.res.Resources.class,
          org.xmlpull.v1.XmlPullParser.class,
          android.util.AttributeSet.class
        })
  })
  public void testGetIntrinsicWidthAndHeight() throws XmlPullParserException, IOException {
    // testimage is set in res/drawable/rotatedrawable.xml
    Drawable drawable = mContext.getResources().getDrawable(R.drawable.testimage);
    assertEquals(drawable.getIntrinsicWidth(), mRotateDrawable.getIntrinsicWidth());
    assertEquals(drawable.getIntrinsicHeight(), mRotateDrawable.getIntrinsicHeight());

    RotateDrawable rotateDrawable = new RotateDrawable();
    Resources r = mContext.getResources();
    XmlPullParser parser = r.getXml(R.drawable.rotatedrawable);
    while (parser.next() != XmlPullParser.START_TAG) {
      // ignore event, just seek to first tag
    }
    AttributeSet attrs = Xml.asAttributeSet(parser);
    rotateDrawable.inflate(r, parser, attrs);
    assertEquals(drawable.getIntrinsicWidth(), rotateDrawable.getIntrinsicWidth());
    assertEquals(drawable.getIntrinsicHeight(), rotateDrawable.getIntrinsicHeight());

    try {
      mRotateDrawable.inflate(null, null, null);
      fail("did not throw NullPointerException when parameters are null.");
    } catch (NullPointerException e) {
      // expected, test success
    }
  }
Пример #17
0
  @TestTargetNew(
      level = TestLevel.COMPLETE,
      method = "inflate",
      args = {
        android.content.res.Resources.class,
        org.xmlpull.v1.XmlPullParser.class,
        android.util.AttributeSet.class
      })
  @ToBeFixed(
      bug = "1386429",
      explanation =
          "no getter can not be tested,"
              + " and there should not be a NullPointerException thrown out.")
  public void testInflate() {
    Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
    InsetDrawable insetDrawable = new InsetDrawable(d, 0);

    Resources r = mContext.getResources();
    XmlPullParser parser = r.getXml(R.layout.framelayout_layout);
    AttributeSet attrs = Xml.asAttributeSet(parser);

    try {
      insetDrawable.inflate(r, parser, attrs);
      fail("There should be a XmlPullParserException thrown out.");
    } catch (XmlPullParserException e) {
      // expected, test success
    } catch (IOException e) {
      fail("There should not be an IOException thrown out.");
    }

    // input null as params
    try {
      insetDrawable.inflate(null, null, null);
      fail("There should be a NullPointerException thrown out.");
    } catch (XmlPullParserException e) {
      fail("There should not be a XmlPullParserException thrown out.");
    } catch (IOException e) {
      fail("There should not be an IOException thrown out.");
    } catch (NullPointerException e) {
      // expected, test success
    }
  }
Пример #18
0
  /**
   * Inflate a new hierarchy from the specified XML node. Throws InflaterException if there is an
   * error.
   *
   * <p><em><strong>Important</strong></em>&nbsp;&nbsp;&nbsp;For performance reasons, inflation
   * relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not
   * currently possible to use inflater with an XmlPullParser over a plain XML file at runtime.
   *
   * @param parser XML dom node containing the description of the hierarchy.
   * @param root Optional to be the parent of the generated hierarchy (if <em>attachToRoot</em> is
   *     true), or else simply an object that provides a set of values for root of the returned
   *     hierarchy (if <em>attachToRoot</em> is false.)
   * @return The root of the inflated hierarchy. If root was supplied, this is root; otherwise it is
   *     the root of the inflated XML file.
   */
  public Preference inflate(XmlPullParser parser, @Nullable PreferenceGroup root) {
    synchronized (mConstructorArgs) {
      final AttributeSet attrs = Xml.asAttributeSet(parser);
      mConstructorArgs[0] = mContext;
      final Preference result;

      try {
        // Look for the root node.
        int type;
        do {
          type = parser.next();
        } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);

        if (type != XmlPullParser.START_TAG) {
          throw new InflateException(parser.getPositionDescription() + ": No start tag found!");
        }

        // Temp is the root that was found in the xml
        Preference xmlRoot = createItemFromTag(parser.getName(), attrs);

        result = onMergeRoots(root, (PreferenceGroup) xmlRoot);

        // Inflate all children under temp
        rInflate(parser, result, attrs);

      } catch (InflateException e) {
        throw e;
      } catch (XmlPullParserException e) {
        final InflateException ex = new InflateException(e.getMessage());
        ex.initCause(e);
        throw ex;
      } catch (IOException e) {
        final InflateException ex =
            new InflateException(parser.getPositionDescription() + ": " + e.getMessage());
        ex.initCause(e);
        throw ex;
      }

      return result;
    }
  }
Пример #19
0
  private void parseKeyboardAttributes(
      Context askContext, Resources res, XmlResourceParser parser) {
    TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable);
    Resources askRes = askContext.getResources();
    // some defaults
    mDefaultWidth = mDisplayWidth / 10;
    mDefaultHeightCode = -1;
    mDefaultHorizontalGap = 0;
    mDefaultVerticalGap = askRes.getDimensionPixelOffset(R.dimen.default_key_vertical_gap);
    // now reading from XML
    int n = a.getIndexCount();
    for (int i = 0; i < n; i++) {
      final int remoteIndex = a.getIndex(i);
      final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]);
      try {
        switch (localAttrId) {
          case android.R.attr.keyWidth:
            mDefaultWidth =
                getDimensionOrFraction(a, remoteIndex, mDisplayWidth, mDisplayWidth / 10);
            break;
          case android.R.attr.keyHeight:
            mDefaultHeightCode = getKeyHeightCode(a, remoteIndex, -1);
            break;
          case android.R.attr.horizontalGap:
            mDefaultHorizontalGap = getDimensionOrFraction(a, remoteIndex, mDisplayWidth, 0);
            break;
          case android.R.attr.verticalGap:
            mDefaultVerticalGap =
                getDimensionOrFraction(a, remoteIndex, mDisplayWidth, mDefaultVerticalGap);
            break;
        }
      } catch (Exception e) {
        Log.w(TAG, "Failed to set data from XML!", e);
      }
    }
    a.recycle();

    mProximityThreshold = (int) (mDefaultWidth * SEARCH_DISTANCE);
    // Square it for comparison
    mProximityThreshold = mProximityThreshold * mProximityThreshold;
  }
  public void testInflate() throws XmlPullParserException, IOException {
    final int width = 80;
    final int height = 120;
    final int[] COLOR = new int[width * height];
    Bitmap bitmap = Bitmap.createBitmap(COLOR, width, height, Bitmap.Config.RGB_565);
    NinePatchDrawable ninePatchDrawable =
        new NinePatchDrawable(mResources, bitmap, new byte[1000], null, "TESTNAME");

    assertEquals(height, ninePatchDrawable.getIntrinsicHeight());
    assertEquals(width, ninePatchDrawable.getIntrinsicWidth());
    XmlResourceParser parser = mResources.getXml(R.drawable.ninepatchdrawable);
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
        && type != XmlPullParser.START_TAG) {}
    AttributeSet attrs = Xml.asAttributeSet(parser);
    ninePatchDrawable.inflate(mResources, parser, attrs);

    assertTrue(ninePatchDrawable.getPaint().isDither());
    assertTrue(height != ninePatchDrawable.getIntrinsicHeight());
    assertTrue(width != ninePatchDrawable.getIntrinsicWidth());
  }
  public static Drawable createFromXml(Context c, Resources r, XmlPullParser parser)
      throws XmlPullParserException, IOException, NoSuchMethodException {
    AttributeSet attrs = Xml.asAttributeSet(parser);

    int type;
    while ((type = parser.next()) != XmlPullParser.START_TAG
        && type != XmlPullParser.END_DOCUMENT) {
      // Empty loop.
    }

    if (type != XmlPullParser.START_TAG) {
      throw new XmlPullParserException("No start tag found");
    }

    Drawable drawable = createFromXmlInner(c, r, parser, attrs);

    if (drawable == null) {
      throw new RuntimeException("Unknown initial tag: " + parser.getName());
    }

    return drawable;
  }
Пример #22
0
  /**
   * 获取字符串id对应的url
   *
   * @param strId
   * @param context
   * @return url
   */
  public static String getUrl(int strId, Context context) {
    try {
      XmlResourceParser parser = context.getResources().getXml(R.xml.address);
      AttributeSet attrs = Xml.asAttributeSet(parser);
      XmlUtils.beginDocument(parser, TAG_FTP);

      final int depth = parser.getDepth();
      int type;
      while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
          && type != XmlPullParser.END_DOCUMENT) {

        if (type != XmlPullParser.START_TAG) {
          continue;
        }

        final String name = parser.getName();
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UrlAddress);
        if (TAG_URLADDRESS.equals(name)) {
          int id = a.getResourceId(R.styleable.UrlAddress_refId, 0);
          if (id == strId) {
            String url = a.getString(R.styleable.UrlAddress_address);
            a.recycle();
            a = null;
            parser.close();
            parser = null;
            return url;
          }
        }
        a.recycle();
      }
      parser.close();
      parser = null;
    } catch (XmlPullParserException e) {
    } catch (IOException e) {
    }

    return null;
  }
Пример #23
0
  /**
   * 获取下载地址 配置文件在res/xml/address.xml
   *
   * @param context
   * @return
   */
  public static HashMap<Integer, String> getUrlList(Context context) {
    try {
      XmlResourceParser parser = context.getResources().getXml(R.xml.address);
      AttributeSet attrs = Xml.asAttributeSet(parser);
      XmlUtils.beginDocument(parser, TAG_FTP);

      HashMap<Integer, String> urlMap = new HashMap<Integer, String>(8);
      final int depth = parser.getDepth();
      int type;
      while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
          && type != XmlPullParser.END_DOCUMENT) {

        if (type != XmlPullParser.START_TAG) {
          continue;
        }

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UrlAddress);
        final String name = parser.getName();
        if (TAG_URLADDRESS.equals(name)) {
          UrlAddress address = getUrlAddress(a);
          if (address != null && address.mStringId > 0) {
            urlMap.put(address.mStringId, address.mUrl);
          }
          address = null;
        }
        a.recycle();
      }
      parser.close();
      parser = null;
      return urlMap;
    } catch (XmlPullParserException e) {
    } catch (IOException e) {
    }

    return null;
  }
  /**
   * Parse the given XML file as a header description, adding each parsed Header into the target
   * list.
   *
   * @param resid The XML resource to load and parse.
   * @param target The list in which the parsed headers should be placed.
   */
  public void loadHeadersFromResource(int resid, List<Header> target) {
    XmlResourceParser parser = null;
    try {
      parser = getResources().getXml(resid);
      AttributeSet attrs = Xml.asAttributeSet(parser);

      int type;
      while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
          && type != XmlPullParser.START_TAG) {
        // Parse next until start tag is found
      }

      String nodeName = parser.getName();
      if (!"preference-headers".equals(nodeName)) {
        throw new RuntimeException(
            "XML document must start with <preference-headers> tag; found"
                + nodeName
                + " at "
                + parser.getPositionDescription());
      }

      Bundle curBundle = null;

      final int outerDepth = parser.getDepth();
      while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
          && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
          continue;
        }

        nodeName = parser.getName();
        if ("header".equals(nodeName)) {
          Header header = new Header();

          TypedArray sa = getResources().obtainAttributes(attrs, R.styleable.PreferenceHeader);
          header.id = sa.getResourceId(R.styleable.PreferenceHeader_id, (int) HEADER_ID_UNDEFINED);
          TypedValue tv = sa.peekValue(R.styleable.PreferenceHeader_title);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.titleRes = tv.resourceId;
            } else {
              header.title = tv.string;
            }
          }
          tv = sa.peekValue(R.styleable.PreferenceHeader_summary);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.summaryRes = tv.resourceId;
            } else {
              header.summary = tv.string;
            }
          }
          tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbTitle);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.breadCrumbTitleRes = tv.resourceId;
            } else {
              header.breadCrumbTitle = tv.string;
            }
          }
          tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbShortTitle);
          if (tv != null && tv.type == TypedValue.TYPE_STRING) {
            if (tv.resourceId != 0) {
              header.breadCrumbShortTitleRes = tv.resourceId;
            } else {
              header.breadCrumbShortTitle = tv.string;
            }
          }
          header.iconRes = sa.getResourceId(R.styleable.PreferenceHeader_icon, 0);
          header.fragment = sa.getString(R.styleable.PreferenceHeader_fragment);
          sa.recycle();

          if (curBundle == null) {
            curBundle = new Bundle();
          }

          final int innerDepth = parser.getDepth();
          while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
              && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
              continue;
            }

            String innerNodeName = parser.getName();
            if (innerNodeName.equals("extra")) {
              getResources().parseBundleExtra("extra", attrs, curBundle);
              XmlUtils.skipCurrentTag(parser);

            } else if (innerNodeName.equals("intent")) {
              header.intent = Intent.parseIntent(getResources(), parser, attrs);

            } else {
              XmlUtils.skipCurrentTag(parser);
            }
          }

          if (curBundle.size() > 0) {
            header.fragmentArguments = curBundle;
            curBundle = null;
          }

          target.add(header);
        } else {
          XmlUtils.skipCurrentTag(parser);
        }
      }

    } catch (XmlPullParserException e) {
      throw new RuntimeException("Error parsing headers", e);
    } catch (IOException e) {
      throw new RuntimeException("Error parsing headers", e);
    } finally {
      if (parser != null) parser.close();
    }
  }
Пример #25
0
    /**
     * Loads the default set of favorite packages from an xml file.
     *
     * @param db The database to write the values into
     */
    private int loadFavorites(SQLiteDatabase db) {
      Intent intent = new Intent(Intent.ACTION_MAIN, null);
      intent.addCategory(Intent.CATEGORY_LAUNCHER);
      ContentValues values = new ContentValues();

      PackageManager packageManager = mContext.getPackageManager();
      int i = 0;
      try {
        String optr = SystemProperties.get("ro.operator.optr");
        XmlResourceParser parser = null;
        if (optr.equals("OP02")) {
          parser = mContext.getResources().getXml(R.xml.cu_workspace);
        } else {
          parser = mContext.getResources().getXml(R.xml.default_workspace);
        }
        AttributeSet attrs = Xml.asAttributeSet(parser);
        XmlUtils.beginDocument(parser, TAG_FAVORITES);

        final int depth = parser.getDepth();

        int type;
        while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
            && type != XmlPullParser.END_DOCUMENT) {

          if (type != XmlPullParser.START_TAG) {
            continue;
          }

          boolean added = false;
          final String name = parser.getName();

          TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);

          values.clear();
          values.put(
              LauncherSettings.Favorites.CONTAINER, LauncherSettings.Favorites.CONTAINER_DESKTOP);
          values.put(LauncherSettings.Favorites.SCREEN, a.getString(R.styleable.Favorite_screen));
          values.put(LauncherSettings.Favorites.CELLX, a.getString(R.styleable.Favorite_x));
          values.put(LauncherSettings.Favorites.CELLY, a.getString(R.styleable.Favorite_y));

          if (TAG_FAVORITE.equals(name)) {
            added = addAppShortcut(db, values, a, packageManager, intent);
          } else if (TAG_SEARCH.equals(name)) {
            added = addSearchWidget(db, values);
          } else if (TAG_CLOCK.equals(name)) {
            added = addClockWidget(db, values);
          } else if (TAG_APPWIDGET.equals(name)) {
            added = addAppWidget(db, values, a, packageManager);
          } else if (TAG_SHORTCUT.equals(name)) {
            added = addUriShortcut(db, values, a);
          }

          if (added) i++;

          a.recycle();
        }
      } catch (XmlPullParserException e) {
        Log.w(TAG, "Got exception parsing favorites.", e);
      } catch (IOException e) {
        Log.w(TAG, "Got exception parsing favorites.", e);
      }

      return i;
    }
 private Drawable loadDrawableFromDelegates(Context paramContext, int paramInt) {
   if ((mDelegates != null) && (!mDelegates.isEmpty())) {
     if (mKnownDrawableIdTags != null) {
       localObject1 = (String) mKnownDrawableIdTags.get(paramInt);
       if (("appcompat_skip_skip".equals(localObject1))
           || ((localObject1 != null) && (mDelegates.get(localObject1) == null))) {
         localObject1 = null;
         return (Drawable) localObject1;
       }
     } else {
       mKnownDrawableIdTags = new SparseArray();
     }
     if (mTypedValue == null) {
       mTypedValue = new TypedValue();
     }
     TypedValue localTypedValue = mTypedValue;
     Object localObject1 = paramContext.getResources();
     ((Resources) localObject1).getValue(paramInt, localTypedValue, true);
     long l = assetCookie << 32 | data;
     Drawable localDrawable = getCachedDelegateDrawable(paramContext, l);
     if (localDrawable != null) {
       return localDrawable;
     }
     Object localObject2 = localDrawable;
     XmlResourceParser localXmlResourceParser;
     AttributeSet localAttributeSet;
     if (string != null) {
       localObject2 = localDrawable;
       if (string.toString().endsWith(".xml")) {
         localObject2 = localDrawable;
         try {
           localXmlResourceParser = ((Resources) localObject1).getXml(paramInt);
           localObject2 = localDrawable;
           localAttributeSet = Xml.asAttributeSet(localXmlResourceParser);
           int i;
           do {
             localObject2 = localDrawable;
             i = localXmlResourceParser.next();
           } while ((i != 2) && (i != 1));
           if (i != 2) {
             localObject2 = localDrawable;
             throw new XmlPullParserException("No start tag found");
           }
         } catch (Exception paramContext) {
           Log.e("AppCompatDrawableManager", "Exception while inflating drawable", paramContext);
         }
       }
     }
     for (paramContext = (Context) localObject2; ; paramContext = (Context) localObject1) {
       localObject1 = paramContext;
       if (paramContext != null) {
         break;
       }
       mKnownDrawableIdTags.append(paramInt, "appcompat_skip_skip");
       return paramContext;
       localObject2 = localDrawable;
       localObject1 = localXmlResourceParser.getName();
       localObject2 = localDrawable;
       mKnownDrawableIdTags.append(paramInt, localObject1);
       localObject2 = localDrawable;
       AppCompatDrawableManager.InflateDelegate localInflateDelegate =
           (AppCompatDrawableManager.InflateDelegate) mDelegates.get(localObject1);
       localObject1 = localDrawable;
       if (localInflateDelegate != null) {
         localObject2 = localDrawable;
         localObject1 =
             localInflateDelegate.createFromXmlInner(
                 paramContext, localXmlResourceParser, localAttributeSet, paramContext.getTheme());
       }
       if (localObject1 != null) {
         localObject2 = localObject1;
         ((Drawable) localObject1).setChangingConfigurations(changingConfigurations);
         localObject2 = localObject1;
         boolean bool = addCachedDelegateDrawable(paramContext, l, (Drawable) localObject1);
         if (!bool) {}
       }
     }
   }
   return null;
 }
Пример #27
0
  /**
   * Create a key with the given top-left coordinate and extract its attributes from the XML parser.
   *
   * @param res resources associated with the caller's context
   * @param params the keyboard building parameters.
   * @param row the row that this key belongs to. row's x-coordinate will be the right edge of this
   *     key.
   * @param parser the XML parser containing the attributes for this key
   * @throws XmlPullParserException
   */
  public Key(Resources res, Keyboard.Params params, Keyboard.Builder.Row row, XmlPullParser parser)
      throws XmlPullParserException {
    final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
    final int keyHeight = row.mRowHeight;
    mVerticalGap = params.mVerticalGap;
    mHeight = keyHeight - mVerticalGap;

    final TypedArray keyAttr =
        res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key);

    final KeyStyle style = params.mKeyStyles.getKeyStyle(keyAttr, parser);
    final float keyXPos = row.getKeyX(keyAttr);
    final float keyWidth = row.getKeyWidth(keyAttr, keyXPos);
    final int keyYPos = row.getKeyY();

    // Horizontal gap is divided equally to both sides of the key.
    mX = Math.round(keyXPos + horizontalGap / 2);
    mY = keyYPos;
    mWidth = Math.round(keyWidth - horizontalGap);
    mHorizontalGap = Math.round(horizontalGap);
    mHitBox.set(
        Math.round(keyXPos), keyYPos, Math.round(keyXPos + keyWidth) + 1, keyYPos + keyHeight);
    // Update row to have current x coordinate.
    row.setXPos(keyXPos + keyWidth);

    mBackgroundType =
        style.getInt(
            keyAttr, R.styleable.Keyboard_Key_backgroundType, row.getDefaultBackgroundType());

    mVisualInsetsLeft =
        Math.round(
            Keyboard.Builder.getDimensionOrFraction(
                keyAttr, R.styleable.Keyboard_Key_visualInsetsLeft, params.mBaseWidth, 0));
    mVisualInsetsRight =
        Math.round(
            Keyboard.Builder.getDimensionOrFraction(
                keyAttr, R.styleable.Keyboard_Key_visualInsetsRight, params.mBaseWidth, 0));
    mIconId = KeySpecParser.getIconId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyIcon));
    mDisabledIconId =
        KeySpecParser.getIconId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled));
    mPreviewIconId =
        KeySpecParser.getIconId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyIconPreview));

    mLabelFlags =
        style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
            | row.getDefaultKeyLabelFlags();
    final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId);
    final Locale locale = params.mId.mLocale;
    int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
    String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);

    int moreKeysColumn =
        style.getInt(
            keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
    int value;
    if ((value = KeySpecParser.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) {
      moreKeysColumn = value & MORE_KEYS_COLUMN_MASK;
    }
    if ((value = KeySpecParser.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) {
      moreKeysColumn = MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER | (value & MORE_KEYS_COLUMN_MASK);
    }
    if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_HAS_LABELS)) {
      moreKeysColumn |= MORE_KEYS_FLAGS_HAS_LABELS;
    }
    if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_NEEDS_DIVIDERS)) {
      moreKeysColumn |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS;
    }
    if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_EMBEDDED_MORE_KEY)) {
      moreKeysColumn |= MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY;
    }
    mMoreKeysColumnAndFlags = moreKeysColumn;

    final String[] additionalMoreKeys;
    if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
      additionalMoreKeys = null;
    } else {
      additionalMoreKeys =
          style.getStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
    }
    moreKeys = KeySpecParser.insertAdditionalMoreKeys(moreKeys, additionalMoreKeys);
    if (moreKeys != null) {
      actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
      mMoreKeys = new MoreKeySpec[moreKeys.length];
      for (int i = 0; i < moreKeys.length; i++) {
        mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpperCase, locale, params.mCodesSet);
      }
    } else {
      mMoreKeys = null;
    }
    mActionFlags = actionFlags;

    if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
      mLabel = params.mId.mCustomActionLabel;
    } else {
      mLabel =
          KeySpecParser.toUpperCaseOfStringForLocale(
              style.getString(keyAttr, R.styleable.Keyboard_Key_keyLabel),
              needsToUpperCase,
              locale);
    }
    if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) {
      mHintLabel = null;
    } else {
      mHintLabel =
          KeySpecParser.toUpperCaseOfStringForLocale(
              style.getString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel),
              needsToUpperCase,
              locale);
    }
    String outputText =
        KeySpecParser.toUpperCaseOfStringForLocale(
            style.getString(keyAttr, R.styleable.Keyboard_Key_keyOutputText),
            needsToUpperCase,
            locale);
    final int code =
        KeySpecParser.parseCode(
            style.getString(keyAttr, R.styleable.Keyboard_Key_code),
            params.mCodesSet,
            CODE_UNSPECIFIED);
    // Choose the first letter of the label as primary code if not specified.
    if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) {
      if (StringUtils.codePointCount(mLabel) == 1) {
        // Use the first letter of the hint label if shiftedLetterActivated flag is
        // specified.
        if (hasShiftedLetterHint()
            && isShiftedLetterActivated()
            && !TextUtils.isEmpty(mHintLabel)) {
          mCode = mHintLabel.codePointAt(0);
        } else {
          mCode = mLabel.codePointAt(0);
        }
      } else {
        // In some locale and case, the character might be represented by multiple code
        // points, such as upper case Eszett of German alphabet.
        outputText = mLabel;
        mCode = CODE_OUTPUT_TEXT;
      }
    } else if (code == CODE_UNSPECIFIED && outputText != null) {
      if (StringUtils.codePointCount(outputText) == 1) {
        mCode = outputText.codePointAt(0);
        outputText = null;
      } else {
        mCode = CODE_OUTPUT_TEXT;
      }
    } else {
      mCode = KeySpecParser.toUpperCaseOfCodeForLocale(code, needsToUpperCase, locale);
    }
    mOutputText = outputText;
    mAltCode =
        KeySpecParser.toUpperCaseOfCodeForLocale(
            KeySpecParser.parseCode(
                style.getString(keyAttr, R.styleable.Keyboard_Key_altCode),
                params.mCodesSet,
                CODE_UNSPECIFIED),
            needsToUpperCase,
            locale);
    mHashCode = computeHashCode(this);

    keyAttr.recycle();

    if (hasShiftedLetterHint() && TextUtils.isEmpty(mHintLabel)) {
      Log.w(TAG, "hasShiftedLetterHint specified without keyHintLabel: " + this);
    }
  }
Пример #28
0
  private boolean parseCaseCondition(final XmlPullParser parser) {
    final KeyboardId id = mParams.mId;
    if (id == null) {
      return true;
    }
    final AttributeSet attr = Xml.asAttributeSet(parser);
    final TypedArray caseAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Case);
    try {
      final boolean keyboardLayoutSetMatched =
          matchString(
              caseAttr,
              R.styleable.Keyboard_Case_keyboardLayoutSet,
              SubtypeLocaleUtils.getKeyboardLayoutSetName(id.mSubtype));
      final boolean keyboardLayoutSetElementMatched =
          matchTypedValue(
              caseAttr,
              R.styleable.Keyboard_Case_keyboardLayoutSetElement,
              id.mElementId,
              KeyboardId.elementIdToName(id.mElementId));
      final boolean modeMatched =
          matchTypedValue(
              caseAttr, R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
      final boolean navigateNextMatched =
          matchBoolean(caseAttr, R.styleable.Keyboard_Case_navigateNext, id.navigateNext());
      final boolean navigatePreviousMatched =
          matchBoolean(caseAttr, R.styleable.Keyboard_Case_navigatePrevious, id.navigatePrevious());
      final boolean passwordInputMatched =
          matchBoolean(caseAttr, R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
      final boolean clobberSettingsKeyMatched =
          matchBoolean(
              caseAttr, R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
      final boolean shortcutKeyEnabledMatched =
          matchBoolean(
              caseAttr, R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
      final boolean shortcutKeyOnSymbolsMatched =
          matchBoolean(
              caseAttr, R.styleable.Keyboard_Case_shortcutKeyOnSymbols, id.mShortcutKeyOnSymbols);
      final boolean hasShortcutKeyMatched =
          matchBoolean(caseAttr, R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
      final boolean languageSwitchKeyEnabledMatched =
          matchBoolean(
              caseAttr,
              R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
              id.mLanguageSwitchKeyEnabled);
      final boolean isMultiLineMatched =
          matchBoolean(caseAttr, R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
      final boolean imeActionMatched =
          matchInteger(caseAttr, R.styleable.Keyboard_Case_imeAction, id.imeAction());
      final boolean localeCodeMatched =
          matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
      final boolean languageCodeMatched =
          matchString(caseAttr, R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
      final boolean countryCodeMatched =
          matchString(caseAttr, R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
      final boolean selected =
          keyboardLayoutSetMatched
              && keyboardLayoutSetElementMatched
              && modeMatched
              && navigateNextMatched
              && navigatePreviousMatched
              && passwordInputMatched
              && clobberSettingsKeyMatched
              && shortcutKeyEnabledMatched
              && shortcutKeyOnSymbolsMatched
              && hasShortcutKeyMatched
              && languageSwitchKeyEnabledMatched
              && isMultiLineMatched
              && imeActionMatched
              && localeCodeMatched
              && languageCodeMatched
              && countryCodeMatched;

      if (DEBUG) {
        startTag(
            "<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s",
            TAG_CASE,
            textAttr(
                caseAttr.getString(R.styleable.Keyboard_Case_keyboardLayoutSet),
                "keyboardLayoutSet"),
            textAttr(
                caseAttr.getString(R.styleable.Keyboard_Case_keyboardLayoutSetElement),
                "keyboardLayoutSetElement"),
            textAttr(caseAttr.getString(R.styleable.Keyboard_Case_mode), "mode"),
            textAttr(caseAttr.getString(R.styleable.Keyboard_Case_imeAction), "imeAction"),
            booleanAttr(caseAttr, R.styleable.Keyboard_Case_navigateNext, "navigateNext"),
            booleanAttr(caseAttr, R.styleable.Keyboard_Case_navigatePrevious, "navigatePrevious"),
            booleanAttr(
                caseAttr, R.styleable.Keyboard_Case_clobberSettingsKey, "clobberSettingsKey"),
            booleanAttr(caseAttr, R.styleable.Keyboard_Case_passwordInput, "passwordInput"),
            booleanAttr(
                caseAttr, R.styleable.Keyboard_Case_shortcutKeyEnabled, "shortcutKeyEnabled"),
            booleanAttr(
                caseAttr, R.styleable.Keyboard_Case_shortcutKeyOnSymbols, "shortcutKeyOnSymbols"),
            booleanAttr(caseAttr, R.styleable.Keyboard_Case_hasShortcutKey, "hasShortcutKey"),
            booleanAttr(
                caseAttr,
                R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
                "languageSwitchKeyEnabled"),
            booleanAttr(caseAttr, R.styleable.Keyboard_Case_isMultiLine, "isMultiLine"),
            textAttr(caseAttr.getString(R.styleable.Keyboard_Case_localeCode), "localeCode"),
            textAttr(caseAttr.getString(R.styleable.Keyboard_Case_languageCode), "languageCode"),
            textAttr(caseAttr.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"),
            selected ? "" : " skipped");
      }

      return selected;
    } finally {
      caseAttr.recycle();
    }
  }
Пример #29
0
  private void parseGridRows(final XmlPullParser parser, final boolean skip)
      throws XmlPullParserException, IOException {
    if (skip) {
      XmlParseUtils.checkEndTag(TAG_GRID_ROWS, parser);
      if (DEBUG) {
        startEndTag("<%s /> skipped", TAG_GRID_ROWS);
      }
      return;
    }
    final KeyboardRow gridRows = new KeyboardRow(mResources, mParams, parser, mCurrentY);
    final TypedArray gridRowAttr =
        mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_GridRows);
    final int codesArrayId = gridRowAttr.getResourceId(R.styleable.Keyboard_GridRows_codesArray, 0);
    final int textsArrayId = gridRowAttr.getResourceId(R.styleable.Keyboard_GridRows_textsArray, 0);
    gridRowAttr.recycle();
    if (codesArrayId == 0 && textsArrayId == 0) {
      throw new XmlParseUtils.ParseException("Missing codesArray or textsArray attributes", parser);
    }
    if (codesArrayId != 0 && textsArrayId != 0) {
      throw new XmlParseUtils.ParseException(
          "Both codesArray and textsArray attributes specifed", parser);
    }
    final String[] array =
        mResources.getStringArray(codesArrayId != 0 ? codesArrayId : textsArrayId);
    final int counts = array.length;
    final float keyWidth = gridRows.getKeyWidth(null, 0.0f);
    final int numColumns = (int) (mParams.mOccupiedWidth / keyWidth);
    for (int index = 0; index < counts; index += numColumns) {
      final KeyboardRow row = new KeyboardRow(mResources, mParams, parser, mCurrentY);
      startRow(row);
      for (int c = 0; c < numColumns; c++) {
        final int i = index + c;
        if (i >= counts) {
          break;
        }
        final String label;
        final int code;
        final String outputText;
        final int supportedMinSdkVersion;
        if (codesArrayId != 0) {
          final String codeArraySpec = array[i];
          label = CodesArrayParser.parseLabel(codeArraySpec);
          code = CodesArrayParser.parseCode(codeArraySpec);
          outputText = CodesArrayParser.parseOutputText(codeArraySpec);
          supportedMinSdkVersion = CodesArrayParser.getMinSupportSdkVersion(codeArraySpec);
        } else {
          final String textArraySpec = array[i];
          // TODO: Utilize KeySpecParser or write more generic TextsArrayParser.
          label = textArraySpec;
          code = Constants.CODE_OUTPUT_TEXT;
          outputText = textArraySpec + (char) Constants.CODE_SPACE;
          supportedMinSdkVersion = 0;
        }
        if (Build.VERSION.SDK_INT < supportedMinSdkVersion) {
          continue;
        }
        final int x = (int) row.getKeyX(null);
        final int y = row.getKeyY();
        final Key key =
            new Key(
                mParams,
                label,
                null /* hintLabel */,
                0 /* iconId */,
                code,
                outputText,
                x,
                y,
                (int) keyWidth,
                (int) row.getRowHeight(),
                row.getDefaultKeyLabelFlags(),
                row.getDefaultBackgroundType());
        endKey(key);
        row.advanceXPos(keyWidth);
      }
      endRow(row);
    }

    XmlParseUtils.checkEndTag(TAG_GRID_ROWS, parser);
  }
Пример #30
0
  private void parseKeyboardAttributes(final XmlPullParser parser) {
    final AttributeSet attr = Xml.asAttributeSet(parser);
    final TypedArray keyboardAttr =
        mContext.obtainStyledAttributes(
            attr, R.styleable.Keyboard, R.attr.keyboardStyle, R.style.Keyboard);
    final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
    try {
      final KeyboardParams params = mParams;
      final int height = params.mId.mHeight;
      final int width = params.mId.mWidth;
      params.mOccupiedHeight = height;
      params.mOccupiedWidth = width;
      params.mTopPadding =
          (int)
              keyboardAttr.getFraction(R.styleable.Keyboard_keyboardTopPadding, height, height, 0);
      params.mBottomPadding =
          (int)
              keyboardAttr.getFraction(
                  R.styleable.Keyboard_keyboardBottomPadding, height, height, 0);
      params.mLeftPadding =
          (int) keyboardAttr.getFraction(R.styleable.Keyboard_keyboardLeftPadding, width, width, 0);
      params.mRightPadding =
          (int)
              keyboardAttr.getFraction(R.styleable.Keyboard_keyboardRightPadding, width, width, 0);

      final int baseWidth = params.mOccupiedWidth - params.mLeftPadding - params.mRightPadding;
      params.mBaseWidth = baseWidth;
      params.mDefaultKeyWidth =
          (int)
              keyAttr.getFraction(
                  R.styleable.Keyboard_Key_keyWidth,
                  baseWidth,
                  baseWidth,
                  baseWidth / DEFAULT_KEYBOARD_COLUMNS);
      params.mHorizontalGap =
          (int)
              keyboardAttr.getFraction(R.styleable.Keyboard_horizontalGap, baseWidth, baseWidth, 0);
      // TODO: Fix keyboard geometry calculation clearer. Historically vertical gap between
      // rows are determined based on the entire keyboard height including top and bottom
      // paddings.
      params.mVerticalGap =
          (int) keyboardAttr.getFraction(R.styleable.Keyboard_verticalGap, height, height, 0);
      final int baseHeight =
          params.mOccupiedHeight - params.mTopPadding - params.mBottomPadding + params.mVerticalGap;
      params.mBaseHeight = baseHeight;
      params.mDefaultRowHeight =
          (int)
              ResourceUtils.getDimensionOrFraction(
                  keyboardAttr,
                  R.styleable.Keyboard_rowHeight,
                  baseHeight,
                  baseHeight / DEFAULT_KEYBOARD_ROWS);

      params.mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);

      params.mMoreKeysTemplate =
          keyboardAttr.getResourceId(R.styleable.Keyboard_moreKeysTemplate, 0);
      params.mMaxMoreKeysKeyboardColumn =
          keyAttr.getInt(R.styleable.Keyboard_Key_maxMoreKeysColumn, 5);

      params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0);
      params.mIconsSet.loadIcons(keyboardAttr);
      final String language = params.mId.mLocale.getLanguage();
      params.mCodesSet.setLanguage(language);
      params.mTextsSet.setLanguage(language);
      final RunInLocale<Void> job =
          new RunInLocale<Void>() {
            @Override
            protected Void job(final Resources res) {
              params.mTextsSet.loadStringResources(mContext);
              return null;
            }
          };
      // Null means the current system locale.
      final Locale locale =
          SubtypeLocaleUtils.isNoLanguage(params.mId.mSubtype) ? null : params.mId.mLocale;
      job.runInLocale(mResources, locale);

      final int resourceId =
          keyboardAttr.getResourceId(R.styleable.Keyboard_touchPositionCorrectionData, 0);
      if (resourceId != 0) {
        final String[] data = mResources.getStringArray(resourceId);
        params.mTouchPositionCorrection.load(data);
      }
    } finally {
      keyAttr.recycle();
      keyboardAttr.recycle();
    }
  }