summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/compat
diff options
context:
space:
mode:
authorEric Erfanian <erfanian@google.com>2017-02-22 16:32:36 -0800
committerEric Erfanian <erfanian@google.com>2017-03-01 09:56:52 -0800
commitccca31529c07970e89419fb85a9e8153a5396838 (patch)
treea7034c0a01672b97728c13282a2672771cd28baa /java/com/android/dialer/compat
parente7ae4624ba6f25cb8e648db74e0d64c0113a16ba (diff)
Update dialer sources.
Test: Built package and system image. This change clobbers the old source, and is an export from an internal Google repository. The internal repository was forked form Android in March, and this change includes modifications since then, to near the v8 release. Since the fork, we've moved code from monolithic to independent modules. In addition, we've switched to Blaze/Bazel as the build sysetm. This export, however, still uses make. New dependencies have been added: - Dagger - Auto-Value - Glide - Libshortcutbadger Going forward, development will still be in Google3, and the Gerrit release will become an automated export, with the next drop happening in ~ two weeks. Android.mk includes local modifications from ToT. Abridged changelog: Bug fixes ● Not able to mute, add a call when using Phone app in multiwindow mode ● Double tap on keypad triggering multiple key and tones ● Reported spam numbers not showing as spam in the call log ● Crash when user tries to block number while Phone app is not set as default ● Crash when user picks a number from search auto-complete list Visual Voicemail (VVM) improvements ● Share Voicemail audio via standard exporting mechanisms that support file attachment (email, MMS, etc.) ● Make phone number, email and web sites in VVM transcript clickable ● Set PIN before declining VVM Terms of Service {Carrier} ● Set client type for outbound visual voicemail SMS {Carrier} New incoming call and incall UI on older devices (Android M) ● Updated Phone app icon ● New incall UI (large buttons, button labels) ● New and animated Answer/Reject gestures Accessibility ● Add custom answer/decline call buttons on answer screen for touch exploration accessibility services ● Increase size of touch target ● Add verbal feedback when a Voicemail fails to load ● Fix pressing of Phone buttons while in a phone call using Switch Access ● Fix selecting and opening contacts in talkback mode ● Split focus for ‘Learn More’ link in caller id & spam to help distinguish similar text Other ● Backup & Restore for App Preferences ● Prompt user to enable Wi-Fi calling if the call ends due to out of service and Wi-Fi is connected ● Rename “Dialpad” to “Keypad” ● Show "Private number" for restricted calls ● Delete unused items (vcard, add contact, call history) from Phone menu Change-Id: I2a7e53532a24c21bf308bf0a6d178d7ddbca4958
Diffstat (limited to 'java/com/android/dialer/compat')
-rw-r--r--java/com/android/dialer/compat/ActivityCompat.java29
-rw-r--r--java/com/android/dialer/compat/AppCompatConstants.java33
-rw-r--r--java/com/android/dialer/compat/CompatUtils.java222
-rw-r--r--java/com/android/dialer/compat/PathInterpolatorCompat.java120
-rw-r--r--java/com/android/dialer/compat/SdkVersionOverride.java43
5 files changed, 447 insertions, 0 deletions
diff --git a/java/com/android/dialer/compat/ActivityCompat.java b/java/com/android/dialer/compat/ActivityCompat.java
new file mode 100644
index 000000000..e59b11593
--- /dev/null
+++ b/java/com/android/dialer/compat/ActivityCompat.java
@@ -0,0 +1,29 @@
+/*
+ * 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.compat;
+
+import android.app.Activity;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+
+/** Utility for calling methods introduced after Marshmallow for Activities. */
+public class ActivityCompat {
+
+ public static boolean isInMultiWindowMode(Activity activity) {
+ return VERSION.SDK_INT >= VERSION_CODES.N && activity.isInMultiWindowMode();
+ }
+}
diff --git a/java/com/android/dialer/compat/AppCompatConstants.java b/java/com/android/dialer/compat/AppCompatConstants.java
new file mode 100644
index 000000000..4a51d3f9e
--- /dev/null
+++ b/java/com/android/dialer/compat/AppCompatConstants.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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.compat;
+
+import android.provider.CallLog.Calls;
+
+public final class AppCompatConstants {
+
+ public static final int CALLS_INCOMING_TYPE = Calls.INCOMING_TYPE;
+ public static final int CALLS_OUTGOING_TYPE = Calls.OUTGOING_TYPE;
+ public static final int CALLS_MISSED_TYPE = Calls.MISSED_TYPE;
+ public static final int CALLS_VOICEMAIL_TYPE = Calls.VOICEMAIL_TYPE;
+ // Added to android.provider.CallLog.Calls in N+.
+ public static final int CALLS_REJECTED_TYPE = 5;
+ // Added to android.provider.CallLog.Calls in N+.
+ public static final int CALLS_BLOCKED_TYPE = 6;
+ // Added to android.provider.CallLog.Calls in N+.
+ public static final int CALLS_ANSWERED_EXTERNALLY_TYPE = Calls.ANSWERED_EXTERNALLY_TYPE;
+}
diff --git a/java/com/android/dialer/compat/CompatUtils.java b/java/com/android/dialer/compat/CompatUtils.java
new file mode 100644
index 000000000..673cb709b
--- /dev/null
+++ b/java/com/android/dialer/compat/CompatUtils.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2015 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.compat;
+
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+import java.lang.reflect.InvocationTargetException;
+
+public final class CompatUtils {
+
+ private static final String TAG = CompatUtils.class.getSimpleName();
+
+ /** PrioritizedMimeType is added in API level 23. */
+ public static boolean hasPrioritizedMimeType() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M;
+ }
+
+ /**
+ * Determines if this version is compatible with multi-SIM and the phone account APIs. Can also
+ * force the version to be lower through SdkVersionOverride.
+ *
+ * @return {@code true} if multi-SIM capability is available, {@code false} otherwise.
+ */
+ public static boolean isMSIMCompatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP)
+ >= Build.VERSION_CODES.LOLLIPOP_MR1;
+ }
+
+ /**
+ * Determines if this version is compatible with video calling. Can also force the version to be
+ * lower through SdkVersionOverride.
+ *
+ * @return {@code true} if video calling is allowed, {@code false} otherwise.
+ */
+ public static boolean isVideoCompatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP) >= Build.VERSION_CODES.M;
+ }
+
+ /**
+ * Determines if this version is capable of using presence checking for video calling. Support for
+ * video call presence indication is added in SDK 24.
+ *
+ * @return {@code true} if video presence checking is allowed, {@code false} otherwise.
+ */
+ public static boolean isVideoPresenceCompatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) > Build.VERSION_CODES.M;
+ }
+
+ /**
+ * Determines if this version is compatible with call subject. Can also force the version to be
+ * lower through SdkVersionOverride.
+ *
+ * @return {@code true} if call subject is a feature on this device, {@code false} otherwise.
+ */
+ public static boolean isCallSubjectCompatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP) >= Build.VERSION_CODES.M;
+ }
+
+ /**
+ * Determines if this version is compatible with a default dialer. Can also force the version to
+ * be lower through {@link SdkVersionOverride}.
+ *
+ * @return {@code true} if default dialer is a feature on this device, {@code false} otherwise.
+ */
+ public static boolean isDefaultDialerCompatible() {
+ return isMarshmallowCompatible();
+ }
+
+ /**
+ * Determines if this version is compatible with Lollipop Mr1-specific APIs. Can also force the
+ * version to be lower through SdkVersionOverride.
+ *
+ * @return {@code true} if runtime sdk is compatible with Lollipop MR1, {@code false} otherwise.
+ */
+ public static boolean isLollipopMr1Compatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP_MR1)
+ >= Build.VERSION_CODES.LOLLIPOP_MR1;
+ }
+
+ /**
+ * Determines if this version is compatible with Marshmallow-specific APIs. Can also force the
+ * version to be lower through SdkVersionOverride.
+ *
+ * @return {@code true} if runtime sdk is compatible with Marshmallow, {@code false} otherwise.
+ */
+ public static boolean isMarshmallowCompatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP) >= Build.VERSION_CODES.M;
+ }
+
+ /**
+ * Determines if the given class is available. Can be used to check if system apis exist at
+ * runtime.
+ *
+ * @param className the name of the class to look for.
+ * @return {@code true} if the given class is available, {@code false} otherwise or if className
+ * is empty.
+ */
+ public static boolean isClassAvailable(@Nullable String className) {
+ if (TextUtils.isEmpty(className)) {
+ return false;
+ }
+ try {
+ Class.forName(className);
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ } catch (Throwable t) {
+ Log.e(
+ TAG,
+ "Unexpected exception when checking if class:" + className + " exists at " + "runtime",
+ t);
+ return false;
+ }
+ }
+
+ /**
+ * Determines if the given class's method is available to call. Can be used to check if system
+ * apis exist at runtime.
+ *
+ * @param className the name of the class to look for
+ * @param methodName the name of the method to look for
+ * @param parameterTypes the needed parameter types for the method to look for
+ * @return {@code true} if the given class is available, {@code false} otherwise or if className
+ * or methodName are empty.
+ */
+ public static boolean isMethodAvailable(
+ @Nullable String className, @Nullable String methodName, Class<?>... parameterTypes) {
+ if (TextUtils.isEmpty(className) || TextUtils.isEmpty(methodName)) {
+ return false;
+ }
+
+ try {
+ Class.forName(className).getMethod(methodName, parameterTypes);
+ return true;
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ Log.v(TAG, "Could not find method: " + className + "#" + methodName);
+ return false;
+ } catch (Throwable t) {
+ Log.e(
+ TAG,
+ "Unexpected exception when checking if method: "
+ + className
+ + "#"
+ + methodName
+ + " exists at runtime",
+ t);
+ return false;
+ }
+ }
+
+ /**
+ * Invokes a given class's method using reflection. Can be used to call system apis that exist at
+ * runtime but not in the SDK.
+ *
+ * @param instance The instance of the class to invoke the method on.
+ * @param methodName The name of the method to invoke.
+ * @param parameterTypes The needed parameter types for the method.
+ * @param parameters The parameter values to pass into the method.
+ * @return The result of the invocation or {@code null} if instance or methodName are empty, or if
+ * the reflection fails.
+ */
+ @Nullable
+ public static Object invokeMethod(
+ @Nullable Object instance,
+ @Nullable String methodName,
+ Class<?>[] parameterTypes,
+ Object[] parameters) {
+ if (instance == null || TextUtils.isEmpty(methodName)) {
+ return null;
+ }
+
+ String className = instance.getClass().getName();
+ try {
+ return Class.forName(className)
+ .getMethod(methodName, parameterTypes)
+ .invoke(instance, parameters);
+ } catch (ClassNotFoundException
+ | NoSuchMethodException
+ | IllegalArgumentException
+ | IllegalAccessException
+ | InvocationTargetException e) {
+ Log.v(TAG, "Could not invoke method: " + className + "#" + methodName);
+ return null;
+ } catch (Throwable t) {
+ Log.e(
+ TAG,
+ "Unexpected exception when invoking method: "
+ + className
+ + "#"
+ + methodName
+ + " at runtime",
+ t);
+ return null;
+ }
+ }
+
+ /**
+ * Determines if this version is compatible with Lollipop-specific APIs. Can also force the
+ * version to be lower through SdkVersionOverride.
+ *
+ * @return {@code true} if call subject is a feature on this device, {@code false} otherwise.
+ */
+ public static boolean isLollipopCompatible() {
+ return SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.LOLLIPOP)
+ >= Build.VERSION_CODES.LOLLIPOP;
+ }
+}
diff --git a/java/com/android/dialer/compat/PathInterpolatorCompat.java b/java/com/android/dialer/compat/PathInterpolatorCompat.java
new file mode 100644
index 000000000..7139bc4af
--- /dev/null
+++ b/java/com/android/dialer/compat/PathInterpolatorCompat.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2015 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.compat;
+
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.os.Build;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+
+public class PathInterpolatorCompat {
+
+ public static Interpolator create(
+ float controlX1, float controlY1, float controlX2, float controlY2) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ return new PathInterpolator(controlX1, controlY1, controlX2, controlY2);
+ }
+ return new PathInterpolatorBase(controlX1, controlY1, controlX2, controlY2);
+ }
+
+ private static class PathInterpolatorBase implements Interpolator {
+
+ /** Governs the accuracy of the approximation of the {@link Path}. */
+ private static final float PRECISION = 0.002f;
+
+ private final float[] mX;
+ private final float[] mY;
+
+ public PathInterpolatorBase(Path path) {
+ final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);
+
+ final float pathLength = pathMeasure.getLength();
+ final int numPoints = (int) (pathLength / PRECISION) + 1;
+
+ mX = new float[numPoints];
+ mY = new float[numPoints];
+
+ final float[] position = new float[2];
+ for (int i = 0; i < numPoints; ++i) {
+ final float distance = (i * pathLength) / (numPoints - 1);
+ pathMeasure.getPosTan(distance, position, null /* tangent */);
+
+ mX[i] = position[0];
+ mY[i] = position[1];
+ }
+ }
+
+ public PathInterpolatorBase(float controlX, float controlY) {
+ this(createQuad(controlX, controlY));
+ }
+
+ public PathInterpolatorBase(
+ float controlX1, float controlY1, float controlX2, float controlY2) {
+ this(createCubic(controlX1, controlY1, controlX2, controlY2));
+ }
+
+ private static Path createQuad(float controlX, float controlY) {
+ final Path path = new Path();
+ path.moveTo(0.0f, 0.0f);
+ path.quadTo(controlX, controlY, 1.0f, 1.0f);
+ return path;
+ }
+
+ private static Path createCubic(
+ float controlX1, float controlY1, float controlX2, float controlY2) {
+ final Path path = new Path();
+ path.moveTo(0.0f, 0.0f);
+ path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0f, 1.0f);
+ return path;
+ }
+
+ @Override
+ public float getInterpolation(float t) {
+ if (t <= 0.0f) {
+ return 0.0f;
+ } else if (t >= 1.0f) {
+ return 1.0f;
+ }
+
+ // Do a binary search for the correct x to interpolate between.
+ int startIndex = 0;
+ int endIndex = mX.length - 1;
+ while (endIndex - startIndex > 1) {
+ int midIndex = (startIndex + endIndex) / 2;
+ if (t < mX[midIndex]) {
+ endIndex = midIndex;
+ } else {
+ startIndex = midIndex;
+ }
+ }
+
+ final float xRange = mX[endIndex] - mX[startIndex];
+ if (xRange == 0) {
+ return mY[startIndex];
+ }
+
+ final float tInRange = t - mX[startIndex];
+ final float fraction = tInRange / xRange;
+
+ final float startY = mY[startIndex];
+ final float endY = mY[endIndex];
+
+ return startY + (fraction * (endY - startY));
+ }
+ }
+}
diff --git a/java/com/android/dialer/compat/SdkVersionOverride.java b/java/com/android/dialer/compat/SdkVersionOverride.java
new file mode 100644
index 000000000..1d253a355
--- /dev/null
+++ b/java/com/android/dialer/compat/SdkVersionOverride.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 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.compat;
+
+import android.os.Build.VERSION;
+
+/**
+ * Class used to override the current sdk version to test specific branches of compatibility logic.
+ * When such branching occurs, use {@link #getSdkVersion(int)} rather than explicitly calling {@link
+ * VERSION#SDK_INT}. This allows the sdk version to be forced to a specific value.
+ */
+public class SdkVersionOverride {
+
+ /** Flag used to determine if override sdk versions are returned. */
+ private static final boolean ALLOW_OVERRIDE_VERSION = false;
+
+ private SdkVersionOverride() {}
+
+ /**
+ * Gets the sdk version
+ *
+ * @param overrideVersion the version to attempt using
+ * @return overrideVersion if the {@link #ALLOW_OVERRIDE_VERSION} flag is set to {@code true},
+ * otherwise the current version
+ */
+ public static int getSdkVersion(int overrideVersion) {
+ return ALLOW_OVERRIDE_VERSION ? overrideVersion : VERSION.SDK_INT;
+ }
+}