diff options
Diffstat (limited to 'java/com/android/dialer/common')
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<MyInputType> 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<MyInputType, MyOutputType> { + * 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<MyInputType> 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<MyInputType, MyOutputType> { + * 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> |