blob: ad99bf832a3a288ced5cb1ea1b9598090dc4f02b [file] [log] [blame]
Makoto Onuki4b722a92009-11-02 16:44:18 +09001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dmitri Plotnikov18ffaa22010-12-03 14:28:00 -080017package com.android.contacts.editor;
Makoto Onuki4b722a92009-11-02 16:44:18 +090018
Makoto Onuki4b722a92009-11-02 16:44:18 +090019import android.os.Bundle;
20import android.os.Parcel;
21import android.os.Parcelable;
22
Yorke Leecd321f62013-10-28 15:20:15 -070023import com.android.contacts.common.model.RawContactDelta;
Chiao Cheng738ff862012-11-30 12:06:03 -080024import com.android.contacts.common.model.ValuesDelta;
Chiao Cheng428f0082012-11-13 18:38:56 -080025import com.android.contacts.common.model.dataitem.DataKind;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070026
Makoto Onuki4b722a92009-11-02 16:44:18 +090027/**
Gary Mai65971d02016-09-15 15:00:16 -070028 * A class that provides unique view ids for {@link ContentEditorView},
Daniel Lehmann392ccec2010-11-01 20:50:03 -070029 * {@link LabeledEditorView} and {@link EditView} on {@link EditContactActivity}.
Makoto Onuki4b722a92009-11-02 16:44:18 +090030 * It is used to assign a unique but consistent id to each view across {@link EditContactActivity}'s
31 * lifecycle, so that we can re-construct view state (e.g. focused view) when the screen rotates.
32 *
33 * <p>This class is not thread safe.
34 */
35public final class ViewIdGenerator implements Parcelable {
36 private static final int INVALID_VIEW_ID = 0;
37 private static final int INITIAL_VIEW_ID = 1;
38
39 public static final int NO_VIEW_INDEX = -1;
40
41 private int mNextId;
42
43 /**
44 * Used as a map from the "key" of the views to actual ids. {@link #getId()} generates keys for
45 * the views.
46 */
47 private Bundle mIdMap = new Bundle();
48
49 private static final char KEY_SEPARATOR = '*';
50
51 private final static StringBuilder sWorkStringBuilder = new StringBuilder();
52
53 public ViewIdGenerator() {
54 mNextId = INITIAL_VIEW_ID;
55 }
56
57 /** {@inheritDoc} */
58 public int describeContents() {
59 return 0;
60 }
61
62 /**
63 * Returns an id for a view associated with specified contact field.
64 *
Maurice Chu851222a2012-06-21 11:43:08 -070065 * @param entity {@link RawContactDelta} associated with the view
Makoto Onuki4b722a92009-11-02 16:44:18 +090066 * @param kind {@link DataKind} associated with the view, or null if none exists.
67 * @param values {@link ValuesDelta} associated with the view, or null if none exists.
68 * @param viewIndex index of the view in the parent {@link Editor}, if it's a leave view.
69 * Otherwise, pass {@link #NO_VIEW_INDEX}.
70 */
Maurice Chu851222a2012-06-21 11:43:08 -070071 public int getId(RawContactDelta entity, DataKind kind, ValuesDelta values,
Makoto Onuki4b722a92009-11-02 16:44:18 +090072 int viewIndex) {
73 final String k = getMapKey(entity, kind, values, viewIndex);
74
75 int id = mIdMap.getInt(k, INVALID_VIEW_ID);
76 if (id == INVALID_VIEW_ID) {
77 // Make sure the new id won't conflict with auto-generated ids by masking with 0xffff.
78 id = (mNextId++) & 0xFFFF;
79 mIdMap.putInt(k, id);
80 }
81 return id;
82 }
83
Maurice Chu851222a2012-06-21 11:43:08 -070084 private static String getMapKey(RawContactDelta entity, DataKind kind, ValuesDelta values,
Makoto Onuki4b722a92009-11-02 16:44:18 +090085 int viewIndex) {
86 sWorkStringBuilder.setLength(0);
87 if (entity != null) {
88 sWorkStringBuilder.append(entity.getValues().getId());
89
90 if (kind != null) {
91 sWorkStringBuilder.append(KEY_SEPARATOR);
92 sWorkStringBuilder.append(kind.mimeType);
93
94 if (values != null) {
95 sWorkStringBuilder.append(KEY_SEPARATOR);
96 sWorkStringBuilder.append(values.getId());
97
98 if (viewIndex != NO_VIEW_INDEX) {
99 sWorkStringBuilder.append(KEY_SEPARATOR);
100 sWorkStringBuilder.append(viewIndex);
101 }
102 }
103 }
104 }
105 return sWorkStringBuilder.toString();
106 }
107
108 /** {@Override} */
109 public void writeToParcel(Parcel dest, int flags) {
110 dest.writeInt(mNextId);
111 dest.writeBundle(mIdMap);
112 }
113
114 private void readFromParcel(Parcel src) {
115 mNextId = src.readInt();
116 mIdMap = src.readBundle();
117 }
118
119 public static final Parcelable.Creator<ViewIdGenerator> CREATOR =
120 new Parcelable.Creator<ViewIdGenerator>() {
121 public ViewIdGenerator createFromParcel(Parcel in) {
122 final ViewIdGenerator vig = new ViewIdGenerator();
123 vig.readFromParcel(in);
124 return vig;
125 }
126
127 public ViewIdGenerator[] newArray(int size) {
128 return new ViewIdGenerator[size];
129 }
130 };
131}