Merge "Some networks may have null ifaces, I guess?" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index 584246b..2a3c086 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4490,6 +4490,7 @@
public class KeyguardManager {
method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
+ method public android.content.Intent getConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence);
method public boolean inKeyguardRestrictedInputMode();
method public boolean isKeyguardLocked();
method public boolean isKeyguardSecure();
@@ -7680,7 +7681,6 @@
field public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER";
field public static final java.lang.String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS";
field public static final java.lang.String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
- field public static final java.lang.String ACTION_CONFIRM_DEVICE_CREDENTIAL = "android.intent.action.CONFIRM_DEVICE_CREDENTIAL";
field public static final java.lang.String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";
field public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
field public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
@@ -7824,7 +7824,6 @@
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
- field public static final java.lang.String EXTRA_DETAILS = "android.intent.extra.DETAILS";
field public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE";
field public static final int EXTRA_DOCK_STATE_CAR = 2; // 0x2
field public static final int EXTRA_DOCK_STATE_DESK = 1; // 0x1
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index db91742a..50e3a10 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -16,6 +16,7 @@
package android.app;
+import android.content.Intent;
import android.os.Binder;
import android.os.RemoteException;
import android.os.IBinder;
@@ -24,7 +25,7 @@
import android.view.WindowManagerGlobal;
/**
- * Class that can be used to lock and unlock the keyboard. Get an instance of this
+ * Class that can be used to lock and unlock the keyboard. Get an instance of this
* class by calling {@link android.content.Context#getSystemService(java.lang.String)}
* with argument {@link android.content.Context#KEYGUARD_SERVICE}. The
* actual class to control the keyboard locking is
@@ -34,6 +35,45 @@
private IWindowManager mWM;
/**
+ * Intent used to prompt user for device credentials.
+ * @hide
+ */
+ public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL =
+ "android.app.action.CONFIRM_DEVICE_CREDENTIAL";
+
+ /**
+ * A CharSequence dialog title to show to the user when used with a
+ * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
+ * @hide
+ */
+ public static final String EXTRA_TITLE = "android.app.extra.TITLE";
+
+ /**
+ * A CharSequence description to show to the user when used with
+ * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
+ * @hide
+ */
+ public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
+
+ /**
+ * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
+ * for the current user of the device. The caller is expected to launch this activity using
+ * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
+ * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
+ *
+ * @return the intent for launching the activity or null if no password is required.
+ **/
+ public Intent getConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
+ if (!isKeyguardSecure()) return null;
+ Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
+ intent.putExtra(EXTRA_TITLE, title);
+ intent.putExtra(EXTRA_DESCRIPTION, description);
+ // For security reasons, only allow this to come from system settings.
+ intent.setPackage("com.android.settings");
+ return intent;
+ }
+
+ /**
* @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD}
* and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
* instead; this allows you to seamlessly hide the keyguard as your application
@@ -58,7 +98,7 @@
*
* A good place to call this is from {@link android.app.Activity#onResume()}
*
- * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
+ * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
* is enabled that requires a password.
*
* <p>This method requires the caller to hold the permission
@@ -121,7 +161,7 @@
* permissions be requested.
*
* Enables you to lock or unlock the keyboard. Get an instance of this class by
- * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
+ * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
* This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}.
* @param tag A tag that informally identifies who you are (for debugging who
* is disabling he keyguard).
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index abe4f0a..61e105b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1419,21 +1419,6 @@
public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
/**
- * Activity Action: Prompt the user to confirm credentials (pin, pattern or password)
- * for the current user of the device. Launch this activity using
- * {@link android.app.Activity#startActivityForResult(Intent, int)} and check if the
- * result is {@link android.app.Activity#RESULT_OK} for a successful response to the
- * challenge.<p/>
- * This intent is handled by the system at a high priority and applications cannot intercept
- * it.<p/>
- * You can use {@link android.app.KeyguardManager#isKeyguardSecure()} to determine if the user will be
- * prompted.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL = "android.intent.action.CONFIRM_DEVICE_CREDENTIAL";
-
-
- /**
* Specify whether the package should be uninstalled for all users.
* @hide because these should not be part of normal application flow.
*/
@@ -3192,17 +3177,11 @@
/**
* A CharSequence dialog title to provide to the user when used with a
- * {@link #ACTION_CHOOSER} or {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
+ * {@link #ACTION_CHOOSER}.
*/
public static final String EXTRA_TITLE = "android.intent.extra.TITLE";
/**
- * A CharSequence description to provide to the user when used with
- * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
- */
- public static final String EXTRA_DETAILS = "android.intent.extra.DETAILS";
-
- /**
* A Parcelable[] of {@link Intent} or
* {@link android.content.pm.LabeledIntent} objects as set with
* {@link #putExtra(String, Parcelable[])} of additional activities to place
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a536b2d..a82fa65 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1320,8 +1320,8 @@
attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
boolean focusable = mMovement != null || getKeyListener() != null;
- boolean clickable = focusable;
- boolean longClickable = focusable;
+ boolean clickable = focusable || isClickable();
+ boolean longClickable = focusable || isLongClickable();
n = a.getIndexCount();
for (int i = 0; i < n; i++) {
diff --git a/core/res/res/color/primary_text_leanback_formwizard_dark.xml b/core/res/res/color/primary_text_leanback_formwizard_dark.xml
new file mode 100644
index 0000000..8fe02b2
--- /dev/null
+++ b/core/res/res/color/primary_text_leanback_formwizard_dark.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false"
+ android:alpha="@dimen/disabled_alpha_leanback_formwizard"
+ android:color="@color/primary_text_leanback_formwizard_default_dark"/>
+ <item android:color="@color/primary_text_leanback_formwizard_default_dark"/>
+</selector>
diff --git a/core/res/res/values/colors_leanback.xml b/core/res/res/values/colors_leanback.xml
index dc0c673..e52a861e 100644
--- a/core/res/res/values/colors_leanback.xml
+++ b/core/res/res/values/colors_leanback.xml
@@ -25,4 +25,5 @@
<color name="primary_text_leanback_light">#cc222222</color>
<color name="secondary_text_leanback_light">#99222222</color>
+ <color name="primary_text_leanback_formwizard_default_dark">#ffeeeeee</color>
</resources>
diff --git a/core/res/res/values/dimens_leanback.xml b/core/res/res/values/dimens_leanback.xml
new file mode 100644
index 0000000..fb5f8f0
--- /dev/null
+++ b/core/res/res/values/dimens_leanback.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <!-- Default alpha value for disabled elements. -->
+ <item name="disabled_alpha_leanback_formwizard" format="float" type="dimen">0.2</item>
+</resources>
diff --git a/core/res/res/values/styles_leanback.xml b/core/res/res/values/styles_leanback.xml
index 256ef00..72735f7 100644
--- a/core/res/res/values/styles_leanback.xml
+++ b/core/res/res/values/styles_leanback.xml
@@ -39,25 +39,29 @@
<style name="TextAppearance.Leanback.FormWizard" parent="@style/TextAppearance.Material">
<item name="textSize">18sp</item>
<item name="fontFamily">sans-serif-light</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.Small" parent="@style/TextAppearance.Material.Small">
<item name="textSize">18sp</item>
<item name="fontFamily">sans-serif-light</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.Medium" parent="@style/TextAppearance.Material.Medium">
<item name="textSize">36sp</item>
<item name="fontFamily">sans-serif-thin</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.Large" parent="@style/TextAppearance.Material.Large">
<item name="textSize">56sp</item>
<item name="fontFamily">sans-serif-thin</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.ListItem" parent="@style/TextAppearance.Material.Subhead">
- <item name="textSize">18sp</item>
+ <item name="textSize">16sp</item>
<item name="fontFamily">sans-serif-condensed</item>
</style>
diff --git a/core/res/res/values/themes_leanback.xml b/core/res/res/values/themes_leanback.xml
index 321b827..1cda843 100644
--- a/core/res/res/values/themes_leanback.xml
+++ b/core/res/res/values/themes_leanback.xml
@@ -57,5 +57,6 @@
<item name="textAppearanceLarge">@style/TextAppearance.Leanback.FormWizard.Large</item>
<item name="textAppearanceListItem">@style/TextAppearance.Leanback.FormWizard.ListItem</item>
<item name="textAppearance">@style/TextAppearance.Leanback.FormWizard</item>
+ <item name="textColorPrimary">@color/primary_text_leanback_formwizard_dark</item>
</style>
</resources>
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index f5e63ae..40adf94 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -16,6 +16,7 @@
package android.graphics.drawable;
+import android.annotation.NonNull;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -27,6 +28,7 @@
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Matrix;
+import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
@@ -598,6 +600,16 @@
}
@Override
+ public void getOutline(@NonNull Outline outline) {
+ super.getOutline(outline);
+ if (mBitmapState.mBitmap.hasAlpha()) {
+ // Bitmaps with alpha can't report a non-0 alpha,
+ // since they may not fill their rectangular bounds
+ outline.setAlpha(0.0f);
+ }
+ }
+
+ @Override
public void setAlpha(int alpha) {
final int oldAlpha = mBitmapState.mPaint.getAlpha();
if (alpha != oldAlpha) {
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 7661d58..702f150 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -2691,6 +2691,9 @@
case ResTable_config::DENSITY_XXHIGH:
res.append("xxhdpi");
break;
+ case ResTable_config::DENSITY_XXXHIGH:
+ res.append("xxxhdpi");
+ break;
case ResTable_config::DENSITY_NONE:
res.append("nodpi");
break;
@@ -2852,17 +2855,16 @@
struct ResTable::Package
{
Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)
- : owner(_owner), header(_header), package(_package), typeIdOffset(0) {
- if (dtohs(package->header.headerSize) == sizeof(package)) {
+ : owner(_owner), header(_header), typeIdOffset(0) {
+ if (_package != NULL && dtohs(_package->header.headerSize) == sizeof(_package)) {
// The package structure is the same size as the definition.
// This means it contains the typeIdOffset field.
- typeIdOffset = package->typeIdOffset;
+ typeIdOffset = _package->typeIdOffset;
}
}
const ResTable* const owner;
const Header* const header;
- const ResTable_package* const package;
ResStringPool typeStrings;
ResStringPool keyStrings;
@@ -3361,6 +3363,10 @@
header->header = (const ResTable_header*) resHeader;
mHeaders.add(header);
+
+ PackageGroup* pg = new PackageGroup(this, String16(), 0);
+ pg->packages.add(new Package(this, header, NULL));
+ mPackageGroups.add(pg);
return (mError=NO_ERROR);
}
@@ -5929,7 +5935,7 @@
*outSize += 2 * sizeof(uint16_t);
// overlay packages are assumed to contain only one package group
- const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);
+ const String16 overlayPackage(overlay.mPackageGroups[0]->name);
for (size_t typeIndex = 0; typeIndex < pg->types.size(); ++typeIndex) {
const TypeList& typeList = pg->types[typeIndex];
@@ -6204,11 +6210,6 @@
if (mError != 0) {
printf("mError=0x%x (%s)\n", mError, strerror(mError));
}
-#if 0
- char localeStr[RESTABLE_MAX_LOCALE_LEN];
- mParams.getBcp47Locale(localeStr);
- printf("mParams=%s,\n" localeStr);
-#endif
size_t pgCount = mPackageGroups.size();
printf("Package Groups (%d)\n", (int)pgCount);
for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
@@ -6217,13 +6218,6 @@
(int)pgIndex, pg->id, (int)pg->packages.size(),
String8(pg->name).string());
- size_t pkgCount = pg->packages.size();
- for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
- const Package* pkg = pg->packages[pkgIndex];
- printf(" Package %d id=%d name=%s\n", (int)pkgIndex,
- pkg->package->id, String8(String16(pkg->package->name)).string());
- }
-
for (size_t typeIndex=0; typeIndex < pg->types.size(); typeIndex++) {
const TypeList& typeList = pg->types[typeIndex];
if (typeList.isEmpty()) {
diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp
index 8016a82..68c228e 100644
--- a/libs/androidfw/tests/ResTable_test.cpp
+++ b/libs/androidfw/tests/ResTable_test.cpp
@@ -195,4 +195,21 @@
ASSERT_EQ(uint32_t(400), val.data);
}
+TEST(ResTableTest, emptyTableHasSensibleDefaults) {
+ const int32_t expectedCookie = 1;
+
+ ResTable table;
+ ASSERT_EQ(NO_ERROR, table.addEmpty(expectedCookie));
+
+ ASSERT_EQ(uint32_t(1), table.getTableCount());
+ ASSERT_EQ(uint32_t(1), table.getBasePackageCount());
+ ASSERT_EQ(expectedCookie, table.getTableCookie(0));
+
+ const DynamicRefTable* dynamicRefTable = table.getDynamicRefTableForCookie(expectedCookie);
+ ASSERT_TRUE(dynamicRefTable != NULL);
+
+ Res_value val;
+ ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0);
+}
+
}
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 5ecd77a..78d569d 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "RT-Animator"
-
#include "Animator.h"
#include <inttypes.h>
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 15bed58..054a164 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "DamageAccumulator"
-
#include "DamageAccumulator.h"
#include <cutils/log.h>
@@ -26,12 +24,6 @@
namespace android {
namespace uirenderer {
-NullDamageAccumulator NullDamageAccumulator::sInstance;
-
-NullDamageAccumulator* NullDamageAccumulator::instance() {
- return &sInstance;
-}
-
enum TransformType {
TransformInvalid = 0,
TransformRenderNode,
@@ -60,6 +52,30 @@
mHead->type = TransformNone;
}
+static void computeTransformImpl(const DirtyStack* currentFrame, Matrix4* outMatrix) {
+ if (currentFrame->prev != currentFrame) {
+ computeTransformImpl(currentFrame->prev, outMatrix);
+ }
+ switch (currentFrame->type) {
+ case TransformRenderNode:
+ currentFrame->renderNode->applyViewPropertyTransforms(*outMatrix);
+ break;
+ case TransformMatrix4:
+ outMatrix->multiply(*currentFrame->matrix4);
+ break;
+ case TransformNone:
+ // nothing to be done
+ break;
+ default:
+ LOG_ALWAYS_FATAL("Tried to compute transform with an invalid type: %d", currentFrame->type);
+ }
+}
+
+void DamageAccumulator::computeCurrentTransform(Matrix4* outMatrix) const {
+ outMatrix->loadIdentity();
+ computeTransformImpl(mHead, outMatrix);
+}
+
void DamageAccumulator::pushCommon() {
if (!mHead->next) {
DirtyStack* nextFrame = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack));
diff --git a/libs/hwui/DamageAccumulator.h b/libs/hwui/DamageAccumulator.h
index 90d9425..6f0bd8c 100644
--- a/libs/hwui/DamageAccumulator.h
+++ b/libs/hwui/DamageAccumulator.h
@@ -31,18 +31,7 @@
class RenderNode;
class Matrix4;
-class IDamageAccumulator {
-public:
- virtual void pushTransform(const RenderNode* transform) = 0;
- virtual void pushTransform(const Matrix4* transform) = 0;
- virtual void popTransform() = 0;
- virtual void dirty(float left, float top, float right, float bottom) = 0;
- virtual void peekAtDirty(SkRect* dest) = 0;
-protected:
- virtual ~IDamageAccumulator() {}
-};
-
-class DamageAccumulator : public IDamageAccumulator {
+class DamageAccumulator {
PREVENT_COPY_AND_ASSIGN(DamageAccumulator);
public:
DamageAccumulator();
@@ -51,17 +40,19 @@
// Push a transform node onto the stack. This should be called prior
// to any dirty() calls. Subsequent calls to dirty()
// will be affected by the transform when popTransform() is called.
- virtual void pushTransform(const RenderNode* transform);
- virtual void pushTransform(const Matrix4* transform);
+ void pushTransform(const RenderNode* transform);
+ void pushTransform(const Matrix4* transform);
// Pops a transform node from the stack, propagating the dirty rect
// up to the parent node. Returns the IDamageTransform that was just applied
- virtual void popTransform();
+ void popTransform();
- virtual void dirty(float left, float top, float right, float bottom);
+ void dirty(float left, float top, float right, float bottom);
// Returns the current dirty area, *NOT* transformed by pushed transforms
- virtual void peekAtDirty(SkRect* dest);
+ void peekAtDirty(SkRect* dest);
+
+ void computeCurrentTransform(Matrix4* outMatrix) const;
void finish(SkRect* totalDirty);
@@ -74,24 +65,6 @@
DirtyStack* mHead;
};
-class NullDamageAccumulator : public IDamageAccumulator {
- PREVENT_COPY_AND_ASSIGN(NullDamageAccumulator);
-public:
- virtual void pushTransform(const RenderNode* transform) { }
- virtual void pushTransform(const Matrix4* transform) { }
- virtual void popTransform() { }
- virtual void dirty(float left, float top, float right, float bottom) { }
- virtual void peekAtDirty(SkRect* dest) { dest->setEmpty(); }
-
- ANDROID_API static NullDamageAccumulator* instance();
-
-private:
- NullDamageAccumulator() {}
- ~NullDamageAccumulator() {}
-
- static NullDamageAccumulator sInstance;
-};
-
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f0a6e55..94162fc 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -66,7 +66,7 @@
"prepareDirty called a second time during a recording!");
mDisplayListData = new DisplayListData();
- initializeSaveStack(0, 0, getWidth(), getHeight());
+ initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3());
mDirtyClip = opaque;
mRestoreSaveCount = -1;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index d05cabc..8639ae1 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -53,6 +53,7 @@
deferredList = NULL;
convexMask = NULL;
caches.resourceCache.incrementRefcount(this);
+ rendererLightPosDirty = true;
}
Layer::~Layer() {
@@ -80,6 +81,17 @@
}
}
+void Layer::updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer) {
+ if (renderer && rendererLightPosDirty) {
+ // re-init renderer's light position, based upon last cached location in window
+ Vector3 lightPos = rootRenderer.getLightCenter();
+ cachedInvTransformInWindow.mapPoint3d(lightPos);
+ renderer->initLight(lightPos, rootRenderer.getLightRadius(),
+ rootRenderer.getAmbientShadowAlpha(), rootRenderer.getSpotShadowAlpha());
+ rendererLightPosDirty = false;
+ }
+}
+
bool Layer::resize(const uint32_t width, const uint32_t height) {
uint32_t desiredWidth = computeIdealWidth(width);
uint32_t desiredHeight = computeIdealWidth(height);
@@ -203,7 +215,8 @@
}
}
-void Layer::defer() {
+void Layer::defer(const OpenGLRenderer& rootRenderer) {
+ updateLightPosFromRenderer(rootRenderer);
const float width = layer.getWidth();
const float height = layer.getHeight();
@@ -253,7 +266,8 @@
}
}
-void Layer::render() {
+void Layer::render(const OpenGLRenderer& rootRenderer) {
+ updateLightPosFromRenderer(rootRenderer);
renderer->setViewport(layer.getWidth(), layer.getHeight());
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
!isBlend());
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 0bf05d0..38c29c7 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -86,6 +86,11 @@
regionRect.translate(layer.left, layer.top);
}
+ void setWindowTransform(Matrix4& windowTransform) {
+ cachedInvTransformInWindow.loadInverse(windowTransform);
+ rendererLightPosDirty = true;
+ }
+
void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
inline uint32_t getWidth() const {
@@ -257,10 +262,10 @@
return transform;
}
- void defer();
+ void defer(const OpenGLRenderer& rootRenderer);
void cancelDefer();
void flush();
- void render();
+ void render(const OpenGLRenderer& rootRenderer);
/**
* Bounds of the layer.
@@ -304,6 +309,7 @@
private:
void requireRenderer();
+ void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
Caches& caches;
@@ -383,6 +389,12 @@
mat4 transform;
/**
+ * Cached transform of layer in window, updated only on creation / resize
+ */
+ mat4 cachedInvTransformInWindow;
+ bool rendererLightPosDirty;
+
+ /**
* Used to defer display lists when the layer is updated with a
* display list.
*/
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3fcfbc1..721ab3d 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -188,8 +188,7 @@
void OpenGLRenderer::setupFrameState(float left, float top,
float right, float bottom, bool opaque) {
mCaches.clearGarbage();
-
- initializeSaveStack(left, top, right, bottom);
+ initializeSaveStack(left, top, right, bottom, mLightCenter);
mOpaque = opaque;
mTilingClip.set(left, top, right, bottom);
}
@@ -481,9 +480,9 @@
}
if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
- layer->render();
+ layer->render(*this);
} else {
- layer->defer();
+ layer->defer(*this);
}
if (inFrame) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index fc95c18..e9ca5d9 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -345,8 +345,10 @@
}
#endif
- const Vector3& getLightCenter() const { return mLightCenter; }
+ const Vector3& getLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
float getLightRadius() const { return mLightRadius; }
+ uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
+ uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
protected:
/**
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index e3732a1..0db6198 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -116,6 +116,7 @@
void RenderNode::prepareTree(TreeInfo& info) {
ATRACE_CALL();
+ LOG_ALWAYS_FATAL_IF(!info.damageAccumulator, "DamageAccumulator missing");
prepareTreeImpl(info);
}
@@ -163,16 +164,26 @@
return;
}
+ bool transformUpdateNeeded = false;
if (!mLayer) {
mLayer = LayerRenderer::createRenderLayer(info.renderState, getWidth(), getHeight());
applyLayerPropertiesToLayer(info);
damageSelf(info);
+ transformUpdateNeeded = true;
} else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) {
if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) {
LayerRenderer::destroyLayer(mLayer);
mLayer = 0;
}
damageSelf(info);
+ transformUpdateNeeded = true;
+ }
+
+ if (transformUpdateNeeded) {
+ // update the transform in window of the layer to reset its origin wrt light source position
+ Matrix4 windowTransform;
+ info.damageAccumulator->computeCurrentTransform(&windowTransform);
+ mLayer->setWindowTransform(windowTransform);
}
SkRect dirty;
@@ -406,7 +417,7 @@
* If true3dTransform is set to true, the transform applied to the input matrix will use true 4x4
* matrix computation instead of the Skia 3x3 matrix + camera hackery.
*/
-void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) {
+void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) const {
if (properties().getLeft() != 0 || properties().getTop() != 0) {
matrix.translate(properties().getLeft(), properties().getTop());
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index fa310e0..afa17d5 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -174,6 +174,8 @@
// UI thread only!
ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+ void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const;
+
private:
typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair;
@@ -189,8 +191,6 @@
kPositiveZChildren
};
- void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false);
-
void computeOrderingImpl(DrawRenderNodeOp* opState,
const SkPath* outlineOfProjectionSurface,
Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface,
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 6f19275..ecc47d2 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -55,7 +55,8 @@
, empty(false)
, alpha(s->alpha)
, roundRectClipState(s->roundRectClipState)
- , mViewportData(s->mViewportData) {
+ , mViewportData(s->mViewportData)
+ , mRelativeLightCenter(s->mRelativeLightCenter) {
if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
mTransformRoot.load(*s->transform);
transform = &mTransformRoot;
@@ -200,6 +201,13 @@
///////////////////////////////////////////////////////////////////////////////
void Snapshot::resetTransform(float x, float y, float z) {
+ // before resetting, map current light pos with inverse of current transform
+ Vector3 center = mRelativeLightCenter;
+ mat4 inverse;
+ inverse.loadInverse(*transform);
+ inverse.mapPoint3d(center);
+ mRelativeLightCenter = center;
+
transform = &mTransformRoot;
transform->loadTranslate(x, y, z);
}
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 98e2440..ad4ee9d 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -161,6 +161,9 @@
int getViewportHeight() const { return mViewportData.mHeight; }
const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; }
+ const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; }
+ void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; }
+
/**
* Sets (and replaces) the current clipping outline
*/
@@ -302,6 +305,7 @@
SkRegion mClipRegionRoot;
ViewportData mViewportData;
+ Vector3 mRelativeLightCenter;
}; // class Snapshot
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp
index dc41157..06c5ab4 100644
--- a/libs/hwui/StatefulBaseRenderer.cpp
+++ b/libs/hwui/StatefulBaseRenderer.cpp
@@ -35,11 +35,12 @@
}
void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop,
- float clipRight, float clipBottom) {
+ float clipRight, float clipBottom, const Vector3& lightCenter) {
mSnapshot = new Snapshot(mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
mSnapshot->fbo = getTargetFbo();
+ mSnapshot->setRelativeLightCenter(lightCenter);
mSaveCount = 1;
}
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
index 6d83b4c..3957d36 100644
--- a/libs/hwui/StatefulBaseRenderer.h
+++ b/libs/hwui/StatefulBaseRenderer.h
@@ -52,7 +52,8 @@
* the render target.
*/
virtual void setViewport(int width, int height);
- void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom);
+ void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom,
+ const Vector3& lightCenter);
// getters
bool hasRectToRectTransform() const {
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index c5fc21f..0a9aeb8 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "OpenGLRenderer"
-#define ATRACE_TAG ATRACE_TAG_VIEW
-
#include <utils/JenkinsHash.h>
#include <utils/Trace.h>
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index de09755..331f157 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -65,7 +65,7 @@
, frameTimeMs(0)
, animationHook(NULL)
, prepareTextures(mode == MODE_FULL)
- , damageAccumulator(NullDamageAccumulator::instance())
+ , damageAccumulator(NULL)
, renderState(renderState)
, renderer(NULL)
, errorHandler(NULL)
@@ -88,8 +88,9 @@
// TODO: Remove this? Currently this is used to signal to stop preparing
// textures if we run out of cache space.
bool prepareTextures;
- // Must not be null
- IDamageAccumulator* damageAccumulator;
+
+ // Must not be null during actual usage
+ DamageAccumulator* damageAccumulator;
RenderState& renderState;
// The renderer that will be drawing the next frame. Use this to push any
// layer updates or similar. May be NULL.
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 756f660..e673b0d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "CanvasContext"
-
#include "CanvasContext.h"
#include <private/hwui/DrawGlInfo.h>
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 986e808..d9b96f6c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "RenderProxy"
-
#include "RenderProxy.h"
#include "CanvasContext.h"
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 03e98d5..403e164 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#define LOG_TAG "RenderThread"
-
#include "RenderThread.h"
+#if defined(HAVE_PTHREADS)
+#include <sys/resource.h>
+#endif
#include <gui/DisplayEventReceiver.h>
#include <utils/Log.h>
@@ -244,6 +245,9 @@
}
bool RenderThread::threadLoop() {
+#if defined(HAVE_PTHREADS)
+ setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
+#endif
initThreadLocals();
int timeoutMillis = -1;
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 3d2b0d9..cb5401c 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -15,6 +15,9 @@
*/
#include <sys/sysinfo.h>
+#if defined(HAVE_PTHREADS)
+#include <sys/resource.h>
+#endif
#include "TaskManager.h"
#include "Task.h"
@@ -79,6 +82,13 @@
// Thread
///////////////////////////////////////////////////////////////////////////////
+status_t TaskManager::WorkerThread::readyToRun() {
+#if defined(HAVE_PTHREADS)
+ setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
+#endif
+ return NO_ERROR;
+}
+
bool TaskManager::WorkerThread::threadLoop() {
mSignal.wait();
Vector<TaskWrapper> tasks;
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
index f2a216f..5a933ab 100644
--- a/libs/hwui/thread/TaskManager.h
+++ b/libs/hwui/thread/TaskManager.h
@@ -84,6 +84,7 @@
void exit();
private:
+ virtual status_t readyToRun();
virtual bool threadLoop();
// Lock for the list of tasks
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index b8ac3e7..3e2a398 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -25,9 +25,12 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.os.AsyncTask;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.phone.PhoneManager;
import android.provider.MediaStore;
+import android.telecomm.TelecommManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
@@ -246,7 +249,18 @@
}
public void launchPhone() {
- mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */);
+ TelecommManager tm = TelecommManager.from(mContext);
+ if (tm.isInAPhoneCall()) {
+ final PhoneManager pm = (PhoneManager) mContext.getSystemService(Context.PHONE_SERVICE);
+ AsyncTask.execute(new Runnable() {
+ @Override
+ public void run() {
+ pm.showCallScreen(false /* showDialpad */);
+ }
+ });
+ } else {
+ mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */);
+ }
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 3fcd067..b2575e6 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -252,6 +252,15 @@
return false;
}
+ void removeAllWindows() {
+ for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
+ WindowState win = allAppWindows.get(winNdx);
+ if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) Slog.w(WindowManagerService.TAG,
+ "removeAllWindows: removing win=" + win);
+ win.mService.removeWindowLocked(win.mSession, win);
+ }
+ }
+
@Override
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index dfb1200..238c77e 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -155,7 +155,7 @@
final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
- if (winAnimator.isAnimating() && !winAnimator.isDummyAnimation()) {
+ if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) {
return true;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 711cf9c..2295656 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3592,7 +3592,7 @@
return;
}
final Task oldTask = mTaskIdToTask.get(atoken.groupId);
- removeAppFromTaskLocked(atoken);
+ oldTask.removeAppToken(atoken);
atoken.groupId = groupId;
Task newTask = mTaskIdToTask.get(groupId);
@@ -4634,6 +4634,8 @@
}
void removeAppFromTaskLocked(AppWindowToken wtoken) {
+ wtoken.removeAllWindows();
+
final Task task = mTaskIdToTask.get(wtoken.groupId);
if (task != null) {
if (!task.removeAppToken(wtoken)) {
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index d5e4f1b..44aacfc 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -539,7 +539,10 @@
connection.getCallerDisplayNamePresentation(),
connection.getVideoProvider() == null ?
null : connection.getVideoProvider().getInterface(),
- connection.getVideoState()));
+ connection.getVideoState(),
+ connection.isRequestingRingback(),
+ connection.getAudioModeIsVoip(),
+ connection.getStatusHints()));
}
private void abort(String callId) {
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index 78dd64a..7a87b87 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -38,6 +38,9 @@
private int mCallerDisplayNamePresentation;
private IVideoProvider mVideoProvider;
private int mVideoState;
+ private boolean mRequestingRingback;
+ private boolean mAudioModeIsVoip;
+ private StatusHints mStatusHints;
/** @hide */
public ParcelableConnection(
@@ -49,7 +52,10 @@
String callerDisplayName,
int callerDisplayNamePresentation,
IVideoProvider videoProvider,
- int videoState) {
+ int videoState,
+ boolean requestingRingback,
+ boolean audioModeIsVoip,
+ StatusHints statusHints) {
mPhoneAccount = phoneAccount;
mState = state;
mCapabilities = capabilities;
@@ -59,6 +65,9 @@
mCallerDisplayNamePresentation = callerDisplayNamePresentation;
mVideoProvider = videoProvider;
mVideoState = videoState;
+ mRequestingRingback = requestingRingback;
+ mAudioModeIsVoip = audioModeIsVoip;
+ mStatusHints = statusHints;
}
public PhoneAccountHandle getPhoneAccount() {
@@ -98,6 +107,18 @@
return mVideoState;
}
+ public boolean isRequestingRingback() {
+ return mRequestingRingback;
+ }
+
+ public boolean getAudioModeIsVoip() {
+ return mAudioModeIsVoip;
+ }
+
+ public final StatusHints getStatusHints() {
+ return mStatusHints;
+ }
+
@Override
public String toString() {
return new StringBuilder()
@@ -126,6 +147,9 @@
IVideoProvider videoCallProvider =
IVideoProvider.Stub.asInterface(source.readStrongBinder());
int videoState = source.readInt();
+ boolean requestingRingback = source.readByte() == 1;
+ boolean audioModeIsVoip = source.readByte() == 1;
+ StatusHints statusHints = source.readParcelable(classLoader);
return new ParcelableConnection(
phoneAccount,
@@ -136,7 +160,10 @@
callerDisplayName,
callerDisplayNamePresentation,
videoCallProvider,
- videoState);
+ videoState,
+ requestingRingback,
+ audioModeIsVoip,
+ statusHints);
}
@Override
@@ -164,5 +191,8 @@
destination.writeStrongBinder(
mVideoProvider != null ? mVideoProvider.asBinder() : null);
destination.writeInt(mVideoState);
+ destination.writeByte((byte) (mRequestingRingback ? 1 : 0));
+ destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0));
+ destination.writeParcelable(mStatusHints, 0);
}
}
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
index 13b0834..d3972d31 100644
--- a/telecomm/java/android/telecomm/RemoteConnection.java
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -24,9 +24,11 @@
import android.telephony.DisconnectCause;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* A connection provided to a {@link ConnectionService} by another {@code ConnectionService}
@@ -182,7 +184,8 @@
private IConnectionService mConnectionService;
private final String mConnectionId;
- private final Set<Listener> mListeners = new HashSet<>();
+ private final Set<Listener> mListeners = Collections.newSetFromMap(
+ new ConcurrentHashMap<Listener, Boolean>(2));
private final Set<RemoteConnection> mConferenceableConnections = new HashSet<>();
private int mState = Connection.STATE_NEW;
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index cf3dd0a..137c85c 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -485,9 +485,13 @@
find_max_opacity(image->rows, innerStartX, innerStartY, innerMidX, innerMidY, 1, 1,
&diagonalInset);
- // Determine source radius based upon inset
- // radius = 1 / (sqrt(2) - 1) * inset
- image->outlineRadius = 2.4142f * diagonalInset;
+ /* Determine source radius based upon inset:
+ * sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r
+ * sqrt(2) * r = sqrt(2) * i + r
+ * (sqrt(2) - 1) * r = sqrt(2) * i
+ * r = sqrt(2) / (sqrt(2) - 1) * i
+ */
+ image->outlineRadius = 3.4142f * diagonalInset;
NOISY(printf("outline insets %d %d %d %d, rad %f, alpha %x\n",
image->outlineInsetsLeft,