Merge "Add Person class." into pi-preview1-androidx-dev
diff --git a/compat/api/current.txt b/compat/api/current.txt
index f315dad..666b594 100644
--- a/compat/api/current.txt
+++ b/compat/api/current.txt
@@ -571,6 +571,29 @@
field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
}
+ public class Person {
+ method public static androidx.core.app.Person fromBundle(android.os.Bundle);
+ method public android.graphics.Bitmap getIcon();
+ method public java.lang.String getKey();
+ method public java.lang.CharSequence getName();
+ method public java.lang.String getUri();
+ method public boolean isBot();
+ method public boolean isImportant();
+ method public androidx.core.app.Person.Builder toBuilder();
+ method public android.os.Bundle toBundle();
+ }
+
+ public static class Person.Builder {
+ ctor public Person.Builder();
+ method public androidx.core.app.Person build();
+ method public androidx.core.app.Person.Builder setBot(boolean);
+ method public androidx.core.app.Person.Builder setIcon(android.graphics.Bitmap);
+ method public androidx.core.app.Person.Builder setImportant(boolean);
+ method public androidx.core.app.Person.Builder setKey(java.lang.String);
+ method public androidx.core.app.Person.Builder setName(java.lang.CharSequence);
+ method public androidx.core.app.Person.Builder setUri(java.lang.String);
+ }
+
public final class RemoteInput {
method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String, android.net.Uri>);
method public static void addResultsToIntent(androidx.core.app.RemoteInput[], android.content.Intent, android.os.Bundle);
diff --git a/compat/src/androidTest/java/androidx/core/app/PersonTest.java b/compat/src/androidTest/java/androidx/core/app/PersonTest.java
new file mode 100644
index 0000000..20b2090
--- /dev/null
+++ b/compat/src/androidTest/java/androidx/core/app/PersonTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PersonTest {
+ private static final CharSequence TEST_NAME = "Example Name";
+ private static final Bitmap TEST_ICON = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ private static final String TEST_URI = "mailto:example@example.com";
+ private static final String TEST_KEY = "example-key";
+ private static final boolean TEST_IS_BOT = true;
+ private static final boolean TEST_IS_IMPORTANT = true;
+
+ @Test
+ @SdkSuppress(minSdkVersion = 12)
+ public void bundle() {
+ Person person = new Person.Builder()
+ .setImportant(TEST_IS_IMPORTANT)
+ .setBot(TEST_IS_BOT)
+ .setKey(TEST_KEY)
+ .setUri(TEST_URI)
+ .setIcon(TEST_ICON)
+ .setName(TEST_NAME)
+ .build();
+
+ Bundle personBundle = person.toBundle();
+ Person result = Person.fromBundle(personBundle);
+
+ assertEquals(TEST_NAME, result.getName());
+ assertEquals(TEST_URI, result.getUri());
+ assertEquals(TEST_KEY, result.getKey());
+ assertEquals(TEST_IS_BOT, result.isBot());
+ assertEquals(TEST_IS_IMPORTANT, result.isImportant());
+
+ // Requires SDK >= 12
+ assertTrue(TEST_ICON.sameAs(result.getIcon()));
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 12)
+ public void toBuilder() {
+ Person person = new Person.Builder()
+ .setImportant(TEST_IS_IMPORTANT)
+ .setBot(TEST_IS_BOT)
+ .setKey(TEST_KEY)
+ .setUri(TEST_URI)
+ .setIcon(TEST_ICON)
+ .setName(TEST_NAME)
+ .build();
+ Person result = person.toBuilder().build();
+
+ assertEquals(TEST_NAME, result.getName());
+ assertEquals(TEST_URI, result.getUri());
+ assertEquals(TEST_KEY, result.getKey());
+ assertEquals(TEST_IS_BOT, result.isBot());
+ assertEquals(TEST_IS_IMPORTANT, result.isImportant());
+
+ // Requires SDK >= 12
+ assertTrue(TEST_ICON.sameAs(result.getIcon()));
+ }
+
+ @Test
+ public void getName() {
+ Person person = new Person.Builder().setName(TEST_NAME).build();
+ assertEquals(TEST_NAME, person.getName());
+ }
+
+ @Test
+ public void getIcon() {
+ Person person = new Person.Builder().setIcon(TEST_ICON).build();
+ assertEquals(TEST_ICON, person.getIcon());
+ }
+
+ @Test
+ public void getUri() {
+ Person person = new Person.Builder().setUri(TEST_URI).build();
+ assertEquals(TEST_URI, person.getUri());
+ }
+
+ @Test
+ public void getKey() {
+ Person person = new Person.Builder().setKey(TEST_KEY).build();
+ assertEquals(TEST_KEY, person.getKey());
+ }
+
+ @Test
+ public void isBot() {
+ Person person = new Person.Builder().setBot(TEST_IS_BOT).build();
+ assertEquals(TEST_IS_BOT, person.isBot());
+ }
+
+ @Test
+ public void isImportant() {
+ Person person = new Person.Builder().setImportant(TEST_IS_IMPORTANT).build();
+ assertEquals(TEST_IS_IMPORTANT, person.isImportant());
+ }
+}
diff --git a/compat/src/main/java/androidx/core/app/Person.java b/compat/src/main/java/androidx/core/app/Person.java
new file mode 100644
index 0000000..3bda510
--- /dev/null
+++ b/compat/src/main/java/androidx/core/app/Person.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.app;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Provides an immutable reference to an entity that appears repeatedly on different surfaces of the
+ * platform. For example, this could represent the sender of a message.
+ */
+public class Person {
+ private static final String NAME_KEY = "name";
+ private static final String ICON_KEY = "icon";
+ private static final String URI_KEY = "uri";
+ private static final String KEY_KEY = "key";
+ private static final String IS_BOT_KEY = "isBot";
+ private static final String IS_IMPORTANT_KEY = "isImportant";
+
+ /**
+ * Extracts and returns the {@link Person} written to the {@code bundle}. A bundle can be
+ * created from a {@link Person} using {@link #toBundle()}.
+ */
+ public static Person fromBundle(Bundle bundle) {
+ return new Builder()
+ .setName(bundle.getCharSequence(NAME_KEY))
+ .setIcon((Bitmap) bundle.getParcelable(ICON_KEY))
+ .setUri(bundle.getString(URI_KEY))
+ .setKey(bundle.getString(KEY_KEY))
+ .setBot(bundle.getBoolean(IS_BOT_KEY))
+ .setImportant(bundle.getBoolean(IS_IMPORTANT_KEY))
+ .build();
+ }
+
+ @Nullable private CharSequence mName;
+ @Nullable private Bitmap mIcon;
+ @Nullable private String mUri;
+ @Nullable private String mKey;
+ private boolean mIsBot;
+ private boolean mIsImportant;
+
+ private Person(Builder builder) {
+ mName = builder.mName;
+ mIcon = builder.mIcon;
+ mUri = builder.mUri;
+ mKey = builder.mKey;
+ mIsBot = builder.mIsBot;
+ mIsImportant = builder.mIsImportant;
+ }
+
+ /**
+ * Writes and returns a new {@link Bundle} that represents this {@link Person}. This bundle can
+ * be converted back by using {@link #fromBundle(Bundle)}.
+ */
+ public Bundle toBundle() {
+ Bundle result = new Bundle();
+ result.putCharSequence(NAME_KEY, mName);
+ result.putParcelable(ICON_KEY, mIcon);
+ result.putString(URI_KEY, mUri);
+ result.putString(KEY_KEY, mKey);
+ result.putBoolean(IS_BOT_KEY, mIsBot);
+ result.putBoolean(IS_IMPORTANT_KEY, mIsImportant);
+ return result;
+ }
+
+ /** Creates and returns a new {@link Builder} initialized with this Person's data. */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * Returns the name for this {@link Person} or {@code null} if no name was provided. This could
+ * be a full name, nickname, username, etc.
+ */
+ @Nullable
+ public CharSequence getName() {
+ return mName;
+ }
+
+ /** Returns the icon for this {@link Person} or {@code null} if no icon was provided. */
+ @Nullable
+ public Bitmap getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * Returns the raw URI for this {@link Person} or {@code null} if no URI was provided. A URI can
+ * be any of the following:
+ * <ul>
+ * <li>The {@code String} representation of a
+ * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}</li>
+ * <li>A {@code mailto:} schema*</li>
+ * <li>A {@code tel:} schema*</li>
+ * </ul>
+ *
+ * <p>*Note for these schemas, the path portion of the URI must exist in the contacts
+ * database in their appropriate column, otherwise the reference should be discarded.
+ */
+ @Nullable
+ public String getUri() {
+ return mUri;
+ }
+
+ /**
+ * Returns the key for this {@link Person} or {@code null} if no key was provided. This is
+ * provided as a unique identifier between other {@link Person}s.
+ */
+ @Nullable
+ public String getKey() {
+ return mKey;
+ }
+
+ /**
+ * Returns whether or not this {@link Person} is a machine rather than a human. Used primarily
+ * to identify automated tooling.
+ */
+ public boolean isBot() {
+ return mIsBot;
+ }
+
+ /**
+ * Returns whether or not this {@link Person} is important to the user of this device with
+ * regards to how frequently they interact.
+ */
+ public boolean isImportant() {
+ return mIsImportant;
+ }
+
+ /** Builder for the immutable {@link Person} class. */
+ public static class Builder {
+ @Nullable private CharSequence mName;
+ @Nullable private Bitmap mIcon;
+ @Nullable private String mUri;
+ @Nullable private String mKey;
+ private boolean mIsBot;
+ private boolean mIsImportant;
+
+ /** Creates a new, empty {@link Builder}. */
+ public Builder() { }
+
+ private Builder(Person person) {
+ mName = person.mName;
+ mIcon = person.mIcon;
+ mUri = person.mUri;
+ mKey = person.mKey;
+ mIsBot = person.mIsBot;
+ mIsImportant = person.mIsImportant;
+ }
+
+ /**
+ * Give this {@link Person} a name to use for display. This can be, for example, a full
+ * name, nickname, username, etc.
+ */
+ @NonNull
+ public Builder setName(@Nullable CharSequence name) {
+ mName = name;
+ return this;
+ }
+
+ /**
+ * Set an icon for this {@link Person}.
+ *
+ * <p>The system will prefer this icon over any images that are resolved from
+ * {@link #setUri(String)}.
+ */
+ @NonNull
+ public Builder setIcon(@Nullable Bitmap icon) {
+ mIcon = icon;
+ return this;
+ }
+
+ /**
+ * Set a URI for this {@link Person} which can be any of the following:
+ * <ul>
+ * <li>The {@code String} representation of a
+ * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}</li>
+ * <li>A {@code mailto:} schema*</li>
+ * <li>A {@code tel:} schema*</li>
+ * </ul>
+ *
+ * <p>*Note for these schemas, the path portion of the URI must exist in the contacts
+ * database in their appropriate column, otherwise the reference will be discarded.
+ */
+ @NonNull
+ public Builder setUri(@Nullable String uri) {
+ mUri = uri;
+ return this;
+ }
+
+ /**
+ * Set a unique identifier for this {@link Person}. This is especially useful if the
+ * {@link #setName(CharSequence)} value isn't unique. This value is preferred for
+ * identification, but if it's not provided, the person's name will be used in its place.
+ */
+ @NonNull
+ public Builder setKey(@Nullable String key) {
+ mKey = key;
+ return this;
+ }
+
+ /**
+ * Sets whether or not this {@link Person} represents a machine rather than a human. This is
+ * used primarily for testing and automated tooling.
+ */
+ @NonNull
+ public Builder setBot(boolean bot) {
+ mIsBot = bot;
+ return this;
+ }
+
+ /**
+ * Sets whether this is an important person. Use this method to denote users who frequently
+ * interact with the user of this device when {@link #setUri(String)} isn't provided with
+ * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, and instead with
+ * the {@code mailto:} or {@code tel:} schemas.
+ */
+ @NonNull
+ public Builder setImportant(boolean important) {
+ mIsImportant = important;
+ return this;
+ }
+
+ /** Creates and returns the {@link Person} this builder represents. */
+ @NonNull
+ public Person build() {
+ return new Person(this);
+ }
+ }
+}