14b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki/* 24b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * Copyright (C) 2009 The Android Open Source Project 34b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * 44b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 54b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * you may not use this file except in compliance with the License. 64b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * You may obtain a copy of the License at 74b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * 84b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 94b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * 104b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * Unless required by applicable law or agreed to in writing, software 114b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 124b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * See the License for the specific language governing permissions and 144b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * limitations under the License. 154b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki */ 164b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor; 184b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 194b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onukiimport android.os.Bundle; 204b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onukiimport android.os.Parcel; 214b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onukiimport android.os.Parcelable; 224b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 23851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta; 24738ff8623dc77dd91a1b9023861e924ba5e4c27eChiao Chengimport com.android.contacts.common.model.ValuesDelta; 25428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.dataitem.DataKind; 26e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 274b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki/** 284b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * A class that provides unique view ids for {@link ContentEditorView}, {@link KindSectionView}, 29392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * {@link LabeledEditorView} and {@link EditView} on {@link EditContactActivity}. 304b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * It is used to assign a unique but consistent id to each view across {@link EditContactActivity}'s 314b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * lifecycle, so that we can re-construct view state (e.g. focused view) when the screen rotates. 324b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * 334b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * <p>This class is not thread safe. 344b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki */ 354b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onukipublic final class ViewIdGenerator implements Parcelable { 364b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private static final int INVALID_VIEW_ID = 0; 374b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private static final int INITIAL_VIEW_ID = 1; 384b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 394b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public static final int NO_VIEW_INDEX = -1; 404b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 414b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private int mNextId; 424b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 434b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki /** 444b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * Used as a map from the "key" of the views to actual ids. {@link #getId()} generates keys for 454b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * the views. 464b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki */ 474b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private Bundle mIdMap = new Bundle(); 484b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 494b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private static final char KEY_SEPARATOR = '*'; 504b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 514b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private final static StringBuilder sWorkStringBuilder = new StringBuilder(); 524b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 534b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public ViewIdGenerator() { 544b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki mNextId = INITIAL_VIEW_ID; 554b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 564b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 574b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki /** {@inheritDoc} */ 584b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public int describeContents() { 594b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki return 0; 604b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 614b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 624b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki /** 634b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * Returns an id for a view associated with specified contact field. 644b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * 65851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu * @param entity {@link RawContactDelta} associated with the view 664b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * @param kind {@link DataKind} associated with the view, or null if none exists. 674b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * @param values {@link ValuesDelta} associated with the view, or null if none exists. 684b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * @param viewIndex index of the view in the parent {@link Editor}, if it's a leave view. 694b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki * Otherwise, pass {@link #NO_VIEW_INDEX}. 704b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki */ 71851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public int getId(RawContactDelta entity, DataKind kind, ValuesDelta values, 724b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki int viewIndex) { 734b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki final String k = getMapKey(entity, kind, values, viewIndex); 744b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 754b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki int id = mIdMap.getInt(k, INVALID_VIEW_ID); 764b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki if (id == INVALID_VIEW_ID) { 774b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki // Make sure the new id won't conflict with auto-generated ids by masking with 0xffff. 784b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki id = (mNextId++) & 0xFFFF; 794b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki mIdMap.putInt(k, id); 804b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 814b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki return id; 824b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 834b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 84851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private static String getMapKey(RawContactDelta entity, DataKind kind, ValuesDelta values, 854b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki int viewIndex) { 864b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.setLength(0); 874b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki if (entity != null) { 884b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(entity.getValues().getId()); 894b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 904b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki if (kind != null) { 914b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(KEY_SEPARATOR); 924b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(kind.mimeType); 934b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 944b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki if (values != null) { 954b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(KEY_SEPARATOR); 964b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(values.getId()); 974b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 984b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki if (viewIndex != NO_VIEW_INDEX) { 994b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(KEY_SEPARATOR); 1004b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki sWorkStringBuilder.append(viewIndex); 1014b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1024b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1034b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1044b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1054b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki return sWorkStringBuilder.toString(); 1064b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1074b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 1084b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki /** {@Override} */ 1094b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public void writeToParcel(Parcel dest, int flags) { 1104b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki dest.writeInt(mNextId); 1114b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki dest.writeBundle(mIdMap); 1124b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1134b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 1144b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki private void readFromParcel(Parcel src) { 1154b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki mNextId = src.readInt(); 1164b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki mIdMap = src.readBundle(); 1174b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1184b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 1194b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public static final Parcelable.Creator<ViewIdGenerator> CREATOR = 1204b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki new Parcelable.Creator<ViewIdGenerator>() { 1214b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public ViewIdGenerator createFromParcel(Parcel in) { 1224b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki final ViewIdGenerator vig = new ViewIdGenerator(); 1234b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki vig.readFromParcel(in); 1244b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki return vig; 1254b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1264b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki 1274b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki public ViewIdGenerator[] newArray(int size) { 1284b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki return new ViewIdGenerator[size]; 1294b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki } 1304b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki }; 1314b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki} 132