1f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov/*
2f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
3f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov *
4f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * use this file except in compliance with the License. You may obtain a copy of
6f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * the License at
7f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov *
8f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0
9f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov *
10f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
11f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * License for the specific language governing permissions and limitations under
14f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * the License
15f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */
16f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovpackage com.android.providers.contacts;
17f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
18f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.content.ContentValues;
196d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikovimport android.content.Context;
20f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.Cursor;
21f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.sqlite.SQLiteDatabase;
22f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
23f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
240f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shraunerimport android.provider.ContactsContract.PhoneticNameStyle;
25f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.text.TextUtils;
26f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
2738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.SearchIndexManager.IndexBuilder;
2838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.aggregation.ContactAggregator;
2938210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki
30f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov/**
31f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Handler for email address data rows.
32f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */
33f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovpublic class DataRowHandlerForStructuredName extends DataRowHandler {
34f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    private final NameSplitter mSplitter;
35f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    private final NameLookupBuilder mNameLookupBuilder;
36eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    private final StringBuilder mSb = new StringBuilder();
37f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
386d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov    public DataRowHandlerForStructuredName(Context context, ContactsDatabaseHelper dbHelper,
39f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            ContactAggregator aggregator, NameSplitter splitter,
40f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            NameLookupBuilder nameLookupBuilder) {
416d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov        super(context, dbHelper, aggregator, StructuredName.CONTENT_ITEM_TYPE);
42f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        mSplitter = splitter;
43f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        mNameLookupBuilder = nameLookupBuilder;
44f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    }
45f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
46f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    @Override
47f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    public long insert(SQLiteDatabase db, TransactionContext txContext, long rawContactId,
48f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            ContentValues values) {
49f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        fixStructuredNameComponents(values, values);
50f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
51f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        long dataId = super.insert(db, txContext, rawContactId, values);
52f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
53f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        String name = values.getAsString(StructuredName.DISPLAY_NAME);
54f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        Integer fullNameStyle = values.getAsInteger(StructuredName.FULL_NAME_STYLE);
55f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        mNameLookupBuilder.insertNameLookup(rawContactId, dataId, name,
56f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                fullNameStyle != null
57f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                        ? mSplitter.getAdjustedFullNameStyle(fullNameStyle)
58f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                        : FullNameStyle.UNDEFINED);
59f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        fixRawContactDisplayName(db, txContext, rawContactId);
60bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov        triggerAggregation(txContext, rawContactId);
61f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        return dataId;
62f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    }
63f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
64f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    @Override
65f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    public boolean update(SQLiteDatabase db, TransactionContext txContext, ContentValues values,
66f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            Cursor c, boolean callerIsSyncAdapter) {
67f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        final long dataId = c.getLong(DataUpdateQuery._ID);
68f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        final long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID);
69f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
70f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        final ContentValues augmented = getAugmentedValues(db, dataId, values);
71f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        if (augmented == null) {  // No change
72f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            return false;
73f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        }
74f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
75f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        fixStructuredNameComponents(augmented, values);
76f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
77f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        super.update(db, txContext, values, c, callerIsSyncAdapter);
788a8ddc3d1ceee9872ace06326ebe999ba171f70bMakoto Onuki        if (values.containsKey(StructuredName.DISPLAY_NAME)) {
79f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            augmented.putAll(values);
80f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            String name = augmented.getAsString(StructuredName.DISPLAY_NAME);
81f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            mDbHelper.deleteNameLookup(dataId);
82f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            Integer fullNameStyle = augmented.getAsInteger(StructuredName.FULL_NAME_STYLE);
83f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            mNameLookupBuilder.insertNameLookup(rawContactId, dataId, name,
84f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                    fullNameStyle != null
85f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                            ? mSplitter.getAdjustedFullNameStyle(fullNameStyle)
86f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                            : FullNameStyle.UNDEFINED);
87f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        }
88f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        fixRawContactDisplayName(db, txContext, rawContactId);
89bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov        triggerAggregation(txContext, rawContactId);
90f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        return true;
91f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    }
92f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
93f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    @Override
94f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    public int delete(SQLiteDatabase db, TransactionContext txContext, Cursor c) {
95f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        long dataId = c.getLong(DataDeleteQuery._ID);
96f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID);
97f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
98f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        int count = super.delete(db, txContext, c);
99f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
100f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        mDbHelper.deleteNameLookup(dataId);
101f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        fixRawContactDisplayName(db, txContext, rawContactId);
102bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov        triggerAggregation(txContext, rawContactId);
103f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        return count;
104f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    }
105f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
106f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    /**
107f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     * Specific list of structured fields.
108f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     */
109f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    private final String[] STRUCTURED_FIELDS = new String[] {
110f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            StructuredName.PREFIX, StructuredName.GIVEN_NAME, StructuredName.MIDDLE_NAME,
111f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            StructuredName.FAMILY_NAME, StructuredName.SUFFIX
112f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    };
113f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
114f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    /**
115f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     * Parses the supplied display name, but only if the incoming values do
116f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     * not already contain structured name parts. Also, if the display name
117f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     * is not provided, generate one by concatenating first name and last
118f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     * name.
119f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov     */
120f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    public void fixStructuredNameComponents(ContentValues augmented, ContentValues update) {
121f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        final String unstruct = update.getAsString(StructuredName.DISPLAY_NAME);
122f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
123f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        final boolean touchedUnstruct = !TextUtils.isEmpty(unstruct);
124f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        final boolean touchedStruct = !areAllEmpty(update, STRUCTURED_FIELDS);
125f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
126f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        if (touchedUnstruct && !touchedStruct) {
127f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            NameSplitter.Name name = new NameSplitter.Name();
128f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            mSplitter.split(name, unstruct);
129f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            name.toValues(update);
130f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        } else if (!touchedUnstruct
131f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                && (touchedStruct || areAnySpecified(update, STRUCTURED_FIELDS))) {
132f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            // We need to update the display name when any structured components
133f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            // are specified, even when they are null, which is why we are checking
134f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            // areAnySpecified.  The touchedStruct in the condition is an optimization:
135f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            // if there are non-null values, we know for a fact that some values are present.
136f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            NameSplitter.Name name = new NameSplitter.Name();
137f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            name.fromValues(augmented);
138f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            // As the name could be changed, let's guess the name style again.
139f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            name.fullNameStyle = FullNameStyle.UNDEFINED;
1400f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            name.phoneticNameStyle = PhoneticNameStyle.UNDEFINED;
141f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            mSplitter.guessNameStyle(name);
142f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            int unadjustedFullNameStyle = name.fullNameStyle;
143f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            name.fullNameStyle = mSplitter.getAdjustedFullNameStyle(name.fullNameStyle);
14455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            final String joined = mSplitter.join(name, true, true);
145f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            update.put(StructuredName.DISPLAY_NAME, joined);
146f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
147f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            update.put(StructuredName.FULL_NAME_STYLE, unadjustedFullNameStyle);
148f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            update.put(StructuredName.PHONETIC_NAME_STYLE, name.phoneticNameStyle);
149f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        } else if (touchedUnstruct && touchedStruct){
150f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            if (!update.containsKey(StructuredName.FULL_NAME_STYLE)) {
151f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                update.put(StructuredName.FULL_NAME_STYLE,
152f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov                        mSplitter.guessFullNameStyle(unstruct));
153f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            }
154f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            if (!update.containsKey(StructuredName.PHONETIC_NAME_STYLE)) {
1550f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                NameSplitter.Name name = new NameSplitter.Name();
1560f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                name.fromValues(update);
1570f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                name.phoneticNameStyle = PhoneticNameStyle.UNDEFINED;
1580f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                mSplitter.guessNameStyle(name);
1590f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                update.put(StructuredName.PHONETIC_NAME_STYLE, name.phoneticNameStyle);
160f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov            }
161f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov        }
162f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov    }
163f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov
164eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    @Override
165eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    public boolean hasSearchableData() {
166eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov        return true;
167eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    }
168eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov
169eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    @Override
170eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    public boolean containsSearchableColumns(ContentValues values) {
171eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov        return values.containsKey(StructuredName.FAMILY_NAME)
172eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.GIVEN_NAME)
173eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.MIDDLE_NAME)
174eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.PHONETIC_FAMILY_NAME)
175eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.PHONETIC_GIVEN_NAME)
176eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.PHONETIC_MIDDLE_NAME)
177eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.PREFIX)
178eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov                || values.containsKey(StructuredName.SUFFIX);
179eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    }
180eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov
181eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    @Override
182eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    public void appendSearchableData(IndexBuilder builder) {
18392ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        String name = builder.getString(StructuredName.DISPLAY_NAME);
18492ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        Integer fullNameStyle = builder.getInt(StructuredName.FULL_NAME_STYLE);
18592ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov
18692ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        mNameLookupBuilder.appendToSearchIndex(builder, name, fullNameStyle != null
18792ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov                        ? mSplitter.getAdjustedFullNameStyle(fullNameStyle)
18892ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov                        : FullNameStyle.UNDEFINED);
18930cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov
19030cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        String phoneticFamily = builder.getString(StructuredName.PHONETIC_FAMILY_NAME);
19130cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        String phoneticMiddle = builder.getString(StructuredName.PHONETIC_MIDDLE_NAME);
19230cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        String phoneticGiven = builder.getString(StructuredName.PHONETIC_GIVEN_NAME);
19330cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov
19430cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        // Phonetic name is often spelled without spaces
19530cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        if (!TextUtils.isEmpty(phoneticFamily) || !TextUtils.isEmpty(phoneticMiddle)
19630cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                || !TextUtils.isEmpty(phoneticGiven)) {
19730cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            mSb.setLength(0);
19830cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            if (!TextUtils.isEmpty(phoneticFamily)) {
199155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov                builder.appendName(phoneticFamily);
20030cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                mSb.append(phoneticFamily);
20130cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            }
20230cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            if (!TextUtils.isEmpty(phoneticMiddle)) {
203155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov                builder.appendName(phoneticMiddle);
20430cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                mSb.append(phoneticMiddle);
20530cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            }
20630cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            if (!TextUtils.isEmpty(phoneticGiven)) {
207155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov                builder.appendName(phoneticGiven);
20830cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                mSb.append(phoneticGiven);
20930cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov            }
2100f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            final String phoneticName = mSb.toString().trim();
2110f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            int phoneticNameStyle = builder.getInt(StructuredName.PHONETIC_NAME_STYLE);
2120f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            if (phoneticNameStyle == PhoneticNameStyle.UNDEFINED) {
2130f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                phoneticNameStyle = mSplitter.guessPhoneticNameStyle(phoneticName);
2140f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            }
2150f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            builder.appendName(phoneticName);
2160f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            mNameLookupBuilder.appendNameShorthandLookup(builder, phoneticName,
2170f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner                    phoneticNameStyle);
21830cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        }
219eeeed5669d98897501bf2b18c88579c7effd0955Dmitri Plotnikov    }
220f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov}
221