10b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka/*
28632bff2d5a8e1160989008dea6eff4b94b065ddTadashi G. Takaoka * Copyright (C) 2010 The Android Open Source Project
30b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka *
48aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License");
58aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * you may not use this file except in compliance with the License.
68aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * You may obtain a copy of the License at
70b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka *
88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
90b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka *
100b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
118aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS,
128aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * See the License for the specific language governing permissions and
148aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * limitations under the License.
150b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka */
160b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
1772934bd5967d0127f71fd4d66158b18b4e6ceefeTadashi G. Takaokapackage com.android.inputmethod.keyboard.internal;
180b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
190b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaokaimport android.content.res.TypedArray;
200b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaokaimport android.util.Log;
2156853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaokaimport android.util.SparseArray;
220b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
23c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokaimport com.android.inputmethod.latin.R;
24e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.XmlParseUtils;
25c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
26406a54f41c3e2bb90bedefb6ff80d7b874242f83Tadashi G. Takaokaimport org.xmlpull.v1.XmlPullParser;
274665463ccd4880c2392d26baa784c5d28de986ccTadashi G. Takaokaimport org.xmlpull.v1.XmlPullParserException;
28406a54f41c3e2bb90bedefb6ff80d7b874242f83Tadashi G. Takaoka
292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaimport java.util.Arrays;
300b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaokaimport java.util.HashMap;
310b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
329d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaokaimport javax.annotation.Nonnull;
339d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaokaimport javax.annotation.Nullable;
349d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka
35a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class KeyStylesSet {
3635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private static final String TAG = KeyStylesSet.class.getSimpleName();
379b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka    private static final boolean DEBUG = false;
380b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
399d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka    @Nonnull
40a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka    private final HashMap<String, KeyStyle> mStyles = new HashMap<>();
410b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
429d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka    @Nonnull
4335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private final KeyboardTextsSet mTextsSet;
449d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka    @Nonnull
452be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka    private final KeyStyle mEmptyKeyStyle;
469d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka    @Nonnull
472f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka    private static final String EMPTY_STYLE_NAME = "<empty>";
482be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka
499d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka    public KeyStylesSet(@Nonnull final KeyboardTextsSet textsSet) {
506bfd5f631908c4afd893c9b25b353e5e16c5fc0cTadashi G. Takaoka        mTextsSet = textsSet;
5135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mEmptyKeyStyle = new EmptyKeyStyle(textsSet);
522f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka        mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
532be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka    }
542be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka
55a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaoka    private static final class EmptyKeyStyle extends KeyStyle {
569d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        EmptyKeyStyle(@Nonnull final KeyboardTextsSet textsSet) {
5735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            super(textsSet);
582be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka        }
590b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
605a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka        @Override
619d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        @Nullable
6235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public String[] getStringArray(final TypedArray a, final int index) {
632be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka            return parseStringArray(a, index);
649b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka        }
659b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka
669b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka        @Override
679d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        @Nullable
6835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public String getString(final TypedArray a, final int index) {
692be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka            return parseString(a, index);
700b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
710b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
725a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka        @Override
7335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public int getInt(final TypedArray a, final int index, final int defaultValue) {
740b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka            return a.getInt(index, defaultValue);
750b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
760b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
775a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka        @Override
780cfd2b08af8cab26ac858c8296c13f4a5e076666Tadashi G. Takaoka        public int getFlags(final TypedArray a, final int index) {
7917f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            return a.getInt(index, 0);
809b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka        }
810b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka    }
820b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
83a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaoka    private static final class DeclaredKeyStyle extends KeyStyle {
8435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        private final HashMap<String, KeyStyle> mStyles;
852f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka        private final String mParentStyleName;
86a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka        private final SparseArray<Object> mStyleAttributes = new SparseArray<>();
870b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
889d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        public DeclaredKeyStyle(@Nonnull final String parentStyleName,
899d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                @Nonnull final KeyboardTextsSet textsSet,
909d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                @Nonnull final HashMap<String, KeyStyle> styles) {
9135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            super(textsSet);
922f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            mParentStyleName = parentStyleName;
9335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mStyles = styles;
942be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka        }
952be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka
960b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        @Override
979d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        @Nullable
9835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public String[] getStringArray(final TypedArray a, final int index) {
9917f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            if (a.hasValue(index)) {
10017f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka                return parseStringArray(a, index);
10117f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
10256853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka            final Object value = mStyleAttributes.get(index);
10356853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka            if (value != null) {
1042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                final String[] array = (String[])value;
1052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                return Arrays.copyOf(array, array.length);
1062f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            }
1072f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            final KeyStyle parentStyle = mStyles.get(mParentStyleName);
1082f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            return parentStyle.getStringArray(a, index);
1099b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka        }
1109b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka
1119b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka        @Override
1129d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        @Nullable
11335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public String getString(final TypedArray a, final int index) {
11417f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            if (a.hasValue(index)) {
1152be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka                return parseString(a, index);
11617f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
11756853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka            final Object value = mStyleAttributes.get(index);
11856853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka            if (value != null) {
11956853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka                return (String)value;
1202f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            }
1212f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            final KeyStyle parentStyle = mStyles.get(mParentStyleName);
1222f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            return parentStyle.getString(a, index);
1230b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1240b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
1250b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        @Override
12635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public int getInt(final TypedArray a, final int index, final int defaultValue) {
12717f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            if (a.hasValue(index)) {
12817f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka                return a.getInt(index, defaultValue);
12917f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
13056853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka            final Object value = mStyleAttributes.get(index);
13156853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka            if (value != null) {
13256853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka                return (Integer)value;
1332f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            }
1342f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            final KeyStyle parentStyle = mStyles.get(mParentStyleName);
1352f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            return parentStyle.getInt(a, index, defaultValue);
1360b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1370b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
1380b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        @Override
1390cfd2b08af8cab26ac858c8296c13f4a5e076666Tadashi G. Takaoka        public int getFlags(final TypedArray a, final int index) {
14047b71c82eca80b06e76d960c4a501b9a6c64654bTadashi G. Takaoka            final int parentFlags = mStyles.get(mParentStyleName).getFlags(a, index);
1410cfd2b08af8cab26ac858c8296c13f4a5e076666Tadashi G. Takaoka            final Integer value = (Integer)mStyleAttributes.get(index);
14247b71c82eca80b06e76d960c4a501b9a6c64654bTadashi G. Takaoka            final int styleFlags = (value != null) ? value : 0;
14347b71c82eca80b06e76d960c4a501b9a6c64654bTadashi G. Takaoka            final int flags = a.getInt(index, 0);
14447b71c82eca80b06e76d960c4a501b9a6c64654bTadashi G. Takaoka            return flags | styleFlags | parentFlags;
1450b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1460b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
14735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        public void readKeyAttributes(final TypedArray keyAttr) {
1480b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka            // TODO: Currently not all Key attributes can be declared as style.
149ed3bac91f242850c6d1833a5f8981b9cc208c5ddTadashi G. Takaoka            readString(keyAttr, R.styleable.Keyboard_Key_altCode);
1509684b33b69a62a058c767786ae6a23b809d27385Tadashi G. Takaoka            readString(keyAttr, R.styleable.Keyboard_Key_keySpec);
15138d6a18821794dc733760b55fd2a896626f784e2Tadashi G. Takaoka            readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
15238d6a18821794dc733760b55fd2a896626f784e2Tadashi G. Takaoka            readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
15315c99e9f1a7776b95325d36cf9e38b6d674e483bTadashi G. Takaoka            readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
1540cfd2b08af8cab26ac858c8296c13f4a5e076666Tadashi G. Takaoka            readFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
155cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            readString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
1569d5601e9013c5ec9a7ac75db16f4a0a8218b02bfTadashi G. Takaoka            readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
1577918ed016960908700582e47322e52d74c328cc7Tadashi G. Takaoka            readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
1580cfd2b08af8cab26ac858c8296c13f4a5e076666Tadashi G. Takaoka            readFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
1590b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1600b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
16135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        private void readString(final TypedArray a, final int index) {
16217f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            if (a.hasValue(index)) {
1632be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka                mStyleAttributes.put(index, parseString(a, index));
16417f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
1650b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1660b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
16735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        private void readInt(final TypedArray a, final int index) {
16817f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            if (a.hasValue(index)) {
16917f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka                mStyleAttributes.put(index, a.getInt(index, 0));
17017f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
1710b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1720b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
1730cfd2b08af8cab26ac858c8296c13f4a5e076666Tadashi G. Takaoka        private void readFlags(final TypedArray a, final int index) {
17417f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            if (a.hasValue(index)) {
1752be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka                final Integer value = (Integer)mStyleAttributes.get(index);
17647b71c82eca80b06e76d960c4a501b9a6c64654bTadashi G. Takaoka                final int styleFlags = value != null ? value : 0;
17747b71c82eca80b06e76d960c4a501b9a6c64654bTadashi G. Takaoka                mStyleAttributes.put(index, a.getInt(index, 0) | styleFlags);
17817f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
1790b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
1800b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
18135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        private void readStringArray(final TypedArray a, final int index) {
1822be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka            if (a.hasValue(index)) {
1832be51f4fd0c5cd70c7a2757558ffe45e703700cfTadashi G. Takaoka                mStyleAttributes.put(index, parseStringArray(a, index));
18417f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            }
18517f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka        }
18617f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka    }
1870b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
18835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
18935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            final XmlPullParser parser) throws XmlPullParserException {
19009430720d5eee7e2de405d600059bd39aa1d3e49Tadashi G. Takaoka        final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
1919d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        if (styleName == null) {
1929d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka            throw new XmlParseUtils.ParseException(
1939d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                    KeyboardBuilder.TAG_KEY_STYLE + " has no styleName attribute", parser);
1949d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        }
19517f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka        if (DEBUG) {
19617f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka            Log.d(TAG, String.format("<%s styleName=%s />",
19735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka                    KeyboardBuilder.TAG_KEY_STYLE, styleName));
19805bfd189a88be79ddfc74d0ea21792e2fb78f2aaTadashi G. Takaoka            if (mStyles.containsKey(styleName)) {
1999d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                Log.d(TAG, KeyboardBuilder.TAG_KEY_STYLE + " " + styleName + " is overridden at "
20005bfd189a88be79ddfc74d0ea21792e2fb78f2aaTadashi G. Takaoka                        + parser.getPositionDescription());
20105bfd189a88be79ddfc74d0ea21792e2fb78f2aaTadashi G. Takaoka            }
20217f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka        }
2030b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
2049d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        final String parentStyleInAttr = keyStyleAttr.getString(
2059d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                R.styleable.Keyboard_KeyStyle_parentStyle);
2069d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        if (parentStyleInAttr != null && !mStyles.containsKey(parentStyleInAttr)) {
2079d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka            throw new XmlParseUtils.ParseException(
2089d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                    "Unknown parentStyle " + parentStyleInAttr, parser);
2090b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        }
2109d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        final String parentStyleName = (parentStyleInAttr == null) ? EMPTY_STYLE_NAME
2119d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka                : parentStyleInAttr;
21235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
21317f53103ee0d0360d8f93f6bac41ef37a0021402Tadashi G. Takaoka        style.readKeyAttributes(keyAttrs);
2140b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka        mStyles.put(styleName, style);
2150b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka    }
2160b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka
2179d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka    @Nonnull
21835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
2192f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            throws XmlParseUtils.ParseException {
2209d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
2219d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        if (styleName == null) {
2222f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            return mEmptyKeyStyle;
2232f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka        }
2249d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        final KeyStyle style = mStyles.get(styleName);
2259d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        if (style == null) {
2262f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka            throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
2272f83e9e53244651dded489f91879f5150fb9c39dTadashi G. Takaoka        }
2289d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka        return style;
2290b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka    }
2300b60f831922b9341a7ef5d2eba87aa91580d371fTadashi G. Takaoka}
231