summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/common
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/common')
-rw-r--r--java/com/android/dialer/common/AndroidManifest.xml3
-rw-r--r--java/com/android/dialer/common/Assert.java219
-rw-r--r--java/com/android/dialer/common/ConfigProvider.java27
-rw-r--r--java/com/android/dialer/common/ConfigProviderBindings.java76
-rw-r--r--java/com/android/dialer/common/ConfigProviderFactory.java26
-rw-r--r--java/com/android/dialer/common/DpUtil.java31
-rw-r--r--java/com/android/dialer/common/FragmentUtils.java98
-rw-r--r--java/com/android/dialer/common/LogUtil.java214
-rw-r--r--java/com/android/dialer/common/MathUtil.java57
-rw-r--r--java/com/android/dialer/common/NetworkUtil.java192
-rw-r--r--java/com/android/dialer/common/PackageUtils.java54
-rw-r--r--java/com/android/dialer/common/PerAccountSharedPreferences.java146
-rw-r--r--java/com/android/dialer/common/UiUtil.java41
-rw-r--r--java/com/android/dialer/common/concurrent/AsyncTaskExecutor.java51
-rw-r--r--java/com/android/dialer/common/concurrent/AsyncTaskExecutors.java92
-rw-r--r--java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java260
-rw-r--r--java/com/android/dialer/common/concurrent/DialerExecutor.java100
-rw-r--r--java/com/android/dialer/common/concurrent/DialerExecutorFactory.java63
-rw-r--r--java/com/android/dialer/common/concurrent/DialerExecutors.java134
-rw-r--r--java/com/android/dialer/common/concurrent/DialerUiTaskFragment.java170
-rw-r--r--java/com/android/dialer/common/concurrent/FallibleAsyncTask.java94
-rw-r--r--java/com/android/dialer/common/concurrent/ThreadUtil.java38
-rw-r--r--java/com/android/dialer/common/proguard.flags4
-rw-r--r--java/com/android/dialer/common/res/values-af/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-am/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ar/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-az/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-b+sr+Latn/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-be/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-bg/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-bn/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-bs/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ca/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-cs/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-da/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-de/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-el/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-en-rAU/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-en-rGB/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-en-rIN/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-es-rUS/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-es/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-et/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-eu/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-fa/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-fi/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-fr-rCA/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-fr/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-gl/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-gu/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-hi/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-hr/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-hu/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-hy/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-in/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-is/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-it/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-iw/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ja/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ka/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-kk/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-km/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-kn/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ko/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ky/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-lo/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-lt/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-lv/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-mk/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ml/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-mn/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-mr/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ms/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-my/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-nb/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ne/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-nl/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-no/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-pa/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-pl/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-pt-rBR/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-pt-rPT/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-pt/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ro/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ru/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-si/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-sk/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-sl/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-sq/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-sr/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-sv/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-sw/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ta/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-te/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-th/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-tl/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-tr/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-uk/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-ur/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-uz/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-vi/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-zh-rCN/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-zh-rHK/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-zh-rTW/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values-zu/strings.xml6
-rw-r--r--java/com/android/dialer/common/res/values/config.xml4
-rw-r--r--java/com/android/dialer/common/res/values/strings.xml5
107 files changed, 2691 insertions, 0 deletions
diff --git a/java/com/android/dialer/common/AndroidManifest.xml b/java/com/android/dialer/common/AndroidManifest.xml
new file mode 100644
index 000000000..ae43d6693
--- /dev/null
+++ b/java/com/android/dialer/common/AndroidManifest.xml
@@ -0,0 +1,3 @@
+<manifest
+ package="com.android.dialer.common">
+</manifest>
diff --git a/java/com/android/dialer/common/Assert.java b/java/com/android/dialer/common/Assert.java
new file mode 100644
index 000000000..189d209c8
--- /dev/null
+++ b/java/com/android/dialer/common/Assert.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import javax.annotation.CheckReturnValue;
+
+/** Assertions which will result in program termination unless disabled by flags. */
+public class Assert {
+
+ private static boolean areThreadAssertsEnabled = true;
+
+ public static void setAreThreadAssertsEnabled(boolean areThreadAssertsEnabled) {
+ Assert.areThreadAssertsEnabled = areThreadAssertsEnabled;
+ }
+
+ public static boolean areThreadAssertsEnabled() {
+ return areThreadAssertsEnabled;
+ }
+
+ /**
+ * Called when a truly exceptional case occurs.
+ *
+ * @throws AssertionError
+ * @deprecated Use throw Assert.create*FailException() instead.
+ */
+ @Deprecated
+ public static void fail() {
+ throw new AssertionError("Fail");
+ }
+
+ /**
+ * Called when a truly exceptional case occurs.
+ *
+ * @param reason the optional reason to supply as the exception message
+ * @throws AssertionError
+ * @deprecated Use throw Assert.create*FailException() instead.
+ */
+ @Deprecated
+ public static void fail(String reason) {
+ throw new AssertionError(reason);
+ }
+
+ @CheckReturnValue
+ public static AssertionError createAssertionFailException(String msg) {
+ return new AssertionError(msg);
+ }
+
+ @CheckReturnValue
+ public static UnsupportedOperationException createUnsupportedOperationFailException() {
+ return new UnsupportedOperationException();
+ }
+
+ @CheckReturnValue
+ public static UnsupportedOperationException createUnsupportedOperationFailException(String msg) {
+ return new UnsupportedOperationException(msg);
+ }
+
+ @CheckReturnValue
+ public static IllegalStateException createIllegalStateFailException() {
+ return new IllegalStateException();
+ }
+
+ @CheckReturnValue
+ public static IllegalStateException createIllegalStateFailException(String msg) {
+ return new IllegalStateException(msg);
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(boolean expression) {
+ checkArgument(expression, null);
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param messageTemplate the message to log, possible with format arguments.
+ * @param args optional arguments to be used in the formatted string.
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(
+ boolean expression, @Nullable String messageTemplate, Object... args) {
+ if (!expression) {
+ throw new IllegalArgumentException(format(messageTemplate, args));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling instance, but not
+ * involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalStateException if {@code expression} is false
+ */
+ public static void checkState(boolean expression) {
+ checkState(expression, null);
+ }
+
+ /**
+ * Ensures the truth of an expression involving the state of the calling instance, but not
+ * involving any parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param messageTemplate the message to log, possible with format arguments.
+ * @param args optional arguments to be used in the formatted string.
+ * @throws IllegalStateException if {@code expression} is false
+ */
+ public static void checkState(
+ boolean expression, @Nullable String messageTemplate, Object... args) {
+ if (!expression) {
+ throw new IllegalStateException(format(messageTemplate, args));
+ }
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling method is not null.
+ *
+ * @param reference an object reference
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ @NonNull
+ public static <T> T isNotNull(@Nullable T reference) {
+ return isNotNull(reference, null);
+ }
+
+ /**
+ * Ensures that an object reference passed as a parameter to the calling method is not null.
+ *
+ * @param reference an object reference
+ * @param messageTemplate the message to log, possible with format arguments.
+ * @param args optional arguments to be used in the formatted string.
+ * @return the non-null reference that was validated
+ * @throws NullPointerException if {@code reference} is null
+ */
+ @NonNull
+ public static <T> T isNotNull(
+ @Nullable T reference, @Nullable String messageTemplate, Object... args) {
+ if (reference == null) {
+ throw new NullPointerException(format(messageTemplate, args));
+ }
+ return reference;
+ }
+
+ /**
+ * Ensures that the current thread is the main thread.
+ *
+ * @throws IllegalStateException if called on a background thread
+ */
+ public static void isMainThread() {
+ isMainThread(null);
+ }
+
+ /**
+ * Ensures that the current thread is the main thread.
+ *
+ * @param messageTemplate the message to log, possible with format arguments.
+ * @param args optional arguments to be used in the formatted string.
+ * @throws IllegalStateException if called on a background thread
+ */
+ public static void isMainThread(@Nullable String messageTemplate, Object... args) {
+ if (!areThreadAssertsEnabled) {
+ return;
+ }
+ checkState(Looper.getMainLooper().equals(Looper.myLooper()), messageTemplate, args);
+ }
+
+ /**
+ * Ensures that the current thread is a worker thread.
+ *
+ * @throws IllegalStateException if called on the main thread
+ */
+ public static void isWorkerThread() {
+ isWorkerThread(null);
+ }
+
+ /**
+ * Ensures that the current thread is a worker thread.
+ *
+ * @param messageTemplate the message to log, possible with format arguments.
+ * @param args optional arguments to be used in the formatted string.
+ * @throws IllegalStateException if called on the main thread
+ */
+ public static void isWorkerThread(@Nullable String messageTemplate, Object... args) {
+ if (!areThreadAssertsEnabled) {
+ return;
+ }
+ checkState(!Looper.getMainLooper().equals(Looper.myLooper()), messageTemplate, args);
+ }
+
+ private static String format(@Nullable String messageTemplate, Object... args) {
+ if (messageTemplate == null) {
+ return null;
+ }
+ return String.format(messageTemplate, args);
+ }
+}
diff --git a/java/com/android/dialer/common/ConfigProvider.java b/java/com/android/dialer/common/ConfigProvider.java
new file mode 100644
index 000000000..c0791e979
--- /dev/null
+++ b/java/com/android/dialer/common/ConfigProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+/** Gets config values from the container application. */
+public interface ConfigProvider {
+
+ String getString(String key, String defaultValue);
+
+ long getLong(String key, long defaultValue);
+
+ boolean getBoolean(String key, boolean defaultValue);
+}
diff --git a/java/com/android/dialer/common/ConfigProviderBindings.java b/java/com/android/dialer/common/ConfigProviderBindings.java
new file mode 100644
index 000000000..9f045add4
--- /dev/null
+++ b/java/com/android/dialer/common/ConfigProviderBindings.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.os.UserManagerCompat;
+
+/** Accessor for getting a {@link ConfigProvider}. */
+public class ConfigProviderBindings {
+
+ private static ConfigProvider configProvider;
+ private static ConfigProvider configProviderStub;
+
+ public static ConfigProvider get(@NonNull Context context) {
+ Assert.isNotNull(context);
+ if (configProvider != null) {
+ return configProvider;
+ }
+ if (!UserManagerCompat.isUserUnlocked(context)) {
+ if (configProviderStub == null) {
+ configProviderStub = new ConfigProviderStub();
+ }
+ return configProviderStub;
+ }
+
+ Context application = context.getApplicationContext();
+ if (application instanceof ConfigProviderFactory) {
+ configProvider = ((ConfigProviderFactory) application).getConfigProvider();
+ }
+
+ if (configProvider == null) {
+ configProvider = new ConfigProviderStub();
+ }
+
+ return configProvider;
+ }
+
+ @VisibleForTesting
+ public static void setForTesting(@Nullable ConfigProvider configProviderForTesting) {
+ configProvider = configProviderForTesting;
+ }
+
+ private static class ConfigProviderStub implements ConfigProvider {
+ @Override
+ public String getString(String key, String defaultValue) {
+ return defaultValue;
+ }
+
+ @Override
+ public long getLong(String key, long defaultValue) {
+ return defaultValue;
+ }
+
+ @Override
+ public boolean getBoolean(String key, boolean defaultValue) {
+ return defaultValue;
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/ConfigProviderFactory.java b/java/com/android/dialer/common/ConfigProviderFactory.java
new file mode 100644
index 000000000..aeb4f303a
--- /dev/null
+++ b/java/com/android/dialer/common/ConfigProviderFactory.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+/**
+ * This interface should be implementated by the Application subclass. It allows dialer code to get
+ * references to a config provider.
+ */
+public interface ConfigProviderFactory {
+
+ ConfigProvider getConfigProvider();
+}
diff --git a/java/com/android/dialer/common/DpUtil.java b/java/com/android/dialer/common/DpUtil.java
new file mode 100644
index 000000000..0388824cd
--- /dev/null
+++ b/java/com/android/dialer/common/DpUtil.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.content.Context;
+
+/** Utility for dp to px conversion */
+public class DpUtil {
+
+ public static float pxToDp(Context context, float px) {
+ return px / context.getResources().getDisplayMetrics().density;
+ }
+
+ public static float dpToPx(Context context, float dp) {
+ return dp * context.getResources().getDisplayMetrics().density;
+ }
+}
diff --git a/java/com/android/dialer/common/FragmentUtils.java b/java/com/android/dialer/common/FragmentUtils.java
new file mode 100644
index 000000000..cb036959d
--- /dev/null
+++ b/java/com/android/dialer/common/FragmentUtils.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.support.annotation.CheckResult;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+
+/** Utility methods for working with Fragments */
+public class FragmentUtils {
+
+ private static Object parentForTesting;
+
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ public static void setParentForTesting(Object parentForTesting) {
+ FragmentUtils.parentForTesting = parentForTesting;
+ }
+
+ /**
+ * @return The parent of frag that implements the callbackInterface or null if no such parent can
+ * be found
+ */
+ @CheckResult(suggest = "#checkParent(Fragment, Class)}")
+ @Nullable
+ public static <T> T getParent(@NonNull Fragment fragment, @NonNull Class<T> callbackInterface) {
+ if (callbackInterface.isInstance(parentForTesting)) {
+ @SuppressWarnings("unchecked") // Casts are checked using runtime methods
+ T parent = (T) parentForTesting;
+ return parent;
+ }
+
+ Fragment parentFragment = fragment.getParentFragment();
+ if (callbackInterface.isInstance(parentFragment)) {
+ @SuppressWarnings("unchecked") // Casts are checked using runtime methods
+ T parent = (T) parentFragment;
+ return parent;
+ } else {
+ FragmentActivity activity = fragment.getActivity();
+ if (callbackInterface.isInstance(activity)) {
+ @SuppressWarnings("unchecked") // Casts are checked using runtime methods
+ T parent = (T) activity;
+ return parent;
+ }
+ }
+ return null;
+ }
+
+ /** Returns the parent or throws. Should perform check elsewhere(e.g. onAttach, newInstance). */
+ @NonNull
+ public static <T> T getParentUnsafe(
+ @NonNull Fragment fragment, @NonNull Class<T> callbackInterface) {
+ return Assert.isNotNull(getParent(fragment, callbackInterface));
+ }
+
+ /**
+ * Ensures fragment has a parent that implements the corresponding interface
+ *
+ * @param frag The Fragment whose parents are to be checked
+ * @param callbackInterface The interface class that a parent should implement
+ * @throws IllegalStateException if no parents are found that implement callbackInterface
+ */
+ public static void checkParent(@NonNull Fragment frag, @NonNull Class<?> callbackInterface)
+ throws IllegalStateException {
+ if (parentForTesting != null) {
+ return;
+ }
+ if (FragmentUtils.getParent(frag, callbackInterface) == null) {
+ String parent =
+ frag.getParentFragment() == null
+ ? frag.getActivity().getClass().getName()
+ : frag.getParentFragment().getClass().getName();
+ throw new IllegalStateException(
+ frag.getClass().getName()
+ + " must be added to a parent"
+ + " that implements "
+ + callbackInterface.getName()
+ + ". Instead found "
+ + parent);
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/LogUtil.java b/java/com/android/dialer/common/LogUtil.java
new file mode 100644
index 000000000..32d7b960b
--- /dev/null
+++ b/java/com/android/dialer/common/LogUtil.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+
+/** Provides logging functions. */
+public class LogUtil {
+
+ public static final String TAG = "Dialer";
+ private static final String SEPARATOR = " - ";
+
+ private LogUtil() {}
+
+ /**
+ * Log at a verbose level. Verbose logs should generally be filtered out, but may be useful when
+ * additional information is needed (e.g. to see how a particular flow evolved). These logs will
+ * not generally be available on production builds.
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'.
+ * @param msg The message you would like logged, possibly with format arguments.
+ * @param args Optional arguments to be used in the formatted string.
+ * @see {@link String#format(String, Object...)}
+ * @see {@link android.util.Log#v(String, String)}
+ */
+ public static void v(@NonNull String tag, @Nullable String msg, @Nullable Object... args) {
+ println(android.util.Log.VERBOSE, TAG, tag, msg, args);
+ }
+
+ /**
+ * Log at a debug level. Debug logs should provide known-useful information to aid in
+ * troubleshooting or evaluating flow. These logs will not generally be available on production
+ * builds.
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'
+ * @param msg The message you would like logged, possibly with format arguments
+ * @param args Optional arguments to be used in the formatted string
+ * @see {@link String#format(String, Object...)}
+ * @see {@link android.util.Log#d(String, String)}
+ */
+ public static void d(@NonNull String tag, @Nullable String msg, @Nullable Object... args) {
+ println(android.util.Log.DEBUG, TAG, tag, msg, args);
+ }
+
+ /**
+ * Log at an info level. Info logs provide information that would be useful to have on production
+ * builds for troubleshooting.
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'.
+ * @param msg The message you would like logged, possibly with format arguments.
+ * @param args Optional arguments to be used in the formatted string.
+ * @see {@link String#format(String, Object...)}
+ * @see {@link android.util.Log#i(String, String)}
+ */
+ public static void i(@NonNull String tag, @Nullable String msg, @Nullable Object... args) {
+ println(android.util.Log.INFO, TAG, tag, msg, args);
+ }
+
+ /**
+ * Log entry into a method at the info level.
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'.
+ */
+ public static void enterBlock(String tag) {
+ println(android.util.Log.INFO, TAG, tag, "enter");
+ }
+
+ /**
+ * Log at a warn level. Warn logs indicate a possible error (e.g. a default switch branch was hit,
+ * or a null object was expected to be non-null), but recovery is possible. This may be used when
+ * it is not guaranteed that an indeterminate or bad state was entered, just that something may
+ * have gone wrong.
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'.
+ * @param msg The message you would like logged, possibly with format arguments.
+ * @param args Optional arguments to be used in the formatted string.
+ * @see {@link String#format(String, Object...)}
+ * @see {@link android.util.Log#w(String, String)}
+ */
+ public static void w(@NonNull String tag, @Nullable String msg, @Nullable Object... args) {
+ println(android.util.Log.WARN, TAG, tag, msg, args);
+ }
+
+ /**
+ * Log at an error level. Error logs are used when it is known that an error occurred and is
+ * possibly fatal. This is used to log information that will be useful for troubleshooting a crash
+ * or other severe condition (e.g. error codes, state values, etc.).
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'.
+ * @param msg The message you would like logged, possibly with format arguments.
+ * @param args Optional arguments to be used in the formatted string.
+ * @see {@link String#format(String, Object...)}
+ * @see {@link android.util.Log#e(String, String)}
+ */
+ public static void e(@NonNull String tag, @Nullable String msg, @Nullable Object... args) {
+ println(android.util.Log.ERROR, TAG, tag, msg, args);
+ }
+
+ /**
+ * Log an exception at an error level. Error logs are used when it is known that an error occurred
+ * and is possibly fatal. This is used to log information that will be useful for troubleshooting
+ * a crash or other severe condition (e.g. error codes, state values, etc.).
+ *
+ * @param tag An identifier to allow searching for related logs. Generally of the form
+ * 'Class.method'.
+ * @param msg The message you would like logged.
+ * @param throwable The exception to log.
+ * @see {@link String#format(String, Object...)}
+ * @see {@link android.util.Log#e(String, String)}
+ */
+ public static void e(@NonNull String tag, @Nullable String msg, @NonNull Throwable throwable) {
+ if (!TextUtils.isEmpty(msg)) {
+ println(android.util.Log.ERROR, TAG, tag, msg);
+ }
+ println(android.util.Log.ERROR, TAG, tag, android.util.Log.getStackTraceString(throwable));
+ }
+
+ /**
+ * Used for log statements where we don't want to log various strings (e.g., usernames) with
+ * default logging to avoid leaking PII in logcat.
+ *
+ * @return text as is if {@value #TAG}'s log level is set to DEBUG or VERBOSE or on non-release
+ * builds; returns a redacted version otherwise.
+ */
+ public static String sanitizePii(@Nullable Object object) {
+ if (object == null) {
+ return "null";
+ }
+ if (isDebugEnabled()) {
+ return object.toString();
+ }
+ return "Redacted-" + object.toString().length() + "-chars";
+ }
+
+ /** Anonymizes char to prevent logging personally identifiable information. */
+ public static char sanitizeDialPadChar(char ch) {
+ if (isDebugEnabled()) {
+ return ch;
+ }
+ if (is12Key(ch)) {
+ return '*';
+ }
+ return ch;
+ }
+
+ /** Anonymizes the phone number to prevent logging personally identifiable information. */
+ public static String sanitizePhoneNumber(@Nullable String phoneNumber) {
+ if (isDebugEnabled()) {
+ return phoneNumber;
+ }
+ if (phoneNumber == null) {
+ return null;
+ }
+ StringBuilder stringBuilder = new StringBuilder(phoneNumber.length());
+ for (char c : phoneNumber.toCharArray()) {
+ stringBuilder.append(sanitizeDialPadChar(c));
+ }
+ return stringBuilder.toString();
+ }
+
+ public static boolean isVerboseEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE);
+ }
+
+ public static boolean isDebugEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
+ }
+
+ private static boolean is12Key(char ch) {
+ return PhoneNumberUtils.is12Key(ch);
+ }
+
+ private static void println(
+ int level,
+ @NonNull String tag,
+ @NonNull String localTag,
+ @Nullable String msg,
+ @Nullable Object... args) {
+ // Formatted message is computed lazily if required.
+ String formattedMsg;
+ // Either null is passed as a single argument or more than one argument is passed.
+ boolean hasArgs = args == null || args.length > 0;
+ if ((level >= android.util.Log.INFO) || android.util.Log.isLoggable(tag, level)) {
+ formattedMsg = localTag;
+ if (!TextUtils.isEmpty(msg)) {
+ formattedMsg += SEPARATOR + (hasArgs ? String.format(msg, args) : msg);
+ }
+ android.util.Log.println(level, tag, formattedMsg);
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/MathUtil.java b/java/com/android/dialer/common/MathUtil.java
new file mode 100644
index 000000000..e811a46e2
--- /dev/null
+++ b/java/com/android/dialer/common/MathUtil.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+/** Utility class for common math operations */
+public class MathUtil {
+
+ /**
+ * Interpolates between two integer values based on percentage.
+ *
+ * @param begin Begin value
+ * @param end End value
+ * @param percent Percentage value, between 0 and 1
+ * @return Interpolated result
+ */
+ public static int lerp(int begin, int end, float percent) {
+ return (int) (begin * (1 - percent) + end * percent);
+ }
+
+ /**
+ * Interpolates between two float values based on percentage.
+ *
+ * @param begin Begin value
+ * @param end End value
+ * @param percent Percentage value, between 0 and 1
+ * @return Interpolated result
+ */
+ public static float lerp(float begin, float end, float percent) {
+ return begin * (1 - percent) + end * percent;
+ }
+
+ /**
+ * Clamps a value between two bounds inclusively.
+ *
+ * @param value Value to be clamped
+ * @param min Lower bound
+ * @param max Upper bound
+ * @return Clamped value
+ */
+ public static float clamp(float value, float min, float max) {
+ return Math.max(min, Math.min(value, max));
+ }
+}
diff --git a/java/com/android/dialer/common/NetworkUtil.java b/java/com/android/dialer/common/NetworkUtil.java
new file mode 100644
index 000000000..47d84243e
--- /dev/null
+++ b/java/com/android/dialer/common/NetworkUtil.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresPermission;
+import android.support.annotation.StringDef;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/** Utility class for dealing with network */
+public class NetworkUtil {
+
+ /* Returns the current network type. */
+ @RequiresPermission("android.permission.ACCESS_NETWORK_STATE")
+ @NetworkType
+ public static String getCurrentNetworkType(@Nullable Context context) {
+ if (context == null) {
+ return NetworkType.NONE;
+ }
+ ConnectivityManager connectivityManager =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ return getNetworkType(connectivityManager.getActiveNetworkInfo());
+ }
+
+ /* Returns the current network info. */
+ @Nullable
+ @RequiresPermission("android.permission.ACCESS_NETWORK_STATE")
+ public static NetworkInfo getCurrentNetworkInfo(@Nullable Context context) {
+ if (context == null) {
+ return null;
+ }
+ ConnectivityManager connectivityManager =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ return connectivityManager.getActiveNetworkInfo();
+ }
+
+ /**
+ * Returns the current network type as a string. For mobile network types the subtype name of the
+ * network is appended.
+ */
+ @RequiresPermission("android.permission.ACCESS_NETWORK_STATE")
+ public static String getCurrentNetworkTypeName(@Nullable Context context) {
+ if (context == null) {
+ return NetworkType.NONE;
+ }
+ ConnectivityManager connectivityManager =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
+ @NetworkType String networkType = getNetworkType(netInfo);
+ if (isNetworkTypeMobile(networkType)) {
+ return networkType + " (" + netInfo.getSubtypeName() + ")";
+ }
+ return networkType;
+ }
+
+ @NetworkType
+ public static String getNetworkType(@Nullable NetworkInfo netInfo) {
+ if (netInfo == null || !netInfo.isConnected()) {
+ return NetworkType.NONE;
+ }
+ switch (netInfo.getType()) {
+ case ConnectivityManager.TYPE_WIFI:
+ return NetworkType.WIFI;
+ case ConnectivityManager.TYPE_MOBILE:
+ return getMobileNetworkType(netInfo.getSubtype());
+ default:
+ return NetworkType.UNKNOWN;
+ }
+ }
+
+ public static boolean isNetworkTypeMobile(@NetworkType String networkType) {
+ return Objects.equals(networkType, NetworkType.MOBILE_2G)
+ || Objects.equals(networkType, NetworkType.MOBILE_3G)
+ || Objects.equals(networkType, NetworkType.MOBILE_4G);
+ }
+
+ @RequiresPermission("android.permission.ACCESS_NETWORK_STATE")
+ public static String getCurrentNetworkName(Context context) {
+ @NetworkType String networkType = getCurrentNetworkType(context);
+ switch (networkType) {
+ case NetworkType.WIFI:
+ return getWifiNetworkName(context);
+ case NetworkType.MOBILE_2G:
+ case NetworkType.MOBILE_3G:
+ case NetworkType.MOBILE_4G:
+ case NetworkType.MOBILE_UNKNOWN:
+ return getMobileNetworkName(context);
+ default:
+ return "";
+ }
+ }
+
+ private static String getWifiNetworkName(Context context) {
+ WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ String name = null;
+ if (context.checkSelfPermission("android.permission.ACCESS_WIFI_STATE")
+ == PackageManager.PERMISSION_GRANTED) {
+ //noinspection MissingPermission
+ WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
+ if (wifiInfo == null) {
+ return "";
+ }
+ name = wifiInfo.getSSID();
+ }
+ return TextUtils.isEmpty(name)
+ ? context.getString(R.string.network_name_wifi)
+ : name.replaceAll("\"", "");
+ }
+
+ private static String getMobileNetworkName(Context context) {
+ TelephonyManager telephonyMgr =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ String name = telephonyMgr.getNetworkOperatorName();
+ return TextUtils.isEmpty(name)
+ ? context.getString(R.string.network_name_mobile)
+ : name.replaceAll("\"", "");
+ }
+
+ @NetworkType
+ private static String getMobileNetworkType(int networkSubtype) {
+ switch (networkSubtype) {
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ case TelephonyManager.NETWORK_TYPE_GPRS:
+ case TelephonyManager.NETWORK_TYPE_IDEN:
+ return NetworkType.MOBILE_2G;
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ return NetworkType.MOBILE_3G;
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ return NetworkType.MOBILE_4G;
+ default:
+ return NetworkType.MOBILE_UNKNOWN;
+ }
+ }
+
+ /** Network types. */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef(
+ value = {
+ NetworkType.NONE,
+ NetworkType.WIFI,
+ NetworkType.MOBILE_2G,
+ NetworkType.MOBILE_3G,
+ NetworkType.MOBILE_4G,
+ NetworkType.MOBILE_UNKNOWN,
+ NetworkType.UNKNOWN
+ }
+ )
+ public @interface NetworkType {
+
+ String NONE = "NONE";
+ String WIFI = "WIFI";
+ String MOBILE_2G = "MOBILE_2G";
+ String MOBILE_3G = "MOBILE_3G";
+ String MOBILE_4G = "MOBILE_4G";
+ String MOBILE_UNKNOWN = "MOBILE_UNKNOWN";
+ String UNKNOWN = "UNKNOWN";
+ }
+}
diff --git a/java/com/android/dialer/common/PackageUtils.java b/java/com/android/dialer/common/PackageUtils.java
new file mode 100644
index 000000000..ccef38f04
--- /dev/null
+++ b/java/com/android/dialer/common/PackageUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.support.annotation.NonNull;
+
+/** Utility class for package management. */
+public class PackageUtils {
+
+ private static boolean isPackageInstalled(@NonNull String packageName, @NonNull Context context) {
+ Assert.isNotNull(packageName);
+ Assert.isNotNull(context);
+ try {
+ PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
+ if (info != null && info.packageName != null) {
+ LogUtil.d("PackageUtils.isPackageInstalled", packageName + " is found");
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ LogUtil.d("PackageUtils.isPackageInstalled", packageName + " is NOT found");
+ }
+ return false;
+ }
+
+ /** Returns true if the pkg is installed and enabled/default */
+ public static boolean isPackageEnabled(@NonNull String packageName, @NonNull Context context) {
+ Assert.isNotNull(packageName);
+ Assert.isNotNull(context);
+ if (isPackageInstalled(packageName, context)) {
+ if (context.getPackageManager().getApplicationEnabledSetting(packageName)
+ != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/java/com/android/dialer/common/PerAccountSharedPreferences.java b/java/com/android/dialer/common/PerAccountSharedPreferences.java
new file mode 100644
index 000000000..0ed1b03a5
--- /dev/null
+++ b/java/com/android/dialer/common/PerAccountSharedPreferences.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.annotation.Nullable;
+import android.telecom.PhoneAccountHandle;
+import java.util.Set;
+
+/**
+ * Class that helps us store dialer preferences that are phone account dependent. This is necessary
+ * for cases such as settings that are phone account dependent e.g endless vm. The logic is to
+ * essentially store the shared preference by appending the phone account id to the key.
+ */
+public class PerAccountSharedPreferences {
+ private final String sharedPrefsKeyPrefix;
+ private final SharedPreferences preferences;
+ private final PhoneAccountHandle phoneAccountHandle;
+
+ public PerAccountSharedPreferences(
+ Context context, PhoneAccountHandle handle, SharedPreferences prefs) {
+ preferences = prefs;
+ phoneAccountHandle = handle;
+ sharedPrefsKeyPrefix = "phone_account_dependent_";
+ }
+
+ /**
+ * Not to be used, currently only used by {@VisualVoicemailPreferences} for legacy reasons.
+ */
+ protected PerAccountSharedPreferences(
+ Context context, PhoneAccountHandle handle, SharedPreferences prefs, String prefix) {
+ Assert.checkArgument(prefix.equals("visual_voicemail_"));
+ preferences = prefs;
+ phoneAccountHandle = handle;
+ sharedPrefsKeyPrefix = prefix;
+ }
+
+ public class Editor {
+
+ private final SharedPreferences.Editor editor;
+
+ private Editor() {
+ editor = preferences.edit();
+ }
+
+ public void apply() {
+ editor.apply();
+ }
+
+ public Editor putBoolean(String key, boolean value) {
+ editor.putBoolean(getKey(key), value);
+ return this;
+ }
+
+ public Editor putFloat(String key, float value) {
+ editor.putFloat(getKey(key), value);
+ return this;
+ }
+
+ public Editor putInt(String key, int value) {
+ editor.putInt(getKey(key), value);
+ return this;
+ }
+
+ public Editor putLong(String key, long value) {
+ editor.putLong(getKey(key), value);
+ return this;
+ }
+
+ public Editor putString(String key, String value) {
+ editor.putString(getKey(key), value);
+ return this;
+ }
+
+ public Editor putStringSet(String key, Set<String> value) {
+ editor.putStringSet(getKey(key), value);
+ return this;
+ }
+ }
+
+ public Editor edit() {
+ return new Editor();
+ }
+
+ public boolean getBoolean(String key, boolean defValue) {
+ return getValue(key, defValue);
+ }
+
+ public float getFloat(String key, float defValue) {
+ return getValue(key, defValue);
+ }
+
+ public int getInt(String key, int defValue) {
+ return getValue(key, defValue);
+ }
+
+ public long getLong(String key, long defValue) {
+ return getValue(key, defValue);
+ }
+
+ public String getString(String key, String defValue) {
+ return getValue(key, defValue);
+ }
+
+ @Nullable
+ public String getString(String key) {
+ return getValue(key, null);
+ }
+
+ public Set<String> getStringSet(String key, Set<String> defValue) {
+ return getValue(key, defValue);
+ }
+
+ public boolean contains(String key) {
+ return preferences.contains(getKey(key));
+ }
+
+ private <T> T getValue(String key, T defValue) {
+ if (!contains(key)) {
+ return defValue;
+ }
+ Object object = preferences.getAll().get(getKey(key));
+ if (object == null) {
+ return defValue;
+ }
+ return (T) object;
+ }
+
+ private String getKey(String key) {
+ return sharedPrefsKeyPrefix + key + "_" + phoneAccountHandle.getId();
+ }
+}
diff --git a/java/com/android/dialer/common/UiUtil.java b/java/com/android/dialer/common/UiUtil.java
new file mode 100644
index 000000000..4c4ebea11
--- /dev/null
+++ b/java/com/android/dialer/common/UiUtil.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 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 com.android.dialer.common;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+
+/** Utility class for commons functions used with Android UI. */
+public class UiUtil {
+
+ /** Hides the android keyboard. */
+ public static void hideKeyboardFrom(Context context, View view) {
+ InputMethodManager imm =
+ (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+ }
+
+ /** Opens the android keyboard. */
+ public static void openKeyboardFrom(Context context, View view) {
+ InputMethodManager inputMethodManager =
+ (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ inputMethodManager.toggleSoftInputFromWindow(
+ view.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
+ }
+}
diff --git a/java/com/android/dialer/common/concurrent/AsyncTaskExecutor.java b/java/com/android/dialer/common/concurrent/AsyncTaskExecutor.java
new file mode 100644
index 000000000..3bdcd035b
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/AsyncTaskExecutor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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 com.android.dialer.common.concurrent;
+
+import android.os.AsyncTask;
+import android.support.annotation.MainThread;
+import java.util.concurrent.Executor;
+
+/**
+ * Interface used to submit {@link AsyncTask} objects to run in the background.
+ *
+ * <p>This interface has a direct parallel with the {@link Executor} interface. It exists to
+ * decouple the mechanics of AsyncTask submission from the description of how that AsyncTask will
+ * execute.
+ *
+ * <p>One immediate benefit of this approach is that testing becomes much easier, since it is easy
+ * to introduce a mock or fake AsyncTaskExecutor in unit/integration tests, and thus inspect which
+ * tasks have been submitted and control their execution in an orderly manner.
+ *
+ * <p>Another benefit in due course will be the management of the submitted tasks. An extension to
+ * this interface is planned to allow Activities to easily cancel all the submitted tasks that are
+ * still pending in the onDestroy() method of the Activity.
+ */
+public interface AsyncTaskExecutor {
+
+ /**
+ * Executes the given AsyncTask with the default Executor.
+ *
+ * <p>This method <b>must only be called from the ui thread</b>.
+ *
+ * <p>The identifier supplied is any Object that can be used to identify the task later. Most
+ * commonly this will be an enum which the tests can also refer to. {@code null} is also accepted,
+ * though of course this won't help in identifying the task later.
+ */
+ @MainThread
+ <T> AsyncTask<T, ?, ?> submit(Object identifier, AsyncTask<T, ?, ?> task, T... params);
+}
diff --git a/java/com/android/dialer/common/concurrent/AsyncTaskExecutors.java b/java/com/android/dialer/common/concurrent/AsyncTaskExecutors.java
new file mode 100644
index 000000000..a25e9fbf5
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/AsyncTaskExecutors.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 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 com.android.dialer.common.concurrent;
+
+import android.os.AsyncTask;
+import android.support.annotation.MainThread;
+import com.android.dialer.common.Assert;
+import java.util.concurrent.Executor;
+
+/**
+ * Factory methods for creating AsyncTaskExecutors.
+ *
+ * <p>All of the factory methods on this class check first to see if you have set a static {@link
+ * AsyncTaskExecutorFactory} set through the {@link #setFactoryForTest(AsyncTaskExecutorFactory)}
+ * method, and if so delegate to that instead, which is one way of injecting dependencies for
+ * testing classes whose construction cannot be controlled such as {@link android.app.Activity}.
+ */
+public final class AsyncTaskExecutors {
+
+ /**
+ * A single instance of the {@link AsyncTaskExecutorFactory}, to which we delegate if it is
+ * non-null, for injecting when testing.
+ */
+ private static AsyncTaskExecutorFactory mInjectedAsyncTaskExecutorFactory = null;
+
+ /**
+ * Creates an AsyncTaskExecutor that submits tasks to run with {@link AsyncTask#SERIAL_EXECUTOR}.
+ */
+ public static AsyncTaskExecutor createAsyncTaskExecutor() {
+ synchronized (AsyncTaskExecutors.class) {
+ if (mInjectedAsyncTaskExecutorFactory != null) {
+ return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
+ }
+ return new SimpleAsyncTaskExecutor(AsyncTask.SERIAL_EXECUTOR);
+ }
+ }
+
+ /**
+ * Creates an AsyncTaskExecutor that submits tasks to run with {@link
+ * AsyncTask#THREAD_POOL_EXECUTOR}.
+ */
+ public static AsyncTaskExecutor createThreadPoolExecutor() {
+ synchronized (AsyncTaskExecutors.class) {
+ if (mInjectedAsyncTaskExecutorFactory != null) {
+ return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
+ }
+ return new SimpleAsyncTaskExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+
+ public static void setFactoryForTest(AsyncTaskExecutorFactory factory) {
+ synchronized (AsyncTaskExecutors.class) {
+ mInjectedAsyncTaskExecutorFactory = factory;
+ }
+ }
+
+ /** Interface for creating AsyncTaskExecutor objects. */
+ public interface AsyncTaskExecutorFactory {
+
+ AsyncTaskExecutor createAsyncTaskExeuctor();
+ }
+
+ static class SimpleAsyncTaskExecutor implements AsyncTaskExecutor {
+
+ private final Executor mExecutor;
+
+ public SimpleAsyncTaskExecutor(Executor executor) {
+ mExecutor = executor;
+ }
+
+ @Override
+ @MainThread
+ public <T> AsyncTask<T, ?, ?> submit(Object identifer, AsyncTask<T, ?, ?> task, T... params) {
+ Assert.isMainThread();
+ return task.executeOnExecutor(mExecutor, params);
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java b/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java
new file mode 100644
index 000000000..4b6d81afd
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/DefaultDialerExecutorFactory.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.app.FragmentManager;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutor.Builder;
+import com.android.dialer.common.concurrent.DialerExecutor.FailureListener;
+import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
+import com.android.dialer.common.concurrent.DialerExecutor.Worker;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import javax.inject.Inject;
+
+/** The production {@link DialerExecutorFactory}. */
+public class DefaultDialerExecutorFactory implements DialerExecutorFactory {
+
+ @Inject
+ public DefaultDialerExecutorFactory() {}
+
+ @Override
+ @NonNull
+ public <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createUiTaskBuilder(
+ @NonNull FragmentManager fragmentManager,
+ @NonNull String taskId,
+ @NonNull Worker<InputT, OutputT> worker) {
+ return new UiTaskBuilder<>(
+ Assert.isNotNull(fragmentManager), Assert.isNotNull(taskId), Assert.isNotNull(worker));
+ }
+
+ @Override
+ @NonNull
+ public <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createNonUiTaskBuilder(
+ @NonNull Worker<InputT, OutputT> worker) {
+ return new NonUiTaskBuilder<>(Assert.isNotNull(worker));
+ }
+
+ private abstract static class BaseTaskBuilder<InputT, OutputT>
+ implements DialerExecutor.Builder<InputT, OutputT> {
+
+ private final Worker<InputT, OutputT> worker;
+ private SuccessListener<OutputT> successListener = output -> {};
+ private FailureListener failureListener =
+ throwable -> {
+ throw new RuntimeException(throwable);
+ };
+ @Nullable final ExecutorService serialExecutorService;
+ @Nullable final ExecutorService parallelExecutorService;
+
+ BaseTaskBuilder(
+ Worker<InputT, OutputT> worker,
+ @Nullable ExecutorService serialExecutorService,
+ @Nullable ExecutorService parallelExecutorService) {
+ this.worker = worker;
+ this.serialExecutorService = serialExecutorService;
+ this.parallelExecutorService = parallelExecutorService;
+ }
+
+ @NonNull
+ @Override
+ public Builder<InputT, OutputT> onSuccess(@NonNull SuccessListener<OutputT> successListener) {
+ this.successListener = Assert.isNotNull(successListener);
+ return this;
+ }
+
+ @NonNull
+ @Override
+ public Builder<InputT, OutputT> onFailure(@NonNull FailureListener failureListener) {
+ this.failureListener = Assert.isNotNull(failureListener);
+ return this;
+ }
+ }
+
+ /** Convenience class for use by {@link DialerExecutorFactory} implementations. */
+ public static class UiTaskBuilder<InputT, OutputT> extends BaseTaskBuilder<InputT, OutputT> {
+
+ private final FragmentManager fragmentManager;
+ private final String id;
+
+ private DialerUiTaskFragment<InputT, OutputT> dialerUiTaskFragment;
+
+ UiTaskBuilder(FragmentManager fragmentManager, String id, Worker<InputT, OutputT> worker) {
+ this(
+ fragmentManager,
+ id,
+ worker,
+ null /* serialExecutorService */,
+ null /* parallelExecutorService */);
+ }
+
+ public UiTaskBuilder(
+ FragmentManager fragmentManager,
+ String id,
+ Worker<InputT, OutputT> worker,
+ ExecutorService serialExecutor,
+ ExecutorService parallelExecutor) {
+ super(worker, serialExecutor, parallelExecutor);
+ this.fragmentManager = fragmentManager;
+ this.id = id;
+ }
+
+ @NonNull
+ @Override
+ public DialerExecutor<InputT> build() {
+ dialerUiTaskFragment =
+ DialerUiTaskFragment.create(
+ fragmentManager,
+ id,
+ super.worker,
+ super.successListener,
+ super.failureListener,
+ serialExecutorService,
+ parallelExecutorService);
+ return new UiDialerExecutor<>(dialerUiTaskFragment);
+ }
+ }
+
+ /** Convenience class for use by {@link DialerExecutorFactory} implementations. */
+ public static class NonUiTaskBuilder<InputT, OutputT> extends BaseTaskBuilder<InputT, OutputT> {
+ private static final ExecutorService defaultSerialExecutorService =
+ Executors.newSingleThreadExecutor(
+ new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable runnable) {
+ LogUtil.i("NonUiTaskBuilder.newThread", "creating serial thread");
+ Thread thread = new Thread(runnable, "NonUiTaskBuilder");
+ thread.setPriority(4); // Corresponds to Process.THREAD_PRIORITY_BACKGROUND
+ return thread;
+ }
+ });
+
+ private static final ExecutorService defaultParallelExecutorService =
+ Executors.newFixedThreadPool(
+ 5,
+ new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable runnable) {
+ LogUtil.i("NonUiTaskBuilder.newThread", "creating parallel thread");
+ Thread thread = new Thread(runnable, "NonUiTaskBuilder");
+ thread.setPriority(4); // Corresponds to Process.THREAD_PRIORITY_BACKGROUND
+ return thread;
+ }
+ });
+
+ NonUiTaskBuilder(Worker<InputT, OutputT> worker) {
+ this(worker, defaultSerialExecutorService, defaultParallelExecutorService);
+ }
+
+ public NonUiTaskBuilder(
+ Worker<InputT, OutputT> worker,
+ @NonNull ExecutorService serialExecutor,
+ @NonNull ExecutorService parallelExecutor) {
+ super(worker, Assert.isNotNull(serialExecutor), Assert.isNotNull(parallelExecutor));
+ }
+
+ @NonNull
+ @Override
+ public DialerExecutor<InputT> build() {
+ return new NonUiDialerExecutor<>(
+ super.worker,
+ super.successListener,
+ super.failureListener,
+ serialExecutorService,
+ parallelExecutorService);
+ }
+ }
+
+ private static class UiDialerExecutor<InputT, OutputT> implements DialerExecutor<InputT> {
+
+ private final DialerUiTaskFragment<InputT, OutputT> dialerUiTaskFragment;
+
+ UiDialerExecutor(DialerUiTaskFragment<InputT, OutputT> dialerUiTaskFragment) {
+ this.dialerUiTaskFragment = dialerUiTaskFragment;
+ }
+
+ @Override
+ public void executeSerial(@Nullable InputT input) {
+ dialerUiTaskFragment.executeSerial(input);
+ }
+
+ @Override
+ public void executeParallel(@Nullable InputT input) {
+ dialerUiTaskFragment.executeParallel(input);
+ }
+
+ @Override
+ public void executeOnCustomExecutorService(
+ @NonNull ExecutorService executorService, @Nullable InputT input) {
+ dialerUiTaskFragment.executeOnCustomExecutor(Assert.isNotNull(executorService), input);
+ }
+ }
+
+ private static class NonUiDialerExecutor<InputT, OutputT> implements DialerExecutor<InputT> {
+
+ private final Worker<InputT, OutputT> worker;
+ private final SuccessListener<OutputT> successListener;
+ private final FailureListener failureListener;
+
+ private final ExecutorService serialExecutorService;
+ private final ExecutorService parallelExecutorService;
+
+ NonUiDialerExecutor(
+ Worker<InputT, OutputT> worker,
+ SuccessListener<OutputT> successListener,
+ FailureListener failureListener,
+ ExecutorService serialExecutorService,
+ ExecutorService parallelExecutorService) {
+ this.worker = worker;
+ this.successListener = successListener;
+ this.failureListener = failureListener;
+ this.serialExecutorService = serialExecutorService;
+ this.parallelExecutorService = parallelExecutorService;
+ }
+
+ @Override
+ public void executeSerial(@Nullable InputT input) {
+ executeOnCustomExecutorService(serialExecutorService, input);
+ }
+
+ @Override
+ public void executeParallel(@Nullable InputT input) {
+ executeOnCustomExecutorService(parallelExecutorService, input);
+ }
+
+ @Override
+ public void executeOnCustomExecutorService(
+ @NonNull ExecutorService executorService, @Nullable InputT input) {
+ Assert.isNotNull(executorService)
+ .execute(
+ () -> {
+ OutputT output;
+ try {
+ output = worker.doInBackground(input);
+ } catch (Throwable throwable) {
+ ThreadUtil.postOnUiThread(() -> failureListener.onFailure(throwable));
+ return;
+ }
+ ThreadUtil.postOnUiThread(() -> successListener.onSuccess(output));
+ });
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/concurrent/DialerExecutor.java b/java/com/android/dialer/common/concurrent/DialerExecutor.java
new file mode 100644
index 000000000..0237e3a05
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/DialerExecutor.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.WorkerThread;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Provides a consistent interface for doing background work in either UI or non-UI contexts.
+ *
+ * <p>See {@link DialerExecutors} for usage examples.
+ */
+public interface DialerExecutor<InputT> {
+
+ /** Functional interface for doing work in the background. */
+ interface Worker<InputT, OutputT> {
+ @WorkerThread
+ @Nullable
+ OutputT doInBackground(@Nullable InputT input) throws Throwable;
+ }
+
+ /** Functional interface for handling the result of background work. */
+ interface SuccessListener<OutputT> {
+ @MainThread
+ void onSuccess(@Nullable OutputT output);
+ }
+
+ /** Functional interface for handling an error produced while performing background work. */
+ interface FailureListener {
+ @MainThread
+ void onFailure(@NonNull Throwable throwable);
+ }
+
+ /** Builder for {@link DialerExecutor}. */
+ interface Builder<InputT, OutputT> {
+
+ /**
+ * Optional. Default is no-op.
+ *
+ * @param successListener a function executed on the main thread upon task success. There are no
+ * restraints on this as it is executed on the main thread, so lambdas, anonymous, or inner
+ * classes of your activity or fragment are all fine.
+ */
+ @NonNull
+ Builder<InputT, OutputT> onSuccess(@NonNull SuccessListener<OutputT> successListener);
+
+ /**
+ * Optional. If this is not set and your worker throws an exception, the application will crash.
+ *
+ * @param failureListener a function executed on the main thread upon task failure. There are no
+ * restraints on this as it is executed on the main thread, so lambdas, anonymous, or inner
+ * classes of your activity or fragment are all fine.
+ */
+ @NonNull
+ Builder<InputT, OutputT> onFailure(@NonNull FailureListener failureListener);
+
+ /**
+ * Builds the {@link DialerExecutor} which can be used to execute your task (repeatedly with
+ * differing inputs if desired).
+ */
+ @NonNull
+ DialerExecutor<InputT> build();
+ }
+
+ /** Executes the task such that repeated executions for this executor are serialized. */
+ @MainThread
+ void executeSerial(@Nullable InputT input);
+
+ /**
+ * Executes the task on a thread pool shared across the application. Multiple calls using this
+ * method may result in tasks being executed in parallel.
+ */
+ @MainThread
+ void executeParallel(@Nullable InputT input);
+
+ /**
+ * Executes the task on a custom executor service. This should rarely be used; instead prefer
+ * {@link #executeSerial(Object)} or {@link #executeParallel(Object)}.
+ */
+ @MainThread
+ void executeOnCustomExecutorService(
+ @NonNull ExecutorService executorService, @Nullable InputT input);
+}
diff --git a/java/com/android/dialer/common/concurrent/DialerExecutorFactory.java b/java/com/android/dialer/common/concurrent/DialerExecutorFactory.java
new file mode 100644
index 000000000..82f8c7c3d
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/DialerExecutorFactory.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.app.FragmentManager;
+import android.support.annotation.NonNull;
+import com.android.dialer.common.concurrent.DialerExecutor.Worker;
+
+/**
+ * Factory interface for creating {@link DialerExecutor} objects.
+ *
+ * <p>Factory instances may be used instead of the static methods in {@link DialerExecutors} in
+ * order to improve testability.
+ *
+ * @see DialerExecutors
+ */
+public interface DialerExecutorFactory {
+
+ /**
+ * Must be called from onCreate of your activity or fragment.
+ *
+ * @param taskId used for the headless fragment ID and task ID
+ * @param worker a function executed on a worker thread which accepts an {@link InputT} and
+ * returns an {@link OutputT}. It should ideally not be an inner class of your (meaning it
+ * should not be a lambda, anonymous, or non-static) but it can be a static nested class. The
+ * static nested class should not contain any reference to UI, including any activity or
+ * fragment or activity context, though it may reference some threadsafe system objects such
+ * as the application context.
+ */
+ @NonNull
+ <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createUiTaskBuilder(
+ @NonNull FragmentManager fragmentManager,
+ @NonNull String taskId,
+ @NonNull Worker<InputT, OutputT> worker);
+
+ /**
+ * Create a task from a non-UI context.
+ *
+ * @param worker a function executed on a worker thread which accepts an {@link InputT} and
+ * returns an {@link OutputT}. It should ideally not be an inner class of your (meaning it
+ * should not be a lambda, anonymous, or non-static) but it can be a static nested class. The
+ * static nested class should not contain any reference to UI, including any activity or
+ * fragment or activity context, though it may reference some threadsafe system objects such
+ * as the application context.
+ */
+ @NonNull
+ <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createNonUiTaskBuilder(
+ @NonNull Worker<InputT, OutputT> worker);
+}
diff --git a/java/com/android/dialer/common/concurrent/DialerExecutors.java b/java/com/android/dialer/common/concurrent/DialerExecutors.java
new file mode 100644
index 000000000..148d8660c
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/DialerExecutors.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.app.FragmentManager;
+import android.support.annotation.NonNull;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.concurrent.DialerExecutor.Worker;
+
+/**
+ * Factory methods for creating {@link DialerExecutor} objects for doing background work.
+ *
+ * <p>You may create an executor from a UI component (activity or fragment) or a non-UI component.
+ * Using this class provides a number of benefits:
+ *
+ * <ul>
+ * <li>Ensures that UI tasks keep running across configuration changes by using a headless
+ * fragment.
+ * <li>Forces exceptions to crash the application, unless the user implements their own onFailure
+ * method.
+ * <li>Checks for dead UI components which can be encountered if a UI task runs longer than its
+ * UI. If a dead UI component is encountered, onSuccess/onFailure are not called (because they
+ * can't be) but a message is logged.
+ * <li>Helps prevents memory leaks in UI tasks by ensuring that callbacks are nulled out when the
+ * headless fragment is detached.
+ * <li>UI and non-UI threads are shared across the application and run at reasonable priorities
+ * </ul>
+ *
+ * <p>Executors accept a single input and output parameter which should be immutable data objects.
+ * If you don't require an input or output, use Void and null as needed.
+ *
+ * <p>You may optionally specify onSuccess and onFailure listeners; the default behavior on success
+ * is a no-op and the default behavior on failure is to crash the application.
+ *
+ * <p>To use an executor from a UI component, you must create it in your onCreate method and then
+ * use it from anywhere:
+ *
+ * <pre><code>
+ *
+ * public class MyActivity extends Activity {
+ *
+ * private final DialerExecutor&lt;MyInputType&gt; myExecutor;
+ *
+ * public void onCreate(Bundle state) {
+ * super.onCreate(bundle);
+ *
+ * // Must be called in onCreate; don't use non-static or anonymous inner classes for worker!
+ * myExecutor = DialerExecutors.createUiTaskBuilder(fragmentManager, taskId, worker)
+ * .onSuccess(this::onSuccess) // Lambdas, anonymous, or non-static inner classes all fine
+ * .onFailure(this::onFailure) // Lambdas, anonymous, or non-static inner classes all fine
+ * .build();
+ * );
+ * }
+ *
+ * private static class MyWorker implements Worker&lt;MyInputType, MyOutputType&gt; {
+ * MyOutputType doInBackground(MyInputType input) { ... }
+ * }
+ * private void onSuccess(MyOutputType output) { ... }
+ * private void onFailure(Throwable throwable) { ... }
+ *
+ * private void userDidSomething() { myExecutor.executeParallel(input); }
+ * }
+ * </code></pre>
+ *
+ * <p>Usage for non-UI tasks is the same, except that tasks can be created from anywhere instead of
+ * in onCreate. Non-UI tasks use low-priority threads separate from the UI task threads so as not to
+ * compete with more critical UI tasks.
+ *
+ * <pre><code>
+ *
+ * public class MyManager {
+ *
+ * private final DialerExecutor&lt;MyInputType&gt; myExecutor;
+ *
+ * public void init() {
+ * // Don't use non-static or anonymous inner classes for worker!
+ * myExecutor = DialerExecutors.createNonUiTaskBuilder(worker)
+ * .onSuccess(this::onSuccess) // Lambdas, anonymous, or non-static inner classes all fine
+ * .onFailure(this::onFailure) // Lambdas, anonymous, or non-static inner classes all fine
+ * .build();
+ * );
+ * }
+ *
+ * private static class MyWorker implements Worker&lt;MyInputType, MyOutputType&gt; {
+ * MyOutputType doInBackground(MyInputType input) { ... }
+ * }
+ * private void onSuccess(MyOutputType output) { ... }
+ * private void onFailure(Throwable throwable) { ... }
+ *
+ * private void userDidSomething() { myExecutor.executeParallel(input); }
+ * }
+ * </code></pre>
+ *
+ * Note that non-UI tasks are intended to be relatively quick; for example reading/writing shared
+ * preferences or doing simple database work. If you submit long running non-UI tasks you may
+ * saturate the shared application threads and block other tasks. Also, this class does not create
+ * any wakelocks, so a long running task could be killed if the device goes to sleep while your task
+ * is still running. If you have to do long running or periodic work, consider using a job
+ * scheduler.
+ */
+public final class DialerExecutors {
+
+ /** @see DialerExecutorFactory#createUiTaskBuilder(FragmentManager, String, Worker) */
+ @NonNull
+ public static <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createUiTaskBuilder(
+ @NonNull FragmentManager fragmentManager,
+ @NonNull String taskId,
+ @NonNull Worker<InputT, OutputT> worker) {
+ return new DefaultDialerExecutorFactory()
+ .createUiTaskBuilder(
+ Assert.isNotNull(fragmentManager), Assert.isNotNull(taskId), Assert.isNotNull(worker));
+ }
+
+ /** @see DialerExecutorFactory#createNonUiTaskBuilder(Worker) */
+ @NonNull
+ public static <InputT, OutputT> DialerExecutor.Builder<InputT, OutputT> createNonUiTaskBuilder(
+ @NonNull Worker<InputT, OutputT> worker) {
+ return new DefaultDialerExecutorFactory().createNonUiTaskBuilder(Assert.isNotNull(worker));
+ }
+}
diff --git a/java/com/android/dialer/common/concurrent/DialerUiTaskFragment.java b/java/com/android/dialer/common/concurrent/DialerUiTaskFragment.java
new file mode 100644
index 000000000..627336895
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/DialerUiTaskFragment.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.annotation.MainThread;
+import android.support.annotation.Nullable;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.AsyncTaskExecutors.SimpleAsyncTaskExecutor;
+import com.android.dialer.common.concurrent.DialerExecutor.FailureListener;
+import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
+import com.android.dialer.common.concurrent.DialerExecutor.Worker;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Do not use this class directly. Instead use {@link DialerExecutors}.
+ *
+ * @param <InputT> the type of the object sent to the task upon execution
+ * @param <OutputT> the type of the result of the background computation
+ */
+public final class DialerUiTaskFragment<InputT, OutputT> extends Fragment {
+
+ private String taskId;
+ private Worker<InputT, OutputT> worker;
+ private SuccessListener<OutputT> successListener;
+ private FailureListener failureListener;
+
+ private AsyncTaskExecutor serialExecutor = AsyncTaskExecutors.createAsyncTaskExecutor();
+ private AsyncTaskExecutor parallelExecutor = AsyncTaskExecutors.createThreadPoolExecutor();
+
+ /**
+ * Creates a new {@link DialerUiTaskFragment} or gets an existing one in the event that a
+ * configuration change occurred while the previous activity's task was still running. Must be
+ * called from onCreate of your activity or fragment.
+ *
+ * @param taskId used for the headless fragment ID and task ID
+ * @param worker a function executed on a worker thread which accepts an {@link InputT} and
+ * returns an {@link OutputT}. It should ideally not be an inner class of your
+ * activity/fragment (meaning it should not be a lambda, anonymous, or non-static) but it can
+ * be a static nested class. The static nested class should not contain any reference to UI,
+ * including any activity or fragment or activity context, though it may reference some
+ * threadsafe system objects such as the application context.
+ * @param successListener a function executed on the main thread upon task success. There are no
+ * restraints on this as it is executed on the main thread, so lambdas, anonymous, or inner
+ * classes of your activity or fragment are all fine.
+ * @param failureListener a function executed on the main thread upon task failure. The exception
+ * is already logged so this can often be a no-op. There are no restraints on this as it is
+ * executed on the main thread, so lambdas, anonymous, or inner classes of your activity or
+ * fragment are all fine.
+ * @param <InputT> the type of the object sent to the task upon execution
+ * @param <OutputT> the type of the result of the background computation
+ * @return a {@link DialerUiTaskFragment} which may be used to call the "execute*" methods
+ */
+ @MainThread
+ static <InputT, OutputT> DialerUiTaskFragment<InputT, OutputT> create(
+ FragmentManager fragmentManager,
+ String taskId,
+ Worker<InputT, OutputT> worker,
+ SuccessListener<OutputT> successListener,
+ FailureListener failureListener,
+ @Nullable ExecutorService serialExecutorService,
+ @Nullable ExecutorService parallelExecutorService) {
+ Assert.isMainThread();
+
+ DialerUiTaskFragment<InputT, OutputT> fragment =
+ (DialerUiTaskFragment<InputT, OutputT>) fragmentManager.findFragmentByTag(taskId);
+
+ if (fragment == null) {
+ LogUtil.i("DialerUiTaskFragment.create", "creating new DialerUiTaskFragment");
+ fragment = new DialerUiTaskFragment<>();
+ fragmentManager.beginTransaction().add(fragment, taskId).commit();
+ }
+ fragment.taskId = taskId;
+ fragment.worker = worker;
+ fragment.successListener = successListener;
+ fragment.failureListener = failureListener;
+ if (serialExecutorService != null) {
+ fragment.serialExecutor = new SimpleAsyncTaskExecutor(serialExecutorService);
+ }
+ if (parallelExecutorService != null) {
+ fragment.parallelExecutor = new SimpleAsyncTaskExecutor(parallelExecutorService);
+ }
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ LogUtil.enterBlock("DialerUiTaskFragment.onDetach");
+ taskId = null;
+ successListener = null;
+ failureListener = null;
+ }
+
+ void executeSerial(InputT input) {
+ serialExecutor.submit(taskId, new InternalTask(), input);
+ }
+
+ void executeParallel(InputT input) {
+ parallelExecutor.submit(taskId, new InternalTask(), input);
+ }
+
+ void executeOnCustomExecutor(ExecutorService executor, InputT input) {
+ new SimpleAsyncTaskExecutor(executor).submit(taskId, new InternalTask(), input);
+ }
+
+ private final class InternalTask extends AsyncTask<InputT, Void, InternalTaskResult<OutputT>> {
+
+ @SafeVarargs
+ @Override
+ protected final InternalTaskResult<OutputT> doInBackground(InputT... params) {
+ try {
+ return new InternalTaskResult<>(null, worker.doInBackground(params[0]));
+ } catch (Throwable throwable) {
+ LogUtil.e("InternalTask.doInBackground", "task failed", throwable);
+ return new InternalTaskResult<>(throwable, null);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(InternalTaskResult<OutputT> result) {
+ if (result.throwable != null) {
+ if (failureListener == null) {
+ LogUtil.i("InternalTask.onPostExecute", "task failed but UI is dead");
+ } else {
+ failureListener.onFailure(result.throwable);
+ }
+ } else if (successListener == null) {
+ LogUtil.i("InternalTask.onPostExecute", "task succeeded but UI is dead");
+ } else {
+ successListener.onSuccess(result.result);
+ }
+ }
+ }
+
+ private static class InternalTaskResult<OutputT> {
+
+ private final Throwable throwable;
+ private final OutputT result;
+
+ InternalTaskResult(Throwable throwable, OutputT result) {
+ this.throwable = throwable;
+ this.result = result;
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/concurrent/FallibleAsyncTask.java b/java/com/android/dialer/common/concurrent/FallibleAsyncTask.java
new file mode 100644
index 000000000..6d02fe67f
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/FallibleAsyncTask.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.os.AsyncTask;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import com.android.dialer.common.concurrent.FallibleAsyncTask.FallibleTaskResult;
+import com.google.auto.value.AutoValue;
+
+/**
+ * A task that runs work in the background, passing Throwables from {@link
+ * #doInBackground(Object[])} to {@link #onPostExecute(Object)} through a {@link
+ * FallibleTaskResult}.
+ *
+ * @param <ParamsT> the type of the parameters sent to the task upon execution
+ * @param <ProgressT> the type of the progress units published during the background computation
+ * @param <ResultT> the type of the result of the background computation
+ */
+public abstract class FallibleAsyncTask<ParamsT, ProgressT, ResultT>
+ extends AsyncTask<ParamsT, ProgressT, FallibleTaskResult<ResultT>> {
+
+ @Override
+ protected final FallibleTaskResult<ResultT> doInBackground(ParamsT... params) {
+ try {
+ return FallibleTaskResult.createSuccessResult(doInBackgroundFallible(params));
+ } catch (Throwable t) {
+ return FallibleTaskResult.createFailureResult(t);
+ }
+ }
+
+ /** Performs background work that may result in a Throwable. */
+ @Nullable
+ protected abstract ResultT doInBackgroundFallible(ParamsT... params) throws Throwable;
+
+ /**
+ * Holds the result of processing from {@link #doInBackground(Object[])}.
+ *
+ * @param <ResultT> the type of the result of the background computation
+ */
+ @AutoValue
+ public abstract static class FallibleTaskResult<ResultT> {
+
+ /** Creates an instance of FallibleTaskResult for the given throwable. */
+ private static <ResultT> FallibleTaskResult<ResultT> createFailureResult(@NonNull Throwable t) {
+ return new AutoValue_FallibleAsyncTask_FallibleTaskResult<>(t, null);
+ }
+
+ /** Creates an instance of FallibleTaskResult for the given result. */
+ private static <ResultT> FallibleTaskResult<ResultT> createSuccessResult(
+ @Nullable ResultT result) {
+ return new AutoValue_FallibleAsyncTask_FallibleTaskResult<>(null, result);
+ }
+
+ /**
+ * Returns the Throwable thrown in {@link #doInBackground(Object[])}, or {@code null} if
+ * background work completed without throwing.
+ */
+ @Nullable
+ public abstract Throwable getThrowable();
+
+ /**
+ * Returns the result of {@link #doInBackground(Object[])}, which may be {@code null}, or {@code
+ * null} if the background work threw a Throwable.
+ *
+ * <p>Use {@link #isFailure()} to determine if a {@code null} return is the result of a
+ * Throwable from the background work.
+ */
+ @Nullable
+ public abstract ResultT getResult();
+
+ /**
+ * Returns {@code true} if this object is the result of background work that threw a Throwable.
+ */
+ public boolean isFailure() {
+ //noinspection ThrowableResultOfMethodCallIgnored
+ return getThrowable() != null;
+ }
+ }
+}
diff --git a/java/com/android/dialer/common/concurrent/ThreadUtil.java b/java/com/android/dialer/common/concurrent/ThreadUtil.java
new file mode 100644
index 000000000..21cf4634e
--- /dev/null
+++ b/java/com/android/dialer/common/concurrent/ThreadUtil.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 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 com.android.dialer.common.concurrent;
+
+import android.os.Handler;
+import android.os.Looper;
+
+/** Application-wide utility methods for working with threads. */
+public class ThreadUtil {
+ private static volatile Handler mainThreadHandler;
+
+ /** Posts a runnable to the UI thread. */
+ public static void postOnUiThread(Runnable runnable) {
+ getUiThreadHandler().post(runnable);
+ }
+
+ /** Gets a handler which uses the main looper. */
+ public static Handler getUiThreadHandler() {
+ if (mainThreadHandler == null) {
+ mainThreadHandler = new Handler(Looper.getMainLooper());
+ }
+ return mainThreadHandler;
+ }
+}
diff --git a/java/com/android/dialer/common/proguard.flags b/java/com/android/dialer/common/proguard.flags
new file mode 100644
index 000000000..4b6b84671
--- /dev/null
+++ b/java/com/android/dialer/common/proguard.flags
@@ -0,0 +1,4 @@
+-assumenosideeffects class com.android.dialer.common.LogUtil {
+ public static void v(...);
+ public static void d(...);
+}
diff --git a/java/com/android/dialer/common/res/values-af/strings.xml b/java/com/android/dialer/common/res/values-af/strings.xml
new file mode 100644
index 000000000..10f143177
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-af/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobiel"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-am/strings.xml b/java/com/android/dialer/common/res/values-am/strings.xml
new file mode 100644
index 000000000..4d09ec67d
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-am/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"ዋይፋይ"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"ሞባይል"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ar/strings.xml b/java/com/android/dialer/common/res/values-ar/strings.xml
new file mode 100644
index 000000000..0e837c4b1
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ar/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"الجوال"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-az/strings.xml b/java/com/android/dialer/common/res/values-az/strings.xml
new file mode 100644
index 000000000..59ba93b19
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-az/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/common/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 000000000..52b5f67e6
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilni uređaji"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-be/strings.xml b/java/com/android/dialer/common/res/values-be/strings.xml
new file mode 100644
index 000000000..9bd978f3d
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-be/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мабільны тэлефон"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-bg/strings.xml b/java/com/android/dialer/common/res/values-bg/strings.xml
new file mode 100644
index 000000000..f36aae145
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-bg/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мобилна"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-bn/strings.xml b/java/com/android/dialer/common/res/values-bn/strings.xml
new file mode 100644
index 000000000..ed55edb96
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-bn/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"ওয়াই ফাই"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"মোবাইল"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-bs/strings.xml b/java/com/android/dialer/common/res/values-bs/strings.xml
new file mode 100644
index 000000000..537ccd8ba
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-bs/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilni"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ca/strings.xml b/java/com/android/dialer/common/res/values-ca/strings.xml
new file mode 100644
index 000000000..8d095c76d
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ca/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mòbil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-cs/strings.xml b/java/com/android/dialer/common/res/values-cs/strings.xml
new file mode 100644
index 000000000..c6a50bb6a
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-cs/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilní"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-da/strings.xml b/java/com/android/dialer/common/res/values-da/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-da/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-de/strings.xml b/java/com/android/dialer/common/res/values-de/strings.xml
new file mode 100644
index 000000000..9a54083a1
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-de/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WLAN"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-el/strings.xml b/java/com/android/dialer/common/res/values-el/strings.xml
new file mode 100644
index 000000000..43c28ca41
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-el/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Κινητής τηλεφωνίας"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-en-rAU/strings.xml b/java/com/android/dialer/common/res/values-en-rAU/strings.xml
new file mode 100644
index 000000000..dbc7a0c66
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-en-rAU/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobile"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-en-rGB/strings.xml b/java/com/android/dialer/common/res/values-en-rGB/strings.xml
new file mode 100644
index 000000000..dbc7a0c66
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-en-rGB/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobile"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-en-rIN/strings.xml b/java/com/android/dialer/common/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000..dbc7a0c66
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-en-rIN/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobile"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-es-rUS/strings.xml b/java/com/android/dialer/common/res/values-es-rUS/strings.xml
new file mode 100644
index 000000000..2c219a652
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-es-rUS/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Celular"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-es/strings.xml b/java/com/android/dialer/common/res/values-es/strings.xml
new file mode 100644
index 000000000..2449b3386
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-es/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Móvil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-et/strings.xml b/java/com/android/dialer/common/res/values-et/strings.xml
new file mode 100644
index 000000000..414f78541
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-et/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WiFi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobiil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-eu/strings.xml b/java/com/android/dialer/common/res/values-eu/strings.xml
new file mode 100644
index 000000000..f0f14de5f
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-eu/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mugikorra"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-fa/strings.xml b/java/com/android/dialer/common/res/values-fa/strings.xml
new file mode 100644
index 000000000..04c690785
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-fa/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"دستگاه همراه"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-fi/strings.xml b/java/com/android/dialer/common/res/values-fi/strings.xml
new file mode 100644
index 000000000..1671a9abc
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-fi/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi‑Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobiililaite"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-fr-rCA/strings.xml b/java/com/android/dialer/common/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000..47828be9e
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-fr-rCA/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Appareil mobile"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-fr/strings.xml b/java/com/android/dialer/common/res/values-fr/strings.xml
new file mode 100644
index 000000000..dbc7a0c66
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-fr/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobile"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-gl/strings.xml b/java/com/android/dialer/common/res/values-gl/strings.xml
new file mode 100644
index 000000000..9b5e174f4
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-gl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Móbil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-gu/strings.xml b/java/com/android/dialer/common/res/values-gu/strings.xml
new file mode 100644
index 000000000..0d0f4edbe
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-gu/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"મોબાઇલ"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-hi/strings.xml b/java/com/android/dialer/common/res/values-hi/strings.xml
new file mode 100644
index 000000000..bb064b421
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-hi/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"वाई-फ़ाई"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"मोबाइल"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-hr/strings.xml b/java/com/android/dialer/common/res/values-hr/strings.xml
new file mode 100644
index 000000000..e2e3b7132
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-hr/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilni"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-hu/strings.xml b/java/com/android/dialer/common/res/values-hu/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-hu/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-hy/strings.xml b/java/com/android/dialer/common/res/values-hy/strings.xml
new file mode 100644
index 000000000..1de9c40f3
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-hy/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Բջջային"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-in/strings.xml b/java/com/android/dialer/common/res/values-in/strings.xml
new file mode 100644
index 000000000..f531e13a1
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-in/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Ponsel"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-is/strings.xml b/java/com/android/dialer/common/res/values-is/strings.xml
new file mode 100644
index 000000000..c77dddfa6
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-is/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WiFi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Farsími"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-it/strings.xml b/java/com/android/dialer/common/res/values-it/strings.xml
new file mode 100644
index 000000000..04ac19821
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-it/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Cellulare"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-iw/strings.xml b/java/com/android/dialer/common/res/values-iw/strings.xml
new file mode 100644
index 000000000..2f240bbe9
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-iw/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"נייד"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ja/strings.xml b/java/com/android/dialer/common/res/values-ja/strings.xml
new file mode 100644
index 000000000..938f21dd6
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ja/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"モバイル"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ka/strings.xml b/java/com/android/dialer/common/res/values-ka/strings.xml
new file mode 100644
index 000000000..224fb869e
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ka/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"მობილური"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-kk/strings.xml b/java/com/android/dialer/common/res/values-kk/strings.xml
new file mode 100644
index 000000000..88be76909
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-kk/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Ұялы телефон"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-km/strings.xml b/java/com/android/dialer/common/res/values-km/strings.xml
new file mode 100644
index 000000000..b8fe6c7d3
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-km/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"វ៉ាយហ្វាយ"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"ចល័ត"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-kn/strings.xml b/java/com/android/dialer/common/res/values-kn/strings.xml
new file mode 100644
index 000000000..de4b8de71
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-kn/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"ವೈಫೈ"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"ಮೊಬೈಲ್"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ko/strings.xml b/java/com/android/dialer/common/res/values-ko/strings.xml
new file mode 100644
index 000000000..89b6c07f7
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ko/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"모바일"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ky/strings.xml b/java/com/android/dialer/common/res/values-ky/strings.xml
new file mode 100644
index 000000000..7630f31bf
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ky/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi‑Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мобилдик"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-lo/strings.xml b/java/com/android/dialer/common/res/values-lo/strings.xml
new file mode 100644
index 000000000..9496a6783
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-lo/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"ມືຖື"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-lt/strings.xml b/java/com/android/dialer/common/res/values-lt/strings.xml
new file mode 100644
index 000000000..e3b0355ae
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-lt/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilusis"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-lv/strings.xml b/java/com/android/dialer/common/res/values-lv/strings.xml
new file mode 100644
index 000000000..1cece961b
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-lv/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilais tīkls"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-mk/strings.xml b/java/com/android/dialer/common/res/values-mk/strings.xml
new file mode 100644
index 000000000..928c6d267
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-mk/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мобилен"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ml/strings.xml b/java/com/android/dialer/common/res/values-ml/strings.xml
new file mode 100644
index 000000000..fe40cf57f
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ml/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"മൊബൈല്‍"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-mn/strings.xml b/java/com/android/dialer/common/res/values-mn/strings.xml
new file mode 100644
index 000000000..7f23d3215
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-mn/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WiFi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мобайл"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-mr/strings.xml b/java/com/android/dialer/common/res/values-mr/strings.xml
new file mode 100644
index 000000000..d860dba4e
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-mr/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"वायफाय"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"मोबाईल"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ms/strings.xml b/java/com/android/dialer/common/res/values-ms/strings.xml
new file mode 100644
index 000000000..2ebf4feaf
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ms/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mudah Alih"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-my/strings.xml b/java/com/android/dialer/common/res/values-my/strings.xml
new file mode 100644
index 000000000..314613a93
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-my/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"မိုဘိုင်း"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-nb/strings.xml b/java/com/android/dialer/common/res/values-nb/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-nb/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ne/strings.xml b/java/com/android/dialer/common/res/values-ne/strings.xml
new file mode 100644
index 000000000..287d78d55
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ne/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"मोबाइल"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-nl/strings.xml b/java/com/android/dialer/common/res/values-nl/strings.xml
new file mode 100644
index 000000000..a89409564
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-nl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobiel"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-no/strings.xml b/java/com/android/dialer/common/res/values-no/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-no/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-pa/strings.xml b/java/com/android/dialer/common/res/values-pa/strings.xml
new file mode 100644
index 000000000..2dfa4235e
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-pa/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"ਮੋਬਾਈਲ"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-pl/strings.xml b/java/com/android/dialer/common/res/values-pl/strings.xml
new file mode 100644
index 000000000..6999a90a0
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-pl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Komórka"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-pt-rBR/strings.xml b/java/com/android/dialer/common/res/values-pt-rBR/strings.xml
new file mode 100644
index 000000000..77a4002b3
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-pt-rBR/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Dispositivo móvel"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-pt-rPT/strings.xml b/java/com/android/dialer/common/res/values-pt-rPT/strings.xml
new file mode 100644
index 000000000..4649c4242
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-pt-rPT/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Telemóvel"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-pt/strings.xml b/java/com/android/dialer/common/res/values-pt/strings.xml
new file mode 100644
index 000000000..77a4002b3
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-pt/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Dispositivo móvel"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ro/strings.xml b/java/com/android/dialer/common/res/values-ro/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ro/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ru/strings.xml b/java/com/android/dialer/common/res/values-ru/strings.xml
new file mode 100644
index 000000000..cbc88730b
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ru/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Моб."</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-si/strings.xml b/java/com/android/dialer/common/res/values-si/strings.xml
new file mode 100644
index 000000000..b9babc64f
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-si/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WiFi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"ජංගම"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-sk/strings.xml b/java/com/android/dialer/common/res/values-sk/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-sk/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-sl/strings.xml b/java/com/android/dialer/common/res/values-sl/strings.xml
new file mode 100644
index 000000000..eb4094eaa
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-sl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobilni telefon"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-sq/strings.xml b/java/com/android/dialer/common/res/values-sq/strings.xml
new file mode 100644
index 000000000..9b58fbcb0
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-sq/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Celulari"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-sr/strings.xml b/java/com/android/dialer/common/res/values-sr/strings.xml
new file mode 100644
index 000000000..8b387e6ef
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-sr/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мобилни уређаји"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-sv/strings.xml b/java/com/android/dialer/common/res/values-sv/strings.xml
new file mode 100644
index 000000000..00df25aea
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-sv/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-sw/strings.xml b/java/com/android/dialer/common/res/values-sw/strings.xml
new file mode 100644
index 000000000..df0b97d29
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-sw/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Simu ya mkononi"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ta/strings.xml b/java/com/android/dialer/common/res/values-ta/strings.xml
new file mode 100644
index 000000000..fbce62cfc
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ta/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"வைஃபை"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"மொபைல்"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-te/strings.xml b/java/com/android/dialer/common/res/values-te/strings.xml
new file mode 100644
index 000000000..af1a43cad
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-te/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"మొబైల్"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-th/strings.xml b/java/com/android/dialer/common/res/values-th/strings.xml
new file mode 100644
index 000000000..1ea62f303
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-th/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"อุปกรณ์เคลื่อนที่"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-tl/strings.xml b/java/com/android/dialer/common/res/values-tl/strings.xml
new file mode 100644
index 000000000..d9e8519d0
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-tl/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobile"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-tr/strings.xml b/java/com/android/dialer/common/res/values-tr/strings.xml
new file mode 100644
index 000000000..57c66b548
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-tr/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Kablosuz"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-uk/strings.xml b/java/com/android/dialer/common/res/values-uk/strings.xml
new file mode 100644
index 000000000..0d94f71f3
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-uk/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Мобільний"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-ur/strings.xml b/java/com/android/dialer/common/res/values-ur/strings.xml
new file mode 100644
index 000000000..f21549ef0
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-ur/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wifi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"موبائل"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-uz/strings.xml b/java/com/android/dialer/common/res/values-uz/strings.xml
new file mode 100644
index 000000000..447825a6f
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-uz/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WI-FI"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Mobil"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-vi/strings.xml b/java/com/android/dialer/common/res/values-vi/strings.xml
new file mode 100644
index 000000000..574e92633
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-vi/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Thiết bị di động"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-zh-rCN/strings.xml b/java/com/android/dialer/common/res/values-zh-rCN/strings.xml
new file mode 100644
index 000000000..202aa7f10
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-zh-rCN/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"WLAN"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"移动网络"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-zh-rHK/strings.xml b/java/com/android/dialer/common/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000..454b65e7c
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-zh-rHK/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"流動"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-zh-rTW/strings.xml b/java/com/android/dialer/common/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000..8b5f2b5e3
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-zh-rTW/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"行動網路"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values-zu/strings.xml b/java/com/android/dialer/common/res/values-zu/strings.xml
new file mode 100644
index 000000000..bfa458d05
--- /dev/null
+++ b/java/com/android/dialer/common/res/values-zu/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="network_name_wifi" msgid="3026388992566895417">"I-Wi-Fi"</string>
+ <string name="network_name_mobile" msgid="7655711935020766459">"Iselula"</string>
+</resources>
diff --git a/java/com/android/dialer/common/res/values/config.xml b/java/com/android/dialer/common/res/values/config.xml
new file mode 100644
index 000000000..c4df279ba
--- /dev/null
+++ b/java/com/android/dialer/common/res/values/config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <bool name="spring_hd_codec">false</bool>
+</resources> \ No newline at end of file
diff --git a/java/com/android/dialer/common/res/values/strings.xml b/java/com/android/dialer/common/res/values/strings.xml
new file mode 100644
index 000000000..8e9616178
--- /dev/null
+++ b/java/com/android/dialer/common/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="network_name_wifi">Wifi</string>
+ <string name="network_name_mobile">Mobile</string>
+</resources>