Merge "Hide Sensor.getRequiredPermission API." into lmp-preview-dev
diff --git a/api/current.txt b/api/current.txt
index 4041062..daf7f84 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -490,6 +490,7 @@
field public static final int editTextStyle = 16842862; // 0x101006e
field public static final deprecated int editable = 16843115; // 0x101016b
field public static final int editorExtras = 16843300; // 0x1010224
+ field public static final int elegantTextHeight = 16843867; // 0x101045b
field public static final int elevation = 16843843; // 0x1010443
field public static final int ellipsize = 16842923; // 0x10100ab
field public static final int ems = 16843096; // 0x1010158
@@ -12145,7 +12146,6 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
field public static final android.hardware.camera2.CameraCharacteristics.Key NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_AVAILABLE_CAPABILITIES;
- field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_INPUT_STREAMS;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC_STALLING;
field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_RAW;
@@ -12370,7 +12370,6 @@
field public static final int REQUEST_AVAILABLE_CAPABILITIES_DNG = 5; // 0x5
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 2; // 0x2
- field public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4; // 0x4
field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3
@@ -12669,6 +12668,7 @@
}
public final class TonemapCurve {
+ ctor public TonemapCurve(float[], float[], float[]);
method public void copyColorCurve(int, float[], int);
method public android.graphics.PointF getPoint(int, int);
method public int getPointCount(int);
@@ -15823,6 +15823,8 @@
package android.media.tv {
public final class TvContract {
+ method public static final android.net.Uri buildChannelLogoUri(long);
+ method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
method public static final android.net.Uri buildChannelUri(long);
method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName);
method public static final android.net.Uri buildChannelsUriForInput(android.content.ComponentName, boolean);
@@ -15880,6 +15882,10 @@
field public static final int TYPE_T_DMB = 393216; // 0x60000
}
+ public static final class TvContract.Channels.Logo {
+ field public static final java.lang.String CONTENT_DIRECTORY = "logo";
+ }
+
public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
@@ -15888,8 +15894,10 @@
field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
field public static final java.lang.String COLUMN_TITLE = "title";
field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
@@ -27393,55 +27401,6 @@
field public static final android.os.Parcelable.Creator CREATOR;
}
- public class DisconnectCause {
- method public static java.lang.String toString(int);
- field public static final int BUSY = 4; // 0x4
- field public static final int CALL_BARRED = 20; // 0x14
- field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
- field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
- field public static final int CDMA_CALL_LOST = 41; // 0x29
- field public static final int CDMA_DROP = 27; // 0x1b
- field public static final int CDMA_INTERCEPT = 28; // 0x1c
- field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
- field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
- field public static final int CDMA_PREEMPTED = 33; // 0x21
- field public static final int CDMA_REORDER = 29; // 0x1d
- field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
- field public static final int CDMA_SO_REJECT = 30; // 0x1e
- field public static final int CONGESTION = 5; // 0x5
- field public static final int CS_RESTRICTED = 22; // 0x16
- field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
- field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
- field public static final int DIALED_MMI = 39; // 0x27
- field public static final int EMERGENCY_ONLY = 37; // 0x25
- field public static final int ERROR_UNSPECIFIED = 36; // 0x24
- field public static final int FDN_BLOCKED = 21; // 0x15
- field public static final int ICC_ERROR = 19; // 0x13
- field public static final int INCOMING_MISSED = 1; // 0x1
- field public static final int INCOMING_REJECTED = 16; // 0x10
- field public static final int INVALID_CREDENTIALS = 10; // 0xa
- field public static final int INVALID_NUMBER = 7; // 0x7
- field public static final int LIMIT_EXCEEDED = 15; // 0xf
- field public static final int LOCAL = 3; // 0x3
- field public static final int LOST_SIGNAL = 14; // 0xe
- field public static final int MAXIMUM_VALID_VALUE = 42; // 0x2a
- field public static final int MINIMUM_VALID_VALUE = 0; // 0x0
- field public static final int MMI = 6; // 0x6
- field public static final int NORMAL = 2; // 0x2
- field public static final int NOT_DISCONNECTED = 0; // 0x0
- field public static final int NOT_VALID = -1; // 0xffffffff
- field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
- field public static final int NUMBER_UNREACHABLE = 8; // 0x8
- field public static final int OUT_OF_NETWORK = 11; // 0xb
- field public static final int OUT_OF_SERVICE = 18; // 0x12
- field public static final int POWER_OFF = 17; // 0x11
- field public static final int SERVER_ERROR = 12; // 0xc
- field public static final int SERVER_UNREACHABLE = 9; // 0x9
- field public static final int TIMED_OUT = 13; // 0xd
- field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
- field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
- }
-
public class NeighboringCellInfo implements android.os.Parcelable {
ctor public deprecated NeighboringCellInfo();
ctor public deprecated NeighboringCellInfo(int, int);
@@ -27493,7 +27452,7 @@
method public static boolean isEmergencyNumber(java.lang.String);
method public static boolean isGlobalPhoneNumber(java.lang.String);
method public static boolean isISODigit(char);
- method public static boolean isLocalEmergencyNumber(java.lang.String, android.content.Context);
+ method public static boolean isLocalEmergencyNumber(android.content.Context, java.lang.String);
method public static final boolean isNonSeparator(char);
method public static final boolean isReallyDialable(char);
method public static final boolean isStartsPostDial(char);
@@ -31989,7 +31948,6 @@
method protected int computeVerticalScrollRange();
method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
method public void createContextMenu(android.view.ContextMenu);
- method public final android.animation.ValueAnimator createRevealAnimator(int, int, float, float);
method public void destroyDrawingCache();
method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
method public void dispatchConfigurationChanged(android.content.res.Configuration);
@@ -32637,6 +32595,10 @@
method public abstract boolean onTouch(android.view.View, android.view.MotionEvent);
}
+ public class ViewAnimationUtils {
+ method public static final android.animation.ValueAnimator createCircularReveal(android.view.View, int, int, float, float);
+ }
+
public class ViewConfiguration {
ctor public deprecated ViewConfiguration();
method public static android.view.ViewConfiguration get(android.content.Context);
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 222374a..08cfc87 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -751,6 +751,7 @@
* <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
* stream image format will be RAW_OPAQUE, the associated output stream image format
* should be JPEG.</p>
+ * @hide
*/
public static final Key<Integer> REQUEST_MAX_NUM_INPUT_STREAMS =
new Key<Integer>("android.request.maxNumInputStreams", int.class);
@@ -974,7 +975,7 @@
* <p>The mapping of image formats that are supported by this
* camera device for input streams, to their corresponding output formats.</p>
* <p>All camera devices with at least 1
- * {@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} will have at least one
+ * android.request.maxNumInputStreams will have at least one
* available input format.</p>
* <p>The camera device will support the following map of formats,
* if its dependent capability is supported:</p>
@@ -1021,8 +1022,6 @@
* <p>Attempting to configure an input stream with output streams not
* listed as available in this map is not valid.</p>
* <p>TODO: typedef to ReprocessFormatMap</p>
- *
- * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @hide
*/
public static final Key<int[]> SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP =
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index b3e165e..94a5a79 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -340,6 +340,7 @@
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
* </ul>
+ * <p>@hide this, TODO: remove it when input related APIs are ready.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index f74fbaa..c3e042e 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -446,7 +446,12 @@
@Override
public void onUnconfigured(CameraDevice camera) {
- mUnconfigureDrainer.taskFinished();
+ synchronized (session) {
+ // Ignore #onUnconfigured before #close is called
+ if (mClosed) {
+ mUnconfigureDrainer.taskFinished();
+ }
+ }
}
};
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 9795082..d4adae1 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -101,11 +101,11 @@
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceListener.onOpened(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onOpened(CameraDeviceImpl.this);
}
+ mDeviceListener.onOpened(CameraDeviceImpl.this);
}
}
};
@@ -114,11 +114,11 @@
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceListener.onUnconfigured(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onUnconfigured(CameraDeviceImpl.this);
}
+ mDeviceListener.onUnconfigured(CameraDeviceImpl.this);
}
}
};
@@ -127,11 +127,11 @@
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceListener.onActive(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onActive(CameraDeviceImpl.this);
}
+ mDeviceListener.onActive(CameraDeviceImpl.this);
}
}
};
@@ -140,11 +140,11 @@
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceListener.onBusy(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onBusy(CameraDeviceImpl.this);
}
+ mDeviceListener.onBusy(CameraDeviceImpl.this);
}
}
};
@@ -152,11 +152,11 @@
private final Runnable mCallOnClosed = new Runnable() {
@Override
public void run() {
- mDeviceListener.onClosed(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onClosed(CameraDeviceImpl.this);
}
+ mDeviceListener.onClosed(CameraDeviceImpl.this);
}
};
@@ -164,11 +164,11 @@
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceListener.onIdle(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onIdle(CameraDeviceImpl.this);
}
+ mDeviceListener.onIdle(CameraDeviceImpl.this);
}
}
};
@@ -177,11 +177,11 @@
@Override
public void run() {
if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceListener.onDisconnected(CameraDeviceImpl.this);
StateListener sessionListener = mSessionStateListener;
if (sessionListener != null) {
sessionListener.onDisconnected(CameraDeviceImpl.this);
}
+ mDeviceListener.onDisconnected(CameraDeviceImpl.this);
}
}
};
diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java
index 0fcffac..481d67a 100644
--- a/core/java/android/hardware/camera2/params/TonemapCurve.java
+++ b/core/java/android/hardware/camera2/params/TonemapCurve.java
@@ -78,7 +78,7 @@
/**
* Create a new immutable TonemapCurve instance.
*
- * <p>Values are stored as a contiguous {@code (Pin, Pout}) point.</p>
+ * <p>Values are stored as a contiguous array of {@code (Pin, Pout)} points.</p>
*
* <p>All parameters may have independent length but should have at most
* {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS} * {@value #POINT_SIZE} elements.</p>
@@ -88,15 +88,16 @@
*
* <p>This constructor copies the array contents and does not retain ownership of the array.</p>
*
- * @param elements An array of elements whose length is {@code CHANNEL_COUNT * rows * columns}
+ * @param red An array of elements whose length is divisible by {@value #POINT_SIZE}
+ * @param green An array of elements whose length is divisible by {@value #POINT_SIZE}
+ * @param blue An array of elements whose length is divisible by {@value #POINT_SIZE}
*
* @throws IllegalArgumentException
- * if the {@code elements} array length is invalid,
- * if any of the subelems are not finite
+ * if any of input array length is invalid,
+ * or if any of the elements in the array are not in the range of
+ * [{@value #LEVEL_BLACK}, {@value #LEVEL_WHITE}]
* @throws NullPointerException
- * if any of the parameters is {@code null}
- *
- * @hide
+ * if any of the parameters are {@code null}
*/
public TonemapCurve(float[] red, float[] green, float[] blue) {
// TODO: maxCurvePoints check?
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c7c007e..634ae60 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10609,24 +10609,6 @@
}
/**
- * Returns a ValueAnimator which can animate a clipping circle.
- * <p>
- * The View will be clipped to the animating circle.
- * <p>
- * Any shadow cast by the View will respect the circular clip from this animator.
- *
- * @param centerX The x coordinate of the center of the animating circle.
- * @param centerY The y coordinate of the center of the animating circle.
- * @param startRadius The starting radius of the animating circle.
- * @param endRadius The ending radius of the animating circle.
- */
- public final ValueAnimator createRevealAnimator(int centerX, int centerY,
- float startRadius, float endRadius) {
- return RevealAnimator.ofRevealCircle(this, centerX, centerY,
- startRadius, endRadius, false);
- }
-
- /**
* Returns a ValueAnimator which can animate a clearing circle.
* <p>
* The View is prevented from drawing within the circle, so the content
diff --git a/core/java/android/view/ViewAnimationUtils.java b/core/java/android/view/ViewAnimationUtils.java
new file mode 100644
index 0000000..3854f34
--- /dev/null
+++ b/core/java/android/view/ViewAnimationUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 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 android.view;
+
+import android.animation.RevealAnimator;
+import android.animation.ValueAnimator;
+
+/**
+ * Defines common utilities for working with View's animations.
+ *
+ */
+public class ViewAnimationUtils {
+ private ViewAnimationUtils() {}
+ /**
+ * Returns a ValueAnimator which can animate a clipping circle.
+ *
+ * Any shadow cast by the View will respect the circular clip from this animator.
+ *
+ * @param view The View will be clipped to the animating circle.
+ * @param centerX The x coordinate of the center of the animating circle.
+ * @param centerY The y coordinate of the center of the animating circle.
+ * @param startRadius The starting radius of the animating circle.
+ * @param endRadius The ending radius of the animating circle.
+ */
+ public static final ValueAnimator createCircularReveal(View view,
+ int centerX, int centerY, float startRadius, float endRadius) {
+ return RevealAnimator.ofRevealCircle(view, centerX, centerY,
+ startRadius, endRadius, false);
+ }
+}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a4a9680e..43c8dde 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -222,6 +222,7 @@
* @attr ref android.R.styleable#TextView_imeActionLabel
* @attr ref android.R.styleable#TextView_imeActionId
* @attr ref android.R.styleable#TextView_editorExtras
+ * @attr ref android.R.styleable#TextView_elegantTextHeight
*/
@RemoteView
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -2637,6 +2638,8 @@
* metrics, and also increases top and bottom bounds to provide more space.
*
* @param elegant set the paint's elegant metrics flag.
+ *
+ * @attr ref android.R.styleable#TextView_elegantTextHeight
*/
public void setElegantTextHeight(boolean elegant) {
mTextPaint.setElegantTextHeight(elegant);
diff --git a/core/res/res/layout/preference_category_quantum.xml b/core/res/res/layout/preference_category_quantum.xml
index 032e09d..9dd0d86 100644
--- a/core/res/res/layout/preference_category_quantum.xml
+++ b/core/res/res/layout/preference_category_quantum.xml
@@ -21,8 +21,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="16dip"
android:textAppearance="@style/TextAppearance.Quantum.Body2"
- android:textColor="?android:attr/textColorSecondary"
- android:textStyle="bold"
+ android:textColor="?android:attr/colorAccent"
android:paddingStart="?attr/listPreferredItemPaddingStart"
android:paddingEnd="?attr/listPreferredItemPaddingEnd"
android:paddingTop="16dip" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 88e1cda..5d9f3e5 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2179,6 +2179,7 @@
<public type="attr" name="contentInsetRight" />
<public type="attr" name="paddingMode" />
<public type="attr" name="selectableItemBackgroundBorderless" />
+ <public type="attr" name="elegantTextHeight" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 0ee253a..16548d0 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -94,7 +94,7 @@
boolean changed = super.setVisible(visible, restart);
if (visible) {
if (changed || restart) {
- setFrame(0, true, mCurFrame >= 0);
+ setFrame(0, true, restart || mCurFrame >= 0);
}
} else {
unscheduleSelf(this);
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1512da5..241b89e 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1203,8 +1203,11 @@
st.mAttrStroke = a.extractThemeAttrs();
+ // We have an explicit stroke defined, so the default stroke width
+ // must be at least 0 or the current stroke width.
+ final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth);
final int width = a.getDimensionPixelSize(
- R.styleable.GradientDrawableStroke_width, st.mStrokeWidth);
+ R.styleable.GradientDrawableStroke_width, defaultStrokeWidth);
final float dashWidth = a.getDimension(
R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth);
@@ -1406,10 +1409,13 @@
outline.setOval(bounds);
return true;
case LINE:
- float halfStrokeWidth = mStrokePaint.getStrokeWidth() * 0.5f;
- float centerY = bounds.centerY();
- int top = (int) Math.floor(centerY - halfStrokeWidth);
- int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
+ // Hairlines (0-width stroke) must have a non-empty outline for
+ // shadows to draw correctly, so we'll use a very small width.
+ final float halfStrokeWidth = mStrokePaint == null ?
+ 0.0001f : mStrokePaint.getStrokeWidth() * 0.5f;
+ final float centerY = bounds.centerY();
+ final int top = (int) Math.floor(centerY - halfStrokeWidth);
+ final int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
outline.setRect(bounds.left, top, bounds.right, bottom);
return true;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index f0ae00f..dff4f6c 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -153,6 +153,11 @@
// TODO: rename for consistency
virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
+protected:
+ // NOTE: must override these to avoid calling into super class, which calls GL. These may be
+ // removed once DisplayListRenderer no longer inherits from OpenGLRenderer
+ virtual void onViewportInitialized() {};
+ virtual void onSnapshotRestored() {};
private:
void insertRestoreToCount();
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 6e0586e..5e650c2 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -86,6 +86,27 @@
}
/**
+ * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+ *
+ * @param channelId The ID of the channel whose logo is pointed to.
+ */
+ public static final Uri buildChannelLogoUri(long channelId) {
+ return buildChannelLogoUri(buildChannelUri(channelId));
+ }
+
+ /**
+ * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+ *
+ * @param channelUri The URI of the channel whose logo is pointed to.
+ */
+ public static final Uri buildChannelLogoUri(Uri channelUri) {
+ if (!PATH_CHANNEL.equals(channelUri.getPathSegments().get(0))) {
+ throw new IllegalArgumentException("Not a channel: " + channelUri);
+ }
+ return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY);
+ }
+
+ /**
* Builds a URI that points to all browsable channels from a given TV input.
*
* @param name {@link ComponentName} of the {@link android.media.tv.TvInputService} that
@@ -523,6 +544,48 @@
public static final String COLUMN_VERSION_NUMBER = "version_number";
private Channels() {}
+
+ /**
+ * A sub-directory of a single TV channel that represents its primary logo.
+ * <p>
+ * To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw
+ * channel URI. The resulting URI represents an image file, and should be interacted
+ * using ContentResolver.openAssetFileDescriptor.
+ * </p>
+ * <p>
+ * Note that this sub-directory also supports opening the logo as an asset file in write
+ * mode. Callers can create or replace the primary logo associated with this channel by
+ * opening the asset file and writing the full-size photo contents into it. When the file
+ * is closed, the image will be parsed, sized down if necessary, and stored.
+ * </p>
+ * <p>
+ * Usage example:
+ * <pre>
+ * public void writeChannelLogo(long channelId, byte[] logo) {
+ * Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId);
+ * try {
+ * AssetFileDescriptor fd =
+ * getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw");
+ * OutputStream os = fd.createOutputStream();
+ * os.write(logo);
+ * os.close();
+ * fd.close();
+ * } catch (IOException e) {
+ * // Handle error cases.
+ * }
+ * }
+ * </pre>
+ * </p>
+ */
+ public static final class Logo {
+
+ /**
+ * The directory twig for this sub-table.
+ */
+ public static final String CONTENT_DIRECTORY = "logo";
+
+ private Logo() {}
+ }
}
/** Column definitions for the TV programs table. */
@@ -631,6 +694,26 @@
public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
/**
+ * The URI for the poster art of this TV program.
+ * <p>
+ * Can be empty.
+ * </p><p>
+ * Type: TEXT
+ * </p>
+ */
+ public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
+
+ /**
+ * The URI for the thumbnail of this TV program.
+ * <p>
+ * Can be empty.
+ * </p><p>
+ * Type: TEXT
+ * </p>
+ */
+ public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+
+ /**
* Internal data used by individual TV input services.
* <p>
* This is internal to the provider that inserted it, and should not be decoded by other
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index acfcd83..3f37ed1 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -171,8 +171,3 @@
{
return static_cast<Sensor const*>(sensor)->getStringType().string();
}
-
-const char* ASensor_getRequiredPermission(ASensor const* sensor)
-{
- return static_cast<Sensor const*>(sensor)->getRequiredPermission().string();
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index dcd187c..f013d13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -33,11 +33,13 @@
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewAnimationUtils;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -219,7 +221,8 @@
int heightHalf = mBackgroundNormal.getActualHeight()/2;
float radius = (float) Math.sqrt(widthHalf*widthHalf + heightHalf*heightHalf);
ValueAnimator animator =
- mBackgroundNormal.createRevealAnimator(widthHalf, heightHalf, 0, radius);
+ ViewAnimationUtils.createCircularReveal(mBackgroundNormal,
+ widthHalf, heightHalf, 0, radius);
mBackgroundNormal.setVisibility(View.VISIBLE);
Interpolator interpolator;
Interpolator alphaInterpolator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1dfb8fa..227304c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -77,6 +77,7 @@
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator;
@@ -757,7 +758,8 @@
@Override
public ValueAnimator createRevealAnimator(View v, int centerX, int centerY,
float startRadius, float endRadius) {
- return v.createRevealAnimator(centerX, centerY, startRadius, endRadius);
+ return ViewAnimationUtils.createCircularReveal(v, centerX, centerY,
+ startRadius, endRadius);
}
});
final QSTileHost qsh = new QSTileHost(mContext, this,
diff --git a/telecomm/java/android/telecomm/CallService.java b/telecomm/java/android/telecomm/CallService.java
index d452172..a254459 100644
--- a/telecomm/java/android/telecomm/CallService.java
+++ b/telecomm/java/android/telecomm/CallService.java
@@ -63,6 +63,7 @@
private static final int MSG_STOP_DTMF_TONE = 13;
private static final int MSG_ADD_TO_CONFERENCE = 14;
private static final int MSG_SPLIT_FROM_CONFERENCE = 15;
+ private static final int MSG_ON_POST_DIAL_CONTINUE = 16;
/**
* Default Handler used to consolidate binder method calls onto a single thread.
@@ -150,6 +151,17 @@
}
break;
}
+ case MSG_ON_POST_DIAL_CONTINUE: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ String callId = (String) args.arg1;
+ boolean proceed = (args.argi1 == 1);
+ onPostDialContinue(callId, proceed);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
default:
break;
}
@@ -247,6 +259,14 @@
args.arg2 = callId;
mMessageHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
}
+
+ @Override
+ public void onPostDialContinue(String callId, boolean proceed) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.argi1 = proceed ? 1 : 0;
+ mMessageHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
+ }
}
/**
@@ -422,4 +442,7 @@
* @hide
*/
public abstract void splitFromConference(String conferenceCallId, String callId);
+
+ public void onPostDialContinue(String callId, boolean proceed) {}
+ public void onPostDialWait(Connection conn, String remaining) {}
}
diff --git a/telecomm/java/android/telecomm/CallServiceAdapter.java b/telecomm/java/android/telecomm/CallServiceAdapter.java
index 0c57828..fb5c871 100644
--- a/telecomm/java/android/telecomm/CallServiceAdapter.java
+++ b/telecomm/java/android/telecomm/CallServiceAdapter.java
@@ -217,4 +217,11 @@
} catch (RemoteException ignored) {
}
}
+
+ public void onPostDialWait(String callId, String remaining) {
+ try {
+ mAdapter.onPostDialWait(callId, remaining);
+ } catch (RemoteException ignored) {
+ }
+ }
}
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 8cce8e6..344814f 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -444,6 +444,11 @@
*/
protected void onReject() {}
+ /**
+ * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
+ */
+ protected void onPostDialContinue(boolean proceed) {}
+
private void setState(int state) {
Log.d(this, "setState: %s", stateToString(state));
onSetState(state);
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 31de15c..59e977d 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -146,7 +146,8 @@
}
} else {
addConnection(callInfo.getId(), result[0]);
- Log.d(this, "adapter handleSuccessfulOutgoingCall %s", callInfo.getId());
+ Log.d(this, "adapter handleSuccessfulOutgoingCall %s",
+ callInfo.getId());
getAdapter().handleSuccessfulOutgoingCall(callInfo.getId());
}
}
@@ -288,6 +289,25 @@
// TODO(santoscordon): Find existing conference call and invoke split(connection).
}
+ @Override
+ public final void onPostDialContinue(String callId, boolean proceed) {
+ Log.d(this, "onPostDialContinue(%s)", callId);
+
+ Connection connection = findConnectionForAction(callId, "onPostDialContinue");
+ if (connection == NULL_CONNECTION) {
+ Log.w(this, "Connection missing in post-dial request %s.", callId);
+ return;
+ }
+ connection.onPostDialContinue(proceed);
+ }
+
+ @Override
+ public final void onPostDialWait(Connection conn, String remaining) {
+ Log.d(this, "onPostDialWait(%s, %s)", conn, remaining);
+
+ getAdapter().onPostDialWait(mIdByConnection.get(conn), remaining);
+ }
+
/**
* Find a set of Subscriptions matching a given handle (e.g. phone number).
*
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
index 6838ede..0bef419 100644
--- a/telecomm/java/android/telecomm/InCallAdapter.java
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -174,13 +174,14 @@
* will pause playing the tones and notify the {@link InCallService} that the call is in the
* {@link InCallService#setPostDialWait(String,String)} state. When the user decides to continue
* the postdial sequence, the {@link InCallService} should invoke the
- * {@link #postDialContinue(String)} method.
+ * {@link #postDialContinue(String,boolean)} method.
*
* @param callId The unique ID of the call for which postdial string playing should continue.
+ * @param proceed Whether or not to continue with the post-dial sequence.
*/
- public void postDialContinue(String callId) {
+ public void postDialContinue(String callId, boolean proceed) {
try {
- mAdapter.postDialContinue(callId);
+ mAdapter.postDialContinue(callId, proceed);
} catch (RemoteException e) {
}
}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallService.aidl b/telecomm/java/com/android/internal/telecomm/ICallService.aidl
index 771a3ae..9139aa6 100644
--- a/telecomm/java/com/android/internal/telecomm/ICallService.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ICallService.aidl
@@ -59,4 +59,6 @@
void addToConference(String conferenceCallId, in List<String> callIds);
void splitFromConference(String conferenceCallId, String callId);
+
+ void onPostDialContinue(String callId, boolean proceed);
}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
index f94eb32..17e0487 100644
--- a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
@@ -52,4 +52,6 @@
void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced);
void removeCall(String callId);
+
+ void onPostDialWait(String callId, String remaining);
}
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
index 6a27217..f144043 100644
--- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -44,7 +44,7 @@
void stopDtmfTone(String callId);
- void postDialContinue(String callId);
+ void postDialContinue(String callId, boolean proceed);
void handoffCall(String callId);
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index d2044be..604b895 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -18,6 +18,8 @@
/**
* Contains disconnect call causes generated by the framework and the RIL.
+ *
+ * @hide
*/
public class DisconnectCause {
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 9da032a..6996659 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1742,16 +1742,14 @@
/**
* Checks if a given number is an emergency number for the country that the user is in.
- *
- * @param number the number to look up.
* @param context the specific context which the number should be checked against
+ * @param number the number to look up.
+ *
* @return true if the specified number is an emergency number for the country the user
* is currently in.
*/
- public static boolean isLocalEmergencyNumber(String number, Context context) {
- return isLocalEmergencyNumberInternal(number,
- context,
- true /* useExactMatch */);
+ public static boolean isLocalEmergencyNumber(Context context, String number) {
+ return isLocalEmergencyNumberInternal(context, number, true /* useExactMatch */);
}
/**
@@ -1767,27 +1765,24 @@
* This method is intended for internal use by the phone app when
* deciding whether to allow ACTION_CALL intents from 3rd party apps
* (where we're required to *not* allow emergency calls to be placed.)
- *
- * @param number the number to look up.
* @param context the specific context which the number should be checked against
+ * @param number the number to look up.
+ *
* @return true if the specified number is an emergency number for a local country, based on the
* CountryDetector.
*
* @see android.location.CountryDetector
* @hide
*/
- public static boolean isPotentialLocalEmergencyNumber(String number, Context context) {
- return isLocalEmergencyNumberInternal(number,
- context,
- false /* useExactMatch */);
+ public static boolean isPotentialLocalEmergencyNumber(Context context, String number) {
+ return isLocalEmergencyNumberInternal(context, number, false /* useExactMatch */);
}
/**
* Helper function for isLocalEmergencyNumber() and
* isPotentialLocalEmergencyNumber().
- *
- * @param number the number to look up.
* @param context the specific context which the number should be checked against
+ * @param number the number to look up.
* @param useExactMatch if true, consider a number to be an emergency
* number only if it *exactly* matches a number listed in
* the RIL / SIM. If false, a number is considered to be an
@@ -1799,9 +1794,8 @@
*
* @see android.location.CountryDetector
*/
- private static boolean isLocalEmergencyNumberInternal(String number,
- Context context,
- boolean useExactMatch) {
+ private static boolean isLocalEmergencyNumberInternal(Context context, String number,
+ boolean useExactMatch) {
String countryIso;
CountryDetector detector = (CountryDetector) context.getSystemService(
Context.COUNTRY_DETECTOR);
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index f6143ed..f8dd7cf 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -276,7 +276,7 @@
// Change the callerInfo number ONLY if it is an emergency number
// or if it is the voicemail number. If it is either, take a
// shortcut and skip the query.
- if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
+ if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
return new CallerInfo().markAsEmergency(context);
} else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
return new CallerInfo().markAsVoiceMail();
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 74f73b5..34fed5e 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -399,7 +399,7 @@
cw.number = number;
// check to see if these are recognized numbers, and use shortcuts if we can.
- if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
+ if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
cw.event = EVENT_EMERGENCY_NUMBER;
} else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
cw.event = EVENT_VOICEMAIL_NUMBER;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index e9daffd..a417479 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -977,7 +977,7 @@
/*package*/ static void native_drawText(long nativeCanvas,
final char[] text, final int index, final int count,
final float startX, final float startY, final int flags, long paint,
- long typeface) {
+ final long typeface) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
new GcSnapshot.Drawable() {
@@ -985,6 +985,11 @@
public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
// WARNING: the logic in this method is similar to Paint_Delegate.measureText.
// Any change to this method should be reflected in Paint.measureText
+
+ // assert that the typeface passed is actually the one stored in paint.
+ assert (typeface == paintDelegate.mNativeTypeface);
+
+
// Paint.TextAlign indicates how the text is positioned relative to X.
// LEFT is the default and there's nothing to do.
float x = startX;
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 9ea4538..d73adab 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -21,6 +21,8 @@
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.content.res.AssetManager;
+
import java.awt.Font;
import java.io.File;
import java.util.ArrayList;
@@ -47,7 +49,6 @@
private static final String FONT_SUFFIX_BOLDITALIC = "BoldItalic.ttf";
private static final String FONT_SUFFIX_BOLD = "Bold.ttf";
private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
- private static final String FONT_SUBSTRING_COMPACT = "UI";
/**
* A class associating {@link Font} with its metadata.
@@ -56,11 +57,6 @@
Font mFont;
/** Regular, Bold, Italic, or BoldItalic. */
int mStyle;
- /**
- * The variant of the Font - compact or elegant.
- * @see Paint#setElegantTextHeight(boolean)
- */
- boolean mIsCompact;
}
// ---- delegate manager ----
@@ -75,6 +71,14 @@
// ---- delegate data ----
private List<FontInfo> mFonts = new ArrayList<FontInfo>();
+ /**
+ * The variant of the Font Family - compact or elegant.
+ * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
+ * android.graphics.FontFamily
+ *
+ * @see Paint#setElegantTextHeight(boolean)
+ */
+ private FontVariant mVariant;
// Path of fonts that haven't been created since sFontLoader hasn't been initialized.
private List<String> mPath = new ArrayList<String>();
@@ -93,37 +97,22 @@
sPostInitDelegate.clear();
}
- public Font getFont(int style, boolean isCompact) {
+ public Font getFont(int style) {
FontInfo plainFont = null;
- FontInfo styledFont = null; // Font matching the style but not isCompact
for (FontInfo font : mFonts) {
if (font.mStyle == style) {
- if (font.mIsCompact == isCompact) {
- return font.mFont;
- }
- styledFont = font;
+ return font.mFont;
}
- if (font.mStyle == Font.PLAIN) {
- if (plainFont == null) {
- plainFont = font;
- continue;
- }
- if (font.mIsCompact == isCompact) {
- // Override the previous selection of plain font since we've found a better one.
- plainFont = font;
- }
+ if (font.mStyle == Font.PLAIN && plainFont == null) {
+ plainFont = font;
}
}
- if (styledFont != null) {
- return styledFont.mFont;
- }
// No font with the mentioned style is found. Try to derive one.
if (plainFont != null && style > 0 && style < 4) {
- styledFont = new FontInfo();
+ FontInfo styledFont = new FontInfo();
styledFont.mFont = plainFont.mFont.deriveFont(style);
styledFont.mStyle = style;
- styledFont.mIsCompact = plainFont.mIsCompact;
// Add the font to the list of fonts so that we don't have to derive it the next time.
mFonts.add(styledFont);
return styledFont.mFont;
@@ -131,11 +120,20 @@
return null;
}
+ public FontVariant getVariant() {
+ return mVariant;
+ }
+
+
// ---- native methods ----
@LayoutlibDelegate
- /*package*/ static long nCreateFamily() {
+ /*package*/ static long nCreateFamily(String lang, int variant) {
+ // TODO: support lang. This is required for japanese locale.
FontFamily_Delegate delegate = new FontFamily_Delegate();
+ // variant can be 0, 1 or 2.
+ assert variant < 3;
+ delegate.mVariant = FontVariant.values()[variant];
if (sFontLocation != null) {
delegate.init();
} else {
@@ -164,6 +162,13 @@
return false;
}
+ @LayoutlibDelegate
+ /*package*/ static boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, String path) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "FontFamily.addFontFromAsset is not supported.", null /*throwable*/, null /*data*/);
+ return false;
+ }
+
private void init() {
for (String path : mPath) {
addFont(path);
@@ -195,13 +200,6 @@
style = Font.ITALIC;
}
fontInfo.mStyle = style;
-
- // Names of compact fonts end with UI-<style>.ttf. For example, NotoNakshUI-Regular.ttf.
- // This should go away when this info is passed on by nAddFont().
- int hyphenIndex = fontName.lastIndexOf('-');
- fontInfo.mIsCompact = hyphenIndex > 0 &&
- fontName.substring(0, hyphenIndex).endsWith(FONT_SUBSTRING_COMPACT);
-
}
private static Font loadFont(String path) {
@@ -214,7 +212,7 @@
} catch (Exception e) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
String.format("Unable to load font %1$s", relativePath),
- null /*throwable*/, null /*data*/);
+ e /*throwable*/, null /*data*/);
}
} else {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -224,4 +222,12 @@
return null;
}
+
+
+ // ---- Public helper class ----
+
+ public enum FontVariant {
+ // The order needs to be kept in sync with android.graphics.FontFamily.
+ NONE, COMPACT, ELEGANT
+ }
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 911f4e7..6ee307e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -21,6 +21,7 @@
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.graphics.FontFamily_Delegate.FontVariant;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.FontMetricsInt;
import android.text.TextUtils;
@@ -30,7 +31,6 @@
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.Collections;
@@ -81,7 +81,8 @@
private float mTextScaleX;
private float mTextSkewX;
private int mHintingMode = Paint.HINTING_ON;
- private boolean mIsCompact = true;
+ // Variant of the font.
+ private FontVariant mFontVariant = FontVariant.NONE;
private Xfermode_Delegate mXfermode;
private ColorFilter_Delegate mColorFilter;
@@ -92,6 +93,8 @@
private Locale mLocale = Locale.getDefault();
+ // Used only to assert invariants.
+ public long mNativeTypeface;
// ---- Public Helper methods ----
@@ -437,7 +440,7 @@
/*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
- return delegate != null && !delegate.mIsCompact;
+ return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
}
@LayoutlibDelegate
@@ -448,7 +451,7 @@
return;
}
- delegate.mIsCompact = !elegant;
+ delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
}
@LayoutlibDelegate
@@ -887,6 +890,7 @@
}
delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
+ delegate.mNativeTypeface = typeface;
delegate.updateFontObject();
return typeface;
}
@@ -965,15 +969,10 @@
}
@LayoutlibDelegate
- /*package*/ static float native_getTextRunAdvances(long native_object,
- long native_typeface /*ignored*/,
+ /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
char[] text, int index, int count, int contextIndex, int contextCount,
int flags, float[] advances, int advancesIndex) {
- // native_typeface is passed here since Framework's old implementation did not have the
- // typeface object associated with the Paint. Since, we follow the new framework way,
- // we store the typeface with the paint and use it directly.
-
if (advances != null)
for (int i = advancesIndex; i< advancesIndex+count; i++)
advances[i]=0;
@@ -982,6 +981,12 @@
if (delegate == null) {
return 0.f;
}
+
+ // native_typeface is passed here since Framework's old implementation did not have the
+ // typeface object associated with the Paint. Since, we follow the new framework way,
+ // we store the typeface with the paint and use it directly.
+ assert (native_typeface == delegate.mNativeTypeface);
+
boolean isRtl = isRtl(flags);
int limit = index + count;
@@ -1022,37 +1027,41 @@
}
@LayoutlibDelegate
- /*package*/ static void native_getTextPath(long native_object, int bidiFlags,
- char[] text, int index, int count, float x, float y, long path) {
+ /*package*/ static void native_getTextPath(long native_object, long native_typeface,
+ int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Paint.getTextPath is not supported.", null, null /*data*/);
}
@LayoutlibDelegate
- /*package*/ static void native_getTextPath(long native_object, int bidiFlags,
- String text, int start, int end, float x, float y, long path) {
+ /*package*/ static void native_getTextPath(long native_object, long native_typeface,
+ int bidiFlags, String text, int start, int end, float x, float y, long path) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Paint.getTextPath is not supported.", null, null /*data*/);
}
@LayoutlibDelegate
- /*package*/ static void nativeGetStringBounds(long nativePaint, String text, int start,
- int end, int bidiFlags, Rect bounds) {
- nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bidiFlags,
- bounds);
+ /*package*/ static void nativeGetStringBounds(long nativePaint, long native_typeface,
+ String text, int start, int end, int bidiFlags, Rect bounds) {
+ nativeGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
+ end - start, bidiFlags, bounds);
}
@LayoutlibDelegate
- /*package*/ static void nativeGetCharArrayBounds(long nativePaint, char[] text, int index,
- int count, int bidiFlags, Rect bounds) {
+ /*package*/ static void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
+ char[] text, int index, int count, int bidiFlags, Rect bounds) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(nativePaint);
if (delegate == null) {
return;
}
+
+ // assert that the typeface passed is actually the one that we had stored.
+ assert (native_typeface == delegate.mNativeTypeface);
+
delegate.measureText(text, index, count, isRtl(bidiFlags)).roundOut(bounds);
}
@@ -1079,6 +1088,7 @@
mJoin = paint.mJoin;
mTextAlign = paint.mTextAlign;
mTypeface = paint.mTypeface;
+ mNativeTypeface = paint.mNativeTypeface;
mStrokeWidth = paint.mStrokeWidth;
mStrokeMiter = paint.mStrokeMiter;
mTextSize = paint.mTextSize;
@@ -1102,6 +1112,7 @@
mJoin = Paint.Join.MITER.nativeInt;
mTextAlign = 0;
mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
+ mNativeTypeface = 0;
mStrokeWidth = 1.f;
mStrokeMiter = 4.f;
mTextSize = 20.f;
@@ -1124,7 +1135,7 @@
private void updateFontObject() {
if (mTypeface != null) {
// Get the fonts from the TypeFace object.
- List<Font> fonts = mTypeface.getFonts(mIsCompact);
+ List<Font> fonts = mTypeface.getFonts(mFontVariant);
// create new font objects as well as FontMetrics, based on the current text size
// and skew info.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 9746b48..908bb64 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -22,6 +22,7 @@
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.res.AssetManager;
+import android.graphics.FontFamily_Delegate.FontVariant;
import java.awt.Font;
import java.io.File;
@@ -69,17 +70,28 @@
return sManager.getDelegate(nativeTypeface);
}
- public List<Font> getFonts(boolean compact) {
+ public List<Font> getFonts(FontVariant variant) {
List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
+ // If we are unable to find fonts matching the variant, we return the fonts from the
+ // other variant since we always want to draw something, rather than nothing.
+ // TODO: check this behaviour with platform.
+ List<Font> otherVariantFonts = new ArrayList<Font>();
for (FontFamily_Delegate ffd : mFontFamilies) {
if (ffd != null) {
- Font font = ffd.getFont(mStyle, compact);
+ Font font = ffd.getFont(mStyle);
if (font != null) {
- fonts.add(font);
+ if (ffd.getVariant() == variant || ffd.getVariant() == FontVariant.NONE) {
+ fonts.add(font);
+ } else {
+ otherVariantFonts.add(font);
+ }
}
}
}
- return fonts;
+ if (fonts.size() > 0) {
+ return fonts;
+ }
+ return otherVariantFonts;
}
// ---- native methods ----
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index ffab4de..cc69af2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -214,7 +214,8 @@
Capability.EXTENDED_VIEWINFO,
Capability.FIXED_SCALABLE_NINE_PATCH,
Capability.RTL,
- Capability.ACTION_BAR);
+ Capability.ACTION_BAR,
+ Capability.SIMULATE_PLATFORM);
BridgeAssetManager.initSystem();